typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
MaxProcessInfoClass
} PROCESSINFOCLASS;
Figure 3 NTQUERYINFORMATIONPROCESSDEMO
//==================================================
// NTQUERYINFORMATIONPROCESSDEMO - Matt Pietrek 1997
// Microsoft Systems Journal, January 1997
// FILE: NTQUERYINFORMATIONPROCESSDEMO.CPP
//==================================================
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
#include "psapi.h"
#include "ntqueryinformationprocess.h"
#include "ntqueryinformationprocessdemo.h"
// Helper function prototypes
void Handle_WM_COMMAND(HWND hDlg, WPARAM wParam, LPARAM lParam);
void Handle_WM_INITDIALOG(HWND hDlg);
void Handle_WM_CLOSE( HWND hDlg );
BOOL CALLBACK NtQueryInformationProcessDemoDlgProc(HWND,UINT,WPARAM,LPARAM);
int lbprintf(HWND hWnd, char * format, ...);
void StrFromLONGLONG( LONGLONG val , PSTR szOut );
DWORD GetDlgSelectedItemData( HWND hDlg, int ctlID );
void FakeFirstLbItemSelection( HWND hDlg, int listboxID );
void GetSetPositionInfoFromRegistry( BOOL fSave, POINT *lppt );
// ======================= String literals ===============================
char gszRegistryKey[]
= "Software\\WheatyProductions\\NtQueryInformationProcessDemo";
char g_AboutMsgTxt[] =
"NtQueryInformationProcessDemo shows processes information obtained "
"from the NtQueryInformationProcess function";
char g_AboutTitleTxt[]
= "NtQueryInformationProcessDemo - Matt Pietrek 1997, for MSJ";
// ======================= Start of code ===============================
//
// Wrapper function around NtQueryInformationProcess. Lets you pass
// in a PID, and takes care of creating and closing a process handle.
// Also takes care of other housecleaning work.
//
BOOL QueryProcessInformation( DWORD pid,
PROCESSINFOCLASS infoEnum,
void * pBuffer,
unsigned cbBuffer )
{
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid );
if ( !hProcess )
return FALSE;
// Zero the input buffer that NtQueryInformationProcess sees
memset( pBuffer, 0, cbBuffer );
DWORD retLen;
int retValue;
retValue = NtQueryInformationProcess( hProcess, infoEnum,
pBuffer, cbBuffer, &retLen );
CloseHandle( hProcess );
if ( retValue < 0 ) // NtQueryInformationProcess returns a negative
return FALSE; // value if it fails
return TRUE;
}
//
// Using functions from PSAPI.DLL, update the listbox in the upper left
// corner, and store the associated PID with each entry.
//
void UpdateProcessList( HWND hDlg )
{
// Get the treeview's HWND, then clear it
HWND hWnd = GetDlgItem( hDlg,IDC_LB_PROCESSES );
// Get the list of process IDs
DWORD aProcesses[1024], cbNeeded;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return;
// Calculate how many process IDs were returned
DWORD cProcesses = cbNeeded / sizeof(DWORD);
// Spit out the information for each ID
for ( unsigned i = 0; i < cProcesses; i++ )
{
char szProcessName[MAX_PATH] = "unknown";
DWORD pid = aProcesses[i];
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, pid );
if ( !hProcess ) // OpenProcess failed...
continue;
HMODULE hMod;
DWORD cbNeeded;
// Get just the first module in the process. This appears to
// always be the executable file.
if ( EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName) );
}
CloseHandle( hProcess );
// Add the string to the process listbox, and associate the PID with it
long lbIndex = lbprintf( hWnd, "%3X %s", pid, szProcessName );
SendMessage( hWnd, LB_SETITEMDATA, lbIndex, pid );
}
}
// Helper function called by UpdateProcessInfoFields
void UpdateProcessBasicInformation( HWND hDlg, DWORD pid )
{
HWND hWndLb = GetDlgItem( hDlg, IDC_LB_BASIC_INFO );
SendMessage( hWndLb, LB_RESETCONTENT, 0, 0 );
PROCESS_BASIC_INFORMATION pbi;
if ( QueryProcessInformation( pid, ProcessBasicInformation,
&pbi, sizeof(pbi)) )
{
lbprintf( hWndLb, "ExitStatus: %X", pbi.ExitStatus );
lbprintf( hWndLb, "PebBaseAddress: %08X", pbi.PebBaseAddress );
lbprintf( hWndLb, "AffinityMask: %08X", pbi.AffinityMask );
lbprintf( hWndLb, "BasePriority: %X", pbi.BasePriority );
lbprintf( hWndLb, "UniqueProcessId: %X", pbi.UniqueProcessId );
lbprintf( hWndLb, "InheritedFromProcessId: %X",
pbi.InheritedFromUniqueProcessId );
}
}
// Helper function called by UpdateProcessInfoFields
void UpdateProcessMiscFields( HWND hDlg, DWORD pid )
{
HWND hWndLb = GetDlgItem( hDlg, IDC_LB_MISC );
SendMessage( hWndLb, LB_RESETCONTENT, 0, 0 );
DWORD dwVal;
if ( QueryProcessInformation(pid, ProcessDebugPort, &dwVal, sizeof(dwVal)))
lbprintf( hWndLb, "DebugPort: %08X", dwVal );
if ( QueryProcessInformation( pid, ProcessDefaultHardErrorMode,
&dwVal, sizeof(dwVal)) )
lbprintf( hWndLb, "DefaultHardErrorMode: %08X", dwVal );
if ( QueryProcessInformation( pid, ProcessWx86Information,
&dwVal, sizeof(dwVal)))
lbprintf( hWndLb, "Wx86Information: %08X", dwVal );
if ( QueryProcessInformation(pid, ProcessHandleCount,&dwVal,sizeof(dwVal)))
lbprintf( hWndLb, "HandleCount: %X", dwVal );
if (QueryProcessInformation(pid,ProcessPriorityBoost,&dwVal,sizeof(dwVal)))
lbprintf( hWndLb, "PriorityBoost: %X", dwVal );
}
•
•
•