home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / status1.zip / STATUS.C < prev    next >
Text File  |  1989-11-28  |  34KB  |  839 lines

  1. #define PROGRAM       "STATUS"         // Program Name
  2. #define LEVEL         "00"             // Program Level
  3. #define COPYRIGHT     "Copyright (c) 1989 George Brickner 70040,104"
  4.  
  5. #pragma title (PROGRAM " Level " LEVEL " - Display OS/2 Status")
  6. #pragma linesize(132)
  7. #pragma pagesize(55)
  8. #pragma comment(exestr,PROGRAM "-Level " LEVEL "-" __TIMESTAMP__ "-" COPYRIGHT)
  9.  
  10. /*****************************************************************************
  11. **            STATUS - Display OS/2 Status via DosQProcStatus API           **
  12. **                    Level 00 - November 27th, 1989                        **
  13. **                                                                          **
  14. **  Command line parameters:                                                **
  15. **    -A = Display all information                                          **
  16. **    -D = Display debug Infomation                                         **
  17. **    -L = Display OS/2 Resource Modules (sorted alphabetically)            **
  18. **    -M = Display OS/2 Shared Memory Segments (sorted alphabetically)      **
  19. **    -N = Sort Processes by PID (-P), Modules by ModID (-L)                **
  20. **    -P = Display OS/2 Processes (Default) (sorted alphabetically)         **
  21. **    -S = Display OS/2 System Semaphores (sorted alphabetically)           **
  22. *****************************************************************************/
  23. #define  INCL_DOS                      // Include Base OS/2 Calls
  24. #define  INCL_DOSERRORS                // Include Base OS/2 Errors
  25. #include <os2.h>                       // Standard OS/2 Definitions
  26. #include <stdio.h>                     // C/2 Standard I/O Defs
  27. #include <stdlib.h>                    // C/2 Standard Library
  28. #include <string.h>                    // C/2 Standard String Defs
  29. #include <STATUS.h>                    // Includes For STATUS.c
  30.  
  31. /********************************************************************
  32. **               Define Module Table Data Structure                **
  33. ********************************************************************/
  34. typedef struct _MODTBL                 // Define Module Table Entry
  35.   {
  36.     HMODULE ModID;                     // Module ID
  37.     USHORT  MaxDeps;                   // Maximum Dependencies
  38.     PUSHORT pDeps;                     // Pointer To Dependencies Table
  39.     PCHAR   pName;                     // Pointer To Module Name
  40.   } MODTBL;
  41. typedef MODTBL FAR *PMODTBL;           // Define Pointer
  42.  
  43. /********************************************************************
  44. **               Define Process Table Data Structure               **
  45. ********************************************************************/
  46. typedef struct _PROCTBL                // Define Process Table Entry
  47.   {
  48.     PID     Pid;                       // Process ID
  49.     PID     PPid;                      // Parent Process ID
  50.     USHORT  SessionID;                 // OS/2 Session ID
  51.     USHORT  Threads;                   // Number Of Threads
  52.     USHORT  Children;                  // Child Processes
  53.     HMODULE ModID;                     // Module ID
  54.     PCHAR   pName;                     // Module Name
  55.   } PROCTBL;
  56. typedef PROCTBL FAR *PPROCTBL;         // Define Pointer
  57.  
  58. #pragma subtitle ("Define Static & Global Data Areas")
  59. #pragma page()
  60. /**********************************************************************
  61. **                     Define Static Data Areas                      **
  62. **********************************************************************/
  63. static CHAR const eyepopper[] = PROGRAM "-Level " LEVEL "-" __TIMESTAMP__ "-" COPYRIGHT;
  64.  
  65. static BYTE bBuf[65535];               // Data Feedback Buffer
  66.  
  67. static BOOL Show_Procs   = FALSE;      // Display Process Switch
  68. static BOOL Show_Mods    = FALSE;      // Display Modules Switch
  69. static BOOL Show_Sems    = FALSE;      // Display Semaphores Switch
  70. static BOOL Show_Segs    = FALSE;      // Display Shared Memory Switch
  71. static BOOL Sort_Pid_Num = FALSE;      // Numeric Sort (PID)
  72. static BOOL Sort_Mod_Num = FALSE;      // Numeric Sort (ModID)
  73. static BOOL Debug_Mode   = FALSE;      // Debug Mode
  74.  
  75. static PPROCTBL *pProcTbl = NULL;      // Process Table Anchor Ptr
  76. static USHORT   ProcMax   = 0;         // Max Process Table Entries
  77. static USHORT   ProcNdx   = 0;         // Current Process Table Index
  78.  
  79. static PTYPE1   *pThdTbl  = NULL;      // Thread Table Anchor Ptr
  80. static USHORT   ThdMax    = 0;         // Max Thread Table Entries
  81. static USHORT   ThdNdx    = 0;         // Current Thread Table Index
  82.  
  83. static PMODTBL  *pModTbl  = NULL;      // Module Table Anchor Ptr
  84. static USHORT   ModMax    = 0;         // Max Module Table Entries
  85. static USHORT   ModNdx    = 0;         // Current Module Table Index
  86.  
  87. static PTYPE3   *pSemTbl  = NULL;      // Semaphore Table Anchor Ptr
  88. static USHORT   SemMax    = 0;         // Max Sem Table Entries
  89. static USHORT   SemNdx    = 0;         // Current Sem Table Index
  90.  
  91. static PTYPE4   *pMemTbl  = NULL;      // Memory Table Anchor Ptr
  92. static USHORT   MemMax    = 0;         // Max Memory Table Entries
  93. static USHORT   MemNdx    = 0;         // Current Memory Table Index
  94.  
  95. #pragma subtitle ("Show Program Usage")
  96. #pragma page()
  97. /**********************************************************************
  98. **                       Show Program Usage                          **
  99. **********************************************************************/
  100. VOID ShowUsage (VOID)
  101.   {
  102.     fprintf (stderr, "\nSTATUS Display OS/2 Status Information\n");
  103.     fprintf (stderr, "Usage:  STATUS [-A][-L][-M][-N][-P][-S]\n");
  104.     fprintf (stderr, "Parameters:\n");
  105.     fprintf (stderr, "\t-A = Display all information\n");
  106.     fprintf (stderr, "\t-D = Display debug information\n");
  107.     fprintf (stderr, "\t-L = Display library module information, sort by name\n");
  108.     fprintf (stderr, "\t-LN = Same as above but sort by Module ID\n");
  109.     fprintf (stderr, "\t-M = Display shared memory segments\n");
  110.     fprintf (stderr, "\t-N = Numeric Sort (PID/Mod ID)\n");
  111.     fprintf (stderr, "\t-P = Display process information, sort by name (default)\n");
  112.     fprintf (stderr, "\t-PN = Same as above but sort by Process ID\n");
  113.     fprintf (stderr, "\t-S = Display system semaphores\n");
  114.     exit (0);
  115.   }
  116.  
  117. #pragma subtitle ("Process Parameters")
  118. #pragma page()
  119. /**********************************************************************
  120. **                  Process Command Line Parameters                  **
  121. **********************************************************************/
  122. VOID Process_Parameters (USHORT argc, PCHAR argv[])
  123.   {
  124.   USHORT i;                            // Index
  125.  
  126.     for (i=1; i < argc; i++)
  127.       {
  128.         if (argv[i][0] == '-' || argv[i][0] == '/')  // Parameter
  129.           {
  130.             switch (argv[i][1])        // Validate Parameter
  131.               {
  132.                 case ('a'):            // Show All
  133.                 case ('A'):            // Show All
  134.                   {
  135.                     Show_Procs = Show_Mods = Show_Segs = Show_Sems = TRUE;
  136.                     break;
  137.                   }
  138.                 case ('d'):            // Show Debug
  139.                 case ('D'):            // Show Debug
  140.                   {
  141.                     Debug_Mode = TRUE;
  142.                     break;
  143.                   }
  144.                 case ('l'):            // Show Library Modules
  145.                 case ('L'):            // Show Library Modules
  146.                   {
  147.                     Show_Mods = TRUE;
  148.                     if (strpbrk (argv[i], "nN")) // Numeric Sort
  149.                       {
  150.                         Sort_Mod_Num = TRUE;
  151.                       }
  152.                     break;
  153.                   }
  154.                 case ('m'):            // Show Shared Memory
  155.                 case ('M'):            // Show Shared Memory
  156.                   {
  157.                     Show_Segs = TRUE;
  158.                     break;
  159.                   }
  160.                 case ('n'):            // Numeric Sort
  161.                 case ('N'):            // Numeric Sort
  162.                   {
  163.                     Sort_Pid_Num = TRUE;
  164.                     Sort_Mod_Num = TRUE;
  165.                     break;
  166.                   }
  167.                 case ('p'):            // Show Processes
  168.                 case ('P'):            // Show Processes
  169.                   {
  170.                     Show_Procs = TRUE;
  171.                     if (strpbrk (argv[i], "nN")) // Numeric Sort
  172.                       {
  173.                         Sort_Pid_Num = TRUE;
  174.                       }
  175.                     break;
  176.                   }
  177.                 case ('s'):            // Show Semaphores
  178.                 case ('S'):            // Show Semaphores
  179.                   {
  180.                     Show_Sems = TRUE;
  181.                     break;
  182.                   }
  183.                 case ('?'):            // Show Usage
  184.                 case ('h'):            // Show Usage
  185.                 case ('H'):            // Show Usage
  186.                   {
  187.                     ShowUsage ();
  188.                     break;
  189.                   }
  190.                 default:               // Invalid Parameter
  191.                   {
  192.                     fprintf (stderr, "Invalid parameter: %s\n", argv[i]);
  193.                     ShowUsage ();
  194.                     break;
  195.                   }
  196.               }
  197.           }
  198.       }
  199.   }
  200.  
  201. #pragma subtitle ("Sort By Module ID")
  202. #pragma page()
  203. /**********************************************************************
  204. **                 Sort Compare Routine - Module ID                  **
  205. **********************************************************************/
  206. INT Mod_Sort (PMODTBL *arg1, PMODTBL *arg2)
  207.   {
  208.     if ((*arg1)->ModID < (*arg2)->ModID)
  209.       {
  210.         return -1;
  211.       }
  212.     else if ((*arg1)->ModID > (*arg2)->ModID)
  213.       {
  214.         return 1;
  215.       }
  216.     else
  217.       {
  218.         return 0;
  219.       }
  220.   }
  221.  
  222. #pragma subtitle ("Sort By Module Name")
  223. #pragma page()
  224. /**********************************************************************
  225. **                 Sort Compare Routine - Module Name                **
  226. **********************************************************************/
  227. INT Mod_Name_Sort (PMODTBL *arg1, PMODTBL *arg2)
  228.   {
  229.     return stricmp ((*arg1)->pName, (*arg2)->pName);
  230.   }
  231.  
  232. #pragma subtitle ("Sort By Process ID")
  233. #pragma page()
  234. /**********************************************************************
  235. **                 Sort Compare Routine - Process ID                 **
  236. **********************************************************************/
  237. INT Pid_Sort (PPROCTBL *arg1, PPROCTBL *arg2)
  238.   {
  239.     if ((*arg1)->Pid < (*arg2)->Pid)
  240.       {
  241.         return -1;
  242.       }
  243.     else if ((*arg1)->Pid > (*arg2)->Pid)
  244.       {
  245.         return 1;
  246.       }
  247.     else
  248.       {
  249.         return 0;
  250.       }
  251.   }
  252.  
  253. #pragma subtitle ("Sort By Process Name")
  254. #pragma page()
  255. /**********************************************************************
  256. **                 Sort Compare Routine - Process Name               **
  257. **********************************************************************/
  258. INT Pid_Name_Sort (PPROCTBL *arg1, PPROCTBL *arg2)
  259.   {
  260.     if ((*arg1)->pName == NULL && (*arg2)->pName == NULL)
  261.       {
  262.         return 0;
  263.       }
  264.     else if ((*arg1)->pName == NULL)   // No Name Specified
  265.       {
  266.         return -1;
  267.       }
  268.     else if ((*arg2)->pName == NULL)   // No Name Specified
  269.       {
  270.         return 1;
  271.       }
  272.     return stricmp ((*arg1)->pName, (*arg2)->pName);
  273.   }
  274.  
  275. #pragma subtitle ("Sort By Thread ID")
  276. #pragma page()
  277. /**********************************************************************
  278. **                 Sort Compare Routine - Thread ID                  **
  279. **********************************************************************/
  280. INT Tid_Sort (PTYPE1 *arg1, PTYPE1 *arg2)
  281.   {
  282.     if ((*arg1)->ProcessID < (*arg2)->ProcessID)
  283.       {
  284.         return -1;
  285.       }
  286.     else if ((*arg1)->ProcessID > (*arg2)->ProcessID)
  287.       {
  288.         return 1;
  289.       }
  290.     else
  291.       {
  292.         if ((*arg1)->ThreadID < (*arg2)->ThreadID)
  293.           {
  294.             return -1;
  295.           }
  296.         else if ((*arg1)->ThreadID > (*arg2)->ThreadID)
  297.           {
  298.             return 1;
  299.           }
  300.         else
  301.           {
  302.             return 0;
  303.           }
  304.       }
  305.   }
  306.  
  307. #pragma subtitle ("Sort By Semaphore Name")
  308. #pragma page()
  309. /**********************************************************************
  310. **                 Sort Compare Routine - Semaphore Name             **
  311. **********************************************************************/
  312. INT Sem_Sort (PTYPE3 *arg1, PTYPE3 *arg2)
  313.   {
  314.     return stricmp ((*arg1)->SemaphoreName, (*arg2)->SemaphoreName);
  315.   }
  316.  
  317. #pragma subtitle ("Sort By Shared Segment Name")
  318. #pragma page()
  319. /**********************************************************************
  320. **                 Sort Compare Routine - Shared Segment Name        **
  321. **********************************************************************/
  322. INT Seg_Sort (PTYPE4 *arg1, PTYPE4 *arg2)
  323.   {
  324.     return stricmp ((*arg1)->SegmentName, (*arg2)->SegmentName);
  325.   }
  326.  
  327. #pragma subtitle ("Initialization")
  328. #pragma page()
  329. /**********************************************************************
  330. **                       Initialization Routine                      **
  331. **********************************************************************/
  332. USHORT Initialization (VOID)
  333.   {
  334.   USHORT       rc = NO_ERROR;          // Return Code
  335.   USHORT       Next = 0;               // Offset To Next Record
  336.   USHORT       i, j;                   // Index
  337.   PPROC_STATUS pBuf;                   // Proc Status Area Ptr
  338.  
  339.     rc = DosQProcStatus (bBuf, sizeof (bBuf));
  340.  
  341.     if (rc == NO_ERROR)                // API Call Successful
  342.       {
  343.         pBuf = (PPROC_STATUS) bBuf;    // Initialize Pointer
  344.  
  345.         while (pBuf->TypeCode != TYPE_END) // Do until end of list
  346.           {
  347.             Next = pBuf->Next;         // Offset To Next Record
  348.  
  349.             switch (pBuf->TypeCode)
  350.               {
  351.  
  352.                 case TYPE_PID:         // Type 0 - Process Info
  353.                   {
  354.                     if (Debug_Mode && Show_Procs) // Display Debug Info
  355.                       {
  356.                         printf ("\n[%p] Record Type %04X  Next=%04X  Process Information Record\n",
  357.                             pBuf, pBuf->TypeCode, pBuf->Next);
  358.                         printf ("\tPID=%04X  PPID=%04X  Sess=%02X  Mod#=%04X\n",
  359.                             pBuf->Type.Type_0.ProcessID,
  360.                             pBuf->Type.Type_0.ParentPID,
  361.                             pBuf->Type.Type_0.SessionID,
  362.                             pBuf->Type.Type_0.ModID);
  363.                       }
  364.  
  365.                     if (ProcNdx >= ProcMax)    // Increase Table Size
  366.                       {
  367.                         ProcMax += 50;         // Increment Table Size
  368.                         pProcTbl = (PPROCTBL *) realloc (pProcTbl, ProcMax * sizeof (PPROCTBL));
  369.                         if (!pProcTbl)         // Allocation Failed
  370.                           {
  371.                             printf ("\aProcess table realloc failed\n");
  372.                             exit (1);
  373.                           }
  374.                       }
  375.  
  376.                     pProcTbl[ProcNdx] = (PPROCTBL) calloc (1, sizeof (PROCTBL));  // Allocate Table Entry
  377.                     if (!pProcTbl[ProcNdx])    // Allocation Failed
  378.                       {
  379.                         printf ("\aProcess table entry alloc failed\n");
  380.                         exit (1);
  381.                       }
  382.  
  383.                     pProcTbl[ProcNdx]->Pid       = pBuf->Type.Type_0.ProcessID;
  384.                     pProcTbl[ProcNdx]->PPid      = pBuf->Type.Type_0.ParentPID;
  385.                     pProcTbl[ProcNdx]->ModID     = pBuf->Type.Type_0.ModID;
  386.                     pProcTbl[ProcNdx]->SessionID = pBuf->Type.Type_0.SessionID;
  387.                     pProcTbl[ProcNdx]->Threads   = 0;
  388.                     pProcTbl[ProcNdx]->Children  = 0;
  389.                     pProcTbl[ProcNdx]->pName     = NULL;
  390.                     ProcNdx++;         // Increment Process Table Index
  391.                     break;             // Exit Case
  392.                   }
  393.  
  394.                 case TYPE_TID:         // Thread Info
  395.                   {
  396.                     if (Debug_Mode && Show_Procs) // Display Debug Info
  397.                       {
  398.                         printf ("\n[%p] Record Type %04X  Next=%04X  Thread Information Record\n",
  399.                             pBuf, pBuf->TypeCode, pBuf->Next);
  400.                         printf ("\tSysTID=%02X  Unkn=%02X PID=%04X  TID=%02X  Prty=%04X  Flgs=%04X  BlockID=%08lX\n",
  401.                             pBuf->Type.Type_1.SysThreadID,
  402.                             pBuf->Type.Type_1.Unknown,
  403.                             pBuf->Type.Type_1.ProcessID,
  404.                             pBuf->Type.Type_1.ThreadID,
  405.                             pBuf->Type.Type_1.Priority,
  406.                             pBuf->Type.Type_1.Flags,
  407.                             pBuf->Type.Type_1.BlockID);
  408.                       }
  409.  
  410.                     if (ThdNdx >= ThdMax)      // Increase Table Size
  411.                       {
  412.                         ThdMax += 50;          // Increment Table Size
  413.                         pThdTbl = (PTYPE1 *) realloc (pThdTbl, ThdMax * sizeof (PTYPE1));
  414.                         if (!pThdTbl)          // Allocation Failed
  415.                           {
  416.                             printf ("\aThread table realloc failed\n");
  417.                             exit (1);
  418.                           }
  419.                       }
  420.                     pThdTbl[ThdNdx] = &pBuf->Type.Type_1;   // Save Pointer
  421.  
  422.                     for (i=0; i < ProcNdx; i++)
  423.                       {
  424.                         if (pProcTbl[i]->Pid == pBuf->Type.Type_1.ProcessID) // Found Process
  425.                           {
  426.                             pProcTbl[i]->Threads++;    // Bump Thread Counter
  427.                             break;                     // Exit Loop
  428.                           }
  429.                       }
  430.                     ThdNdx++;          // Increment Thread Index
  431.                     break;             // Exit Case
  432.                   }
  433.  
  434.                 case TYPE_MOD:         // Module Info
  435.                   {
  436.                     if (Debug_Mode && Show_Mods) // Display Debug Info
  437.                       {
  438.                         printf ("\n[%p] Record Type %04X  Next=%04X  Module Information Record\n",
  439.                             pBuf, pBuf->TypeCode, pBuf->Next);
  440.                         printf ("\tMod#=%04X  Deps=%04X  DepOff=%04X  NameOff=%04X  Name=%s\n",
  441.                             pBuf->Type.Type_2.ModID,
  442.                             pBuf->Type.Type_2.MaxDeps,
  443.                             pBuf->Type.Type_2.Dep_Offset,
  444.                             pBuf->Type.Type_2.Mod_Name_Offset,
  445.                             MAKEP (SELECTOROF (pBuf), pBuf->Type.Type_2.Mod_Name_Offset));
  446.                       }
  447.  
  448.                     if (ModNdx >= ModMax)      // Increase Table Size
  449.                       {
  450.                         ModMax += 50;          // Increment Table Size
  451.                         pModTbl = (PMODTBL *) realloc (pModTbl, ModMax * sizeof (PMODTBL));
  452.                         if (!pModTbl)          // Allocation Failed
  453.                           {
  454.                             printf ("\aModule table realloc failed\n");
  455.                             exit (1);
  456.                           }
  457.                       }
  458.  
  459.                     pModTbl[ModNdx] = (PMODTBL) calloc (1, sizeof (MODTBL));  // Allocate Table Entry
  460.                     if (!pModTbl[ModNdx])      // Allocation Failed
  461.                       {
  462.                         printf ("\aModule table entry alloc failed\n");
  463.                         exit (1);
  464.                       }
  465.  
  466.                     pModTbl[ModNdx]->ModID   = pBuf->Type.Type_2.ModID;
  467.                     pModTbl[ModNdx]->MaxDeps = pBuf->Type.Type_2.MaxDeps;
  468.  
  469.                     if (pModTbl[ModNdx]->MaxDeps)  // Dependents Exist
  470.                       {
  471.                         pModTbl[ModNdx]->pDeps = MAKEP (SELECTOROF (pBuf), pBuf->Type.Type_2.Dep_Offset);
  472.                       }
  473.  
  474.                     pModTbl[ModNdx]->pName = MAKEP (SELECTOROF (pBuf), pBuf->Type.Type_2.Mod_Name_Offset);
  475.                     ModNdx++;          // Increment Module Table Index
  476.                     break;             // Exit Case
  477.                   }
  478.  
  479.                 case TYPE_SEM:         // System Semaphore Info
  480.                   {
  481.                     if (Debug_Mode && Show_Sems) // Display Debug Info
  482.                       {
  483.                         printf ("\n[%p] Record Type %04X  Next=%04X  Semaphore Information Record\n",
  484.                             pBuf, pBuf->TypeCode, pBuf->Next);
  485.                         printf ("\tSysTID=%02X  Unkn=%02X Ref=%02X  Req=%02X  Flgs=%04X  Name=%s\n",
  486.                             pBuf->Type.Type_3.SysThreadID,
  487.                             pBuf->Type.Type_3.Unknown,
  488.                             pBuf->Type.Type_3.RefCount,
  489.                             pBuf->Type.Type_3.ReqCount,
  490.                             pBuf->Type.Type_3.Flags,
  491.                             pBuf->Type.Type_3.SemaphoreName);
  492.                       }
  493.  
  494.                     if (SemNdx >= SemMax)      // Increase Table Size
  495.                       {
  496.                         SemMax += 50;          // Increment Table Size
  497.                         pSemTbl = (PTYPE3 *) realloc (pSemTbl, SemMax * sizeof (PTYPE3));
  498.                         if (!pSemTbl)          // Allocation Failed
  499.                           {
  500.                             printf ("\aSemaphore table realloc failed\n");
  501.                             exit (1);
  502.                           }
  503.                       }
  504.                     pSemTbl[SemNdx] = &pBuf->Type.Type_3;   // Save Pointer
  505.                     SemNdx++;          // Increment Semaphore Index
  506.                     break;             // Exit Case
  507.                   }
  508.  
  509.                 case TYPE_MEM:         // Shared Memory Info
  510.                   {
  511.                     if (Debug_Mode && Show_Segs) // Display Debug Info
  512.                       {
  513.                         printf ("\n[%p] Record Type %04X  Next=%04X  Memory Information Record\n",
  514.                             pBuf, pBuf->TypeCode, pBuf->Next);
  515.                         printf ("\tHandle=%04X  Sel=%04X  Use=%04X  Name=%s\n",
  516.                             pBuf->Type.Type_4.Handle,
  517.                             pBuf->Type.Type_4.Selector,
  518.                             pBuf->Type.Type_4.UseCount,
  519.                             pBuf->Type.Type_4.SegmentName);
  520.                       }
  521.  
  522.                     if (MemNdx >= MemMax)      // Increase Table Size
  523.                       {
  524.                         MemMax += 50;          // Increment Table Size
  525.                         pMemTbl = (PTYPE4 *) realloc (pMemTbl, MemMax * sizeof (PTYPE4));
  526.                         if (!pMemTbl)          // Allocation Failed
  527.                           {
  528.                             printf ("\aShared memory table realloc failed\n");
  529.                             exit (1);
  530.                           }
  531.                       }
  532.                     pMemTbl[MemNdx] = &pBuf->Type.Type_4;   // Save Pointer
  533.                     MemNdx++;          // Increment Shared Memory Index
  534.                     break;             // Exit Case
  535.                   }
  536.  
  537.                 default:               // Unknown Record Type
  538.                   {
  539.                     printf ("\n[%p] Record Type %04X  Next=%04X  Unknown Record Type\n",
  540.                         pBuf, pBuf->TypeCode, pBuf->Next);
  541.                     break;             // Exit Case
  542.                   }
  543.               }
  544.             OFFSETOF (pBuf) = Next;    // Bump to next record
  545.           }
  546.  
  547.         for (i=0; i < ProcNdx; i++)    // Cross Reference Procs & Mods
  548.           {
  549.             for (j=0; j < ModNdx; j++)
  550.               {
  551.                 if (pProcTbl[i]->ModID == pModTbl[j]->ModID) // Found Module
  552.                   {
  553.                     pProcTbl[i]->pName    = pModTbl[j]->pName;
  554.                     break;                 // Exit Inner Loop
  555.                   }
  556.               }
  557.           }
  558.  
  559.         for (i=0; i < ProcNdx; i++)    // Cross Reference Child Procs
  560.           {
  561.             for (j=0; j < ProcNdx; j++)
  562.               {
  563.                 if (pProcTbl[i]->Pid == pProcTbl[j]->PPid) // Found Child
  564.                   {
  565.                     pProcTbl[i]->Children++;
  566.                   }
  567.               }
  568.           }
  569.       }
  570.  
  571.     return rc;                         // Return To Main
  572.   }
  573.  
  574. #pragma subtitle ("Display Processes")
  575. #pragma page()
  576. /**********************************************************************
  577. **                     Display Process Information                   **
  578. **********************************************************************/
  579. VOID Display_Processes (VOID)
  580.   {
  581.   USHORT i, b, t;                      // Index
  582.   PCHAR  pName;                        // Process Name
  583.  
  584.     if (Sort_Pid_Num)                  // Numeric Sort by PID
  585.       {
  586.         qsort (pProcTbl, ProcNdx, sizeof (PPROCTBL), Pid_Sort);
  587.       }
  588.     else                               // Alpha Sort
  589.       {
  590.         qsort (pProcTbl, ProcNdx, sizeof (PPROCTBL), Pid_Name_Sort);
  591.       }
  592.     qsort (pThdTbl, ThdNdx, sizeof (PTYPE1), Tid_Sort);
  593.  
  594.     printf ("\n\t\tDisplay Process and Thread Information\n");
  595.     printf (" PID  PPID  Sess  Mod#  Proc Name   Chld  TID  sTID  Prty  Block ID  Flgs\n");
  596.     printf ("----  ----  ----  ----  ----------  ----  ---  ----  ----  --------  ----\n");
  597.  
  598.     for (i=0; i < ProcNdx; i++)        // Display Process Table
  599.       {
  600.         if (!pProcTbl[i]->pName)       // No Module Name
  601.           {
  602.             if (!pProcTbl[i]->ModID)   // No Module Handle - Kernal
  603.               {
  604.                 if (pProcTbl[i]->SessionID) // Must Be Dos Compat Box
  605.                   {
  606.                     pName = "(DosBox)";
  607.                   }
  608.                 else                   // Must be Kernal
  609.                   {
  610.                     pName = "(Kernal)";
  611.                   }
  612.               }
  613.             else                       // Unknown Module Name
  614.               {
  615.                 pName = "(Unknown)";
  616.               }
  617.           }
  618.         else                           // Use Specified Module Name
  619.           {
  620.             pName = pProcTbl[i]->pName;
  621.           }
  622.  
  623.         for (b=0; b < ThdNdx; b++)         // Find First Thread
  624.           {
  625.             if (pThdTbl[b]->ProcessID == pProcTbl[i]->Pid) // Found
  626.               {
  627.                 break;
  628.               }
  629.           }
  630.  
  631.         printf ("%04X  %04X   %02X   %04X  %-10.10s  %4u   %02X   %02X   %04X  %08lX  %04X\n",
  632.             pProcTbl[i]->Pid,
  633.             pProcTbl[i]->PPid,
  634.             pProcTbl[i]->SessionID,
  635.             pProcTbl[i]->ModID,
  636.             pName,
  637.             pProcTbl[i]->Children,
  638.             pThdTbl[b]->ThreadID,
  639.             pThdTbl[b]->SysThreadID,
  640.             pThdTbl[b]->Priority,
  641.             pThdTbl[b]->BlockID,
  642.             pThdTbl[b]->Flags);
  643.  
  644.         for (t=1; t < pProcTbl[i]->Threads; t++)
  645.           {
  646.             printf ("%42.42s %02X   %02X   %04X  %08lX  %04x\n", "",
  647.                 pThdTbl[b+t]->ThreadID,
  648.                 pThdTbl[b+t]->SysThreadID,
  649.                 pThdTbl[b+t]->Priority,
  650.                 pThdTbl[b+t]->BlockID,
  651.                 pThdTbl[b+t]->Flags);
  652.           }
  653.       }
  654.   }
  655.  
  656. #pragma subtitle ("Display Modules")
  657. #pragma page()
  658. /**********************************************************************
  659. **                     Display Module Information                    **
  660. **********************************************************************/
  661. VOID Display_Modules (VOID)
  662.   {
  663.   USHORT i, j;                         // Index
  664.  
  665.     if (Sort_Mod_Num)                  // Numeric Sort by ModID
  666.       {
  667.         qsort (pModTbl, ModNdx, sizeof (PMODTBL), Mod_Sort);
  668.       }
  669.     else                               // Alpha Sort
  670.       {
  671.         qsort (pModTbl, ModNdx, sizeof (PMODTBL), Mod_Name_Sort);
  672.       }
  673.  
  674.     printf ("\n\t\t\tDisplay Module Information\n");
  675.     printf ("Mod#  Deps  Name        Resource Module IDs\n");
  676.     printf ("----  ----  ----------  -------------------------------------------------\n");
  677.  
  678.     for (i=0; i < ModNdx; i++)         // Display Module Table
  679.       {
  680.         printf ("%04X  %4u  %-10.10s  ",
  681.             pModTbl[i]->ModID,
  682.             pModTbl[i]->MaxDeps,
  683.             pModTbl[i]->pName);
  684.  
  685.         if (pModTbl[i]->MaxDeps)       // Display Dependent Mod IDs
  686.           {
  687.             for (j=0; j < pModTbl[i]->MaxDeps; j++)
  688.               {
  689.                 if (j && !(j % 10))    // Force New Line
  690.                   {
  691.                     printf ("\n%24.24s", "");
  692.                   }
  693.                 printf ("%04X ", pModTbl[i]->pDeps[j]);
  694.               }
  695.           }
  696.         printf ("\n");
  697.       }
  698.   }
  699.  
  700. #pragma subtitle ("Display Semaphores")
  701. #pragma page()
  702. /**********************************************************************
  703. **                   Display Semaphore Information                   **
  704. **********************************************************************/
  705. VOID Display_Semaphores (VOID)
  706.   {
  707.   USHORT i, t, p;                      // Index
  708.   PID    Pid;                          // Process ID
  709.   PCHAR  pName;                        // Process Name
  710.  
  711.     qsort (pSemTbl, SemNdx, sizeof (PTYPE3), Sem_Sort);
  712.  
  713.     printf ("\n\t\tDisplay System Semaphore Information\n");
  714.     printf ("Owning Process  sTID  Unkn  Ref  Req  Flgs  System Semaphore Name\n");
  715.     printf ("--------------  ----  ----  ---  ---  ----  ---------------------\n");
  716.  
  717.     for (i=0; i < SemNdx; i++)         // Display Semaphore Table
  718.       {
  719.         pName = "????????";            // Unknown Owner
  720.         Pid = 0;                       // Unknown Process
  721.  
  722.         if (pSemTbl[i]->SysThreadID)   // Display Owner
  723.           {
  724.             for (t=0; t < ThdNdx; t++) // Find Owning Thread
  725.               {
  726.                 if (pSemTbl[i]->SysThreadID == pThdTbl[t]->SysThreadID) // Found Thread
  727.                   {
  728.                     for (p=0; p < ProcNdx; p++) // Find Owning Process
  729.                       {
  730.                         if (pThdTbl[t]->ProcessID == pProcTbl[p]->Pid) // Found Process
  731.                           {
  732.                             pName = pProcTbl[p]->pName;  // Process Name
  733.                             Pid = pProcTbl[p]->Pid;      // Process ID
  734.                             break;
  735.                           }
  736.                       }
  737.                     break;
  738.                   }
  739.               }
  740.           }
  741.  
  742.         if (pSemTbl[i]->SysThreadID)   // Semaphore is owned
  743.           {
  744.             printf ("%-10.10s%04X   %02X    %02X    %02X   %02X  %04X  %s\n",
  745.                 pName,
  746.                 Pid,
  747.                 pSemTbl[i]->SysThreadID,
  748.                 pSemTbl[i]->Unknown,
  749.                 pSemTbl[i]->RefCount,
  750.                 pSemTbl[i]->ReqCount,
  751.                 pSemTbl[i]->Flags,
  752.                 pSemTbl[i]->SemaphoreName);
  753.           }
  754.         else                           // Semaphore is not owned
  755.           {
  756.             printf ("%-14.14s   %02X    %02X    %02X   %02X  %04X  %s\n",
  757.                 "",
  758.                 pSemTbl[i]->SysThreadID,
  759.                 pSemTbl[i]->Unknown,
  760.                 pSemTbl[i]->RefCount,
  761.                 pSemTbl[i]->ReqCount,
  762.                 pSemTbl[i]->Flags,
  763.                 pSemTbl[i]->SemaphoreName);
  764.           }
  765.       }
  766.   }
  767.  
  768. #pragma subtitle ("Display Shared Memory")
  769. #pragma page()
  770. /**********************************************************************
  771. **                 Display Shared Memory Information                 **
  772. **********************************************************************/
  773. VOID Display_Memory (VOID)
  774.   {
  775.   USHORT i;                            // Index
  776.  
  777.     qsort (pMemTbl, MemNdx, sizeof (PTYPE4), Seg_Sort);
  778.  
  779.     printf ("\n\t\tDisplay Shared Memory Segment Information\n");
  780.     printf ("Hand   Sel   Use  Shared Memory Segment Name\n");
  781.     printf ("----  ----  ----  --------------------------\n");
  782.  
  783.     for (i=0; i < MemNdx; i++)         // Display Memory Table
  784.       {
  785.         printf ("%04X  %04X  %4u  \\SHAREMEM\\%s\n",
  786.             pMemTbl[i]->Handle,
  787.             pMemTbl[i]->Selector,
  788.             pMemTbl[i]->UseCount,
  789.             pMemTbl[i]->SegmentName);
  790.       }
  791.   }
  792.  
  793. #pragma subtitle ("Main Program")
  794. #pragma page()
  795. /**********************************************************************
  796. **                       Testing Main Entry Point                    **
  797. **********************************************************************/
  798. USHORT main (USHORT argc, PCHAR argv[])
  799.   {
  800.   USHORT rc = NO_ERROR;                // Return Code
  801.  
  802.     if (argc > 1)                      // Process Arguments
  803.       {
  804.         Process_Parameters (argc, argv);
  805.       }
  806.  
  807.     if (!Show_Procs && !Show_Mods && !Show_Sems && !Show_Segs) // Default
  808.       {
  809.         Show_Procs = TRUE;             // Display Processes
  810.       }
  811.  
  812.     rc = Initialization ();            // Initialize Data
  813.  
  814.     if (rc == NO_ERROR)                // Success
  815.       {
  816.         if (Show_Procs)                // Display Processes & Threads
  817.           {
  818.             Display_Processes ();
  819.           }
  820.  
  821.         if (Show_Mods)                 // Display Modules
  822.           {
  823.             Display_Modules ();
  824.           }
  825.  
  826.         if (Show_Sems)                 // Display System Semaphores
  827.           {
  828.             Display_Semaphores ();
  829.           }
  830.  
  831.         if (Show_Segs)                 // Display Shared Memory
  832.           {
  833.             Display_Memory ();
  834.           }
  835.       }
  836.  
  837.     return rc;                         // Return To OS/2
  838.   }
  839.