home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / taman002.zip / TASKMANA.ZIP / src / TaskMgrProt.c < prev    next >
C/C++ Source or Header  |  2000-04-29  |  39KB  |  942 lines

  1. /* $Id: TaskMgrProt.c,v 1.1 2000/04/29 19:06:34 stknut Exp $
  2.  *
  3.  * Textmode prototype made for testing purposes of the OS/2 taskmgr.
  4.  *
  5.  * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  6.  *
  7.  * (GPL licensed)
  8.  *
  9.  */
  10. /*******************************************************************************
  11. *   Defined Constants And Macros                                               *
  12. *******************************************************************************/
  13. #define INCL_DOSERRORS
  14. #define INCL_DOSPROCESS
  15.  
  16. /*******************************************************************************
  17. *   Header Files                                                               *
  18. *******************************************************************************/
  19. #include <os2.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <malloc.h>
  23. #include <assert.h>
  24.  
  25. /*******************************************************************************
  26. *   From the OS/2 4.5 toolkit.                                                 *
  27. *******************************************************************************/
  28. /* defines and structures for DosQuerySysState */
  29. #pragma pack(1)
  30. /* record types */
  31. #define QS_PROCESS      0x0001
  32. #define QS_SEMAPHORE    0x0002
  33. #define QS_MTE          0x0004
  34. #define QS_FILESYS      0x0008
  35. #define QS_SHMEMORY     0x0010
  36. #define QS_DISK         0x0020
  37. #define QS_HWCONFIG     0x0040
  38. #define QS_NAMEDPIPE    0x0080
  39. #define QS_THREAD       0x0100
  40. #define QS_MODVER       0x0200
  41.  
  42. /* valid EntityList bit settings */
  43. #define QS_SUPPORTED    (QS_PROCESS|QS_SEMAPHORE|QS_MTE|QS_FILESYS|QS_SHMEMORY|QS_MODVER)
  44.  
  45. /* All structures must be padded to dword boundaries if necessary  */
  46. /* The semicolon that is needed to terminate the structure field   */
  47. /* must be added in the structure definition itself, because H2INC */
  48. /* ignores it in a #define statement. */
  49. #define PADSHORT        USHORT        pad_sh
  50. #define PADCHAR         UCHAR         pad_ch
  51.  
  52. #define QS_END          0L       /* last FILESYS record */
  53.  
  54. /* Global Record structure
  55.  * Holds all global system information. Placed first in user buffer
  56.  */
  57. typedef struct qsGrec_s {  /* qsGrec */
  58.         ULONG         cThrds;
  59.         ULONG         c32SSem;
  60.         ULONG         cMFTNodes;
  61. } qsGrec_t;
  62.  
  63. /* Thread Record structure
  64.  *      Holds all per thread information.
  65.  */
  66. typedef struct qsTrec_s {  /* qsTrec */
  67.         ULONG         RecType;        /* Record Type */
  68.         USHORT        tid;            /* thread ID */
  69.         USHORT        slot;           /* "unique" thread slot number */
  70.         ULONG         sleepid;        /* sleep id thread is sleeping on */
  71.         ULONG         priority;       /* thread priority */
  72.         ULONG         systime;        /* thread system time */
  73.         ULONG         usertime;       /* thread user time */
  74.         UCHAR         state;          /* thread state */
  75.         PADCHAR;
  76.         PADSHORT;
  77. } qsTrec_t;
  78.  
  79. /* Process Record structure
  80.  *      Holds all per process information.
  81.  *      ________________________________
  82.  *      |       RecType                 |
  83.  *      |-------------------------------|
  84.  *      |       pThrdRec                |----|
  85.  *      |-------------------------------|    |
  86.  *      |       pid                     |    |
  87.  *      |-------------------------------|    |
  88.  *      |       ppid                    |    |
  89.  *      |-------------------------------|    |
  90.  *      |       type                    |    |
  91.  *      |-------------------------------|    |
  92.  *      |       stat                    |    |
  93.  *      |-------------------------------|    |
  94.  *      |       sgid                    |    |
  95.  *      |-------------------------------|    |
  96.  *      |       hMte                    |    |
  97.  *      |-------------------------------|    |
  98.  *      |       cTCB                    |    |
  99.  *      |-------------------------------|    |
  100.  *      |       c32PSem                 |    |
  101.  *      |-------------------------------|    |
  102.  *      |       p32SemRec               |----|---|
  103.  *      |-------------------------------|    |   |
  104.  *      |       c16Sem                  |    |   |
  105.  *      |-------------------------------|    |   |
  106.  *      |       cLib                    |    |   |
  107.  *      |-------------------------------|    |   |
  108.  *      |       cShrMem                 |    |   |
  109.  *      |-------------------------------|    |   |
  110.  *      |       cFS                     |    |   |
  111.  *      |-------------------------------|    |   |
  112.  *      |       p16SemRec               |----|---|----|
  113.  *      |-------------------------------|    |   |    |
  114.  *      |       pLibRec                 |----|---|----|------|
  115.  *      |-------------------------------|    |   |    |      |
  116.  *      |       pShrMemRec              |----|---|----|------|----|
  117.  *      |-------------------------------|    |   |    |      |    |
  118.  *      |       pFSRec                  |----|---|----|------|----|-----|
  119.  *      |-------------------------------|    |   |    |      |    |     |
  120.  *      |       32SemPPRUN[0]           |<---|---|    |      |    |     |
  121.  *      |          .                    |    |        |      |    |     |
  122.  *      |          .                    |    |        |      |    |     |
  123.  *      |          .                    |    |        |      |    |     |
  124.  *      |       32SemPPRUN[c32PSem-1]   |    |        |      |    |     |
  125.  *      |-------------------------------|    |        |      |    |     |
  126.  *      |       16SemIndx[0]            |<---|--------|      |    |     |
  127.  *      |          .                    |    |               |    |     |
  128.  *      |          .                    |    |               |    |     |
  129.  *      |          .                    |    |               |    |     |
  130.  *      |       16SemIndx[c16Sem-1]     |    |               |    |     |
  131.  *      |-------------------------------|    |               |    |     |
  132.  *      |       hmte[0] (or "name str") |<---|---------------|    |     |
  133.  *      |          .                    |    |                    |     |
  134.  *      |          .                    |    |                    |     |
  135.  *      |          .                    |    |                    |     |
  136.  *      |       hmte[cLib-1]            |    |                    |     |
  137.  *      |-------------------------------|    |                    |     |
  138.  *      |       hshmem[0]               |<---|--------------------|     |
  139.  *      |          .                    |    |                          |
  140.  *      |          .                    |    |                          |
  141.  *      |          .                    |    |                          |
  142.  *      |       hshmem[cShrMem-1]       |    |                          |
  143.  *      |-------------------------------|    |                          |
  144.  *      |       fsinfo[0]               |<---|--------------------------|
  145.  *      |          .                    |    |
  146.  *      |          .                    |    |
  147.  *      |          .                    |    |
  148.  *      |       fsinfo[cFS-1]           |    |
  149.  *      |-------------------------------|    |
  150.  *                                      <-----
  151.  *      NOTE that the process name string will be stored in place of hmtes
  152.  *              if MTE information is NOT being requested.
  153.  *      NOTE that following this structure in the user buffer is
  154.  *              an array c32Sems long of PRUN structures for 32 bit sems
  155.  *              an array c16Sems long of indices for 16 bit sems
  156.  *              the process name string
  157.  */
  158. typedef struct qsPrec_s {  /* qsPrec */
  159.         ULONG         RecType;        /* type of record being processed */
  160.         qsTrec_t  FAR *pThrdRec;      /* ptr to thread recs for this proc */
  161.         USHORT        pid;            /* process ID */
  162.         USHORT        ppid;           /* parent process ID */
  163.         ULONG         type;           /* process type */
  164.         ULONG         stat;           /* process status */
  165.         ULONG         sgid;           /* process screen group */
  166.         USHORT        hMte;           /* program module handle for process */
  167.         USHORT        cTCB;           /* # of TCBs in use */
  168.         ULONG         c32PSem;        /* # of private 32-bit sems in use */
  169.         void      FAR *p32SemRec;     /* pointer to head of 32bit sem info */
  170.         USHORT        c16Sem;         /* # of 16 bit system sems in use */
  171.         USHORT        cLib;           /* number of runtime linked libraries */
  172.         USHORT        cShrMem;        /* number of shared memory handles */
  173.         USHORT        cFH;            /* number of open files */
  174.         USHORT   FAR  *p16SemRec;     /* pointer to head of 16 bit sem info */
  175.         USHORT   FAR  *pLibRec;       /* ptr to list of runtime libraries */
  176.         USHORT   FAR  *pShrMemRec;    /* ptr to list of shared mem handles */
  177.         USHORT   FAR  *pFSRec;        /* pointer to list of file handles */
  178. } qsPrec_t;
  179.  
  180. /*
  181.  *      16 bit system semaphore structure
  182.  *      ________________________________
  183.  *      |       pNextRec                |----|
  184.  *      |-------------------------------|    |
  185.  *      |SysSemData     :               |    |
  186.  *      |       SysSemOwner             |    |
  187.  *      |       SysSemFlag              |    |
  188.  *      |       SysSemRecCnt            |    |
  189.  *      |       SysSemProcCnt           |    |
  190.  *      |-------------------------------|    |
  191.  *      |-------------------------------|    |
  192.  *      |-------------------------------|    |
  193.  *      |       SysSemPtr               |    |
  194.  *      |-------------------------------|    |
  195.  *      |SysSemName:                    |    |
  196.  *      |       "pathname"              |    |
  197.  *      |-------------------------------|    |
  198.  *                                      <-----
  199.  */
  200.  
  201.  
  202. /* SysSemFlag values */
  203.  
  204. #define QS_SYSSEM_WAITING 0x01               /* a thread is waiting on the sem */
  205. #define QS_SYSSEM_MUXWAITING 0x02            /* a thread is muxwaiting on the sem */
  206. #define QS_SYSSEM_OWNER_DIED 0x04            /* the process/thread owning the sem died */
  207. #define QS_SYSSEM_EXCLUSIVE 0x08             /* indicates a exclusive system semaphore */
  208. #define QS_SYSSEM_NAME_CLEANUP 0x10          /* name table entry needs to be removed */
  209. #define QS_SYSSEM_THREAD_OWNER_DIED 0x20     /* the thread owning the sem died */
  210. #define QS_SYSSEM_EXITLIST_OWNER 0x40        /* the exitlist thread owns the sem */
  211.  
  212. typedef struct qsS16rec_s {   /* qsS16rec */
  213.         ULONG         NextRec;        /* offset to next record in buffer */
  214.                                       /* System Semaphore Table Structure */
  215.         USHORT        SysSemOwner ;   /* thread owning this semaphore */
  216.         UCHAR         SysSemFlag ;    /* system semaphore flag bit field */
  217.         UCHAR         SysSemRefCnt ;  /* number of references to this sys sem */
  218.         UCHAR         SysSemProcCnt ; /* number of requests for this owner */
  219.         UCHAR         SysSemPad ;     /* pad byte to round structure up to word */
  220.         USHORT        pad_sh;
  221.         USHORT        SemPtr;         /* RMP SysSemPtr field */
  222.         char          SemName;        /* start of semaphore name string */
  223. } qsS16rec_t;
  224.  
  225. typedef struct qsS16Headrec_s {  /* qsS16Hrec */
  226.         ULONG         SRecType;
  227.         ULONG         SpNextRec;      /* overlays NextRec of 1st qsS16rec_t*/
  228.         ULONG         S32SemRec;
  229.         ULONG         S16TblOff;      /* offset of SysSemDataTable */
  230.         ULONG         pSem16Rec;
  231. } qsS16Headrec_t;
  232.  
  233. /*
  234.  *      System wide Shared Mem information
  235.  *      ________________________________
  236.  *      |       NextRec                 |
  237.  *      |-------------------------------|
  238.  *      |       hmem                    |
  239.  *      |-------------------------------|
  240.  *      |       sel                     |
  241.  *      |-------------------------------|
  242.  *      |       refcnt                  |
  243.  *      |-------------------------------|
  244.  *      |       name                    |
  245.  *      |_______________________________|
  246.  *
  247.  */
  248. typedef struct qsMrec_s {  /* qsMrec */
  249.         ULONG         MemNextRec;       /* offset to next record in buffer */
  250.         USHORT        hmem;             /* handle for shared memory */
  251.         USHORT        sel;              /* selector */
  252.         USHORT        refcnt;           /* reference count */
  253.         char          Memname;          /* start of shared memory name string */
  254. } qsMrec_t;
  255.  
  256. /*
  257.  *      32 bit system semaphore structure
  258.  *      ________________________________
  259.  *      |       pNextRec                |----|
  260.  *      |-------------------------------|    |
  261.  *      |       QSHUN[0]                |    |
  262.  *      |-------------------------------|    |
  263.  *      |         MuxQ                  |    |
  264.  *      |-------------------------------|    |
  265.  *      |         OpenQ                 |    |
  266.  *      |-------------------------------|    |
  267.  *      |         SemName               |    |
  268.  *      |-------------------------------|<---|
  269.  *      |          .                    |
  270.  *      |          .                    |
  271.  *      |-------------------------------|<---|
  272.  *      |       pNextRec                |----|
  273.  *      |-------------------------------|    |
  274.  *      |       QSHUN[c32SSem-1]        |    |
  275.  *      |-------------------------------|    |
  276.  *      |         MuxQ                  |    |
  277.  *      |-------------------------------|    |
  278.  *      |         OpenQ                 |    |
  279.  *      |-------------------------------|    |
  280.  *      |         SemName               |    |
  281.  *      |-------------------------------|<---|
  282.  */
  283.  
  284. /*
  285.  *  32- bit Semaphore flags
  286.  */
  287.  
  288. #define QS_DC_SEM_SHARED   0x0001   //  Shared Mutex, Event or MUX semaphore
  289. #define QS_DCMW_WAIT_ANY   0x0002   //  Wait on any event/mutex to occur
  290. #define QS_DCMW_WAIT_ALL   0x0004   //  Wait on all events/mutexs to occur
  291. #define QS_DCM_MUTEX_SEM   0x0008   //  Mutex semaphore
  292. #define QS_DCE_EVENT_SEM   0x0010   //  Event semaphore
  293. #define QS_DCMW_MUX_SEM    0x0020   //  Muxwait semaphore
  294. #define QS_DC_SEM_PM       0x0040   //  PM Shared Event Semphore
  295. #define QS_DE_POSTED       0x0040   //  event sem is in the posted state
  296. #define QS_DM_OWNER_DIED   0x0080   //  The owning process died
  297. #define QS_DMW_MTX_MUX     0x0100   //  MUX contains mutex sems
  298. #define QS_DHO_SEM_OPEN    0x0200   //  Device drivers have opened this semaphore
  299. #define QS_DE_16BIT_MW     0x0400   //  Part of a 16-bit MuxWait
  300. #define QS_DCE_POSTONE     0x0800   //  Post one flag event semaphore
  301. #define QS_DCE_AUTORESET   0x1000   //  Auto-reset event semaphore
  302.  
  303. typedef struct qsopenq_s {    /* qsopenq */
  304.         PID           pidOpener;      /* process id of opening process */
  305.         USHORT        OpenCt;         /* number of opens for this process */
  306. } QSOPENQ;
  307. typedef struct qsevent_s {    /* qsevent */
  308.         QSOPENQ       *pOpenQ;        /* pointer to open q entries */
  309.         UCHAR         *pName;         /* pointer to semaphore name */
  310.         ULONG         *pMuxQ;         /* pointer to the mux queue */
  311.         USHORT        flags;
  312.         USHORT        PostCt;         /* # of posts */
  313. } QSEVENT;
  314. typedef struct qsmutex_s {    /* qsmutex */
  315.         QSOPENQ       *pOpenQ;        /* pointer to open q entries */
  316.         UCHAR         *pName;         /* pointer to semaphore name */
  317.         ULONG         *pMuxQ;         /* pointer to the mux queue */
  318.         USHORT        flags;
  319.         USHORT        ReqCt;          /* # of requests */
  320.         USHORT        SlotNum;        /* slot # of owning thread */
  321.         PADSHORT;
  322. } QSMUTEX;
  323. typedef struct qsmux_s {   /* qsmux */
  324.         QSOPENQ         *pOpenQ;        /* pointer to open q entries */
  325.         UCHAR           *pName;         /* pointer to semaphore name */
  326.         void            *pSemRec;       /* array of semaphore record entries */
  327.         USHORT          flags;
  328.         USHORT          cSemRec;        /* count of semaphore records */
  329.         USHORT          WaitCt;         /* # threads waiting on the mux */
  330.         PADSHORT;
  331. } QSMUX;
  332. typedef struct qsshun_s {  /* qsshun */
  333.         QSEVENT         qsSEvt;         /* shared event sem */
  334.         QSMUTEX         qsSMtx;         /* shared mutex sem */
  335.         QSMUX           qsSMux;         /* shared mux sem */
  336. } QSHUN;
  337. typedef struct qsS32rec_s {   /* qsS32rec */
  338.         void            *pNextRec;      /* pointer to next record in buffer */
  339.         QSHUN           qsh;            /* qstate version of SHUN record */
  340. } qsS32rec_t;
  341.  
  342. /*
  343.  *      System wide MTE information
  344.  *      ________________________________
  345.  *      |       pNextRec                |----|
  346.  *      |-------------------------------|    |
  347.  *      |       hmte                    |    |
  348.  *      |-------------------------------|    |
  349.  *      |       ctImpMod                |    |
  350.  *      |-------------------------------|    |
  351.  *      |       ctObj                   |    |
  352.  *      |-------------------------------|    |
  353.  *      |       pObjInfo                |----|----------|
  354.  *      |-------------------------------|    |          |
  355.  *      |       pName                   |----|----|     |
  356.  *      |-------------------------------|    |    |     |
  357.  *      |       imported module handles |    |    |     |
  358.  *      |          .                    |    |    |     |
  359.  *      |          .                    |    |    |     |
  360.  *      |          .                    |    |    |     |
  361.  *      |-------------------------------| <--|----|     |
  362.  *      |       "pathname"              |    |          |
  363.  *      |-------------------------------| <--|----------|
  364.  *      |       Object records          |    |
  365.  *      |       (if requested)          |    |
  366.  *      |_______________________________|    |
  367.  *                                      <-----
  368.  *      NOTE that if the level bit is set to QS_MTE, the base Lib record will be followed
  369.  *      by a series of object records (qsLObj_t); one for each object of the
  370.  *      module.
  371.  */
  372.  
  373. typedef struct qsLObjrec_s {  /* qsLOrec */
  374.         ULONG         oaddr;  /* object address */
  375.         ULONG         osize;  /* object size */
  376.         ULONG         oflags; /* object flags */
  377. } qsLObjrec_t;
  378.  
  379. typedef struct qsLrec_s {     /* qsLrec */
  380.         void  FAR        *pNextRec;      /* pointer to next record in buffer */
  381.         USHORT           hmte;           /* handle for this mte */
  382.         USHORT           fFlat;          /* true if 32 bit module */
  383.         ULONG            ctImpMod;       /* # of imported modules in table */
  384.         ULONG            ctObj;          /* # of objects in module (mte_objcnt)*/
  385.         qsLObjrec_t FAR  *pObjInfo;      /* pointer to per object info if any */
  386.         UCHAR     FAR    *pName;         /* -> name string following struc */
  387. } qsLrec_t;
  388.  
  389. /* Used for 9th bit (Extended Module Data Summary)*/
  390. typedef struct qsExLrec_s {   /* qsELrec */
  391.         struct          qsExLrec_s *next; /*  Pointer to next Extended Module Data */
  392.         USHORT          hndmod;           /*  Module Handle */
  393.         USHORT          pid;              /*  Process ID */
  394.         USHORT          type;             /*  Type of Module */
  395.         ULONG           refcnt;           /*  Size of reference array */
  396.         ULONG           segcnt;           /*  Number of segments in module */
  397.         void            *_reserved_;
  398.         UCHAR FAR       *name;            /*  Pointer to Module Name  */
  399.         ULONG           ModuleVersion;    /*  Module version value  */
  400.         UCHAR FAR       *ShortModName;    /*  New Pointer to Module short name */
  401.         ULONG           modref;           /*  Start of array of handles of module */
  402. }qsExLrec_t;
  403.  
  404. /*
  405.  *      System wide FILE information
  406.  *      ________________________________
  407.  *      |       RecType                 |
  408.  *      |-------------------------------|
  409.  *      |       pNextRec                |-------|
  410.  *      |-------------------------------|       |
  411.  *      |       ctSft                   |       |
  412.  *      |-------------------------------|       |
  413.  *      |       pSft                    |---|   |
  414.  *      |-------------------------------|   |   |
  415.  *      |       name                    |   |   |
  416.  *      |-------------------------------|<--|   |
  417.  *      |       qsSft[0]                |       |
  418.  *      |-------------------------------|       |
  419.  *      |       ...                     |       |
  420.  *      |-------------------------------|       |
  421.  *      |       qsSft[ctSft -1]         |       |
  422.  *      |_______________________________|       |
  423.  *      |       name                    |
  424.  *      |_______________________________|
  425.  *                                      <-------|
  426.  */
  427. typedef struct qsSft_s {   /* qsSft */
  428.         USHORT        sfn;            /* SFN sf_fsi.sfi_selfSFN */
  429.         USHORT        refcnt;         /* sf_ref_count */
  430.         USHORT        flags;          /* sf_flags */
  431.         USHORT        flags2;         /* sf_flags2 */
  432.         USHORT        mode;           /* sf_fsi.sfi_mode - mode of access */
  433.         USHORT        mode2;          /* sf_fsi.sfi_mode2 - mode of access */
  434.         ULONG         size;           /* sf_fsi.sfi_size */
  435.         USHORT        hVPB;           /* sf_fsi.sfi_hVPB handle of volume */
  436.         USHORT        attr;           /* sf_attr */
  437.         PADSHORT;
  438. } qsSft_t;
  439.  
  440. typedef struct qsFrec_s {  /* qsFrec */
  441.         ULONG         RecType;        /* Record Type */
  442.         void          *pNextRec;      /* pointer to next record in buffer */
  443.         ULONG         ctSft;          /* # sft entries for this MFT entry */
  444.         qsSft_t       *pSft;          /* -> start of sft entries in buf */
  445.  
  446.         char          name[1];        /* kso: start of name? */
  447.  
  448. } qsFrec_t;
  449.  
  450.  
  451. /* Pointer Record Structure
  452.  *      This structure is the first in the user buffer.
  453.  *      It contains pointers to heads of record types that are loaded
  454.  *      into the buffer.
  455.  */
  456.  
  457. typedef struct qsPtrRec_s {   /* qsPRec */
  458.         qsGrec_t        *pGlobalRec;
  459.         qsPrec_t        *pProcRec;      /* ptr to head of process records */
  460.         qsS16Headrec_t  *p16SemRec;     /* ptr to head of 16 bit sem recds */
  461.         qsS32rec_t      *p32SemRec;     /* ptr to head of 32 bit sem recds */
  462.         qsMrec_t        *pMemRec;       /* ptr to head of shared mem recs */
  463.         qsLrec_t        *pLibRec;       /* ptr to head of mte records */
  464.         qsMrec_t        *pShrMemRec;    /* ptr to head of shared mem records */
  465.         qsFrec_t        *pFSRec;        /* ptr to head of file sys records */
  466. } qsPtrRec_t;
  467.  
  468.  
  469. APIRET  APIENTRY DosQuerySysState(ULONG EntityList,
  470.                                   ULONG EntityLevel,
  471.                                   PID pid,
  472.                                   TID tid,
  473.                                   PVOID pDataBuf,
  474.                                   ULONG cbBuf);
  475.  
  476. /*******************************************************************************
  477. *   Structures and Typedefs                                                    *
  478. *******************************************************************************/
  479. typedef struct ProcessData
  480. {
  481.     USHORT       usPid;                 /* sort key - process identificator. */
  482.     ULONG        ulUserTime;            /* total time in user code */
  483.     ULONG        ulSysTime;             /* total time in system code */
  484.     BOOL         fDead;                 /* Dead flag. */
  485.     BOOL         fDirty;                /* Update flag. Set: update container element. */
  486.     ULONG        cbProcRec;             /* Size of all the data used in pProcRec. */
  487.     qsPrec_t    *pProcRec;              /* Pointer to data returned by DosQuerySysState */
  488.                                         /* Note that this data is voilatile! */
  489.     PVOID        pvRecordCore;          /* Pointer to container record core. */
  490.     struct ProcessData *pNext;          /* Next pointer */
  491.     struct ProcessData *pPrev;          /* Prev pointer */
  492. } PROCESSDATA, *PPROCESSDATA;
  493.  
  494.  
  495. /*******************************************************************************
  496. *   Global Variables                                                           *
  497. *******************************************************************************/
  498. static PPROCESSDATA     pProcFirst = NULL;
  499. static PPROCESSDATA     pProcLast = NULL;
  500. static PPROCESSDATA     pProcCur = NULL;
  501. static qsLrec_t *       pMTEs = NULL;
  502. static qsS16Headrec_t * p16Sems = NULL;
  503. static qsS32rec_t *     p32Sems = NULL;
  504. static qsMrec_t *       pMemRecs = NULL;
  505. static qsMrec_t *       pShrMemRecs = NULL;
  506. static qsFrec_t *       pFSRecs = NULL;
  507. static qsGrec_t *       pGlobalRec = NULL;
  508. static unsigned         cBuffers = 2;
  509. static unsigned         cbBuffer = 128*1024;
  510. static char             achBuffer[2][128*1024];
  511. static unsigned         iCurBuffer = 1;
  512.  
  513.  
  514.  
  515. /*******************************************************************************
  516. *   Internal Functions                                                         *
  517. *******************************************************************************/
  518. BOOL            QSUpdateStataData(VOID);
  519. VOID            QSInsertProcessData(PPROCESSDATA pProcData);
  520. PPROCESSDATA    QSGetProcessData(USHORT usPid);
  521. qsLrec_t *      QSGetMteData(register USHORT hMTE);
  522. qsFrec_t *      QSGetSfnData(USHORT usSFN);
  523. VOID            QSDumpProcessData(VOID);
  524. VOID            QSDumpFileSystemData(VOID);
  525.  
  526.  
  527.  
  528.  
  529. /**
  530.  * Main function.
  531.  * @returns   0
  532.  * @param     argc  not used
  533.  * @param     argv  not used
  534.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  535.  * @remark
  536.  */
  537. void main(int argc, char **argv)
  538. {
  539.     PPROCESSDATA pCur;
  540. #if 0
  541.     QSUpdateStataData();
  542.     QSDumpProcessData();
  543.     DosSleep(0);
  544.  
  545.     /* clean stuff */
  546.     for (pCur = pProcFirst; pCur != NULL; pCur = pCur->pNext)
  547.         pCur->fDirty = FALSE;
  548. #endif
  549.     QSUpdateStataData();
  550.     QSDumpProcessData();
  551.     QSDumpFileSystemData();
  552.  
  553. }
  554.  
  555.  
  556. /**
  557.  * Updates the status data.
  558.  * @returns   TRUE - success
  559.  *            FALSE - failure.
  560.  * @status
  561.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  562.  * @remark    Single threaded!
  563.  */
  564. BOOL            QSUpdateStataData(void)
  565. {
  566.     APIRET      rc;
  567.  
  568.     /*
  569.      * Find correct buffer, Zero it, and query sys stata.
  570.      */
  571.     iCurBuffer = (iCurBuffer + 1) % cBuffers;
  572.     memset(achBuffer[iCurBuffer], 0, cbBuffer);
  573.     rc = DosQuerySysState(QS_PROCESS | QS_SEMAPHORE | QS_MTE | QS_FILESYS | QS_SHMEMORY, /* information requested */
  574.                           0UL,                      /* unused for QS_PROCESS */
  575.                           0UL,                      /* PID. 0 is all processes. */
  576.                           0UL,                      /* TID. 0 is all threads. (PID=0 too) */
  577.                           achBuffer[iCurBuffer],    /* Pointer to databuffer. */
  578.                           cbBuffer);                /* Size of databuffer. */
  579.     if (rc == NO_ERROR)
  580.     {
  581.         qsPtrRec_t *pPtrRec;            /* Pointer to pointer record at buffer start. */
  582.         qsPrec_t   *pProcRec;           /* Current process record. */
  583.         PPROCESSDATA pProcData;
  584.  
  585.         /*
  586.          * Local data
  587.          */
  588.         pPtrRec = (qsPtrRec_t*)achBuffer[iCurBuffer];
  589.         pProcRec = pPtrRec->pProcRec;
  590.  
  591.         /*
  592.          * Global data
  593.          */
  594.         pMTEs = pPtrRec->pLibRec;
  595.         p16Sems = pPtrRec->p16SemRec;
  596.         p32Sems = pPtrRec->p32SemRec;
  597.         pMemRecs = pPtrRec->pMemRec;
  598.         pShrMemRecs = pPtrRec->pShrMemRec;
  599.         pFSRecs = pPtrRec->pFSRec;
  600.         pGlobalRec = pPtrRec->pGlobalRec;
  601.  
  602.         /*
  603.          * Set dead flag before starting to update and add processes.
  604.          * When a process have been found in the new stat data, the
  605.          * dead flag is cleared.
  606.          */
  607.         for (pProcData = pProcFirst; pProcData != NULL; pProcData = pProcData->pNext)
  608.             pProcData->fDead = TRUE;
  609.  
  610.         /*
  611.          * Loop thru all processes which was found and update or add
  612.          * data to the linked list of processes.
  613.          */
  614.         while (pProcRec != NULL && pProcRec->RecType == QS_PROCESS)
  615.         {
  616.             unsigned long ulSysTime;    /* Used when calculating total time in system code. */
  617.             unsigned long ulUserTime;   /* Used when calculating total time in user code. */
  618.             unsigned      cbProcRec;    /* Size of qsPrec (with all additional data!) */
  619.             int           i;            /* Loop counter (threads) */
  620.  
  621.             pProcData = QSGetProcessData(pProcRec->pid);
  622.             if (pProcData == NULL)
  623.             {   /*
  624.                  * New process.
  625.                  * Allocate a new process data struct and set to following:
  626.                  *    usPid        to Pid number
  627.                  *    fDirty       to TRUE
  628.                  *    pProcRec     is NULL (indiactes a new process)
  629.                  *    cbProcRec    is 0
  630.                  *    pvRecordCore is NULL (indicates a new process)
  631.                  * And insert the process data.
  632.                  */
  633.                 pProcData = (PPROCESSDATA)calloc(sizeof(PROCESSDATA), 1);
  634.                 assert(pProcData != NULL); if (pProcData == NULL) break;
  635.                 pProcData->usPid = pProcRec->pid;
  636.                 pProcData->fDirty = TRUE;
  637.                 QSInsertProcessData(pProcData);
  638.             }
  639.             /* This process is not dead! fDead to false! */
  640.             pProcData->fDead = FALSE;
  641.  
  642.             /*
  643.              * Calc record size for the new data and see if it matches the size
  644.              * of the old data for this process. If is doesn't match, something have been changed!
  645.              */
  646.             cbProcRec = (unsigned)(pProcRec->pThrdRec + pProcRec->cTCB) - (unsigned)pProcRec;
  647.             if (pProcData->cbProcRec != cbProcRec)
  648.             {
  649.                 pProcData->cbProcRec = cbProcRec;
  650.                 pProcData->fDirty = TRUE;
  651.             }
  652.  
  653.             /*
  654.              * Count total times and evt. update the pProcData struct.
  655.              */
  656.             for (i = 0, ulSysTime = ulUserTime = 0; i < pProcRec->cTCB; i++)
  657.             {
  658.                 ulUserTime += pProcRec->pThrdRec[i].usertime;
  659.                 ulSysTime  += pProcRec->pThrdRec[i].systime;
  660.             }
  661.             if (pProcData->ulSysTime != ulSysTime || pProcData->ulUserTime != ulUserTime)
  662.             {
  663.                 pProcData->fDirty = TRUE;
  664.                 pProcData->ulSysTime = ulSysTime;
  665.                 pProcData->ulUserTime = ulUserTime;
  666.             }
  667.  
  668.             /*
  669.              * Dirty check. If not allready dirty.
  670.              */
  671.             if (!pProcData->fDirty)
  672.             {
  673.                 pProcData->fDirty =
  674.                     pProcData->pProcRec->cTCB != pProcRec->cTCB
  675.                     /* ||  FIXME */
  676.                     ;
  677.             }
  678.  
  679.             /*
  680.              * Set Record pointer
  681.              */
  682.             pProcData->pProcRec = pProcRec;
  683.  
  684.             /* next - DEPENDS on the ThrdRecs to be last */
  685.             pProcRec = (qsPrec_t*)(unsigned)(pProcRec->pThrdRec + pProcRec->cTCB);
  686.         }
  687.     }
  688.  
  689.     memset(achBuffer[(iCurBuffer+1) % cBuffers], 0, cbBuffer);
  690.  
  691.     return rc == NO_ERROR;
  692. }
  693.  
  694.  
  695. /**
  696.  * Inserts a process data node.
  697.  * @param     pProcData  Pointer to the node which is to inserted.
  698.  * @status    completely  implemented.
  699.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  700.  * @remark    The pProcData doubly-linked list is sorted on usPid.
  701.  */
  702. VOID            QSInsertProcessData(PPROCESSDATA pProcData)
  703. {
  704.     PPROCESSDATA pCur;
  705.     BOOL         fDir;                  /* TRUE: Start --> End; FALSE: End --> Start*/
  706.     assert(pProcData != NULL);
  707.  
  708.     /*
  709.      * Semi optimized start location.
  710.      */
  711.     if (pProcCur == NULL)
  712.         pCur = pProcLast;
  713.     else
  714.         pCur = pProcCur;
  715.  
  716.     /*
  717.      * Find the right place for the new node in the list.
  718.      */
  719.     if (pCur != NULL)
  720.     {
  721.         if (pCur->usPid <= pProcData->usPid)
  722.         {
  723.             fDir = TRUE;
  724.             while (pCur != NULL && pCur->usPid < pProcData->usPid)
  725.                 pCur = pCur->pNext;
  726.         }
  727.         else
  728.         {
  729.             fDir = FALSE;
  730.             while (pCur != NULL && pCur->usPid >= pProcData->usPid)
  731.                 pCur = pCur->pPrev;
  732.  
  733.             /* insert before, so we'll have to goback one node */
  734.             if (pCur != NULL)
  735.                 pCur = pCur->pNext;
  736.         }
  737.         assert(pCur == NULL || pCur->usPid != pProcData->usPid);
  738.     }
  739.  
  740.     /*
  741.      * case pCur == NULL && fDir:
  742.      *      Last in the list. (or empty list)
  743.      * case pCur == NULL && !fDir:
  744.      *      First in the list. (or empty list)
  745.      * case pCur != NULL:
  746.      *      Insert before pCur
  747.      */
  748.     if (pCur == NULL)
  749.     {
  750.         if (fDir)
  751.         {   /* last */
  752.             pProcData->pNext = NULL;
  753.             pProcData->pPrev = pProcLast;
  754.             if (pProcLast != NULL)
  755.                 pProcLast->pNext = pProcData;
  756.             else
  757.                 pProcFirst = pProcData;
  758.             pProcLast = pProcData;
  759.         }
  760.         else
  761.         {   /* first */
  762.             pProcData->pNext = pProcFirst;
  763.             pProcData->pPrev = NULL;
  764.             if (pProcFirst != NULL)
  765.                 pProcFirst->pPrev = pProcData;
  766.             else
  767.                 pProcLast = pProcData;
  768.             pProcFirst = pProcData;
  769.         }
  770.     }
  771.     else
  772.     {   /* before */
  773.         pProcData->pNext = pCur;
  774.         pProcData->pPrev = pCur->pPrev;
  775.         if (pCur->pPrev != NULL)
  776.             pCur->pPrev->pNext = pProcData;
  777.         else
  778.             pProcFirst = pProcData;
  779.         pCur->pPrev = pProcData;
  780.     }
  781.  
  782.     /*
  783.      * Set the last found node as this might optimize next access to the list.
  784.      */
  785.     pProcCur = pProcData;
  786. }
  787.  
  788.  
  789. /**
  790.  * Finds a process data node by PID number.
  791.  * @returns   NULL if not found. Pointer to node if found.
  792.  * @param     usPid  Process identificator to find.
  793.  * @status
  794.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  795.  * @remark
  796.  */
  797. PPROCESSDATA    QSGetProcessData(USHORT usPid)
  798. {
  799.     PPROCESSDATA pCur;
  800.  
  801.     /*
  802.      * Semi optimized start location.
  803.      */
  804.     if (pProcCur == NULL)
  805.         pCur = pProcLast;
  806.     else
  807.         pCur = pProcCur;
  808.  
  809.     /*
  810.      * Find the right place for the new node in the list.
  811.      */
  812.     if (pCur != NULL)
  813.     {
  814.         if (pCur->usPid <= usPid)
  815.         {
  816.             while (pCur != NULL && pCur->usPid < usPid)
  817.                 pCur = pCur->pNext;
  818.         }
  819.         else
  820.         {
  821.             while (pCur != NULL && pCur->usPid > usPid)
  822.                 pCur = pCur->pPrev;
  823.         }
  824.     }
  825.  
  826.     return pCur != NULL && pCur->usPid == usPid ? pCur : NULL;
  827. }
  828.  
  829.  
  830. /**
  831.  * Gets a given MTE (library) record from the data returned from DosQuerySysState.
  832.  * @returns   NULL if not found (or error). Pointer to MTE record if found.
  833.  * @param     USHORT  hMTE.
  834.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  835.  */
  836. qsLrec_t *      QSGetMteData(register USHORT hMTE)
  837. {
  838.     /*
  839.      * Searches lineary (no other option) thru the linked list of
  840.      * Mte (Library) records returned by DosQuerySysState.
  841.      */
  842.     register qsLrec_t *pLrec = pMTEs;
  843.     while (pLrec != NULL && pLrec->hmte != hMTE)
  844.         pLrec = pLrec->pNextRec;
  845.  
  846.     return pLrec;
  847. }
  848.  
  849.  
  850.  
  851. /**
  852.  * Get the FS record for the given system file number.
  853.  * @returns   NULL pointer if found or error.
  854.  *            Pointer to FS record on success.
  855.  * @param     usSFN  System File number.
  856.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  857.  */
  858. qsFrec_t *      QSGetSfnData(USHORT usSFN)
  859. {
  860.     /*
  861.      * Searches lineary (no other option) thru the linked list of
  862.      * FS records returned by DosQuerySysState.
  863.      */
  864.     register qsFrec_t * pCur = pFSRecs;
  865.     while (pCur != NULL && pCur->RecType == QS_FILESYS)
  866.     {
  867.         register int i;
  868.         for (i = 0; i < pCur->ctSft; i++)
  869.             if (pCur->pSft[i].sfn == usSFN)
  870.                 return pCur;
  871.         /* next */
  872.         pCur = pCur->pNextRec;
  873.     }
  874.  
  875.  
  876.     return NULL;
  877. }
  878.  
  879.  
  880. /**
  881.  * Debug function which dumps the process list.
  882.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  883.  */
  884. VOID            QSDumpProcessData(VOID)
  885. {
  886.     PPROCESSDATA pProcData = pProcFirst;
  887.  
  888.         printf("pid   ppid  cTCB  SysTime   UserTime  Dirty  Dead  Name\n");
  889.     while (pProcData != NULL)
  890.     {
  891.         int i;
  892.         qsLrec_t *pMTE = QSGetMteData(pProcData->pProcRec->hMte);
  893.  
  894.         printf("%04x  %04x  %04x  %000008x  %000008x  %-4d   %-4d  %s\n",
  895.                pProcData->pProcRec->pid,
  896.                pProcData->pProcRec->ppid,
  897.                pProcData->pProcRec->cTCB,
  898.                pProcData->ulSysTime,
  899.                pProcData->ulUserTime,
  900.                pProcData->fDirty,
  901.                pProcData->fDead,
  902.                pMTE != NULL && pMTE->pName != NULL ? pMTE->pName : "<not found>"
  903.                );
  904.         if (pProcData->pProcRec->pFSRec
  905.             && pProcData->pProcRec->cFH > 0)
  906.             for (i = 0; i < pProcData->pProcRec->cFH; i++)
  907.             {
  908.                 qsFrec_t * pFSRec = QSGetSfnData(pProcData->pProcRec->pFSRec[i]);
  909.                 printf("    sfn %d  %s\n", pProcData->pProcRec->pFSRec[i],
  910.                        pFSRec != NULL ? pFSRec->name : "<not found>"
  911.                        );
  912.             }
  913.  
  914.         /* next */
  915.         pProcData = pProcData->pNext;
  916.     }
  917. }
  918.  
  919.  
  920. /**
  921.  * Debug function which dumps the MFS list.
  922.  * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  923.  */
  924. VOID            QSDumpFileSystemData(VOID)
  925. {
  926.     qsFrec_t *pCur = pFSRecs;
  927.  
  928.     while (pCur != NULL && pCur->RecType == QS_FILESYS)
  929.     {
  930.         int i;
  931.         printf("%s  (",
  932.                pCur->name
  933.                );
  934.         for (i = 0; i < pCur->ctSft; i++)
  935.             printf("%d,", pCur->pSft[i].sfn);
  936.         printf(")\n");
  937.         /* next */
  938.         pCur = pCur->pNextRec;
  939.     }
  940. }
  941.  
  942.