home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
batch
/
library
/
errlvl12
/
findelvl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-12
|
4KB
|
88 lines
/*-------------------------------------------------------------------------*/
/* Program: FindElvl.C */
/* Purpose: Aids in finding the location of ERRORLEVEL within */
/* COMMAND.COM's PSP. */
/* Notes: Compiles with TURBO C++, v1.0; use "tcc -mt -lt findelvl". */
/* Should work on any machine running MS-DOS, v2.xx or */
/* higher. */
/* What this program does is scan thru the PSP owned by */
/* COMMAND.COM for a value -- the *known* return code from */
/* the previous program -- specified by the user. Offsets */
/* with matches are printed. You'll need to iterate at */
/* least twice to cull out spurious matches. In practice, */
/* I've noticed 145, 147, 148, 155, 159, and 167 provide */
/* good guesses; ie, few matches. */
/* You should disregard output from the first run unless you */
/* know exactly what the value of ERRORLEVEL already is. */
/* If you have a copy of UNIQ, the following commandline */
/* should do the trick: "findelvl | findelvl 145 147 | */
/* findelvl 147 148 | sort | uniq -d". */
/* Status: Released into the public domain. Enjoy! If you use it, */
/* let me know what you think. You don't have to send */
/* any money, just comments and suggestions. */
/* Updates: 28-Dec-90, GAT */
/* - initial version. */
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/* Author: George A. Theall */
/* Phone: +1 215 662 0558 */
/* SnailMail: TifaWARE */
/* 506 South 41st St., #3M */
/* Philadelphia, PA. 19104 USA */
/* E-Mail: theall@gdalsrv.sas.upenn.edu (Internet) */
/*-------------------------------------------------------------------------*/
#include <stdio.h>
#include <dos.h> /* for MK_FP(), _psp, etc... */
#include <stdlib.h> /* for exit() */
int main(int argc, char *argv[])
{
char ch;
unsigned char oldrc, /* value to scan for */
newrc; /* return code to use */
unsigned int aPSP, tempPSP; /* values for PSPs */
unsigned int ofs; /* offset with a segment */
/* Parse arguments and provide syntax if necessary. */
if (argc != 3) {
puts("usage: findelvl oldrc newrc\nnow exiting with rc=145");
return 145;
}
oldrc = atoi(argv[1]);
newrc = atoi(argv[2]);
/* Find PSP for COMMAND.COM. */
aPSP = _psp;
do {
tempPSP = aPSP;
aPSP = *((unsigned int far *) MK_FP(aPSP, 0x16));
} while (aPSP < tempPSP);
if (aPSP > tempPSP) {
puts("findelvl: can't locate PSP for COMMAND.COM");
return 255;
}
/*
* Pass anything in stdin straight thru. This lets the user combine
* output from earlier runs with uniq to quickly identify duplicates.
*/
if (isatty(fileno(stdin)) == 0)
while ((ch = getchar()) != EOF)
putchar(ch);
/* Scan through segment reporting matches. */
printf("DOS v%u.%u; PSP at segment: %#06x\n", _osmajor, _osminor, aPSP);
printf("Matches for rc=%u at offsets:\n", oldrc);
for (ofs = 0; ofs < 0xffff; ++ofs)
if (oldrc == *(unsigned char far *) (MK_FP(aPSP, ofs)))
printf(" %#06x\n", ofs);
if (oldrc == *(unsigned char far *) (MK_FP(aPSP, ofs))) /* segment end */
printf(" %#06x\n", ofs);
return newrc;
}