home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------*/
- /* 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;
- }
-