You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
9.9 KiB
C++

// XTPSkinManagerModuleList.cpp: implementation of the CXTPSkinManagerModuleList class.
//
// This file is a part of the XTREME SKINFRAMEWORK MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <tlhelp32.h>
#include "XTPSkinManagerModuleList.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////////
// CModuleEnumerator
class CXTPSkinManagerModuleList::CModuleEnumerator
{
public:
CModuleEnumerator(DWORD dwProcessId);
virtual ~CModuleEnumerator();
virtual HMODULE GetFirstModule() = 0;
virtual HMODULE GetNextModule() = 0;
virtual BOOL GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo) = 0;
protected:
int m_dwProcessId;
};
CXTPSkinManagerModuleList::CModuleEnumerator::CModuleEnumerator(DWORD dwProcessId)
: m_dwProcessId(dwProcessId)
{
}
CXTPSkinManagerModuleList::CModuleEnumerator::~CModuleEnumerator()
{
}
//////////////////////////////////////////////////////////////////////////
// CPsapiModuleEnumerator
class CXTPSkinManagerModuleList::CPsapiModuleEnumerator : public CModuleEnumerator
{
typedef BOOL (WINAPI* PFNENUMPROCESSMODULES) ( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded );
typedef BOOL (WINAPI* PFNGETMODULEINFORMATION) (HANDLE hProcess, HMODULE hModule, XTP_MODULEINFO* lpmodinfo, DWORD cb);
public:
CPsapiModuleEnumerator(DWORD dwProcessId, HMODULE hModPSAPI);
~CPsapiModuleEnumerator();
virtual HMODULE GetFirstModule();
virtual HMODULE GetNextModule();
virtual BOOL GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo);
protected:
PFNENUMPROCESSMODULES m_pfnEnumProcessModules;
PFNGETMODULEINFORMATION m_pfnGetModuleInformation;
HMODULE m_hModPSAPI;
HMODULE* m_pModules;
int m_nIndex;
int m_nCount;
};
CXTPSkinManagerModuleList::CPsapiModuleEnumerator::CPsapiModuleEnumerator(DWORD dwProcessId, HMODULE hModPSAPI)
: CModuleEnumerator(dwProcessId)
{
m_hModPSAPI = hModPSAPI;
ASSERT(m_hModPSAPI);
m_pfnEnumProcessModules = NULL;
m_pfnGetModuleInformation = NULL;
if (m_hModPSAPI)
{
m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES) ::GetProcAddress(m_hModPSAPI, "EnumProcessModules");
m_pfnGetModuleInformation = (PFNGETMODULEINFORMATION) ::GetProcAddress(m_hModPSAPI, "GetModuleInformation");
}
m_pModules = NULL;
m_nIndex = 0;
m_nCount = 0;
}
CXTPSkinManagerModuleList::CPsapiModuleEnumerator::~CPsapiModuleEnumerator()
{
if (m_pModules)
{
delete[] m_pModules;
}
}
BOOL CXTPSkinManagerModuleList::CPsapiModuleEnumerator::GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo)
{
if (!m_pfnGetModuleInformation)
return NULL;
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, m_dwProcessId);
if (!hProcess)
return FALSE;
if (!m_pfnGetModuleInformation(hProcess, hModule, lpmodinfo, sizeof(XTP_MODULEINFO)))
{
::CloseHandle(hProcess);
return FALSE;
}
::CloseHandle(hProcess);
return TRUE;
}
HMODULE CXTPSkinManagerModuleList::CPsapiModuleEnumerator::GetFirstModule()
{
if (!m_pfnEnumProcessModules)
return NULL;
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, m_dwProcessId);
if (!hProcess)
return NULL;
DWORD cbNeeded = 0;
HMODULE hModule;
if (!m_pfnEnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded))
{
::CloseHandle(hProcess);
return NULL;
}
if (cbNeeded == 0)
{
::CloseHandle(hProcess);
return NULL;
}
m_nCount = cbNeeded / sizeof(HMODULE);
m_pModules = new HMODULE[m_nCount];
memset(m_pModules, 0, cbNeeded);
if (!m_pfnEnumProcessModules(hProcess, m_pModules, cbNeeded, &cbNeeded))
{
::CloseHandle(hProcess);
return NULL;
}
m_nIndex = 0;
::CloseHandle(hProcess);
return m_pModules[0];
}
HMODULE CXTPSkinManagerModuleList::CPsapiModuleEnumerator::GetNextModule()
{
ASSERT(m_pModules != NULL);
if (m_pModules == NULL)
return NULL;
m_nIndex++;
if (m_nIndex >= m_nCount)
return NULL;
return m_pModules[m_nIndex];
}
//////////////////////////////////////////////////////////////////////////
// ToolHelp
class CXTPSkinManagerModuleList::CToolHelpModuleEnumerator : public CModuleEnumerator
{
typedef BOOL (WINAPI* PFNMODULE32FIRST) ( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
typedef BOOL (WINAPI* PFNMODULE32NEXT) ( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
typedef HANDLE (WINAPI* PFNCREATETOOLHELP32SNAPSHOT) ( DWORD dwFlags, DWORD th32ProcessID );
public:
CToolHelpModuleEnumerator(DWORD dwProcessId);
~CToolHelpModuleEnumerator();
virtual HMODULE GetFirstModule();
virtual HMODULE GetNextModule();
virtual BOOL GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo);
protected:
HANDLE m_hSnapshot;
PFNCREATETOOLHELP32SNAPSHOT m_pfnCreateToolhelp32Snapshot;
PFNMODULE32NEXT m_pfnModule32Next;
PFNMODULE32FIRST m_pfnModule32First;
MODULEENTRY32 m_me;
};
CXTPSkinManagerModuleList::CToolHelpModuleEnumerator::CToolHelpModuleEnumerator(DWORD dwProcessId)
: CModuleEnumerator(dwProcessId)
{
HMODULE hInstLib = GetModuleHandle(_T("KERNEL32"));
ASSERT(hInstLib);
if (!hInstLib)
return;
//
// 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");
#ifdef UNICODE
m_pfnModule32First = (PFNMODULE32FIRST)
::GetProcAddress(hInstLib, "Module32FirstW");
m_pfnModule32Next = (PFNMODULE32NEXT)
::GetProcAddress(hInstLib, "Module32NextW");
#else
m_pfnModule32First = (PFNMODULE32FIRST)
::GetProcAddress(hInstLib, "Module32First");
m_pfnModule32Next = (PFNMODULE32NEXT)
::GetProcAddress(hInstLib, "Module32Next");
#endif
m_hSnapshot = INVALID_HANDLE_VALUE;
m_me.dwSize = sizeof(MODULEENTRY32);
}
CXTPSkinManagerModuleList::CToolHelpModuleEnumerator::~CToolHelpModuleEnumerator()
{
if (m_hSnapshot != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hSnapshot);
}
}
BOOL CXTPSkinManagerModuleList::CToolHelpModuleEnumerator::GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo)
{
if (m_pfnCreateToolhelp32Snapshot == NULL ||
m_pfnModule32First == NULL || m_pfnModule32Next == NULL)
{
return FALSE;
}
MODULEENTRY32 me;
ZeroMemory(&me, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32);
HANDLE hSnapshot = m_pfnCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_dwProcessId);
if (hSnapshot == INVALID_HANDLE_VALUE)
return FALSE;
if (!m_pfnModule32First(hSnapshot, &me))
return FALSE;
do
{
if (me.hModule == hModule)
{
lpmodinfo->lpBaseOfDll = me.modBaseAddr;
lpmodinfo->EntryPoint = 0;
lpmodinfo->SizeOfImage = me.modBaseSize;
CloseHandle(hSnapshot);
return TRUE;
}
} while (m_pfnModule32Next(hSnapshot, &me));
CloseHandle(hSnapshot);
return FALSE;
}
HMODULE CXTPSkinManagerModuleList::CToolHelpModuleEnumerator::GetFirstModule()
{
if (m_pfnCreateToolhelp32Snapshot == NULL ||
m_pfnModule32First == NULL || m_pfnModule32Next == NULL)
{
return NULL;
}
m_hSnapshot = m_pfnCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_dwProcessId);
if (m_hSnapshot == INVALID_HANDLE_VALUE)
return NULL;
if (m_pfnModule32First(m_hSnapshot, &m_me))
{
return m_me.hModule;
}
return NULL;
}
HMODULE CXTPSkinManagerModuleList::CToolHelpModuleEnumerator::GetNextModule()
{
if (m_hSnapshot == INVALID_HANDLE_VALUE)
return NULL;
if (m_pfnModule32Next(m_hSnapshot, &m_me))
{
return m_me.hModule;
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
// CXTPSkinManagerModuleList
CXTPSkinManagerModuleList::CSharedData::CSharedData()
{
m_hPsapiDll = ::LoadLibraryA("PSAPI.DLL");
m_bExists = m_hPsapiDll != NULL;
if (!m_bExists)
{
HMODULE hModule = ::GetModuleHandle(_T("KERNEL32.DLL"));
if (hModule)
{
if (::GetProcAddress(hModule, "CreateToolhelp32Snapshot") != NULL)
{
m_bExists = TRUE;
}
}
}
}
CXTPSkinManagerModuleList::CSharedData::~CSharedData()
{
if (m_hPsapiDll)
{
//FreeLibrary(m_hPsapiDll); Dangerous to call FreeLibrary in destructors of static objects.
}
}
CXTPSkinManagerModuleList::CSharedData& AFX_CDECL CXTPSkinManagerModuleList::GetSharedData()
{
static CSharedData sData;
return sData;
}
BOOL AFX_CDECL CXTPSkinManagerModuleList::IsEnumeratorExists()
{
return GetSharedData().m_bExists;
}
CXTPSkinManagerModuleList::CXTPSkinManagerModuleList(DWORD dwProcessId)
{
m_pEnumerator = NULL;
if (GetSharedData().m_hPsapiDll)
{
m_pEnumerator = new CPsapiModuleEnumerator(dwProcessId, GetSharedData().m_hPsapiDll);
}
else if (GetSharedData().m_bExists)
{
m_pEnumerator = new CToolHelpModuleEnumerator(dwProcessId);
}
ASSERT(m_pEnumerator);
}
CXTPSkinManagerModuleList::~CXTPSkinManagerModuleList()
{
SAFE_DELETE(m_pEnumerator);
}
HMODULE CXTPSkinManagerModuleList::GetFirstModule()
{
if (m_pEnumerator)
{
return m_pEnumerator->GetFirstModule();
}
return NULL;
}
HMODULE CXTPSkinManagerModuleList::GetNextModule()
{
if (m_pEnumerator)
{
return m_pEnumerator->GetNextModule();
}
return NULL;
}
BOOL CXTPSkinManagerModuleList::GetModuleInformation(HMODULE hModule, XTP_MODULEINFO* lpmodinfo)
{
if (!hModule)
return FALSE;
if (m_pEnumerator)
{
return m_pEnumerator->GetModuleInformation(hModule, lpmodinfo);
}
return FALSE;
}