home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dosqproc.zip / proc2.c < prev    next >
C/C++ Source or Header  |  1996-12-08  |  11KB  |  437 lines

  1. /* PROC2.C
  2.  *
  3.  * Sample program using the DosQPocStatus() function
  4.  * for OS/2 2.x
  5.  *
  6.  * Kai Uwe Rommel - Wed 25-Mar-1992
  7.  *                  Sat 13-Aug-1994
  8.  *
  9.  * can be compiled with
  10.  * - 16-bit compiler in small and large data models (MS C 6.00A tested)
  11.  * - 32-bit compiler (IBM C Set++, IBM VisualAge C++ tested)
  12.  * - emx+gcc (changes from Ewen McNeill)
  13.  *
  14.  * To compile with emx+gcc, an extra step is necessary, the creation
  15.  * of an import library for the undocumented functions. You cannot use 
  16.  * the proc2.def file with emx in this case. Examples:
  17.  *
  18.  *   emximp -o proc2.a proc2.imp
  19.  *   gcc -O -s -o proc2.exe proc2.c proc2.a
  20.  *
  21.  *   emximp -o proc2.lib proc2.imp
  22.  *   gcc -Zomf -O -s -o proc2.exe proc2.c proc2.lib
  23.  */
  24.  
  25. #define INCL_NOPM
  26. #define INCL_DOSPROCESS
  27. #define INCL_DOSMODULEMGR
  28. #define INCL_DOSMEMMGR
  29. #include <os2.h>
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35.  
  36. #if defined(__32BIT__)
  37.   #define PTR(ptr, ofs)  ((void *) ((char *) (ptr) + (ofs)))
  38. #else
  39.   #define DosQueryModuleName DosGetModName
  40.   #define APIENTRY16 APIENTRY
  41.   #if defined(M_I86SM) || defined(M_I86MM)
  42.     #define PTR(ptr, ofs)  ((void *) ((char *) (ptr) + (ofs)))
  43.   #else
  44.     #define PTR(ptr, ofs)  ((void *) ((char *) (((ULONG) procstat & 0xFFFF0000) | (USHORT) (ptr)) + (ofs)))
  45.     /* kludge to transform 0:32 into 16:16 pointer in this special case */
  46.   #endif
  47. #endif
  48.  
  49.  
  50. #ifdef __EMX__
  51.  
  52. USHORT _THUNK_FUNCTION(DosQProcStatus) (PVOID pBuf, USHORT cbBuf);
  53. USHORT _THUNK_FUNCTION(DosGetPrty) (USHORT usScope, PUSHORT pusPriority, USHORT pid);
  54.  
  55. USHORT _DosQProcStatus(PVOID pBuf, USHORT cbBuf)
  56. {
  57.   _THUNK_PROLOG(4+2);
  58.   _THUNK_FAR16(_emx_32to16(pBuf));       /* PVOID  pBuf  = 4 bytes */
  59.   _THUNK_SHORT(cbBuf);                   /* USHORT cbBuf = 2 bytes */
  60.   return (USHORT) _THUNK_CALL(DosQProcStatus);
  61. }
  62.  
  63. USHORT _DosGetPrty(USHORT usScope, PUSHORT pusPriority, USHORT pid)
  64. {
  65.   _THUNK_PROLOG(2+4+2);
  66.   _THUNK_SHORT(usScope);                    /* Flag for type of info */
  67.   _THUNK_FAR16(_emx_32to16(pusPriority));   /* Where to place it */
  68.   _THUNK_SHORT(pid);                        /* Process ID required */
  69.   return (USHORT) _THUNK_CALL(DosGetPrty);
  70. }
  71.  
  72. #define DosQProcStatus _DosQProcStatus
  73. #define DosGetPrty _DosGetPrty
  74.  
  75. #else
  76.  
  77. /* DosQProcStatus() = DOSCALLS.154 */
  78. USHORT APIENTRY16 DosQProcStatus(PVOID pBuf, USHORT cbBuf);
  79. /* DosGetPrty = DOSCALLS.9 */
  80. USHORT APIENTRY16 DosGetPrty(USHORT usScope, PUSHORT pusPriority, USHORT pid);
  81.  
  82. #endif
  83.  
  84.  
  85. struct procstat
  86. {
  87.   ULONG  summary;
  88.   ULONG  processes;
  89.   ULONG  semaphores;
  90.   ULONG  unknown1;
  91.   ULONG  sharedmemory;
  92.   ULONG  modules;
  93.   ULONG  unknown2;
  94.   ULONG  unknown3;
  95. };
  96.  
  97.  
  98. struct process
  99. {
  100.   ULONG  type;
  101.   ULONG  threadlist;
  102.   USHORT processid;
  103.   USHORT parentid;
  104.   ULONG  sessiontype;
  105.   ULONG  status; /* see status #define's below */
  106.   ULONG  sessionid;
  107.   USHORT modulehandle;
  108.   USHORT threads;
  109.   ULONG  reserved1;
  110.   ULONG  reserved2;
  111.   USHORT semaphores;
  112.   USHORT dlls;
  113.   USHORT shrmems;
  114.   USHORT reserved3;
  115.   ULONG  semlist;
  116.   ULONG  dlllist;
  117.   ULONG  shrmemlist;
  118.   ULONG  reserved4;
  119. };
  120.  
  121. #define STAT_EXITLIST 0x01
  122. #define STAT_EXIT1    0x02
  123. #define STAT_EXITALL  0x04
  124. #define STAT_PARSTAT  0x10
  125. #define STAT_SYNCH    0x20
  126. #define STAT_DYING    0x40
  127. #define STAT_EMBRYO   0x80
  128.  
  129.  
  130. struct thread
  131. {
  132.   ULONG  type;
  133.   USHORT threadid;
  134.   USHORT threadslotid;
  135.   ULONG  blockid;
  136.   ULONG  priority;
  137.   ULONG  systime;
  138.   ULONG  usertime;
  139.   UCHAR  status; /* see status #define's below */
  140.   UCHAR  reserved1;
  141.   USHORT reserved2;
  142. };
  143.  
  144. #define TSTAT_READY   1
  145. #define TSTAT_BLOCKED 2
  146. #define TSTAT_RUNNING 5
  147. #define TSTAT_LOADED  9
  148.  
  149. char *threadstat[256] = {NULL, "Ready", "Blocked", NULL, NULL, "Running", 
  150.             NULL, NULL, NULL, "Loaded"};
  151.  
  152.  
  153. struct module
  154. {
  155.   ULONG  nextmodule;
  156.   USHORT modhandle;
  157.   USHORT modtype;
  158.   ULONG  submodules;
  159.   ULONG  segments;
  160.   ULONG  reserved;
  161.   ULONG  namepointer;
  162.   USHORT submodule[1];  /* varying, see member submodules */
  163. };
  164.  
  165.  
  166. struct semaphore
  167. {
  168.   ULONG  nextsem;
  169.   USHORT owner;
  170.   UCHAR  flag;
  171.   UCHAR  refs;
  172.   UCHAR  requests;
  173.   UCHAR  reserved1;
  174.   USHORT reserved2;
  175.   USHORT index;
  176.   USHORT dummy;
  177.   UCHAR  name[1];       /* varying */
  178. };
  179.  
  180.  
  181. struct shmem
  182. {
  183.   ULONG  nextseg;
  184.   USHORT handle;
  185.   USHORT selector;
  186.   USHORT refs;
  187.   UCHAR  name[1];       /* varying */
  188. };
  189.  
  190.  
  191. struct procstat *procstat;
  192.  
  193.  
  194. void timestr(ULONG time, char *buffer)
  195. {
  196.   ULONG seconds, hundredths;
  197.  
  198.   seconds = time / 32;
  199.   hundredths = (time % 32) * 100 / 32;
  200.  
  201.   sprintf(buffer, "%ld:%02ld.%02ld", seconds / 60, seconds % 60, hundredths);
  202. }
  203.  
  204.  
  205. void proctree(USHORT pid, USHORT indent)
  206. {
  207.   struct process *proc;
  208.   UCHAR name[256], time[32];
  209.   USHORT prty = 0;
  210.   struct thread *thread;
  211.   ULONG cpu = 0;
  212.   int i;
  213.  
  214.   for ( proc = PTR(procstat -> processes, 0);
  215.         proc -> type != 3; /* not sure if there isn't another termination */
  216.         proc = PTR(proc -> threadlist,                          /* method */
  217.                    proc -> threads * sizeof(struct thread))
  218.       )
  219.   {
  220.     if ( proc -> parentid == pid && proc -> type != 0 )
  221.     {
  222.       DosQueryModuleName(proc -> modulehandle, sizeof(name), name);
  223.       DosGetPrty(PRTYS_PROCESS, &prty, proc -> processid);
  224.  
  225.       for ( cpu = 0, i = 0, thread = PTR(proc -> threadlist, 0);
  226.        i < proc -> threads; i++, thread++ )
  227.     cpu += (thread -> systime + thread -> usertime);
  228.  
  229.       timestr(cpu, time);
  230.  
  231.       printf("%5d  %5d   %02lX  %4d %04X %10s %*s%s\n",
  232.         proc -> processid, proc -> parentid, proc -> sessionid,
  233.         proc -> threads, prty, time, indent, "", name);
  234.  
  235.       proc -> type = 0;  /* kludge, mark it as already printed */
  236.       proctree(proc -> processid, indent + 2);
  237.     }
  238.   }
  239.  
  240.   if ( pid != 0 )
  241.     return;
  242.  
  243.   /* if at the root level, check for those processes that have lost *
  244.    * their parent process and show them as if they were childs of 0 */
  245.  
  246.   for ( proc = PTR(procstat -> processes, 0);
  247.         proc -> type != 3; /* not sure if there isn't another termination */
  248.         proc = PTR(proc -> threadlist,                          /* method */
  249.                    proc -> threads * sizeof(struct thread))
  250.       )
  251.   {
  252.     if ( proc -> type != 0 )
  253.     {
  254.       DosQueryModuleName(proc -> modulehandle, sizeof(name), name);
  255.       DosGetPrty(PRTYS_PROCESS, &prty, proc -> processid);
  256.  
  257.       for ( cpu = 0, i = 0, thread = PTR(proc -> threadlist, 0);
  258.        i < proc -> threads; i++, thread++ )
  259.     cpu += (thread -> systime + thread -> usertime);
  260.  
  261.       timestr(cpu, time);
  262.  
  263.       printf("%5d  %5d   %02lX  %4d %04X %10s %*s%s\n",
  264.         proc -> processid, proc -> parentid, proc -> sessionid,
  265.         proc -> threads, prty, time, indent, "", name);
  266.  
  267.       proctree(proc -> processid, indent + 2);
  268.     }
  269.  
  270.     proc -> type = 1;    /* kludge, reset mark */
  271.   }
  272. }
  273.  
  274.  
  275. void threadlist(void)
  276. {
  277.   struct process *proc;
  278.   struct thread *thread;
  279.   UCHAR name[256], systime[32], usertime[32];
  280.   USHORT count;
  281.   char *status;
  282.  
  283.   for ( proc = PTR(procstat -> processes, 0);
  284.         proc -> type != 3;
  285.         proc = PTR(proc -> threadlist,
  286.                    proc -> threads * sizeof(struct thread))
  287.       )
  288.   {
  289.     DosQueryModuleName(proc -> modulehandle, sizeof(name), name);
  290.     printf("%s\n", name);
  291.  
  292.     for ( count = 0, thread = PTR(proc -> threadlist, 0);
  293.           count < proc -> threads; count++, thread++ )
  294.     {
  295.       timestr(thread -> systime, systime);
  296.       timestr(thread -> usertime, usertime);
  297.       status = threadstat[thread -> status];
  298.       printf("%5d  %5d  %04lX %-7.7s %08lX %10s %10s\n", 
  299.          thread -> threadid, thread -> threadslotid, thread -> priority, 
  300.          status ? status : "Unknown", thread -> blockid, systime, usertime);
  301.     }
  302.   }
  303. }
  304.  
  305.  
  306. void modlist(int imports)
  307. {
  308.   struct module *mod;
  309.   UCHAR name[256];
  310.   ULONG count;
  311.  
  312.   for ( mod = PTR(procstat -> modules, 0); ;
  313.         mod = PTR(mod -> nextmodule, 0)
  314.       )
  315.   {
  316.     if ( !imports || mod -> submodules )
  317.       if ( imports )
  318.       {
  319.         printf("%04X  %s\n", mod -> modhandle, (char *) PTR(mod -> namepointer, 0));
  320.  
  321.         for ( count = 0; count < mod -> submodules; count++ )
  322.         {
  323.           DosQueryModuleName(mod -> submodule[count], sizeof(name), name);
  324.           printf("  %04X  %s\n", mod -> submodule[count], name);
  325.         }
  326.       }
  327.       else
  328.         printf(" %04X   %2d  %7ld  %6ld  %s\n", mod -> modhandle,
  329.                mod -> modtype ? 32 : 16, mod -> segments,
  330.                mod -> submodules, (char *) PTR(mod -> namepointer, 0));
  331.  
  332.     if ( mod -> nextmodule == 0L )
  333.       break;
  334.   }
  335. }
  336.  
  337.  
  338. void semlist(void)
  339. {
  340.   struct semaphore *sem;
  341.  
  342.   for ( sem = PTR(procstat -> semaphores, 16);
  343.         sem -> nextsem != 0L;
  344.         sem = PTR(sem -> nextsem, 0)
  345.       )
  346.     printf("%3d  %3d   %02X  %4d   %04X  \\SEM%s\n",
  347.            sem -> refs, sem -> requests, sem -> flag,
  348.            sem -> owner, sem -> index, sem -> name);
  349. }
  350.  
  351.  
  352. void shmlist(void)
  353. {
  354.   struct shmem *shmem;
  355.   UCHAR name[256];
  356.   ULONG size;
  357. #if defined(__32BIT__)
  358.   ULONG attrib;
  359.   PVOID base;
  360. #else
  361.   SEL sel;
  362. #endif
  363.  
  364.   for ( shmem = PTR(procstat -> sharedmemory, 0);
  365.         shmem -> nextseg != 0L;
  366.         shmem = PTR(shmem -> nextseg, 0)
  367.       )
  368.   {
  369.     strcpy(name, "\\SHAREMEM\\");
  370.     strcat(name, shmem -> name);
  371.  
  372. #if defined(__32BIT__)
  373.     DosGetNamedSharedMem(&base, name, PAG_READ);
  374.     size = -1;
  375.     attrib = PAG_SHARED | PAG_READ;
  376.     if ( DosQueryMem(base, &size, &attrib) )
  377.       size = 0;
  378.     DosFreeMem(base);
  379. #else
  380.     DosGetShrSeg(name, &sel);
  381.     if ( DosSizeSeg(sel, &size) )
  382.       size = 0;
  383.     DosFreeSeg(sel);
  384. #endif
  385.  
  386.     printf(" %04X   %04X   %08lX  %4d  %s\n", shmem -> handle,
  387.            shmem -> selector, size, shmem -> refs, name);
  388.   }
  389. }
  390.  
  391.  
  392. void main(void)
  393. {
  394.   procstat = malloc(0x8000);
  395.   DosQProcStatus(procstat, 0x8000);
  396.  
  397.   printf("\n» Process list\n");
  398.   printf("\n PID    PPID  SESS THRD PRIO    TIME    PROGRAM");
  399.   printf("\n------ ------ ---- ---- ---- ---------- ------->\n");
  400.  
  401.   proctree(0, 0);
  402.  
  403.   printf("\n» Thread list\n");
  404.   printf("\n TID    TSID  PRIO  STATE  BLOCKID   SYSTIME    USERTIME");
  405.   printf("\n------ ------ ---- ------- -------- ---------- ----------\n");
  406.  
  407.   threadlist();
  408.  
  409.   printf("\n» Module list\n");
  410.   printf("\nHANDLE TYPE SEGMENTS IMPORTS PATH");
  411.   printf("\n------ ---- -------- ------- ---->\n");
  412.  
  413.   modlist(0);
  414.  
  415.   printf("\n» Module tree\n");
  416.   printf("\n--------------\n");
  417.  
  418.   modlist(1);
  419.  
  420.   printf("\n» Semaphore list\n");
  421.   printf("\nREF  REQ  FLAG OWNER INDEX  NAME");
  422.   printf("\n---- ---- ---- ----- ------ ---->\n");
  423.  
  424.   semlist();
  425.  
  426.   printf("\n» Shared memory list\n");
  427.   printf("\nHANDLE  SEL    SEGSIZE    REF  NAME");
  428.   printf("\n------ ------ ---------- ----- ---->\n");
  429.  
  430.   shmlist();
  431.  
  432.   exit(0);
  433. }
  434.  
  435.  
  436. /* End of PROCS.C */
  437.