
/*
 * procstat.h:
 *      header file for procstat.h (querying process information).
 *
 *      Function prefixes (new with V0.81):
 *      --  prc*   Query Process helper functions
 *
 *      Based on Kai Uwe Rommel's "dosqproc" package
 *      available at Hobbes:
 *      Kai Uwe Rommel - Wed 25-Mar-1992
 *                       Sat 13-Aug-1994
 *
 *      Required #include's before including this header:
 *      --  OS2.H with INCL_DOS and INCL_WIN.
 *
 *      This modified version Copyright (C) 1997-99 Ulrich M”ller.
 *      This file is part of the XFolder source package.
 *      XFolder is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published
 *      by the Free Software Foundation, in version 2 as it comes in the
 *      "COPYING" file of the XFolder main distribution.
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 */

#if __cplusplus
extern "C" {
#endif

#ifndef PROCSTAT_HEADER_INCLUDED
    #define PROCSTAT_HEADER_INCLUDED

    #define PTR(ptr, ofs)  ((void *) ((char *) (ptr) + (ofs)))

    /* DosQProcStatus() = DOSCALLS.154 */
    USHORT APIENTRY16 DosQProcStatus(PVOID pBuf, USHORT cbBuf);
    /* DosGetPrty = DOSCALLS.9 */
    USHORT APIENTRY16 DosGetPrty(USHORT usScope, PUSHORT pusPriority, USHORT pid);

    /*
     * QPROCSTAT:
     *      "header" structure returned by DosQProcStat,
     *      containing the offsets to the other data
     */

    typedef struct _QPROCSTAT
    {
        ULONG  ulGlobal;        // offset to global data section
        ULONG  ulProcesses;     // offset to process data section
        ULONG  ulSemaphores;    // offset to semaphore data section
        ULONG  ulUnknown1;
        ULONG  ulSharedMem;     // offset to shared mem data section
        ULONG  ulModules;       // offset to DLL data section
        ULONG  ulUnknown2;
        ULONG  ulUnknown3;
    } QPROCSTAT, *PQPROCSTAT;

    /*
     * QGLOBAL:
     *      at offset QPROCSTAT.ulGlobal, contains
     *      global system information (no. of threads)
     */

    typedef struct _QGLOBAL {
        ULONG  ulThreads;       // total number of threads;
        ULONG  ulReserved1,
               ulReserved2;
    } QGLOBAL, *PQGLOBAL;

    /*
     * QPROCESS:
     *      DosQProcStat structure for process info
     */

    typedef struct _QPROCESS {
        ULONG  ulType;          // 1 for processes
        ULONG  ulThreadList;
        USHORT usPID;
        USHORT usParentPID;
        ULONG  ulSessionType;
        ULONG  ulStatus;        // see status #define's below
        ULONG  ulSID;           // session (screen group) ID
        USHORT usHModule;       // program module handle for process
        USHORT usThreads;       // # of TCBs in use in process
        ULONG  ulReserved1;
        ULONG  ulReserved2;
        USHORT usSemaphores;    // # of 16-bit semaphores
        USHORT usDLLs;          // # of linked DLLs
        USHORT usSharedMems;
        USHORT usReserved3;
        ULONG  ulSemList;       // offset to semaphore list
        ULONG  ulDLLList;       // offset to DLL list
        ULONG  ulSharedMemList; // offset to shared mem list
        ULONG  ulReserved4;
    } QPROCESS, *PQPROCESS;

    // process status flags
    #define STAT_EXITLIST 0x01
    #define STAT_EXIT1    0x02
    #define STAT_EXITALL  0x04
    #define STAT_PARSTAT  0x10
    #define STAT_SYNCH    0x20
    #define STAT_DYING    0x40
    #define STAT_EMBRYO   0x80

    /*
     * QTHREAD:
     *      DosQProcStat structure for thread info
     */

    typedef struct _QTHREAD
    {
        ULONG  ulType;          // 0x100 for thread records
        USHORT usTID;           // thread ID
        USHORT usThreadSlotID;  // ???
        ULONG  ulBlockID;       // sleep id thread is sleeping on
        ULONG  ulPriority;
        ULONG  ulSysTime;
        ULONG  ulUserTime;
        UCHAR  ucStatus;        // TSTAT_* flags
        UCHAR  ucReserved1;
        USHORT usReserved2;
    } QTHREAD, *PQTHREAD;

    // thread status flags
    #define TSTAT_READY   1
    #define TSTAT_BLOCKED 2
    #define TSTAT_RUNNING 5
    #define TSTAT_LOADED  9

    /*
     * QMODULE:
     *      DosQProcStat structure for module info
     */

    typedef struct _QMODULE
    {
        ULONG  nextmodule;
        USHORT modhandle;
        USHORT modtype;
        ULONG  submodules;
        ULONG  segments;
        ULONG  reserved;
        ULONG  namepointer;
        USHORT submodule[1];      // varying, see member submodules */
    } QMODULE, *PQMODULE;

    /*
     * QSEMAPHORE:
     *      DosQProcStat structure for semaphore info (16-bit only, I guess)
     */

    typedef struct _QSEMAPHORE
    {
        ULONG  nextsem;
        USHORT owner;
        UCHAR  flag;
        UCHAR  refs;
        UCHAR  requests;
        UCHAR  reserved1;
        USHORT reserved2;
        USHORT index;
        USHORT dummy;
        UCHAR  name[1];       /* varying */
    } QSEMAPHORE, *PQSEMAPHORE;

    /*
     * QSHAREDMEM:
     *      DosQProcStat structure for shared memory info
     */

    typedef struct _QSHAREDMEM
    {
        ULONG  nextseg;
        USHORT handle;            // handle for shared memory
        USHORT selector;          // shared memory selector
        USHORT refs;              // reference count
        UCHAR  name[1];           // varying
    } QSHAREDMEM, *PQSHAREDMEM;

    /*
     * PRCPROCESS:
     *      additional, more lucid structure
     *      filled by prcQueryProcessInfo
     */

    typedef struct _PRCPROCESS {
        CHAR   szModuleName[CCHMAXPATH];    // module name
        USHORT usPID,                       // process ID
               usParentPID,                 // parent process ID
               usThreads;                   // thread count
        ULONG  ulSID;                       // session ID
        ULONG  ulSessionType;
        ULONG  ulStatus;
        ULONG  ulCPU;                       // CPU usage (sum of thread data)
    } PRCPROCESS, *PPRCPROCESS;

    /*
     * PRCTHREAD:
     *      additional, more lucid structure
     *      filled by prcQueryThreadInfo
     */

    typedef struct _PRCTHREAD {
        USHORT usTID;           // thread ID
        USHORT usThreadSlotID;  // ???
        ULONG  ulBlockID;       // sleep id thread is sleeping on
        ULONG  ulPriority;
        ULONG  ulSysTime;
        ULONG  ulUserTime;
        UCHAR  ucStatus;        // see status #define's below
    } PRCTHREAD, *PPRCTHREAD;

    /*
     * prcQueryProcessInfo:
     *      this searches for a given process ID (usPID) and
     *      fills a given PRCPROCESS structure with lots of
     *      information about this process.
     *      Returns FALSE upon errors.
     */

    BOOL prcQueryProcessInfo(USHORT usPID, PPRCPROCESS pprcp);

    /*
     * prcForEachProcess:
     *      this calls a given callback func for each running
     *      process; this func will be passed the following params:
     *          HWND hwnd       like hwnd passed to prcForEachProcess
     *          ULONG msg       like msg passed to prcForEachProcess
     *          MPARAM mp1      like mp1 passed to prcForEachProcess
     *          PPRCPROCESS mp2 pointer to a PRCPROCESS struct for each process
     *      This function returns the number of running processes on the
     *      system. If pfnwpCallback is NULL, only this number will be
     *      returned.
     */

    ULONG prcForEachProcess(PFNWP pfnwpCallback, HWND hwnd, ULONG ulMsg, MPARAM mp1);

    /*
     * prcQueryThreadCount:
     *      returns the total number of running threads
     *      in the given process. If pid == 0, the
     *      total thread count for the system is returned.
     */

    ULONG prcQueryThreadCount(USHORT usPID);

    /*
     * prcQueryThreadInfo:
     *      this searches for a given thread in a given process
     *      and fills a given PRCTHREAD structure with lots of
     *      information about that thread.
     *      Returns FALSE upon errors.
     *      Note: This function loops thru all processes which
     *      are currently running and is therefore not terribly
     *      fast. Use economically.
     */

    BOOL prcQueryThreadInfo(USHORT usPID, USHORT usTID, PPRCTHREAD pprct);


    /*
     * prcQueryPriority:
     *      shortcut if you want the priority only.
     *      Returns -1 upon errors.
     *      Note: This function loops thru all processes which
     *      are currently running and is therefore not terribly
     *      fast. Use economically.
     */

    ULONG prcQueryThreadPriority(USHORT usPID, USHORT usTID);

#endif

#if __cplusplus
}
#endif

