home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * MODULE NAME : procs.c AUTHOR: Rick Fishman *
- * DATE WRITTEN: 05-30-92 *
- * *
- * DESCRIPTION: *
- * *
- * This program lists all running processes under OS/2 2.0. It uses *
- * the undocumented API DosQProcStatus to get a buffer filled with *
- * information related to the current state of the system. It then *
- * performs the following using the buffer: *
- * *
- * 1. Get the relevant process information for all active pids into *
- * an array. *
- * 2. Go thru the module information table. For each module found, *
- * compare its module reference number against all module *
- * reference numbers associated with the active pids. If any *
- * match, add the module name to the active pid array. *
- * 3. Print the process names that were found. *
- * *
- * UPDATES: *
- * *
- **********************************************************************/
-
-
- /*********************************************************************/
- /*------- Include relevant sections of the OS/2 header files --------*/
- /*********************************************************************/
-
- #define INCL_DOSERRORS
- #define INCL_DOSPROCESS
- #define INCL_VIO
-
- /**********************************************************************/
- /*----------------------------- INCLUDES -----------------------------*/
- /**********************************************************************/
-
- #include <os2.h>
- #include <conio.h>
- #include <ctype.h>
- #include <process.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "procstat.h"
-
- /*********************************************************************/
- /*------------------- APPLICATION DEFINITIONS -----------------------*/
- /*********************************************************************/
-
- #define BUFFER_SIZE 0x8000
-
- #define SCREEN_LINE_OVERHD 3
- #define DEF_SCREEN_LINES 25
-
- // COMMAND-LINE OPTIONS
- #define SUPPRESSMORE 'S' // Suppress More[Y,N] messages
-
- #define OUT_OF_MEMORY_MSG "\nOut of memory!\n"
-
- #define COPYRIGHT_INFO "Procs.exe, 32-bit, Version 2.0\n" \
- "Copyright (c) Code Blazers, Inc. 1991-1992. " \
- "All rights reserved.\n"
-
- #define USAGE_INFO "\nusage: procs StartingPoint [ /s ]\n " \
- "\n StartingPoint is a string that indicates " \
- "\n a ProcessName or partial ProcessName after" \
- "\n which to start listing running processes" \
- "\n" \
- "\n /s - Suppress More[y,n] displays" \
- "\n\n"
-
- /**********************************************************************/
- /*---------------------------- STRUCTURES ----------------------------*/
- /**********************************************************************/
-
- typedef struct _ACTIVEPID // INFO ON AN ACTIVE PROCESS
- {
- USHORT hModRef; // It's module reference handle
- PID pid; // It's Process Id
- PSZ szProcess; // It's name
-
- } ACTIVEPID, *PACTIVEPID;
-
- /**********************************************************************/
- /*----------------------- FUNCTION PROTOTYPES ------------------------*/
- /**********************************************************************/
-
- INT main ( INT argc, PSZ szArg[] );
- BOOL Init ( INT argc, PSZ szArg[] );
- BOOL BuildActivePidTbl ( PPROCESSINFO ppi );
- INT CompareActivePids ( const void *pActivePid1, const void *pActivePid2 );
- VOID Procs ( PSZ szStartingPoint );
- VOID StoreProcessName ( PMODINFO pmi );
- INT CompareProcessNames( const void *pActivePid1, const void *pActivePid2 );
- VOID PrintReport ( PSZ szStartingPoint );
- VOID Term ( VOID );
-
- /**********************************************************************/
- /*------------------------ GLOBAL VARIABLES --------------------------*/
- /**********************************************************************/
-
- BOOL fSuppressMore;
-
- INT iStartingPoint;
-
- USHORT usActiveProcesses, // Number of active processes
- usScreenLines;
-
- ACTIVEPID *aActivePid; // Array of active processes
-
- PBUFFHEADER pbh; // Pointer to buffer header structure
-
- /**********************************************************************/
- /*------------------------------ MAIN --------------------------------*/
- /* */
- /* MAIN DRIVER FOR PROGRAM. */
- /* */
- /* INPUT: number of command-line arguments, */
- /* command-line argument array */
- /* */
- /* 1. Perform program initialization which will issue the */
- /* DosQProcStatus call and obtain the buffer of information. */
- /* 2. If a starting point was given on the commandline, pass that */
- /* to the Procs function that will list running processes. If not,*/
- /* pass a NULL address to the Procs function. */
- /* 3. Perform program termination. */
- /* */
- /* OUTPUT: nothing */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- INT main( INT argc, PSZ szArg[] )
- {
- if( Init( argc, szArg ) )
- if( iStartingPoint )
- Procs( szArg[ iStartingPoint ] );
- else
- Procs( NULL );
-
- Term();
-
- return 0;
- }
-
- /**********************************************************************/
- /*------------------------------ Init --------------------------------*/
- /* */
- /* PERFORM PROGRAM INITIALIZATION. */
- /* */
- /* INPUT: number of command-line arguments, */
- /* command-line argument array */
- /* */
- /* 1. Print copyright notice. */
- /* 2. If too many commandline parms, exit with usage info. */
- /* 3. Process commandline options: */
- /* A. If SUPPRESSMORE option is found, set the appropriate flag. */
- /* B. If an invalid option, exit with usage info. */
- /* C. If a starting point was specified, store the index into */
- /* the argv array for later use. */
- /* 4. Alocate memory for the output from DosQProcStatus. */
- /* 5. Make the DosQProcStatus call. */
- /* 6. Build an array of information related to active processes. */
- /* 7. Get the number of screen lines supported by the window we are */
- /* running under. */
- /* */
- /* OUTPUT: TRUE or FALSE if successful or not */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- BOOL Init( INT argc, PSZ szArg[] )
- {
- SHORT sIndex;
- USHORT usRetCode;
- BOOL fSuccess = TRUE;
-
- printf( COPYRIGHT_INFO );
-
- if( argc > 3 )
- {
- (void) printf( USAGE_INFO );
-
- fSuccess = FALSE;
- }
-
- for( sIndex = 1; fSuccess && sIndex < argc; sIndex++ )
- {
- if( szArg[ sIndex ][ 0 ] == '/' || szArg[ sIndex ][ 0 ] == '-' )
- {
- switch( toupper( szArg[ sIndex ][ 1 ] ) )
- {
- case SUPPRESSMORE:
- fSuppressMore = TRUE;
-
- break;
-
- default:
- (void) printf( USAGE_INFO );
-
- fSuccess = FALSE;
- }
- }
- else if( !iStartingPoint )
- iStartingPoint = sIndex;
- else
- {
- (void) printf( USAGE_INFO );
-
- fSuccess = FALSE;
- }
- }
-
- if( fSuccess && !(pbh = malloc( BUFFER_SIZE )) )
- {
- printf( OUT_OF_MEMORY_MSG );
-
- fSuccess = FALSE;
- }
-
- if( fSuccess )
- {
- usRetCode = DosQProcStatus( pbh, BUFFER_SIZE );
-
- if( usRetCode )
- {
- printf( "\nDosQProcStatus failed. RC: %u.", usRetCode );
-
- fSuccess = FALSE;
- }
- else
- fSuccess = BuildActivePidTbl( pbh->ppi );
- }
-
- if( fSuccess )
- {
- VIOMODEINFO vmi;
-
- vmi.cb = sizeof( VIOMODEINFO );
-
- usRetCode = VioGetMode( &vmi, 0 );
-
- if( usRetCode )
- usScreenLines = DEF_SCREEN_LINES - SCREEN_LINE_OVERHD;
- else
- usScreenLines = vmi.row - SCREEN_LINE_OVERHD;
- }
-
- return fSuccess;
- }
-
- /**********************************************************************/
- /*------------------------ BuildActivePidTbl -------------------------*/
- /* */
- /* BUILD AN ARRAY OF ACTIVE PROCESSES USING THE PROCESS INFO SECTION */
- /* OF THE DosQProcStatus BUFFER. */
- /* */
- /* INPUT: pointer to ProcessInfo section of buffer */
- /* */
- /* 1. Get a count of active processes. */
- /* 2. Allocate memory for the ActiveProcess table. */
- /* 3. Store information about each active process in the table. */
- /* 4. Sort the table in ascending module number order. */
- /* */
- /* OUTPUT: exit code */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- BOOL BuildActivePidTbl( PPROCESSINFO ppi )
- {
- PPROCESSINFO ppiLocal = ppi;
- BOOL fSuccess = TRUE;
-
- // Count the number of processes in the process info section. The process
- // count in the summary record is not reliable (2/17/92 - version 6.177)
-
- usActiveProcesses = 0;
-
- while( ppiLocal->ulEndIndicator != PROCESS_END_INDICATOR )
- {
- usActiveProcesses++;
-
- // Next PROCESSINFO struct found by taking the address of the first
- // thread control block of the current PROCESSINFO structure and
- // adding the size of a THREADINFO structure times the number of
- // threads
-
- ppiLocal = (PPROCESSINFO) (ppiLocal->ptiFirst+ppiLocal->usThreadCount );
- }
-
- if( !(aActivePid = malloc( usActiveProcesses * sizeof( ACTIVEPID ) )) )
- {
- printf( OUT_OF_MEMORY_MSG );
-
- fSuccess = FALSE;
- }
- else
- {
- INT i;
-
- memset( aActivePid, 0, usActiveProcesses * sizeof( ACTIVEPID ) );
-
- for( i = 0; i < usActiveProcesses; i++ )
- {
- aActivePid[ i ].hModRef = ppi->hModRef;
-
- aActivePid[ i ].pid = (PID) ppi->pid;
-
- ppi = (PPROCESSINFO) (ppi->ptiFirst + ppi->usThreadCount);
- }
-
- qsort( aActivePid, usActiveProcesses, sizeof( ACTIVEPID ),
- CompareActivePids );
- }
-
- return fSuccess;
- }
-
- /**********************************************************************/
- /*------------------------ CompareActivePids -------------------------*/
- /* */
- /* COMPARE FUNCTION FOR THE QSORT OF THE ACTIVE PID ARRAY. SORTS */
- /* THE ARRAY IN MODULE HANDLE ORDER. */
- /* */
- /* INPUT: pointer to first element for compare, */
- /* pointer to second element of compare */
- /* */
- /* 1. Do the compare. */
- /* */
- /* OUTPUT: < 0 means first < second */
- /* = 0 means first = second */
- /* > 0 means first > second */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- INT CompareActivePids( const void *pActivePid1, const void *pActivePid2 )
- {
- if( ((PACTIVEPID)pActivePid1)->hModRef < ((PACTIVEPID)pActivePid2)->hModRef )
- return -1;
- else
- if( ((PACTIVEPID)pActivePid1)->hModRef > ((PACTIVEPID)pActivePid2)->hModRef )
- return +1;
- else
- return 0;
- }
-
- /**********************************************************************/
- /*------------------------------ Procs -------------------------------*/
- /* */
- /* LIST ALL RUNNING PROCESSES. */
- /* */
- /* INPUT: starting point of report */
- /* */
- /* 1. Print the titles for the report. */
- /* 2. Store the process names in the ActivePid array. */
- /* 3. Sort the ActivePid array by process name. */
- /* 4. Print the report. */
- /* */
- /* OUTPUT: nothing */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- VOID Procs( PSZ szStartingPoint )
- {
- PMODINFO pmi = pbh->pmi;
-
- printf( "\n%-25.25s %-5.5s %-9.9s",
- "Process Name", "PID", "PID(hex)" );
-
- printf( "\n%-25.25s %-5.5s %-9.9s",
- "──────────────────────", "───", "────────" );
-
- while( pmi )
- {
- StoreProcessName( pmi );
-
- pmi = pmi->pNext;
- }
-
- qsort( aActivePid, usActiveProcesses, sizeof( ACTIVEPID ),
- CompareProcessNames );
-
- PrintReport( szStartingPoint );
- }
-
- /**********************************************************************/
- /*------------------------- StoreProcessName -------------------------*/
- /* */
- /* STORE THE PROCESS NAME FOR LATER PRINTING. */
- /* */
- /* INPUT: pointer to MODINFO structure */
- /* */
- /* 1. Go thru each entry in the ActivePid array: */
- /* A. If the module reference handle in the array is greater */
- /* than the one passed here, we could not find a match */
- /* because at this point the ActivePid array is sorted in */
- /* module reference handle order. */
- /* B. If we find a match: */
- /* 1. Set a pointer to the beginning of the process name, */
- /* since the name in the buffer is fully qualified. */
- /* 2. Allocate memory for the process name in the ActivePid */
- /* array element. */
- /* 3. Copy the process name into the allocated memory. */
- /* */
- /* OUTPUT: nothing */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- VOID StoreProcessName( PMODINFO pmi )
- {
- INT i;
- PSZ szProcess;
-
- for( i = 0; i < usActiveProcesses; i++ )
- {
- if( aActivePid[ i ].hModRef > pmi->hMod )
- break;
-
- if( aActivePid[ i ].hModRef == pmi->hMod )
- {
- szProcess = strrchr( pmi->szModName, '\\' );
-
- if( szProcess )
- szProcess++;
- else
- szProcess = pmi->szModName;
-
- aActivePid[ i ].szProcess = malloc( strlen( szProcess ) + 1 );
-
- if( aActivePid[ i ].szProcess )
- (void) strcpy( aActivePid[ i ].szProcess, szProcess );
- else
- (void) printf( OUT_OF_MEMORY_MSG );
- }
- }
- }
-
- /**********************************************************************/
- /*----------------------- CompareProcessNames ------------------------*/
- /* */
- /* COMPARE FUNCTION FOR THE QSORT OF THE ACTIVE PID ARRAY. SORTS */
- /* THE ARRAY IN PROCESS NAME ORDER. */
- /* */
- /* INPUT: pointer to first element for compare, */
- /* pointer to second element of compare */
- /* */
- /* 1. Do the compare. */
- /* */
- /* OUTPUT: return from stricmp */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- INT CompareProcessNames( const void *pActivePid1, const void *pActivePid2 )
- {
- return stricmp( ((PACTIVEPID) pActivePid1)->szProcess,
- ((PACTIVEPID) pActivePid2)->szProcess );
- }
-
- /**********************************************************************/
- /*--------------------------- PrintReport ----------------------------*/
- /* */
- /* PRINT INFO ABOUT EACH PROCESS. */
- /* */
- /* INPUT: starting point to begin report */
- /* */
- /* 1. For each element in the ActivePid array: */
- /* A. If there is a process name for this element: */
- /* 1. If we are not passed the starting point specified on */
- /* the commandline, get the next element. */
- /* 2. If we have exceeeded the screen lines for the window */
- /* that we are running under and the user has not specified */
- /* to suppress the More[Y,N] messages, display that message */
- /* and wait on a key. If the user wants more displayed, */
- /* continue, else exit. */
- /* 3. Print information about the process. */
- /* */
- /* OUTPUT: nothing */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- VOID PrintReport( PSZ szStartingPoint )
- {
- INT i;
- USHORT usLines = 0;
-
- for( i = 0; i < usActiveProcesses; i++ )
- if( aActivePid[ i ].szProcess )
- {
- if( szStartingPoint &&
- stricmp( szStartingPoint, aActivePid[ i ].szProcess ) > 0 )
- continue;
-
- if( !fSuppressMore && ++usLines > usScreenLines )
- {
- int KbdChar;
-
- printf( "\nMore [Y,N]?" );
-
- fflush( stdout );
-
- KbdChar = getch();
-
- printf( "\r \r" );
-
- fflush( stdout );
-
- if( toupper( KbdChar ) == 'N' )
- return;
-
- usLines = 0;
- }
- else
- printf( "\n" );
-
- printf( "%-25.25s %-5u %-9x", aActivePid[ i ].szProcess,
- aActivePid[ i ].pid, aActivePid[ i ].pid );
- }
- }
-
- /**********************************************************************/
- /*------------------------------ Term --------------------------------*/
- /* */
- /* PERFORM PROGRAM TERMINATION */
- /* */
- /* INPUT: nothing */
- /* */
- /* 1. Free the ActiveProcess array. First free the memory for the */
- /* process name associated with each element of the array. */
- /* 2. Free the buffer allocated for the DosQProcStatus output. */
- /* 3. Return to the operating system. */
- /* */
- /* OUTPUT: nothing */
- /* */
- /*--------------------------------------------------------------------*/
- /**********************************************************************/
- VOID Term()
- {
- if( aActivePid )
- {
- INT i;
-
- for( i = 0; i < usActiveProcesses; i++ )
- if( aActivePid[ i ].szProcess )
- free( aActivePid[ i ].szProcess );
-
- free( aActivePid );
- }
-
- if( pbh )
- free( pbh );
-
- DosExit( EXIT_PROCESS, 0 );
- }
-
- /**********************************************************************
- * END OF SOURCE CODE *
- **********************************************************************/