• Welcome to Jose's Read Only Forum 2023.
 

Process Status API (PSAPI) Examples

Started by José Roca, August 29, 2011, 02:00:15 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
The process status application programming interface (PSAPI) is a helper library that makes it easier for you to obtain information about processes and device drivers.

These functions are available in Psapi.dll.

The same information is generally available through the performance data in the registry.

The process status API (PSAPI) provides sets of functions for retrieving the following information:



  • Process Information

  • Module Information

  • Device Driver Information

  • Process Memory Usage Information

  • Working Set Information

  • Memory-Mapped File Information

José Roca

 
The following sample code uses the EnumProcesses function to enumerate the current processes in the system.


' ========================================================================================
' Enumerating all processes.
' This is a translation of an example included in the MSDN documentation for PSAPI.
' ========================================================================================

' SED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "PSAPI.INC"

' ========================================================================================
' Displays the processes
' ========================================================================================
SUB PrintProcessNameAndID (BYVAL processID AS DWORD)

   LOCAL szProcessName AS ASCIIZ * %MAX_PATH
   LOCAL hProcess AS DWORD
   LOCAL hMod AS DWORD
   LOCAL cbNeeded AS DWORD

   szProcessName = "unknown"
   '// Get a handle to the process.
   hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION OR _
                          %PROCESS_VM_READ, %FALSE, processID)
   '// Get the process name.
   IF ISFALSE hProcess THEN EXIT SUB
   IF ISFALSE EnumProcessModules(hProcess, hMod, SIZEOF(hMod), cbNeeded) THEN EXIT SUB
   GetModuleBaseName hProcess, hMod, szProcessName, SIZEOF(szProcessName)

   '// Print the process name and identifier.
   PRINT "Process ID: ", szProcessName, processID

   CloseHandle hProcess

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   '// Get the list of process identifiers.
   DIM aProcesses(0 TO 1023) AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL cProcesses AS DWORD
   LOCAL i AS DWORD

   IF ISFALSE EnumProcesses(aProcesses(LBOUND(aProcesses)), _
      (UBOUND(aProcesses) - LBOUND(aProcesses) + 1) * 4, cbNeeded) THEN EXIT FUNCTION

   '// Calculate how many process identifiers were returned.
   cProcesses = cbNeeded \ 4

   '// Print the name and process identifier for each process.

   FOR i = 0 TO cProcesses - 1
      PrintProcessNameAndId aProcesses(i)
   NEXT

   WAITKEY$

END FUNCTION
' ========================================================================================


José Roca

 
To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.


' ========================================================================================
' Enumerating all modules for a process.
' This is a translation of an example included in the MSDN documentation for PSAPI.
' ========================================================================================

' SED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "PSAPI.INC"

' ========================================================================================
' Displays the modules
' ========================================================================================
SUB PrintModules (BYVAL processID AS DWORD)

   DIM   hMods(0 TO 1023) AS DWORD
   LOCAL hProcess AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL i AS LONG
   LOCAL szModName AS ASCIIZ * %MAX_PATH

   '// Print the process identifier.
   PRINT "Process ID: ", processID

   '// Get a list of all the modules in this process.
   hProcess = Openprocess (%PROCESS_QUERY_INFORMATION OR _
                           %PROCESS_VM_READ, %FALSE, processID)
   IF hProcess = 0 THEN EXIT SUB

   IF ISFALSE EnumProcessModules(hProcess, hMods(LBOUND(hMods)), _
      (UBOUND(hMods) - LBOUND(hMods) + 1) * 4, cbNeeded) THEN EXIT SUB

   FOR i = 0 TO cbNeeded \ 4
      '// Get full path to the module's file
      IF GetModuleFileNameEx(hProcess, hMods(i), szModName, SIZEOF(szModName)) THEN
         '// Print the module name and handle value.
         PRINT szModName, hMods(i)
      END IF
   NEXT

   CloseHandle hProcess

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   DIM aProcesses(1024) AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL cProcesses AS DWORD
   LOCAL i AS LONG

   IF ISFALSE EnumProcesses(aProcesses(LBOUND(aProcesses)), _
      (UBOUND(aProcesses) - LBOUND(aProcesses) + 1) * 4, cbNeeded) THEN EXIT FUNCTION

   '// Calculate how many process identifiers were returned.
   cProcesses = cbNeeded \ 4

   '// Print the name of the module for each process.

   FOR i = 0 TO cProcesses - 1
      PrintModules aProcesses(i)
   NEXT

   WAITKEY$

END FUNCTION
' ========================================================================================


José Roca

 
The following sample code uses the EnumDeviceDrivers function to enumerate the current device drivers in the system. It passes the load addresses retrieved from this function call to the GetDeviceDriverBaseName function to retrieve a name that can be displayed.


' ========================================================================================
' Enumerating all device drivers.
' The main function obtains a list of load addresses by using the EnumDeviceDrivers
' function. For each address, main calls the PrintDeviceDriverbaseName function passing
' to it the driver address.
' ========================================================================================

' SED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "PSAPI.INC"

' ========================================================================================
' Displays the device driver address and base name
' ========================================================================================
SUB PrintDeviceDriverBaseName (BYVAL dwImageBase AS DWORD)

    LOCAL szBaseName AS ASCIIZ * %MAX_PATH

    PRINT "Driver address: ", dwImageBase;
    GetDeviceDriverBaseName dwImageBase, szBaseName, SIZEOF(szBaseName)
    PRINT szBaseName

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   DIM   aDrivers(0 TO 1023) AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL cAddresses AS DWORD
   LOCAL i AS LONG

   '// Get the list of device drivers addresses
   IF ISFALSE EnumDeviceDrivers(aDrivers(LBOUND(aDrivers)), _
      (UBOUND(aDrivers) - LBOUND(adrivers) + 1) * 4, cbNeeded) THEN EXIT FUNCTION

   '// Calculate how many addresses were returned
   cAddresses = cbNeeded \ 4

   '// Print the base names of the drivers
   FOR i = 0 TO cAddresses - 1
      PrintDeviceDriverBaseName aDrivers(i)
   NEXT

   WAITKEY$

END FUNCTION
' ========================================================================================


José Roca

 
The following sample code uses the EnumDeviceDrivers function to enumerate the current device drivers in the system. It passes the load addresses retrieved from this function call to the GetDeviceDriverFileName function to retrieve a name that can be displayed.


' ========================================================================================
' Enumerating all device drivers.
' The main function obtains a list of load addresses by using the EnumDeviceDrivers
' function. For each address, main calls the PrintDeviceDriverFileName function passing
' to it the driver address.
' ========================================================================================

' SED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "PSAPI.INC"

' ========================================================================================
' Displays the device driver file name
' ========================================================================================
SUB PrintDeviceDriverFileName (BYVAL dwImageBase AS DWORD)

    LOCAL szFileName AS ASCIIZ * %MAX_PATH

    PRINT "Driver address: ", dwImageBase;
    GetDeviceDriverFileName dwImageBase, szFileName, SIZEOF(szFileName)
    PRINT szFileName

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   DIM   aDrivers(0 TO 1023) AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL cAddresses AS DWORD
   LOCAL i AS LONG

   '// Get the list of device drivers addresses
   IF ISFALSE EnumDeviceDrivers(aDrivers(LBOUND(aDrivers)), _
      (UBOUND(aDrivers) - LBOUND(adrivers) + 1) * 4, cbNeeded) THEN EXIT FUNCTION

   '// Calculate how many addresses were returned
   cAddresses = cbNeeded \ 4

   '// Print the base names of the drivers
   FOR i = 0 TO cAddresses - 1
      PrintDeviceDriverFileName aDrivers(i)
   NEXT

   WAITKEY$

END FUNCTION
' ========================================================================================


José Roca

 
To determine the efficiency of your application, you may want to examine its memory usage. The following sample code uses the GetProcessMemoryInfo function to obtain information about the memory usage of a process.


' ========================================================================================
' Collecting memory usage information for a process.
' This is a translation of an example included in the MSDN documentation for PSAPI.
' ========================================================================================

' SED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "PSAPI.INC"

' ========================================================================================
' Displays the information
' ========================================================================================
SUB PrintMemoryInfo (BYVAL processID AS DWORD)

   LOCAL hProcess AS DWORD
   LOCAL pmc AS PROCESS_MEMORY_COUNTERS

   '// Print the process identifier
   PRINT "Process ID: " processID

   '// Print information about the memory usage of the process.
   hProcess = Openprocess (%PROCESS_QUERY_INFORMATION OR _
                           %PROCESS_VM_READ, %FALSE, processID)

   IF hProcess = 0 THEN EXIT SUB

   IF (GetProcessMemoryInfo(hProcess, pmc, SIZEOF(pmc))) THEN
      PRINT "PageFaultCount: ", pmc.PageFaultCount
      PRINT "PeakWorkinSetSize: ", pmc.PeakWorkingSetSize
      PRINT "WorkingSetSize: "pmc.WorkingSetSize
      PRINT "QuotaPeakPagegPoolUsage: ", pmc.QuotaPeakPagedPoolUsage
      PRINT "QuotaPagedPoolUsage: ", pmc.QuotaPagedPoolUsage
      PRINT "QuotaPeakNonPagedPoolUsage: ", pmc.QuotaPeakNonPagedPoolUsage
      PRINT "QuotaNonPagedPoolUsage: ", pmc.QuotaNonPagedPoolUsage
      PRINT "PageFileUsage: ", pmc.PageFileUsage
      PRINT "PeakPageFileUsage: ", pmc.PeakPageFileUsage
   END IF

   CloseHandle hProcess

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   DIM   aProcesses(0 TO 1023) AS DWORD
   LOCAL cbNeeded AS DWORD
   LOCAL cProcesses AS DWORD
   LOCAL i AS LONG

   '// Get the list of process identifiers
   IF ISFALSE EnumProcesses(aProcesses(LBOUND(aProcesses)), _
      (UBOUND(aProcesses) - LBOUND(aProcesses) + 1) * 4, cbNeeded) THEN EXIT FUNCTION

   '// Calculate how many process identifiers were returned.
   cProcesses = cbNeeded \ 4

   '// Print the memory usage for each process
   FOR i= 0 TO cProcesses - 1
      PrintMemoryInfo aProcesses(i)
   NEXT

   WAITKEY$

END FUNCTION
' ========================================================================================