📄 simpleprocessapi.cpp
字号:
/*===========================================================================
(c) Copyright 1999, Emmanuel KARTMANN, all rights reserved
===========================================================================
File : SimpleProcessAPI.h
$Header: $
Author : Emmanuel KARTMANN
Creation : Friday 9/24/99 4:57:06 PM
Remake :
------------------------------- Description -------------------------------
Implementation of the CSimpleProcessAPI class
------------------------------ Modifications ------------------------------
$Log: $
===========================================================================
*/
#include "stdafx.h"
#include "SimpleProcessAPI.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSimpleProcessAPI::CSimpleProcessAPI()
: m_hModule(NULL)
, m_pBuildProcessListFunction(NULL)
, m_pBuildModuleListFunction(NULL)
, m_pEnumProcessModulesFunction(NULL)
, m_pGetModuleFileNameExFunction(NULL)
, m_pCreateToolhelp32SnapshotFunction(NULL)
, m_pProcess32FirstFunction(NULL)
, m_pProcess32NextFunction(NULL)
, m_pModule32FirstFunction(NULL)
, m_pModule32NextFunction(NULL)
{
// Load library and map function, based on OS type (Windows NT or Windows 95/98)
LoadProcessDLL();
}
CSimpleProcessAPI::~CSimpleProcessAPI()
{
UnLoadProcessDLL();
}
BOOL CSimpleProcessAPI::LoadProcessDLL()
{
BOOL bReturnCode = FALSE;
UnLoadProcessDLL();
if (IsRunningWindowsNT()) {
m_hModule = LoadLibrary("psapi.dll");
if (m_hModule) {
m_pBuildProcessListFunction = &CSimpleProcessAPI::WindowsNTBuildProcessList;
m_pBuildModuleListFunction = &CSimpleProcessAPI::WindowsNTBuildModuleList;
m_pEnumProcessModulesFunction = (EnumProcessModulesFunctionPtr)GetProcAddress(m_hModule, "EnumProcessModules");
# ifdef UNICODE
m_pGetModuleFileNameExFunction = (GetModuleFileNameExFunctionPtr)GetProcAddress(m_hModule, "GetModuleFileNameExW");
# else
m_pGetModuleFileNameExFunction = (GetModuleFileNameExFunctionPtr)GetProcAddress(m_hModule, "GetModuleFileNameExA");
# endif // UNICODE
}
} else {
m_hModule = LoadLibrary("kernel32.dll");
if (m_hModule) {
m_pBuildProcessListFunction = &CSimpleProcessAPI::Windows9xBuildProcessList;
m_pBuildModuleListFunction = &CSimpleProcessAPI::Windows9xBuildModuleList;
m_pCreateToolhelp32SnapshotFunction = (CreateToolhelp32SnapshotFunctionPtr)GetProcAddress(m_hModule, "CreateToolhelp32Snapshot");
# ifdef UNICODE
m_pProcess32FirstFunction = (Process32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Process32FirstW");
m_pProcess32NextFunction = (Process32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Process32NextW");
m_pModule32FirstFunction = (Module32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Module32FirstW");
m_pModule32NextFunction = (Module32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Module32NextW");
# else
m_pProcess32FirstFunction = (Process32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Process32First");
m_pProcess32NextFunction = (Process32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Process32Next");
m_pModule32FirstFunction = (Module32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Module32First");
m_pModule32NextFunction = (Module32FirstOrNextFunctionPtr)GetProcAddress(m_hModule, "Module32Next");
# endif // UNICODE
}
}
return(bReturnCode);
}
BOOL CSimpleProcessAPI::UnLoadProcessDLL()
{
BOOL bReturnCode = FALSE;
if (m_hModule) {
bReturnCode = FreeLibrary(m_hModule);
m_hModule = NULL;
}
return(bReturnCode);
}
BOOL CSimpleProcessAPI::IsRunningWindowsNT()
{
OSVERSIONINFO versionInfo;
// set the size of OSVERSIONINFO, before calling the function
versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
// Get the version information
if (::GetVersionEx (&versionInfo)) {
if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
return(TRUE);
}
}
return(FALSE);
}
BOOL CSimpleProcessAPI::BuildProcessList(CMapStringToString &ProcessPIDNameMap)
{
BOOL bReturnCode = FALSE;
ASSERT(m_pBuildProcessListFunction);
if (m_pBuildProcessListFunction) {
bReturnCode = ((*this).*m_pBuildProcessListFunction)(ProcessPIDNameMap);
}
return(bReturnCode);
}
BOOL CSimpleProcessAPI::BuildModuleList(DWORD nCurrentPID, CStringList &ModuleFileNameList)
{
BOOL bReturnCode = FALSE;
ASSERT(m_pBuildProcessListFunction);
if (m_pBuildModuleListFunction) {
bReturnCode = ((*this).*m_pBuildModuleListFunction)(nCurrentPID, ModuleFileNameList);
}
return(bReturnCode);
}
BOOL CSimpleProcessAPI::WindowsNTBuildProcessList(CMapStringToString &ProcessPIDNameMap)
{
// NT Implementation: Uses Registry Performance Data
// Reset list/map
ProcessPIDNameMap.RemoveAll();
//This following was coded using the tlist example
bool bErrorOccured=false;
DWORD rc;
HKEY hKeyNames;
DWORD dwType;
DWORD dwSize;
LPBYTE buf = NULL;
TCHAR szSubKey[1024];
LANGID lid;
LPSTR p;
LPSTR p2;
PPERF_DATA_BLOCK pPerf;
PPERF_OBJECT_TYPE pObj;
PPERF_INSTANCE_DEFINITION pInst;
PPERF_COUNTER_BLOCK pCounter;
PPERF_COUNTER_DEFINITION pCounterDef;
DWORD i;
DWORD dwProcessIdTitle;
DWORD dwProcessIdCounter;
TCHAR szProcessName[MAX_PATH];
DWORD dwLimit = 256;
DWORD dwNumTasks;
lid = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL);
_stprintf( szSubKey, _T("%s\\%03x"), REGKEY_PERF, lid );
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
szSubKey,
0,
KEY_READ,
&hKeyNames
);
if (rc != ERROR_SUCCESS)
{
bErrorOccured=true;
goto exit;
}
//
// get the buffer size for the counter names
//
rc = RegQueryValueEx(hKeyNames,
REGSUBKEY_COUNTERS,
NULL,
&dwType,
NULL,
&dwSize
);
if (rc != ERROR_SUCCESS)
{
bErrorOccured=true;
goto exit;
}
//
// allocate the counter names buffer
//
buf = (LPBYTE) malloc(dwSize);
if (buf == NULL)
{
bErrorOccured=true;
goto exit;
}
memset(buf, 0, dwSize);
//
// read the counter names from the registry
//
rc = RegQueryValueEx( hKeyNames,
REGSUBKEY_COUNTERS,
NULL,
&dwType,
buf,
&dwSize
);
if (rc != ERROR_SUCCESS)
{
bErrorOccured=true;
goto exit;
}
//
// now loop thru the counter names looking for the "Process" counters:
// the buffer contains multiple null terminated strings and then
// finally null terminated at the end. the strings are in pairs of
// counter number and counter name.
//
p =(LPSTR) buf;
while (*p)
{
if (p > (LPSTR)buf)
{
for( p2=p-2; _istdigit(*p2); p2--)
;
}
if (_tcsicmp(p, PROCESS_COUNTER) == 0)
{
// look backwards for the counter number
for(p2=p-2; _istdigit(*p2); p2--)
;
_tcscpy(szSubKey, p2+1);
} else {
if (stricmp(p, PROCESSID_COUNTER) == 0) {
//
// look backwards for the counter number
//
for( p2=p-2; isdigit(*p2); p2--)
;
dwProcessIdTitle = atol( p2+1 );
}
}
//
// next string
//
p += (_tcslen(p) + 1);
}
// free the counter names buffer
free(buf);
// allocate the initial buffer for the performance data
dwSize = INITIAL_SIZE;
buf = (LPBYTE)malloc( dwSize );
if (buf == NULL)
{
bErrorOccured=true;
goto exit;
}
memset(buf, 0, dwSize);
while (true)
{
rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
szSubKey,
NULL,
&dwType,
buf,
&dwSize
);
pPerf = (PPERF_DATA_BLOCK) buf;
// check for success and valid perf data block signature
if ((rc == ERROR_SUCCESS) &&
(dwSize > 0) &&
(pPerf)->Signature[0] == (WCHAR)'P' &&
(pPerf)->Signature[1] == (WCHAR)'E' &&
(pPerf)->Signature[2] == (WCHAR)'R' &&
(pPerf)->Signature[3] == (WCHAR)'F' )
{
break;
}
// if buffer is not big enough, reallocate and try again
if (rc == ERROR_MORE_DATA)
{
dwSize += EXTEND_SIZE;
buf = (LPBYTE)realloc( buf, dwSize );
memset( buf, 0, dwSize );
}
else
{
bErrorOccured=true;
goto exit;
}
}
// set the perf_object_type pointer
pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerf + pPerf->HeaderLength);
//
// loop thru the performance counter definition records looking
// for the process id counter and then save its offset
//
pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength);
for (i=0; i<(DWORD)pObj->NumCounters; i++) {
if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) {
dwProcessIdCounter = pCounterDef->CounterOffset;
break;
}
pCounterDef++;
}
dwNumTasks = min( dwLimit, (DWORD)pObj->NumInstances );
pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength);
// loop thru the performance instance data extracting each process name
for (i=0; i<dwNumTasks; i++)
{
//
// pointer to the process name
//
p = (LPSTR) ((DWORD)pInst + pInst->NameOffset);
//
// convert it to ascii
//
rc = WideCharToMultiByte( CP_ACP,
0,
(LPCWSTR)p,
-1,
szProcessName,
sizeof(szProcessName),
NULL,
NULL
);
if (rc)
{
//m_strArray.Add(szProcessName);
TRACE1("%s\t", szProcessName);
}
// get the process id
pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength);
DWORD nProcessId = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter));
TRACE1("%u\n", nProcessId);
// Do not add the _Total instance: it's NOT a process
if (strcmp("_Total", szProcessName) && nProcessId) {
CString szMapKey;
szMapKey.Format("%u", nProcessId);
ProcessPIDNameMap.SetAt(szMapKey, szProcessName);
}
// next process
pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter + pCounter->ByteLength);
}
exit:
if (buf)
{
free(buf);
}
RegCloseKey(hKeyNames);
RegCloseKey(HKEY_PERFORMANCE_DATA);
return !bErrorOccured;
}
BOOL CSimpleProcessAPI::WindowsNTBuildModuleList(DWORD nCurrentPID, CStringList &ModuleFileNameList)
{
// NT Implementation: Uses PSAPI
BOOL bReturnCode = FALSE;
HANDLE pProcessHandle = NULL;
// Empty the list
ModuleFileNameList.RemoveAll();
if (nCurrentPID == 0) {
// Get current process id
nCurrentPID = GetCurrentProcessId();
pProcessHandle = GetCurrentProcess();
} else {
// Open the process to get an HANDLE on it
pProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, // not inherited
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -