|
|
///////////////////////////////////////////////////////////////////////
// Microsoft Windows //
// Copyright(c) Microsoft Corp., 1998 //
///////////////////////////////////////////////////////////////////////
//
// processs ID related routines
//
#include "inetcplp.h"
#include <tchar.h>
#include "psapi.h"
#include "tlhelp32.h"
#include "process.h"
CProcessInfo::CProcessInfo() { _fNT = IsOS(OS_NT4ORGREATER); // init w95 func pointers
_lpfnCreateToolhelp32Snapshot = NULL; _lpfnProcess32First = NULL; _lpfnProcess32Next = NULL; // init NT func pointers
_hPsapiDLL = NULL; _lpfnEnumProcesses = NULL; _lpfnGetModuleBaseName = NULL;
// process info array
_pProcInfoArray = NULL; _nAlloced = 0; _iProcInfoCount = 0; }
CProcessInfo::~CProcessInfo() { if(_pProcInfoArray) LocalFree(_pProcInfoArray);
if(_hPsapiDLL) FreeLibrary (_hPsapiDLL); }
#define ALLOC_STEP 50
HRESULT CProcessInfo::MakeRoomForInfoArray(int n) { HRESULT hr = S_OK; if (n > _nAlloced) { PROCESSINFO *p; int nSaved = _nAlloced;
while(n > _nAlloced) _nAlloced += ALLOC_STEP;
if (!_pProcInfoArray) { p = (PROCESSINFO *)LocalAlloc(LPTR, sizeof(PROCESSINFO)*_nAlloced); } else { p = (PROCESSINFO *)LocalReAlloc(_pProcInfoArray, sizeof(PROCESSINFO)*_nAlloced, LMEM_MOVEABLE|LMEM_ZEROINIT); }
if (p) _pProcInfoArray = p; else { hr = E_FAIL; _nAlloced = nSaved; } } return hr; }
HRESULT CProcessInfo::EnsureProcessInfo() { HRESULT hr = S_OK; if (!_pProcInfoArray) { if (_fNT) { NTCreateProcessList(); } else { W95CreateProcessList(); } } return hr; } HRESULT CProcessInfo::GetExeNameFromPID(DWORD dwPID, LPTSTR szFile, int cchFile) { HRESULT hr;
hr = EnsureProcessInfo(); if (hr == S_OK) { for (int i = 0; i < _iProcInfoCount; i++) { if (_pProcInfoArray[i].dwPID == dwPID) { _tcsncpy(szFile, _pProcInfoArray[i].szExeName, cchFile); break; } } } return hr; } HRESULT CProcessInfo::NTCreateProcessList() // Testing routine to see if we can get Process IDs.
{ HRESULT hr = E_FAIL;
hr = NTInitPsapi(); if (hr == S_OK) {
UINT iIndex;
DWORD aProcesses[100], cbNeeded;
if (_lpfnEnumProcesses((DWORD * )aProcesses, sizeof(aProcesses), (DWORD *)&cbNeeded)) { // Calculate how many process IDs were returned
DWORD cProcesses = cbNeeded / sizeof(DWORD); hr = MakeRoomForInfoArray(cProcesses); if (S_OK == hr) { // Spit out the information for each ID
for ( iIndex = 0; iIndex < cProcesses; iIndex++ ) { hr = NTFillProcessList(aProcesses[iIndex], iIndex); }
if (hr == S_OK) _iProcInfoCount = iIndex; } } } return hr; }
HRESULT CProcessInfo::NTInitPsapi() { HRESULT hr; // First, load the NT specific library, PSAPI.DLL.
if (!_hPsapiDLL) _hPsapiDLL = LoadLibrary(TEXT("PSAPI.DLL"));
if (_hPsapiDLL) { _lpfnEnumProcesses = (LPFNENUMPROCESSES)GetProcAddress(_hPsapiDLL, "EnumProcesses");
_lpfnGetModuleBaseName = (LPFNGETMODULEBASENAMEW)GetProcAddress(_hPsapiDLL, "GetModuleBaseNameW"); }
Assert(_lpfnEnumProcesses && _lpfnGetModuleBaseName);
hr = (_lpfnEnumProcesses && _lpfnGetModuleBaseName) ? S_OK : E_FAIL;
return hr; }
HRESULT CProcessInfo::NTFillProcessList(DWORD dwProcessID, int iIndex) { HRESULT hr = E_FAIL; TCHAR szProcessName[MAX_PATH] = TEXT("unknown"); int i = -1;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID ); if ( hProcess ) { DWORD dw = _lpfnGetModuleBaseName( hProcess, NULL, szProcessName, sizeof(szProcessName) ); if (dw > 0) hr = S_OK; CloseHandle (hProcess); }
if (hr == S_OK) { // Add PID and associated .EXE file info to list...
_pProcInfoArray[iIndex].dwPID = dwProcessID; _tcsncpy (_pProcInfoArray[iIndex].szExeName, szProcessName, ARRAYSIZE(_pProcInfoArray[iIndex].szExeName)); } return hr; }
HRESULT CProcessInfo::W95CreateProcessList() { HRESULT hr = E_FAIL;
if (S_OK == W95InitToolhelp32()) { hr = W95FillProcessList(); }
return (hr); }
HRESULT CProcessInfo::W95InitToolhelp32() // Win95 specific, sets up the things we need to get the process IDs.
{ HRESULT hr = E_FAIL; HMODULE hKernel = NULL;
// Obtain a module handle to KERNEL so that we can get the addresses of
// the 32-bit Toolhelp functions we need.
hKernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
if (hKernel) { _lpfnCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress(hKernel, "CreateToolhelp32Snapshot");
_lpfnProcess32First = (PROCESSWALK)GetProcAddress(hKernel, "Process32First"); _lpfnProcess32Next = (PROCESSWALK)GetProcAddress(hKernel, "Process32Next");
// All of our addresses must be non-NULL in order for us to be
// successful. If even one of these addresses is NULL, then we
// must fail because we won't be able to walk one of the lists
// we need to.
if (_lpfnProcess32First && _lpfnProcess32Next && _lpfnCreateToolhelp32Snapshot) hr = S_OK; }
return (hr); } #ifdef UNICODE
#undef PROCESSENTRY32
#endif // !UNICODE
HRESULT CProcessInfo::W95FillProcessList() // Fills in the array of process info, and also set the count of the items
{ HRESULT hr = E_FAIL; HANDLE hProcessSnap = NULL; PROCESSENTRY32 pe32 = {0};
// Take a snapshot of all processes currently in the system.
hProcessSnap = _lpfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == (HANDLE)-1) return hr;
// Size of the PROCESSENTRY32 structure must be filled out before use.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Walk the snapshot of processes and for each process, get information
// to display.
if (_lpfnProcess32First(hProcessSnap, &pe32)) { int iIndex = 0;
do // Add PID and associated .EXE file info to list...
{ hr = MakeRoomForInfoArray(iIndex+1); if (hr != S_OK) break;
_pProcInfoArray[iIndex].dwPID = pe32.th32ProcessID; LPSTR pszFile = PathFindFileNameA(pe32.szExeFile); if (pszFile) { SHAnsiToUnicode( pszFile, _pProcInfoArray[iIndex].szExeName, ARRAYSIZE(_pProcInfoArray[iIndex].szExeName)); } iIndex++; } while (_lpfnProcess32Next(hProcessSnap, &pe32));
_iProcInfoCount = iIndex; // takes care of the last failure
hr = S_OK; }
CloseHandle (hProcessSnap); return hr; }
|