ModuleInstance.cpp
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:21k
- //---------------------------------------------------------------------------
- // ModuleInstance.cpp
- //
- // AUTHOR: Ivo Ivanov (ivopi@hotmail.com)
- // ver 1.02
- // 05 September 2001
- //---------------------------------------------------------------------------
- #include "Common.h"
- #include "ModuleInstance.h"
- #include "SysUtils.h"
- //---------------------------------------------------------------------------
- //
- // class CElements
- //
- //---------------------------------------------------------------------------
- CElements::CElements():
- CModuleList()
- {
-
- }
- CElements::~CElements()
- {
-
- }
- //---------------------------------------------------------------------------
- //
- // class CLibHandler
- //
- //---------------------------------------------------------------------------
- CLibHandler::CLibHandler(CRunningProcesses* pProcesses):
- m_pProcesses(pProcesses)
- {
- }
- CLibHandler::~CLibHandler()
- {
- }
- //---------------------------------------------------------------------------
- //
- // class CTaskManager
- //
- //---------------------------------------------------------------------------
- CTaskManager::CTaskManager():
- m_pLibHandler(NULL)
- {
- m_pProcesses = new CRunningProcesses();
- if (IsPsapiSupported())
- m_pLibHandler = new CPsapiHandler(m_pProcesses);
- else
- if (IsToolHelpSupported())
- m_pLibHandler = new CToolhelpHandler(m_pProcesses);
- }
- CTaskManager::~CTaskManager()
- {
- delete m_pLibHandler;
- delete m_pProcesses;
- }
- //---------------------------------------------------------------------------
- // Populate
- //
- // Populate the process and modules list using PSAPI or ToolHlp32
- //---------------------------------------------------------------------------
- BOOL CTaskManager::Populate(BOOL bPopulateModules)
- {
- m_pProcesses->ReleaseAll();
- return m_pLibHandler->PopulateProcesses(bPopulateModules);
- }
- //---------------------------------------------------------------------------
- // PopulateProcess
- //
- // Populate the module list using PSAPI or ToolHlp32
- //---------------------------------------------------------------------------
- BOOL CTaskManager::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules)
- {
- m_pProcesses->ReleaseAll();
- return m_pLibHandler->PopulateProcess(dwProcessId, bPopulateModules);
- }
- //---------------------------------------------------------------------------
- // GetProcessCount
- //
- // Returns a number of currently loaded processes
- //---------------------------------------------------------------------------
- DWORD CTaskManager::GetProcessCount() const
- {
- return m_pProcesses->GetCount();
- }
- //---------------------------------------------------------------------------
- // GetProcessByIndex
- //
- // Returns a process from the container
- //---------------------------------------------------------------------------
- CExeModuleInstance* CTaskManager::GetProcessByIndex(DWORD dwIndex)
- {
- return static_cast<CExeModuleInstance*>(m_pProcesses->GetModule(dwIndex));
- }
- //---------------------------------------------------------------------------
- // GetProcessById
- //
- // Returns a process by its ID
- //---------------------------------------------------------------------------
- CExeModuleInstance* CTaskManager::GetProcessById(DWORD dwProcessId)
- {
- return static_cast<CExeModuleInstance*>
- (m_pProcesses->GetProcessById(dwProcessId));
- }
- //---------------------------------------------------------------------------
- //
- // class CLoadedModules
- //
- //---------------------------------------------------------------------------
- CLoadedModules::CLoadedModules(DWORD dwProcessId):
- CElements(),
- m_dwProcessId(dwProcessId)
- {
-
- }
- CLoadedModules::~CLoadedModules()
- {
-
- }
- //---------------------------------------------------------------------------
- //
- // class CRunningProcesses
- //
- //---------------------------------------------------------------------------
- CRunningProcesses::CRunningProcesses():
- CElements()
- {
- }
- CRunningProcesses::~CRunningProcesses()
- {
- }
- CExeModuleInstance* CRunningProcesses::GetProcessById(DWORD dwProcessId)
- {
- CExeModuleInstance* pResult = NULL;
- CExeModuleInstance* pProcess;
- for (long i = 0; i < GetCount(); i++)
- {
- pProcess = static_cast<CExeModuleInstance*>( GetModule(i) );
- if (pProcess->Get_ProcessId() == dwProcessId)
- {
- pResult = pProcess;
- break;
- } // if
- } // for
- return pResult;
- }
- //---------------------------------------------------------------------------
- //
- // class CPsapiHandler
- //
- //---------------------------------------------------------------------------
- CPsapiHandler::CPsapiHandler(CRunningProcesses* pProcesses):
- CLibHandler(pProcesses),
- m_hModPSAPI(NULL),
- m_pfnEnumProcesses(NULL),
- m_pfnEnumProcessModules(NULL),
- m_pfnGetModuleFileNameExA(NULL)
- {
-
- }
- CPsapiHandler::~CPsapiHandler()
- {
- Finalize();
- }
- //---------------------------------------------------------------------------
- // Initialize
- //
- //---------------------------------------------------------------------------
- BOOL CPsapiHandler::Initialize()
- {
- BOOL bResult = FALSE;
- //
- // Get to the 3 functions in PSAPI.DLL dynamically. We can't
- // be sure that PSAPI.DLL has been installed
- //
- if (NULL == m_hModPSAPI)
- m_hModPSAPI = ::LoadLibraryA("PSAPI.DLL");
- if (NULL != m_hModPSAPI)
- {
- m_pfnEnumProcesses = (PFNENUMPROCESSES)
- ::GetProcAddress(m_hModPSAPI,"EnumProcesses");
- m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES)
- ::GetProcAddress(m_hModPSAPI, "EnumProcessModules");
- m_pfnGetModuleFileNameExA = (PFNGETMODULEFILENAMEEXA)
- ::GetProcAddress(m_hModPSAPI, "GetModuleFileNameExA");
- }
- bResult =
- m_pfnEnumProcesses
- && m_pfnEnumProcessModules
- && m_pfnGetModuleFileNameExA;
- return bResult;
- }
- //---------------------------------------------------------------------------
- // Finalize
- //
- //---------------------------------------------------------------------------
- void CPsapiHandler::Finalize()
- {
- if (NULL != m_hModPSAPI)
- ::FreeLibrary(m_hModPSAPI);
- }
- //---------------------------------------------------------------------------
- // PopulateModules
- //
- // Populate the module list using PSAPI
- //---------------------------------------------------------------------------
- BOOL CPsapiHandler::PopulateModules(CModuleInstance* pProcess)
- {
- BOOL bResult = TRUE;
- CModuleInstance *pDllModuleInstance = NULL;
- if (TRUE == Initialize())
- {
- DWORD pidArray[1024];
- DWORD cbNeeded;
- DWORD nProcesses;
- // EnumProcesses returns an array with process IDs
- if (m_pfnEnumProcesses(pidArray, sizeof(pidArray), &cbNeeded))
- {
- // Determine number of processes
- nProcesses = cbNeeded / sizeof(DWORD);
- // Release the container
- pProcess->ReleaseModules();
- for (DWORD i = 0; i < nProcesses; i++)
- {
- HMODULE hModuleArray[1024];
- HANDLE hProcess;
- DWORD pid = pidArray[i];
- DWORD nModules;
- // Let's open the process
- hProcess = ::OpenProcess(
- PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, pid);
- if (!hProcess)
- continue;
- if (static_cast<CExeModuleInstance*>(pProcess)->Get_ProcessId() != pid)
- {
- ::CloseHandle(hProcess);
- continue;
- }
- // EnumProcessModules function retrieves a handle for
- // each module in the specified process.
- if (!m_pfnEnumProcessModules(
- hProcess, hModuleArray,
- sizeof(hModuleArray), &cbNeeded))
- {
- ::CloseHandle(hProcess);
- continue;
- }
- // Calculate number of modules in the process
- nModules = cbNeeded / sizeof(hModuleArray[0]);
- for (DWORD j = 0; j < nModules; j++)
- {
- HMODULE hModule = hModuleArray[j];
- char szModuleName[MAX_PATH];
- m_pfnGetModuleFileNameExA(
- hProcess,
- hModule,
- szModuleName,
- sizeof(szModuleName)
- );
- if (0 == j) // First module is the EXE.
- {
- // Do nothing.
- } // if
- else // Not the first module. It's a DLL
- {
- pDllModuleInstance = new CModuleInstance(
- szModuleName,
- hModule
- );
- pProcess->AddModule(pDllModuleInstance);
- } // else
- } // for
- ::CloseHandle(hProcess); // We're done with this process handle
- } // for
- bResult = TRUE;
- } // if
- else
- {
- bResult = FALSE;
- }
- } // if
- else
- {
- bResult = FALSE;
- }
- return bResult;
- }
- //---------------------------------------------------------------------------
- // PopulateProcesses
- //
- // Populate the process list using PSAPI
- //---------------------------------------------------------------------------
- BOOL CPsapiHandler::PopulateProcesses(BOOL bPopulateModules)
- {
- BOOL bResult = TRUE;
- CExeModuleInstance* pProcessInfo;
- char szModuleName[MAX_PATH];
-
- if (TRUE == Initialize())
- {
- DWORD pidArray[1024];
- DWORD cbNeeded;
- DWORD nProcesses;
-
- if (m_pfnEnumProcesses(pidArray, sizeof(pidArray), &cbNeeded))
- {
- // Determine number of processes
- nProcesses = cbNeeded / sizeof(DWORD);
- m_pProcesses->ReleaseAll();
- for (DWORD i = 0; i < nProcesses; i++)
- {
- HMODULE hModuleArray[1024];
- HANDLE hProcess;
- DWORD pid = pidArray[i];
- DWORD nModules;
- hProcess = ::OpenProcess(
- PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE,
- pid
- );
- if (!hProcess)
- continue;
- if (!m_pfnEnumProcessModules(hProcess, hModuleArray,
- sizeof(hModuleArray), &cbNeeded))
- {
- ::CloseHandle(hProcess);
- continue;
- }
- // Calculate number of modules in the process
- nModules = cbNeeded / sizeof(hModuleArray[0]);
- for (DWORD j = 0; j < nModules; j++)
- {
- HMODULE hModule = hModuleArray[j];
- m_pfnGetModuleFileNameExA(
- hProcess,
- hModule,
- szModuleName,
- sizeof(szModuleName)
- );
- if (0 == j) // First module is the EXE. Just add it to the map
- {
- pProcessInfo = new CExeModuleInstance(
- this,
- szModuleName,
- hModule,
- pid
- );
- m_pProcesses->Add(*pProcessInfo);
- if (bPopulateModules)
- pProcessInfo->PopulateModules();
- break;
- } // if
- } // for
- ::CloseHandle(hProcess);
- } // for
-
- bResult = TRUE;
- } // if
- else
- {
- bResult = FALSE;
- }
- } // if
- else
- {
- bResult = FALSE;
- }
-
- return bResult;
- }
- //---------------------------------------------------------------------------
- // PopulateProcess
- //
- // Populate all modules of a single process
- //
- //---------------------------------------------------------------------------
- BOOL CPsapiHandler::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules)
- {
- BOOL bResult = TRUE;
- CExeModuleInstance* pProcessInfo;
-
- if (TRUE == Initialize())
- {
- m_pProcesses->ReleaseAll();
- HMODULE hModuleArray[1024];
- HANDLE hProcess;
- DWORD nModules;
- DWORD cbNeeded;
- hProcess = ::OpenProcess(
- PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE,
- dwProcessId
- );
- if (hProcess)
- {
- if (!m_pfnEnumProcessModules(
- hProcess,
- hModuleArray,
- sizeof(hModuleArray),
- &cbNeeded
- ))
- ::CloseHandle(hProcess);
- else
- {
- // Calculate number of modules in the process
- nModules = cbNeeded / sizeof(hModuleArray[0]);
- for (DWORD j = 0; j < nModules; j++)
- {
- HMODULE hModule = hModuleArray[j];
- char szModuleName[MAX_PATH];
- m_pfnGetModuleFileNameExA(
- hProcess,
- hModule,
- szModuleName,
- sizeof(szModuleName)
- );
- if (0 == j) // First module is the EXE. Just add it to the map
- {
- pProcessInfo = new CExeModuleInstance(
- this,
- szModuleName,
- hModule,
- dwProcessId
- );
- m_pProcesses->Add(*pProcessInfo);
- if (bPopulateModules)
- pProcessInfo->PopulateModules();
- break;
- } // if
- } // for
- ::CloseHandle(hProcess);
- } // if
- } // if
- } // if
- else
- {
- bResult = FALSE;
- }
- return bResult;
- }
- //---------------------------------------------------------------------------
- //
- // class CToolhelpHandler
- //
- //---------------------------------------------------------------------------
- CToolhelpHandler::CToolhelpHandler(CRunningProcesses* pProcesses):
- CLibHandler(pProcesses)
- {
-
- }
- CToolhelpHandler::~CToolhelpHandler()
- {
-
- }
- //---------------------------------------------------------------------------
- // Initialize
- //
- //---------------------------------------------------------------------------
- BOOL CToolhelpHandler::Initialize()
- {
- BOOL bResult = FALSE;
- HINSTANCE hInstLib;
- hInstLib = ::LoadLibraryA("Kernel32.DLL");
- if (NULL != hInstLib)
- {
- //
- // We must link to these functions of Kernel32.DLL explicitly. Otherwise
- // a module using this code would fail to load under Windows NT, which does not
- // have the Toolhelp32 functions in the Kernel32.
- //
- m_pfnCreateToolhelp32Snapshot = (PFNCREATETOOLHELP32SNAPSHOT)
- ::GetProcAddress(hInstLib, "CreateToolhelp32Snapshot");
- m_pfnProcess32First = (PFNPROCESS32FIRST)
- ::GetProcAddress(hInstLib, "Process32First");
- m_pfnProcess32Next = (PFNPROCESS32NEXT)
- ::GetProcAddress(hInstLib, "Process32Next");
- m_pfnModule32First = (PFNMODULE32FIRST)
- ::GetProcAddress(hInstLib, "Module32First");
- m_pfnModule32Next = (PFNMODULE32NEXT)
- ::GetProcAddress(hInstLib, "Module32Next");
- ::FreeLibrary( hInstLib );
- bResult = m_pfnCreateToolhelp32Snapshot &&
- m_pfnProcess32First &&
- m_pfnProcess32Next &&
- m_pfnModule32First &&
- m_pfnModule32Next;
- } // if
- return bResult;
- }
- //---------------------------------------------------------------------------
- // PopulateModules
- //
- // Populate the module list using ToolHelp32
- //---------------------------------------------------------------------------
- BOOL CToolhelpHandler::PopulateModules(CModuleInstance* pProcess)
- {
- BOOL bResult = TRUE;
- CModuleInstance *pDllModuleInstance = NULL;
- HANDLE hSnapshot = INVALID_HANDLE_VALUE;
- hSnapshot = m_pfnCreateToolhelp32Snapshot(
- TH32CS_SNAPMODULE,
- static_cast<CExeModuleInstance*>(pProcess)->Get_ProcessId());
- MODULEENTRY32 me = { sizeof(me) };
- for (BOOL bOk = ModuleFirst(hSnapshot, &me); bOk; bOk = ModuleNext(hSnapshot, &me))
- {
- // We don't need to add to the list the process itself.
- // The module list should keep references to DLLs only
- if (0 != stricmp(pProcess->GetBaseName(), me.szModule))
- {
- pDllModuleInstance = new CModuleInstance(me.szExePath, me.hModule);
- pProcess->AddModule(pDllModuleInstance);
- }
- else
- //
- // However, we should fix up the module of the EXE, because
- // th32ModuleID member has meaning only to the tool help functions
- // and it is not usable by Win32 API elements.
- //
- {
- pProcess->Set_Module( me.hModule );
- }
- } // for
- if (hSnapshot != INVALID_HANDLE_VALUE)
- ::CloseHandle(hSnapshot);
- return bResult;
- }
- BOOL CToolhelpHandler::ModuleFirst(HANDLE hSnapshot, PMODULEENTRY32 pme) const
- {
- return m_pfnModule32First(hSnapshot, pme);
- }
- BOOL CToolhelpHandler::ModuleNext(HANDLE hSnapshot, PMODULEENTRY32 pme) const
- {
- return m_pfnModule32Next(hSnapshot, pme);
- }
- BOOL CToolhelpHandler::ProcessFirst(HANDLE hSnapshot, PROCESSENTRY32* pe32) const
- {
- return m_pfnProcess32First(hSnapshot, pe32);
- }
- BOOL CToolhelpHandler::ProcessNext(HANDLE hSnapshot, PROCESSENTRY32* pe32) const
- {
- return m_pfnProcess32Next(hSnapshot, pe32);
- }
- //---------------------------------------------------------------------------
- // PopulateProcesses
- //
- // Populate the process list using Toolhelp
- //---------------------------------------------------------------------------
- BOOL CToolhelpHandler::PopulateProcesses(BOOL bPopulateModules)
- {
- return PopulateProcess(NULL, bPopulateModules);
- }
- //---------------------------------------------------------------------------
- // PopulateProcess
- //
- // Populate all modules of a single process
- //
- //---------------------------------------------------------------------------
- BOOL CToolhelpHandler::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules)
- {
- BOOL bResult = FALSE;
- CExeModuleInstance* pProcessInfo;
- HANDLE hSnapshot = INVALID_HANDLE_VALUE;
- if (TRUE == Initialize())
- {
- hSnapshot = m_pfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, dwProcessId);
- PROCESSENTRY32 pe32 = { sizeof(pe32) };
- for (BOOL bOk = ProcessFirst(hSnapshot, &pe32); bOk; bOk = ProcessNext(hSnapshot, &pe32))
- {
- if ( (dwProcessId != NULL) && (dwProcessId != pe32.th32ProcessID) )
- continue;
- pProcessInfo = new CExeModuleInstance(
- this,
- pe32.szExeFile,
- NULL, // We will fix up later this value
- pe32.th32ProcessID
- );
- m_pProcesses->Add(*pProcessInfo);
- if (bPopulateModules)
- pProcessInfo->PopulateModules();
- if (dwProcessId != NULL)
- break;
- } // for
- if (hSnapshot != INVALID_HANDLE_VALUE)
- ::CloseHandle(hSnapshot);
- bResult = TRUE;
- }
- return bResult;
- }
- //---------------------------------------------------------------------------
- //
- // class CModuleList
- //
- //---------------------------------------------------------------------------
- CModuleList::CModuleList()
- {
- }
- CModuleList::~CModuleList()
- {
- ReleaseAll();
- }
- //---------------------------------------------------------------------------
- // Add
- //
- // Add new object to the container
- //---------------------------------------------------------------------------
- void CModuleList::Add(CModuleInstance &moduleInstance)
- {
- push_back(&moduleInstance);
- }
- //---------------------------------------------------------------------------
- // ReleaseAll
- //
- // Release all objects and clear the list
- //---------------------------------------------------------------------------
- void CModuleList::ReleaseAll()
- {
- CModuleList::iterator itr;
- CModuleInstance *pModuleInstance;
- for (itr = begin(); itr != end(); ++itr)
- {
- pModuleInstance = *itr;
- delete pModuleInstance;
- } // for
- clear();
- }
- //---------------------------------------------------------------------------
- // GetModule
- //
- // Return a module object by its index (Pascal-like style)
- //---------------------------------------------------------------------------
- CModuleInstance* CModuleList::GetModule(DWORD dwIndex) const
- {
- return at(dwIndex);
- }
- //---------------------------------------------------------------------------
- // GetCount
- //
- // Return number of items in the container
- //---------------------------------------------------------------------------
- DWORD CModuleList::GetCount() const
- {
- return size();
- }
- //---------------------------------------------------------------------------
- //
- // class CModuleInstance
- //
- //---------------------------------------------------------------------------
- CModuleInstance::CModuleInstance(char *pszName, HMODULE hModule):
- m_pszName(NULL),
- m_hModule(NULL),
- m_pInternalList(NULL)
- {
- Set_Name(pszName);
- Set_Module(hModule);
-
- }
- CModuleInstance::~CModuleInstance()
- {
- delete m_pInternalList;
- if (NULL != m_pszName)
- delete [] m_pszName;
- }
- void CModuleInstance::AddModule(CModuleInstance* pModuleInstance)
- {
- if (NULL == m_pInternalList)
- m_pInternalList = new CModuleList();
- m_pInternalList->Add(*pModuleInstance);
- }
- void CModuleInstance::ReleaseModules()
- {
- if (NULL != m_pInternalList)
- m_pInternalList->ReleaseAll();
- }
- char* CModuleInstance::Get_Name() const
- {
- return m_pszName;
- }
- char* CModuleInstance::GetBaseName() const
- {
- char *pdest;
- int ch = '\';
- // Search backward
- pdest = strrchr(m_pszName, ch);
- if(pdest != NULL)
- return &pdest[1];
- else
- return m_pszName;
- }
- void CModuleInstance::Set_Name(char *pszName)
- {
- if (NULL != m_pszName)
- delete [] m_pszName;
- if ((NULL != pszName) && (strlen(pszName)))
- {
- m_pszName = new char[strlen(pszName) + 1];
- strcpy(m_pszName, pszName);
- }
- else
- {
- m_pszName = new char[strlen("