home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / WHATFN.ZIP / WHATFUNC.C < prev    next >
C/C++ Source or Header  |  1989-01-22  |  14KB  |  431 lines

  1. /* whatfunc.c */
  2. /* based on previous code in ENUMDLL.C, ENUMPROC.C, and GDT.C */
  3. /* Andrew Schulman 14-Jan-1989 */
  4.  
  5. /*
  6. example:
  7. C>whatfunc 0f6b 0357:0937 01b7:0fc2 0637:0614 817:1098
  8. 0F6B:0000   DOSGETVERSION
  9. 0357:0937   MOUSETSCALEFACT
  10. 01B7:0FC2   VIOSETSTATE
  11. 0637:0614   KBDSETCP
  12. 0817:1098   _printf
  13. */
  14.  
  15. /*
  16. if no args, print help
  17. else, for each arg, print arg and its ASCIIZ name
  18.  
  19. to get ASCIIZ name:
  20. see if in DOSCALLS (ASCIIZ names hard-wired)
  21. else, see if in VIOCALLS, KBDCALLS, MOUCALLS (ASCIIZ names from ENUMPROC)
  22.  
  23. if all else fails:
  24. see what DLL's in memory (ENUMDLL loop)
  25. for each one, call search_dll
  26.  
  27. to do:
  28. 1 -- since search_dll is slow, should be using threads.  Either one thread
  29.      per command-line arg, or one thread per module to search
  30. 2 -- should be "TSR" monitor.  But then tables should be built and kept
  31.      so that searches get faster
  32. */
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38. #define INCL_DOS
  39. #define INCL_DOSDEVICES
  40. #define INCL_DOSSIGNALS
  41. #include "os2.h"
  42.  
  43. typedef unsigned USHORT;
  44. typedef unsigned long ULONG;
  45. typedef void far *FP;
  46.  
  47. #pragma pack(1)
  48.  
  49. typedef struct {
  50.     char *name;
  51.     ULONG procaddr;     /* USHORT (far pascal *procaddr)(); */
  52.     } DOSCALLS;
  53.     
  54. #define REG /*register*/    /*compiler does a better job*/
  55. #define MK_FP(seg,off)  ((FP)(((ULONG)(seg) << 16) | (off)))
  56. #define FAILBUFSIZE 128
  57.  
  58. char failbuffer[FAILBUFSIZE];
  59. USHORT doscalls;
  60. BOOL verbose = FALSE;
  61.  
  62. extern char *enumproc(char *dll, char *buf, USHORT *ord);
  63. char *search_doscalls(FP fp);
  64. char *search_dll(char *dll, FP fp);
  65. char *enumdll(USHORT iter, FP fp);
  66. USHORT htoi(char *s);
  67. void init_doscalls(void);
  68.  
  69. main(int argc, char *argv[])
  70. {
  71.     REG int i;
  72.     
  73.     if (argc < 2)
  74.     {
  75.         printf("WHATFUNC(func) --> ASCIIZ name for func\n");
  76.         printf("syntax: %s XXXX:XXXX\n", argv[0]);
  77.         printf("within CVP: ! %s XXXX:XXXX\n", argv[0]);
  78.         exit(1);
  79.     }
  80.  
  81.     DosLoadModule(failbuffer, FAILBUFSIZE, "DOSCALLS", &doscalls);
  82.     
  83.     init_doscalls();
  84.  
  85.     /* perhapse use separate thread for each command-line argument */
  86.     for (i=1; i<argc; i++)
  87.     {
  88.         FP fp;
  89.         char *s;
  90.         USHORT seg, off;
  91.         if (argv[i][0] == '-' && (argv[i][1] == 'v' || argv[i][1] == 'V'))
  92.         {
  93.             verbose = TRUE;
  94.             continue;
  95.         }
  96.         seg = htoi(strtok(argv[i], ":"));
  97.         off = htoi(strtok(0, ":"));
  98.         fp = MK_FP(seg,off);
  99.         if (s = search_doscalls(fp))
  100.         {
  101.             if (*s == '*')
  102.                 printf("%04X:%04X\t%s\n", seg,off, s+1);
  103.             else
  104.                 printf("%04X:%04X\tDOS%s\n", seg, off, s);
  105.         }
  106.         else
  107.         {
  108.             char *s = search_dll("VIOCALLS", fp);
  109.             if (! s) s = search_dll("KBDCALLS", fp);
  110.             if (! s) s = search_dll("MOUCALLS", fp);
  111.             if (! s) s = search_dll("DOSCALL1", fp);
  112.             if (! s) s = enumdll(4000, fp);
  113.             if (! s) s = "????";
  114.             printf("%04X:%04X\t%s\n", seg, off, s);
  115.         }
  116.     }
  117.     
  118.     return 0;
  119. }
  120.  
  121. USHORT htoi(char *s)
  122. {
  123.     USHORT i = 0, t;
  124.     
  125.     while (*s == ' ' || *s == '\t')
  126.         s++;
  127.     while (1)
  128.     {
  129.         char c = *s;
  130.         if      (c >= '0' && c <= '9') t = 48;
  131.         else if (c >= 'A' && c <= 'F') t = 55;
  132.         else if (c >= 'a' && c <= 'f') t = 87;
  133.         else break;
  134.         i = (i << 4) + (c - t);
  135.         s++;
  136.     }
  137.     return i;
  138. }
  139.  
  140. /**********************************************************************/
  141. #define NUM_DOSCALLS    111
  142.     
  143. extern USHORT far pascal DOSPTRACE();
  144. extern USHORT far pascal DOSSGSWITCH();
  145. extern USHORT far pascal DOSSGSWITCHME();
  146. extern USHORT far pascal DOSSYSTRACE();
  147.  
  148. static DOSCALLS dosfuncs[NUM_DOSCALLS] = {
  149.     "ALLOCHUGE",        (ULONG) DosAllocHuge,
  150.     "ALLOCSEG",         (ULONG) DosAllocSeg,
  151.     "ALLOCSHRSEG",      (ULONG) DosAllocShrSeg,
  152.     "BEEP",             (ULONG) DosBeep,
  153.     "BUFRESET",         (ULONG) DosBufReset,
  154.     "CHDIR",            (ULONG) DosChdir,
  155.     "CHGFILEPTR",       (ULONG) DosChgFilePtr,
  156.     "CLIACCESS",        (ULONG) DosCLIAccess,
  157.     "CLOSE",            (ULONG) DosClose,
  158.     "CLOSESEM",         (ULONG) DosCloseSem,
  159.     "CREATECSALIAS",    (ULONG) DosCreateCSAlias,
  160.     "CREATESEM",        (ULONG) DosCreateSem,
  161.     "CREATETHREAD",     (ULONG) DosCreateThread,
  162.     "CWAIT",            (ULONG) DosCWait,
  163.     "DELETE",           (ULONG) DosDelete,
  164.     "DEVCONFIG",        (ULONG) DosDevConfig,
  165.     "DEVIOCTL",         (ULONG) DosDevIOCtl,
  166.     "DUPHANDLE",        (ULONG) DosDupHandle,
  167.     "ENTERCRITSEC",     (ULONG) DosEnterCritSec,
  168.     "ERRCLASS",         (ULONG) DosErrClass,
  169.     "ERROR",            (ULONG) DosError,
  170.     "EXECPGM",          (ULONG) DosExecPgm,
  171.     "EXIT",             (ULONG) DosExit,
  172.     "EXITCRITSEC",      (ULONG) DosExitCritSec,
  173.     "EXITLIST",         (ULONG) DosExitList,
  174.     "FILELOCKS",        (ULONG) DosFileLocks,
  175.     "FINDCLOSE",        (ULONG) DosFindClose,
  176.     "FINDFIRST",        (ULONG) DosFindFirst,
  177.     "FINDNEXT",         (ULONG) DosFindNext,
  178.     "FLAGPROCESS",      (ULONG) DosFlagProcess,
  179.     "FREEMODULE",       (ULONG) DosFreeModule,
  180.     "FREESEG",          (ULONG) DosFreeSeg,
  181.     "GETCP",            (ULONG) DosGetCp,
  182.     "GETDATETIME",      (ULONG) DosGetDateTime,
  183.     "GETENV",           (ULONG) DosGetEnv,
  184.     "GETHUGESHIFT",     (ULONG) DosGetHugeShift,
  185.     "GETINFOSEG",       (ULONG) DosGetInfoSeg,
  186.     "GETMACHINEMODE",   (ULONG) DosGetMachineMode,
  187.     "GETMODHANDLE",     (ULONG) DosGetModHandle,
  188.     "GETMODNAME",       (ULONG) DosGetModName,
  189.     "GETPID",           (ULONG) DosGetPid,
  190.     "GETPROCADDR",      (ULONG) DosGetProcAddr,
  191.     "GETPRTY",          (ULONG) DosGetPrty,
  192.     "GETSEG",           (ULONG) DosGetSeg,
  193.     "GETSHRSEG",        (ULONG) DosGetShrSeg,
  194.     "GETVERSION",       (ULONG) DosGetVersion,
  195.     "GIVESEG",          (ULONG) DosGiveSeg,
  196.     "HOLDSIGNAL",       (ULONG) DosHoldSignal,
  197.     "KILLPROCESS",      (ULONG) DosKillProcess,
  198.     "LOADMODULE",       (ULONG) DosLoadModule,
  199.     "LOCKSEG",          (ULONG) DosLockSeg,
  200.     "MAKEPIPE",         (ULONG) DosMakePipe,
  201.     "MEMAVAIL",         (ULONG) DosMemAvail,
  202.     "MKDIR",            (ULONG) DosMkdir,
  203.     "MOVE",             (ULONG) DosMove,
  204.     "MUXSEMWAIT",       (ULONG) DosMuxSemWait,
  205.     "NEWSIZE",          (ULONG) DosNewSize,
  206.     "OPEN",             (ULONG) DosOpen,
  207.     "OPENSEM",          (ULONG) DosOpenSem,
  208.     "PHYSICALDISK",     (ULONG) DosPhysicalDisk,
  209.     "PORTACCESS",       (ULONG) DosPortAccess,
  210.     "PTRACE",           (ULONG) DOSPTRACE,
  211.     "QCURDIR",          (ULONG) DosQCurDir,
  212.     "QCURDISK",         (ULONG) DosQCurDisk,
  213.     "QFHANDSTATE",      (ULONG) DosQFHandState,
  214.     "QFILEINFO",        (ULONG) DosQFileInfo,
  215.     "QFILEMODE",        (ULONG) DosQFileMode,
  216.     "QFSINFO",          (ULONG) DosQFSInfo,
  217.     "QHANDTYPE",        (ULONG) DosQHandType,
  218.     "QVERIFY",          (ULONG) DosQVerify,
  219.     "READ",             (ULONG) DosRead,
  220.     "READASYNC",        (ULONG) DosReadAsync,
  221.     "REALLOCHUGE",      (ULONG) DosReallocHuge,
  222.     "REALLOCSEG",       (ULONG) DosReallocSeg,
  223.     "RESUMETHREAD",     (ULONG) DosResumeThread,
  224.     "RMDIR",            (ULONG) DosRmdir,
  225.     "SCANENV",          (ULONG) DosScanEnv,
  226.     "SEARCHPATH",       (ULONG) DosSearchPath,
  227.     "SELECTDISK",       (ULONG) DosSelectDisk,
  228.     "SEMCLEAR",         (ULONG) DosSemClear,
  229.     "SEMREQUEST",       (ULONG) DosSemRequest,
  230.     "SEMSET",           (ULONG) DosSemSet,
  231.     "SEMSETWAIT",       (ULONG) DosSemSetWait,
  232.     "SEMWAIT",          (ULONG) DosSemWait,
  233.     "SENDSIGNAL",       (ULONG) DosSendSignal,
  234.     "SETCP",            (ULONG) DosSetCp,
  235.     "SETDATETIME",      (ULONG) DosSetDateTime,
  236.     "SETFHANDSTATE",    (ULONG) DosSetFHandState,
  237.     "SETFILEINFO",      (ULONG) DosSetFileInfo,
  238.     "SETFILEMODE",      (ULONG) DosSetFileMode,
  239.     "SETFSINFO",        (ULONG) DosSetFSInfo,
  240.     "SETMAXFH",         (ULONG) DosSetMaxFH,
  241.     "SETPRTY",          (ULONG) DosSetPrty,
  242.     "SETSIGHANDLER",    (ULONG) DosSetSigHandler,
  243.     "SETVEC",           (ULONG) DosSetVec,
  244.     "SETVERIFY",        (ULONG) DosSetVerify,
  245.     "SGSWITCH",         (ULONG) DOSSGSWITCH,
  246.     "SGSWITCHME",       (ULONG) DOSSGSWITCHME,
  247.     "SLEEP",            (ULONG) DosSleep,
  248.     "SUBALLOC",         (ULONG) DosSubAlloc,
  249.     "SUBFREE",          (ULONG) DosSubFree,
  250.     "SUBSET",           (ULONG) DosSubSet,
  251.     "SUSPENDTHREAD",    (ULONG) DosSuspendThread,
  252.     "SYSTEMSERVICE",    (ULONG) DosSystemService,
  253.     "SYSTRACE",         (ULONG) DOSSYSTRACE,
  254.     "TIMERASYNC",       (ULONG) DosTimerAsync,
  255.     "TIMERSTART",       (ULONG) DosTimerStart,
  256.     "TIMERSTOP",        (ULONG) DosTimerStop,
  257.     "UNLOCKSEG",        (ULONG) DosUnlockSeg,
  258.     "WRITE",            (ULONG) DosWrite,
  259.     "WRITEASYNC",       (ULONG) DosWriteAsync,
  260.     } ;
  261.  
  262. #define NUM_NEWCALLS    51
  263.  
  264. /* table stores ordinal numbers, until replaced by procaddr */
  265. static DOSCALLS newcalls[NUM_NEWCALLS] = {
  266.     "CALLBACK",           157L,
  267.     "FSRAMSEMCLEAR",      162L,
  268.     "FSRAMSEMREQUEST",    161L,
  269.     "GETSTDA",            119L,  /* 3 wds */
  270.     "GLOBALSEG",          132L,
  271.     "HUGEINCR",           136L,
  272.     "HUGESHIFT",          135L,
  273.     "ICANONICALIZE",      100L,      /* 7 wds */
  274.     "ICREATETHREAD",      1L,        /* 4 wds */
  275.     "IEXECPGM",           4L,        /* 12 wds */
  276.     "IRAMSEMWAKE",        125L,  /* 3 wds */
  277.     "IREAD",              79L,       /* 6 wds */
  278.     "ISEMREQUEST",        18L,   /* 4 wds */
  279.     "ISEMWAIT",           21L,       /* 4 wds */
  280.     "ISETCP",             131L,  /* 2 wds */
  281.     "ISYSSEMCLEAR",       17L,       /* 2 wds */
  282.     "ISYSSEMSET",         19L,   /* 2 wds */
  283.     "IWRITE",             87L,   /* 6 wds */
  284.     "LIBINIT",            96L,     /* 2 wds */
  285.     "PROFILE",            133L,  /* 9 wds */
  286.     "QAPPTYPE",           163L,
  287.     "QPROCSTATUS",        184L,
  288.     "QSYSINFO",           166L,    /* 4 wds */
  289.     "QTRACEINFO",         93L,
  290.     "R2STACKREALLOC",     160L,    /* 1 wds */
  291.     "READPHYS",           103L,
  292.     "SETFGND",            101L,  /* 2 wds */
  293.     "SETPROCCP",          155L,      /* 5 wds */
  294.     "SGSWITCHPROC",       124L,
  295.     "SIZESEG",            126L,    /* 3 wds */
  296.     "SWAPTASKINIT",       102L,
  297.  
  298.     /* names that don't have DOS in front of them */
  299.     "*GETADDR",    111L,
  300.     "*GETHEADERS", 108L,
  301.     "*GETSELADDR", 110L,
  302.     "*STRUCHECK", 106L,
  303.     "*STRURESUPDATE", 107L,
  304.     "*UNUSEDA",    98L,
  305.     "*UNUSEDB",    99L,
  306.     "*UNUSEDC",    126L,
  307.     "*UNUSEDD",    128L,
  308.     "*UNUSEDE",    104L,
  309.     "*UNUSEDF",    105L,
  310.     "*UNUSEDG",    95L,
  311.     "*DBGETKVAR", 109L,
  312.     "*DBGETOWNER", 117L,
  313.     "*DBMEMFREE", 116L,
  314.     "*DBMEMLOCK", 112L,
  315.     "*DBMEMREALLOC", 15L,
  316.     "*DBMEMUNLOCK", 113L,
  317.     "*DBPHYSINFO", 118L,
  318.     "*DBSEGALLOC", 114L,
  319.     } ;
  320.  
  321. void init_doscalls(void)
  322. {
  323.     /* try to install new functions */
  324.     ULONG procaddr;
  325.     REG DOSCALLS *p;
  326.     REG USHORT i;
  327.     
  328.     /* before loop, newcalls[i].procaddr contains DOSCALLS.ord# */
  329.     for (i=0, p=newcalls; i<NUM_NEWCALLS; i++, p++)
  330.         p->procaddr = (DosGetProcAddr(doscalls, p->procaddr, &procaddr)) ?
  331.             0L : procaddr;
  332. }
  333.  
  334. char *search_doscalls(FP fp)
  335. {
  336.     REG DOSCALLS *p;
  337.     REG USHORT i;
  338.  
  339.     for (i=0, p=dosfuncs; i<NUM_DOSCALLS; i++, p++)
  340.     {
  341.         if (fp == p->procaddr)
  342.             return p->name;
  343.         else if (verbose)
  344.             printf("DOSCALLS.DOS%s\t%Fp\n", p->name, p->procaddr);
  345.     }
  346.     /*still here*/
  347.     for (i=0, p=newcalls; i<NUM_NEWCALLS; i++, p++)
  348.     {
  349.         if (fp == p->procaddr)
  350.             return p->name;
  351.         else if (verbose && p->procaddr)
  352.         {
  353.             if (* p->name == '*')
  354.                 printf("DOSCALLS.%s\t%Fp\n", p->name + 1, p->procaddr);
  355.             else
  356.                 printf("DOSCALLS.DOS%s\t%Fp\n", p->name, p->procaddr);
  357.         }
  358.     }
  359.     /*still here*/
  360.     return (char *) 0;
  361. }
  362.  
  363. char *search_dll(char *dll, FP fp)
  364. {
  365.     char buf[128], *funcname=buf;
  366.     char *dllname;
  367.     char *ret = (char *) 0;
  368.     FP procaddr;
  369.     USHORT ord;
  370.     USHORT mod;
  371.  
  372.     /* possibly turn full pathname into module name, for DosLoadModule */
  373.     if (strchr(dll, '\\') && strchr(dll, '.'))
  374.     {
  375.         char buf[128], *p;
  376.         if (! strstr(dll, ".DLL"))  /* DosQAppType is unreliable */
  377.             return (char *) 0;
  378.         strcpy(buf, dll);
  379.         if (p = strchr(buf, '.'))
  380.             *p = '\0';
  381.         if (p = strrchr(buf, '\\'))
  382.             p++;
  383.         if (strstr("VIOCALLS KBDCALLS MOUCALLS DOSCALL1", p))
  384.             return (char *) 0;
  385.         dllname = p;
  386.     }
  387.     else dllname = dll;
  388.  
  389.     /* to get module handle */
  390.     if (DosLoadModule(failbuffer, FAILBUFSIZE, dllname, &mod))
  391.         return (char *) 0;
  392.     
  393.     /* get full pathname of DLL */
  394.     if (DosGetModName(mod, 128, buf))
  395.         return (char *) 0;
  396.     
  397.     if (enumproc(buf, funcname, &ord))
  398.         while (enumproc(0, funcname, &ord))
  399.             if (! DosGetProcAddr(mod, funcname, &procaddr))
  400.             {
  401.                 if (procaddr == fp)
  402.                 {
  403.                     ret = funcname;
  404.                     break;
  405.                 }
  406.                 else if (verbose)
  407.                     printf("%s.%s\t%Fp\n", dllname, funcname, procaddr);
  408.             }
  409.     
  410.     DosFreeModule(mod);
  411.     return ret;
  412. }
  413.  
  414. /* see if it's in any other currently loaded DLL */
  415. char *enumdll(USHORT iter, FP fp)
  416. {
  417.     char buf[128];
  418.     char *ret = (char *) 0;
  419.     REG USHORT i;
  420.     
  421.     for (i=0; i<iter; i++)
  422.         if (! DosGetModName(i, 128, buf))
  423.         {
  424.             if (verbose)
  425.                 printf("%u\t%s\n", i, buf);
  426.             if (ret = search_dll(buf, fp))
  427.                 break;
  428.         }
  429.     return ret;
  430. }
  431.