home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: WPS_PM / WPS_PM.zip / xfld085s.zip / helpers / procstat.c < prev    next >
C/C++ Source or Header  |  1999-02-23  |  14KB  |  462 lines

  1.  
  2. /*
  3.  *@@sourcefile procstat.c:
  4.  *      functions for querying process information.
  5.  *
  6.  *      Function prefixes (new with V0.81):
  7.  *      --  prc*   Query Process helper functions
  8.  *
  9.  *@@include #include <os2.h>
  10.  *@@include #include "procstat.h"
  11.  */
  12.  
  13. /*
  14.  *      Based on Kai Uwe Rommel's "dosqproc" package
  15.  *      available at Hobbes.
  16.  *      This file Copyright (C) 1992-99 Ulrich Möller,
  17.  *                                      Kai Uwe Rommel.
  18.  *      This file is part of the XFolder source package.
  19.  *      XFolder is free software; you can redistribute it and/or modify
  20.  *      it under the terms of the GNU General Public License as published
  21.  *      by the Free Software Foundation, in version 2 as it comes in the
  22.  *      "COPYING" file of the XFolder main distribution.
  23.  *      This program is distributed in the hope that it will be useful,
  24.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26.  *      GNU General Public License for more details.
  27.  */
  28.  
  29. #define INCL_DOS
  30. #define INCL_DOSMODULEMGR
  31. #include <os2.h>
  32.  
  33. #include <stdlib.h>      // already #include'd
  34. #include <string.h>      // already #include'd
  35. #include <stdio.h>
  36.  
  37. #include "procstat.h"
  38.  
  39. /********************************************************************
  40.  *                                                                  *
  41.  *   Functions for querying process information                     *
  42.  *                                                                  *
  43.  ********************************************************************/
  44.  
  45. /*
  46.  * prcTimestr:
  47.  *
  48.  */
  49.  
  50. /* void prcTimestr(ULONG time, char *buffer)
  51. {
  52.   ULONG seconds, hundredths;
  53.  
  54.   seconds = time / 32;
  55.   hundredths = (time % 32) * 100 / 32;
  56.  
  57.   sprintf(buffer, "%ld:%02ld.%02ld", seconds / 60, seconds % 60, hundredths);
  58. } */
  59.  
  60. /*
  61.  * prcSearchProcTree:
  62.  *
  63.  */
  64.  
  65. /* BOOL prcSearchProcTree(PQPROCSTAT pps, USHORT usSearchPID, USHORT usCheckPID, PPRCPROCESS pprcp)
  66. {
  67.     PQPROCESS pProcess;
  68.  
  69.     for ( pProcess = PTR(pps->ulProcesses, 0);
  70.           pProcess->ulType != 3; // not sure if there isn't another termination method
  71.           pProcess = PTR(pProcess->ulThreadList,
  72.                      pProcess->usThreads * sizeof(QTHREAD))
  73.         )
  74.     {
  75.         if (    (pProcess->usParentPID == usCheckPID)
  76.             &&  (pProcess->ulType != 0)
  77.            )
  78.         {
  79.             if (usSearchPID == pProcess->usPID) {
  80.                 prcReport(pProcess, pprcp);
  81.                 return (TRUE);
  82.             }
  83.             pProcess->ulType = 0;  // kludge, mark it as already printed
  84.             if (prcSearchProcTree(pps, usSearchPID, pProcess->usPID, pprcp))
  85.                 return (TRUE);
  86.         }
  87.     }
  88.  
  89.     if ( usCheckPID != 0 )
  90.         return (FALSE);
  91.  
  92.     // if at the root level, check for those processes that have lost
  93.     // their parent process and show them as if they were childs of 0
  94.  
  95.     for ( pProcess = PTR(pps->ulProcesses, 0);
  96.           pProcess->ulType != 3; // not sure if there isn't another termination method
  97.           pProcess = PTR(pProcess->ulThreadList,
  98.                      pProcess->usThreads * sizeof(QTHREAD))
  99.         )
  100.     {
  101.         if ( pProcess->ulType != 0 )
  102.         {
  103.             if (usSearchPID == pProcess->usPID) {
  104.                 prcReport(pProcess, pprcp);
  105.                 return (TRUE);
  106.             }
  107.             if (prcSearchProcTree(pps, usSearchPID, pProcess->usPID, pprcp))
  108.                 return (TRUE);
  109.         }
  110.  
  111.         pProcess->ulType = 1;    // kludge, reset mark
  112.     }
  113.     return (FALSE);
  114. } */
  115.  
  116. /*
  117.  * prcListThreads:
  118.  *
  119.  */
  120.  
  121. /* void prcListThreads(PQPROCSTAT pps)
  122. {
  123.     PQPROCESS pProcess;
  124.     PQTHREAD pThread;
  125.     UCHAR aucName[256], aucSysTime[32], aucUserTime[32];
  126.     USHORT usCount;
  127.     char *pcStatus;
  128.  
  129.     for ( pProcess = PTR(pps->ulProcesses, 0);
  130.           pProcess->ulType != 3;
  131.           pProcess = PTR(pProcess->ulThreadList,
  132.                      pProcess->usThreads * sizeof(QTHREAD))
  133.         )
  134.     {
  135.         DosQueryModuleName(pProcess->usHModule, sizeof(aucName), aucName);
  136.         // printf("%s\n", aucName);
  137.  
  138.         for ( usCount = 0, pThread = PTR(pProcess->ulThreadList, 0);
  139.               usCount < pProcess->usThreads;
  140.               usCount++, pThread++ )
  141.         {
  142.           prcTimestr(pThread->ulSysTime, aucSysTime);
  143.           prcTimestr(pThread->ulUserTime, aucUserTime);
  144.           // pcStatus = threadstat[pThread->ucStatus];
  145.           printf("%5d  %5d  %04lX %-7.7s %08lX %10s %10s\n",
  146.              pThread->usTID, pThread->usThreadSlotID, pThread->ulPriority,
  147.              pcStatus ? pcStatus : "Unknown", pThread->ulBlockID, aucSysTime, aucUserTime);
  148.         }
  149.     }
  150. } */
  151.  
  152. /*
  153.  * prcListModules:
  154.  *
  155.  */
  156.  
  157. /* void prcListModules(PQPROCSTAT pps, int imports)
  158. {
  159.   PQMODULE pModule;
  160.   UCHAR name[256];
  161.   ULONG ulCount;
  162.  
  163.   for ( pModule = PTR(pps->ulModules, 0); ;
  164.         pModule = PTR(pModule->nextmodule, 0)
  165.       )
  166.   {
  167.     if ( !imports || pModule->submodules )
  168.       if ( imports )
  169.       {
  170.         // printf("%04X  %s\n", pModule->modhandle, (char *) PTR(pModule->namepointer, 0));
  171.  
  172.         for ( ulCount = 0; ulCount < pModule->submodules; ulCount++ )
  173.         {
  174.           DosQueryModuleName(pModule->submodule[ulCount], sizeof(name), name);
  175.           // printf("  %04X  %s\n", pModule->submodule[ulCount], name);
  176.         }
  177.       }
  178.       else
  179.         printf(" %04X   %2d  %7ld  %6ld  %s\n", pModule->modhandle,
  180.                pModule->modtype ? 32 : 16, pModule->segments,
  181.                pModule->submodules, (char *) PTR(pModule->namepointer, 0));
  182.  
  183.     if ( pModule->nextmodule == 0L )
  184.       break;
  185.   }
  186. } */
  187.  
  188. /*
  189.  * prcListSemaphores:
  190.  *
  191.  */
  192.  
  193. /* void prcListSemaphores(PQPROCSTAT pps)
  194. {
  195.   PQSEMAPHORE pSemaphore;
  196.  
  197.   for ( pSemaphore = PTR(pps->ulSemaphores, 16);
  198.         pSemaphore->nextsem != 0L;
  199.         pSemaphore = PTR(pSemaphore->nextsem, 0)
  200.       )
  201.     printf("%3d  %3d   %02X  %4d   %04X  \\SEM%s\n",
  202.            pSemaphore->refs, pSemaphore->requests, pSemaphore->flag,
  203.            pSemaphore->owner, pSemaphore->index, pSemaphore->name);
  204.     ;
  205. } */
  206.  
  207.  
  208. /*
  209.  * prcListSharedMem:
  210.  *
  211.  */
  212.  
  213. /* void prcListSharedMem(PQPROCSTAT pps)
  214. {
  215.     PQSHAREDMEM pSharedMem;
  216.     UCHAR name[256];
  217.     ULONG size;
  218.     ULONG attrib;
  219.     PVOID base;
  220.  
  221.     for ( pSharedMem = PTR(pps->ulSharedMem, 0);
  222.           pSharedMem->nextseg != 0L;
  223.           pSharedMem = PTR(pSharedMem->nextseg, 0)
  224.         )
  225.     {
  226.         strcpy(name, "\\SHAREMEM\\");
  227.         strcat(name, pSharedMem->name);
  228.  
  229.         DosGetNamedSharedMem(&base, name, PAG_READ);
  230.         size = -1;
  231.         attrib = PAG_SHARED | PAG_READ;
  232.         if ( DosQueryMem(base, &size, &attrib) )
  233.           size = 0;
  234.         DosFreeMem(base);
  235.  
  236.         printf(" %04X   %04X   %08lX  %4d  %s\n", pSharedMem->handle,
  237.                pSharedMem->selector, size,
  238.                pSharedMem->refs, name);
  239.     }
  240. }  */
  241.  
  242. /*
  243.  * prcReport:
  244.  *      fill PRCPROCESS structure
  245.  */
  246.  
  247. VOID prcReport(PQPROCESS pProcess, PPRCPROCESS pprcp)
  248. {
  249.     USHORT usPriority = 0;
  250.     PQTHREAD pThread;
  251.     int i;
  252.  
  253.     DosQueryModuleName(pProcess->usHModule, sizeof(pprcp->szModuleName), pprcp->szModuleName);
  254.     // DosGetPrty(PRTYS_PROCESS, &(pprcp->usPriority), pProcess->usPID);
  255.  
  256.     // sum up CPU time for process
  257.     for ( pprcp->ulCPU = 0, i = 0, pThread = PTR(pProcess->ulThreadList, 0);
  258.               i < pProcess->usThreads;
  259.               i++, pThread++ )
  260.         pprcp->ulCPU += (pThread->ulSysTime + pThread->ulUserTime);
  261.  
  262.     pprcp->usPID            = pProcess->usPID;
  263.     pprcp->usParentPID      = pProcess->usParentPID;
  264.     pprcp->usThreads        = pProcess->usThreads;
  265.     pprcp->ulSID            = pProcess->ulSID;
  266.     pprcp->ulSessionType    = pProcess->ulSessionType;
  267.     pprcp->ulStatus         = pProcess->ulStatus;
  268. }
  269.  
  270. /*
  271.  *@@ prcQueryProcessInfo:
  272.  *      this searches for a given process ID (usPID) and
  273.  *      fills a given PRCPROCESS structure with lots of
  274.  *      information about this process.
  275.  *      Returns FALSE upon errors.
  276.  */
  277.  
  278. BOOL prcQueryProcessInfo(USHORT usPID, PPRCPROCESS pprcp)
  279. {
  280.     BOOL rc = FALSE;
  281.     PQPROCESS pProcess;
  282.     PQPROCSTAT pps = malloc(0x8000);
  283.     DosQProcStatus(pps, 0x8000);
  284.  
  285.     for ( pProcess = PTR(pps->ulProcesses, 0);
  286.           pProcess->ulType != 3;
  287.           pProcess = PTR(pProcess->ulThreadList,
  288.                      pProcess->usThreads * sizeof(QTHREAD))
  289.         )
  290.     {
  291.         if (pProcess->usPID == usPID) {
  292.             prcReport(pProcess, pprcp);
  293.             rc = TRUE;
  294.             break;
  295.         }
  296.     }
  297.  
  298.     free(pps);
  299.     return (rc);
  300. }
  301.  
  302. /*
  303.  *@@ prcForEachProcess:
  304.  *      this calls a given callback func for each running
  305.  *      process. The callback must be a FNWP, which will be
  306.  *      passed the following parameters for each call:
  307.  * <BR>     HWND hwnd       like hwnd passed to prcForEachProcess
  308.  * <BR>     ULONG msg       like msg passed to prcForEachProcess
  309.  * <BR>     MPARAM mp1      like mp1 passed to prcForEachProcess
  310.  * <BR>     PPRCPROCESS mp2 pointer to a PRCPROCESS struct for each process
  311.  *
  312.  *      This function returns the number of running processes on the
  313.  *      system. If pfnwpCallback is NULL, only this number will be
  314.  *      returned.
  315.  */
  316.  
  317. ULONG prcForEachProcess(PFNWP pfnwpCallback, HWND hwnd, ULONG ulMsg, MPARAM mp1)
  318. {
  319.     ULONG ulrc = 0;
  320.     PQPROCESS pProcess;
  321.     PRCPROCESS prcp;
  322.     PQPROCSTAT pps = malloc(0x8000);
  323.     DosQProcStatus(pps, 0x8000);
  324.  
  325.     for ( pProcess = PTR(pps->ulProcesses, 0);
  326.           pProcess->ulType != 3;
  327.           pProcess = PTR(pProcess->ulThreadList,
  328.                      pProcess->usThreads * sizeof(QTHREAD))
  329.         )
  330.     {
  331.         if (pfnwpCallback) {
  332.             prcReport(pProcess, &prcp);
  333.             (*pfnwpCallback)(hwnd, ulMsg, mp1, &prcp);
  334.         }
  335.         ulrc++;
  336.     }
  337.  
  338.     free(pps);
  339.     return (ulrc);
  340. }
  341.  
  342. /*
  343.  *@@ prcQueryThreadCount:
  344.  *      returns the total number of running threads
  345.  *      in the given process. If pid == 0, the
  346.  *      total thread count for the system is returned.
  347.  */
  348.  
  349. ULONG prcQueryThreadCount(USHORT usPID)
  350. {
  351.     ULONG       ulrc = 0;
  352.     PQPROCSTAT  pps = malloc(0x8000);
  353.     DosQProcStatus(pps, 0x8000);
  354.  
  355.     if (usPID)
  356.     {
  357.         // process query:
  358.         PQPROCESS pProcess;
  359.         for ( pProcess = PTR(pps->ulProcesses, 0);
  360.               pProcess->ulType != 3;
  361.               pProcess = PTR(pProcess->ulThreadList,
  362.                          pProcess->usThreads * sizeof(QTHREAD))
  363.             )
  364.         {
  365.             if (pProcess->usPID == usPID) {
  366.                 ulrc = pProcess->usThreads;
  367.                 break;
  368.             }
  369.         }
  370.     } else
  371.     {
  372.         // global query:
  373.         PQGLOBAL   pg;
  374.         pg = PTR(pps->ulGlobal, 0);
  375.         ulrc = pg->ulThreads;
  376.     }
  377.  
  378.     free(pps);
  379.     return (ulrc);
  380. }
  381.  
  382. /*
  383.  *@@ prcQueryThreadInfo:
  384.  *      this searches for a given thread in a given process
  385.  *      and fills a given PRCTHREAD structure with lots of
  386.  *      information about that thread.
  387.  *
  388.  *      Returns FALSE upon errors.
  389.  *
  390.  *      Note: This function loops thru all processes which
  391.  *      are currently running and is therefore not terribly
  392.  *      fast. Use economically.
  393.  */
  394.  
  395. BOOL prcQueryThreadInfo(USHORT usPID, USHORT usTID, PPRCTHREAD pprct)
  396. {
  397.     BOOL        brc = FALSE;
  398.     PQPROCSTAT  pps = malloc(0x8000);
  399.     PQPROCESS pProcess;
  400.     DosQProcStatus(pps, 0x8000);
  401.  
  402.     // find process:
  403.     for ( pProcess = PTR(pps->ulProcesses, 0);
  404.           pProcess->ulType != 3;
  405.           pProcess = PTR(pProcess->ulThreadList,
  406.                      pProcess->usThreads * sizeof(QTHREAD))
  407.         )
  408.     {
  409.         if (pProcess->usPID == usPID) {
  410.             PQTHREAD pThread;
  411.             int i;
  412.             // process found: find thread
  413.             for ( i = 0, pThread = PTR(pProcess->ulThreadList, 0);
  414.                   i < pProcess->usThreads;
  415.                   i++, pThread++ )
  416.             {
  417.                 if (pThread->usTID == usTID) {
  418.                     // thread found:
  419.                     pprct->usTID          = pThread->usTID;
  420.                     pprct->usThreadSlotID = pThread->usThreadSlotID;
  421.                     pprct->ulBlockID      = pThread->ulBlockID;
  422.                     pprct->ulPriority     = pThread->ulPriority;
  423.                     pprct->ulSysTime      = pThread->ulSysTime;
  424.                     pprct->ulUserTime     = pThread->ulUserTime;
  425.                     pprct->ucStatus       = pThread->ucStatus;
  426.  
  427.                     brc = TRUE;
  428.  
  429.                     break; // thread-for loop
  430.                 }
  431.             } // end for thread
  432.             break; // process-for loop
  433.         }
  434.     } // end for process
  435.  
  436.     free(pps);
  437.     return (brc);
  438. }
  439.  
  440. /*
  441.  *@@ prcQueryPriority:
  442.  *      shortcut to prcQueryThreadInfo if you want the priority only.
  443.  *
  444.  *      Returns -1 upon errors.
  445.  *
  446.  *      Note: This function loops thru all processes which
  447.  *      are currently running and is therefore not terribly
  448.  *      fast. Use economically.
  449.  */
  450.  
  451. ULONG prcQueryThreadPriority(USHORT usPID, USHORT usTID)
  452. {
  453.     PRCTHREAD prct;
  454.     ULONG ulrc = -1;
  455.     if (prcQueryThreadInfo(usPID, usTID, &prct))
  456.         ulrc = prct.ulPriority;
  457.     return (ulrc);
  458. }
  459.  
  460.  
  461.  
  462.