home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / proc2.zip / proc.c < prev    next >
C/C++ Source or Header  |  1994-08-13  |  10KB  |  479 lines

  1. /* PROCS.C
  2.  *
  3.  * Sample program using the DosQPocStatus() function under OS/2 1.x
  4.  * Kai Uwe Rommel - Sat 04-Aug-1990
  5.  */
  6.  
  7. #define INCL_NOPM
  8. #define INCL_DOSPROCESS
  9. #define INCL_DOSMODULEMGR
  10. #define INCL_DOSMEMMGR
  11. #include <os2.h>
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16.  
  17.  
  18. extern USHORT APIENTRY DosQProcStatus(PVOID pBuf, USHORT cbBuf);
  19.  
  20.  
  21. struct process
  22. {
  23.   USHORT pid;
  24.   USHORT ppid;
  25.   USHORT session;
  26.   USHORT threads;
  27.   USHORT children;
  28.   USHORT modhandle;
  29.   USHORT module;
  30. };
  31.  
  32.  
  33. struct module
  34. {
  35.   USHORT modhandle;
  36.   USHORT max_dependents;
  37.   USHORT *dependents;
  38.   UCHAR  *name;
  39.   USHORT listed;
  40. };
  41.  
  42.  
  43. struct semaphore
  44. {
  45.   USHORT refs;
  46.   USHORT requests;
  47.   UCHAR  *name;
  48. };
  49.  
  50.  
  51. struct shmem
  52. {
  53.   USHORT handle;
  54.   USHORT selector;
  55.   USHORT refs;
  56.   UCHAR  *name;
  57. };
  58.  
  59.  
  60. struct process   **proc = NULL;
  61. struct module    **mod  = NULL;
  62. struct semaphore **sem  = NULL;
  63. struct shmem     **shm  = NULL;
  64.  
  65. USHORT max_proc = 0;
  66. USHORT cur_proc = 0;
  67. USHORT max_mod  = 0;
  68. USHORT cur_mod  = 0;
  69. USHORT max_sem  = 0;
  70. USHORT cur_sem  = 0;
  71. USHORT max_shm  = 0;
  72. USHORT cur_shm  = 0;
  73.  
  74.  
  75. int compare_proc(struct process **p1, struct process **p2)
  76. {
  77.   return (*p1) -> pid - (*p2) -> pid;
  78. }
  79.  
  80.  
  81. int compare_mod(struct module **m1, struct module **m2)
  82. {
  83.   return (*m1) -> modhandle - (*m2) -> modhandle;
  84. }
  85.  
  86.  
  87. int parse_buffer(UCHAR * bBuf)
  88. {
  89.   USHORT type, tpid, seminf;
  90.   USHORT count, kount;
  91.   UCHAR buffer[256];
  92.   UCHAR *cptr, *ptr;
  93.   UCHAR *next;
  94.  
  95.   ptr = bBuf;
  96.  
  97.   while ( (type = *(USHORT *) ptr) != 0xFFFFU )
  98.   {
  99.     ptr += 2;
  100.     next = *(UCHAR **) ptr;
  101.     ptr += 2;
  102.  
  103.     switch ( type )
  104.     {
  105.  
  106.     case 0: /* process */
  107.  
  108.       if ( cur_proc >= max_proc )
  109.       {
  110.         max_proc += 50;
  111.  
  112.     if ( !(proc = realloc(proc, max_proc * sizeof(struct process *))) )
  113.           return 1;
  114.       }
  115.  
  116.       if ( !(proc[cur_proc] = calloc(1, sizeof(struct process))) )
  117.         return 1;
  118.  
  119.       proc[cur_proc] -> pid = *(USHORT *) ptr;
  120.       ptr += 2;
  121.       proc[cur_proc] -> ppid = *(USHORT *) ptr;
  122.       ptr += 2;
  123.       proc[cur_proc] -> session = *(USHORT *) ptr;
  124.       ptr += 2;
  125.       proc[cur_proc] -> modhandle = *(USHORT *) ptr;
  126.  
  127.       proc[cur_proc] -> threads = 0;
  128.       proc[cur_proc] -> module  = -1;
  129.       ++cur_proc;
  130.  
  131.       break;
  132.  
  133.     case 1: /* thread */
  134.  
  135.       ptr += 2;
  136.       tpid = *(USHORT *) ptr;
  137.  
  138.       for ( count = 0; count < cur_proc; count++ )
  139.     if ( proc[count] -> pid == tpid )
  140.     {
  141.       ++proc[count] -> threads;
  142.       break;
  143.     }
  144.  
  145.       break;
  146.  
  147.     case 2: /* module */
  148.  
  149.       if ( cur_mod >= max_mod )
  150.       {
  151.         max_mod += 50;
  152.  
  153.     if ( !(mod = realloc(mod, max_mod * sizeof(struct module *))) )
  154.           return 1;
  155.       }
  156.  
  157.       if ( !(mod[cur_mod] = calloc(1, sizeof(struct module))) )
  158.         return 1;
  159.  
  160.       mod[cur_mod] -> modhandle = *(USHORT *) ptr;
  161.       ptr += 2;
  162.       mod[cur_mod] -> max_dependents = *(USHORT *) ptr;
  163.       ptr += 2;
  164.       ptr += 2;
  165.       ptr += 2;
  166.  
  167.       if ( mod[cur_mod] -> max_dependents )
  168.       {
  169.     if ( !(mod[cur_mod] -> dependents = calloc(mod[cur_mod] -> max_dependents, sizeof(USHORT))) )
  170.           return 1;
  171.  
  172.     for ( count = 0; count < mod[cur_mod] -> max_dependents; count++ )
  173.     {
  174.       mod[cur_mod] -> dependents[count] = *(USHORT *) ptr;
  175.       ptr += 2;
  176.     }
  177.       }
  178.  
  179.       for ( cptr = buffer; *cptr++ = *ptr++; );
  180.  
  181.       if ( !(mod[cur_mod] -> name = strdup(buffer)) )
  182.         return 1;
  183.  
  184.       ++cur_mod;
  185.  
  186.       break;
  187.  
  188.     case 3: /* system semaphore */
  189.  
  190.       if ( cur_sem >= max_sem )
  191.       {
  192.         max_sem += 50;
  193.  
  194.     if ( !(sem = realloc(sem, max_sem * sizeof(struct semaphore *))) )
  195.           return 1;
  196.       }
  197.  
  198.       if ( !(sem[cur_sem] = calloc(1, sizeof(struct semaphore))) )
  199.         return 1;
  200.  
  201.       ptr += 2;
  202.       seminf = *(USHORT *) ptr;
  203.       sem[cur_sem] -> refs = seminf & 0xFF;
  204.       sem[cur_sem] -> requests = seminf >> 8;
  205.       ptr += 2;
  206.       ptr += 2;
  207.  
  208.       for ( cptr = buffer; *cptr++ = *ptr++; );
  209.  
  210.       if ( !(sem[cur_sem] -> name = strdup(buffer)) )
  211.         return 1;
  212.  
  213.       ++cur_sem;
  214.  
  215.       break;
  216.  
  217.     case 4: /* shared memory */
  218.  
  219.       if ( cur_shm >= max_shm )
  220.       {
  221.         max_shm += 50;
  222.  
  223.     if ( !(shm = realloc(shm, max_shm * sizeof(struct shmem *))) )
  224.           return 1;
  225.       }
  226.  
  227.       if ( !(shm[cur_shm] = calloc(1, sizeof(struct shmem))) )
  228.         return 1;
  229.  
  230.       shm[cur_shm] -> handle = *(USHORT *) ptr;
  231.       ptr += 2;
  232.       shm[cur_shm] -> selector = *(USHORT *) ptr;
  233.       ptr += 2;
  234.       shm[cur_shm] -> refs = *(USHORT *) ptr;
  235.       ptr += 2;
  236.  
  237.       for ( cptr = buffer; *cptr++ = *ptr++; );
  238.  
  239.       if ( !(shm[cur_shm] -> name = strdup(buffer)) )
  240.         return 1;
  241.  
  242.       ++cur_shm;
  243.  
  244.       break;
  245.  
  246.     default: /* other ? */
  247.       break;
  248.  
  249.     }
  250.  
  251.     ptr = next;
  252.   }
  253.  
  254.   qsort(proc, cur_proc, sizeof(struct process *), compare_proc);
  255.   qsort(mod, cur_mod, sizeof(struct module *), compare_mod);
  256.  
  257.   for ( count = 0; count < cur_proc; count++ )
  258.     for ( kount = 0; kount < cur_mod; kount++ )
  259.       if ( proc[count] -> modhandle == mod[kount] -> modhandle )
  260.       {
  261.         proc[count] -> module = kount;
  262.     break;
  263.       }
  264.  
  265.   for ( count = 0; count < cur_proc; count++ )
  266.     for ( kount = 0; kount < cur_proc; kount++ )
  267.       if ( proc[count] -> pid == proc[kount] -> ppid )
  268.     (proc[count] -> children)++;
  269.  
  270.   return 0;
  271. }
  272.  
  273.  
  274. void free_data()
  275. {
  276.   USHORT count;
  277.  
  278.   for (count = 0; count < cur_proc; count++)
  279.     free(proc[count]);
  280.  
  281.   for (count = 0; count < cur_mod; count++)
  282.   {
  283.     if ( mod[count] -> max_dependents )
  284.       free(mod[count] -> dependents);
  285.  
  286.     free(mod[count] -> name);
  287.     free(mod[count]);
  288.   }
  289.  
  290.   for (count = 0; count < cur_sem; count++)
  291.   {
  292.     free(sem[count] -> name);
  293.     free(sem[count]);
  294.   }
  295.  
  296.   for (count = 0; count < cur_shm; count++)
  297.   {
  298.     free(shm[count] -> name);
  299.     free(shm[count]);
  300.   }
  301.  
  302.   free(proc);
  303.   free(mod);
  304.   free(sem);
  305.   free(shm);
  306.  
  307.   max_proc = max_mod = cur_proc = cur_mod = 0;
  308.   max_sem  = max_shm = cur_sem  = cur_shm = 0;
  309.   proc = NULL;
  310.   mod  = NULL;
  311. }
  312.  
  313.  
  314. void proctree(USHORT pid, USHORT indent)
  315. {
  316.   USHORT count;
  317.   UCHAR *mName, pName[256];
  318.  
  319.   for (count = 0; count < cur_proc; count++)
  320.     if ( proc[count] -> ppid == pid )
  321.     {
  322.       if ( proc[count] -> module != -1 )
  323.       {
  324.         mName = mod[proc[count] -> module] -> name;
  325.         DosGetModName(proc[count] -> modhandle, sizeof(pName), pName);
  326.       }
  327.       else
  328.       {
  329.         mName = "unknown";  /* Zombie process, i.e. result for DosCwait() */
  330.         pName[0] = 0;       /* or DOS box or swapper (?) */
  331.       }
  332.  
  333. #ifdef FULL
  334.       printf("%5d  %5d   %02x  %4d  %4d  %-8s %*s%s\n",
  335.         proc[count] -> pid, proc[count] -> ppid, proc[count] -> session,
  336.         proc[count] -> children, proc[count] -> threads,
  337.         mName, indent, "", pName);
  338. #else
  339.       printf("%5d   %02x  %4d  %-8s %*s%s\n",
  340.         proc[count] -> pid, proc[count] -> session,
  341.         proc[count] -> threads, mName, indent, "", pName);
  342. #endif
  343.  
  344.       proctree(proc[count] -> pid, indent + 2);
  345.     }
  346. }
  347.  
  348.  
  349. void modlist(void)
  350. {
  351.   UCHAR pName[256];
  352.   USHORT count;
  353.  
  354.   for (count = 0; count < cur_mod; count++)
  355.   {
  356.     DosGetModName(mod[count] -> modhandle, sizeof(pName), pName);
  357.     printf("%-8s  %04x  %s\n",
  358.       mod[count] -> name, mod[count] -> modhandle, pName);
  359.   }
  360. }
  361.  
  362.  
  363. void modtree(USHORT module, USHORT indent)
  364. {
  365.   UCHAR *mName, pName[256];
  366.   USHORT cnt1, cnt2;
  367.  
  368.   if ( module == -1 )
  369.     return;
  370.  
  371.   mName = mod[module] -> name;
  372.   DosGetModName(mod[module] -> modhandle, sizeof(pName), pName);
  373.  
  374.   if ( mod[module] -> listed )
  375.   {
  376.     printf("%*s%s*\n", indent, "", mName);
  377.     return;
  378.   }
  379.   else
  380.     printf("%*s%-8s%*s%s\n", indent, "", mName, 32 - indent, "", pName);
  381.  
  382.   mod[module] -> listed = 1;
  383.  
  384.   for ( cnt1 = 0; cnt1 < mod[module] -> max_dependents; cnt1++ )
  385.     for ( cnt2 = 0; cnt2 < cur_mod; cnt2++ )
  386.       if ( mod[cnt2] -> modhandle == mod[module] -> dependents[cnt1] )
  387.         modtree(cnt2, indent + 2);
  388. }
  389.  
  390.  
  391. void semlist(void)
  392. {
  393.   USHORT count;
  394.  
  395.   for (count = 0; count < cur_sem; count++)
  396.     printf("%4d  %4d  %s\n",
  397.       sem[count] -> refs, sem[count] -> requests, sem[count] -> name);
  398. }
  399.  
  400.  
  401. void shmlist(void)
  402. {
  403.   USHORT count;
  404.   ULONG size;
  405.   SEL sel;
  406.   UCHAR name[256];
  407.  
  408.   for (count = 0; count < cur_shm; count++)
  409.   {
  410.     strcpy(name, "\\SHAREMEM\\");
  411.     strcat(name, shm[count] -> name);
  412.  
  413.     DosGetShrSeg(name, &sel);
  414.     if ( DosSizeSeg(sel, &size) )
  415.       size = 0L;
  416.     DosFreeSeg(sel);
  417.  
  418.     printf(" %04x   %04x   %04lx  %4d  %s\n",
  419.       shm[count] -> handle, shm[count] -> selector, size,
  420.       shm[count] -> refs, shm[count] -> name);
  421.   }
  422. }
  423.  
  424.  
  425. void main(void)
  426. {
  427.   UCHAR *pBuf;
  428.   USHORT count;
  429.  
  430.   pBuf = malloc(0x8000);
  431.   DosQProcStatus(pBuf, 0x8000);
  432.  
  433.   if ( parse_buffer(pBuf) )
  434.   {
  435.     printf("Error: Out of memory!\n");
  436.     DosExit(EXIT_PROCESS, 1);
  437.   }
  438.  
  439.   free(pBuf);
  440.  
  441. #ifdef FULL
  442.   printf("\n PID    PPID  SESS CHLDS THRDS MODULE   PROGRAM");
  443.   printf("\n------ ------ ---- ----- ----- -------- ------->\n");
  444. #else
  445.   printf("\n PID   SESS THRDS MODULE   PROGRAM");
  446.   printf("\n------ ---- ----- -------- ------->\n");
  447. #endif
  448.  
  449.   proctree(0, 0);
  450.  
  451.   printf("\nMODULE   HANDLE PATH");
  452.   printf("\n-------- ------ ---->\n");
  453.  
  454.   modlist();
  455.  
  456.   printf("\nMODULE TREE");
  457.   printf("\n-----------\n");
  458.  
  459.   for (count = 0; count < cur_proc; count++)
  460.     modtree(proc[count] -> module, 0);
  461.  
  462.   printf("\n REF   REQ  NAME");
  463.   printf("\n----- ----- ---->\n");
  464.  
  465.   semlist();
  466.  
  467.   printf("\nHANDLE  SEL    SIZE   REF  NAME");
  468.   printf("\n------ ------ ------ ----- ---->\n");
  469.  
  470.   shmlist();
  471.  
  472.   free_data();
  473.  
  474.   DosExit(EXIT_PROCESS, 0);
  475. }
  476.  
  477.  
  478. /* End of PROCS.C */
  479.