// ==========================================================================
// Class Specification :
// COXDLLManager
// ==========================================================================
// Header file : OXDLLManager.h
// Version: 9.3
// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
// //////////////////////////////////////////////////////////////////////////
#ifndef _DLLMANAGER_H
#define _DLLMANAGER_H
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "OXDllExt.h"
#ifndef _INC_TOOLHELP32
#include "tlhelp32.h"
#define _INC_TOOLHELP32
#endif
#ifndef __AFXTEMPL_H__
#include <afxtempl.h>
#endif
// tell linker to link with version.lib for VerQueryValue, etc.
#pragma comment(linker, "/defaultlib:version.lib")
// v9.3 - update 03 - 64-bit - added extra VC6 guard here - TD
#if _MSC_VER < 1400
#ifndef DWORD_PTR // for VC++ 6
typedef DWORD DWORD_PTR;
#endif
#endif
// we need these type definitions to get information about dll version
// we use it in our GetDLLVersionInfo function
#ifndef _OXDLLVERSIONINFO_DECL
#define _OXDLLVERSIONINFO_DECL
#if _MFC_VER >0x0421
#include <shlwapi.h>
#else
typedef struct _DllVersionInfo
{
DWORD cbSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformID;
}DLLVERSIONINFO;
#define DLLVER_PLATFORM_WINDOWS 0 // Windows platform (95/98)
#define DLLVER_PLATFORM_NT 1 // Windows NT platform
typedef int (FAR WINAPI *DLLGETVERSIONPROC) (DLLVERSIONINFO *);
#endif
#endif
///////////////////////////
typedef struct _tagTRANSLATION
{
WORD nLangID; // language ID
WORD nCharset; // character set (code page)
} TRANSLATION;
typedef struct _tagDLLFILEINFO
{
VS_FIXEDFILEINFO fixedInfo;
TRANSLATION translation;
CString sCompanyName;
CString sFileDescription;
CString sFileVersion;
CString sInternalName;
CString sLegalCopyright;
CString sOriginalFilename;
CString sProductName;
CString sProductVersion;
} DLLFILEINFO;
////////////////////////////
typedef struct _tagDLLSNAPSHOT
{
int nRefCount;
CStringArray arrDependantProcesses;
} DLLSNAPSHOT;
typedef struct _tagMODULEINFO
{
HMODULE hModule;
CString sModuleFileName;
_tagMODULEINFO(HMODULE Module=NULL, CString ModuleFileName=_T(""))
{
hModule=Module;
sModuleFileName=ModuleFileName;
}
// assignment operator
_tagMODULEINFO& operator=(const _tagMODULEINFO& mi)
{
if(this==&mi)
return *this;
hModule=mi.hModule;
sModuleFileName=mi.sModuleFileName;
return *this;
}
// compare operator
BOOL operator==(const _tagMODULEINFO mi) const
{
return ((hModule==mi.hModule)&
(sModuleFileName.CompareNoCase(mi.sModuleFileName)==0));
}
/* operator DWORD() const
{
UINT nHandleHash=((DWORD)hModule) >> 4;
UINT nFileNameHash=0;
LPCTSTR key=(LPCTSTR)sModuleFileName;
while(*key)
nFileNameHash=(nFileNameHash<<5)+nFileNameHash+*key++;
return (DWORD)(nHandleHash>>2+nFileNameHash<<2);
}
*/
} MODULEINFO;
#ifdef _BUILD_UTB_INTO_EXTDLL
template UINT AFXAPI HashKey<MODULEINFO> (MODULEINFO moduleInfo);
#else
template<> UINT AFXAPI HashKey<MODULEINFO> (MODULEINFO moduleInfo);
#endif
typedef CMap<MODULEINFO,MODULEINFO,int,int> CModuleMap;
typedef struct _tagPROCESSINFO
{
HMODULE hProcessModule;
CModuleMap moduleMap;
virtual ~_tagPROCESSINFO()
{
moduleMap.RemoveAll();
}
} PROCESSINFO;
class CProcessModulesMap : public CMap<DWORD_PTR,DWORD_PTR,PROCESSINFO*,PROCESSINFO*>
{
public:
virtual ~CProcessModulesMap()
{
POSITION pos=GetStartPosition();
while(pos!=NULL)
{
// v9.3 - update 03 - 64-bit - switch param type - TD
#ifdef _WIN64
DWORD_PTR dwProcessID;
#else
DWORD dwProcessID;
#endif
PROCESSINFO* pProcessInfo;
GetNextAssoc(pos,dwProcessID,pProcessInfo);
ASSERT(pProcessInfo!=NULL);
delete pProcessInfo;
}
RemoveAll();
}
};
//==================== typedefs for ToolHelp32 functions =====================
typedef HANDLE (WINAPI* PFNCREATETOOLHELP32SNAPSHOT)
(DWORD dwFlags, DWORD th32ProcessID);
typedef BOOL (WINAPI* PFNPROCESS32FIRST)
(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
typedef BOOL (WINAPI* PFNPROCESS32NEXT)
(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
typedef BOOL (WINAPI* PFNMODULE32FIRST)
(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
typedef BOOL (WINAPI* PFNMODULE32NEXT)
(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
//====================== typedefs for PSAPI.DLL functions =====================
typedef BOOL (WINAPI* PFNENUMPROCESSES)
(DWORD* lpidProcess, DWORD cb, DWORD* cbNeeded);
typedef BOOL (WINAPI* PFNENUMPROCESSMODULES)
(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);
typedef DWORD (WINAPI* PFNGETMODULEFILENAMEEXA)
(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
/////////////////////////////////////////////////////////////////////////////
// COXDLLManager window
class OX_CLASS_DECL COXDLLManager
{
// Construction
public:
COXDLLManager();
COXDLLManager(LPCTSTR lpLibFileName);
COXDLLManager(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
// Attributes
public:
protected:
static BOOL m_bIsWindowsNT;
HMODULE m_hModule;
BOOL m_bWasAlreadyLoaded;
BOOL m_bIsOwningModule;
// Operations
public:
// static functions
static BOOL IsWindowsNTRunning();
static BOOL GetAllLoadedDLLs(CProcessModulesMap& mapProcessModules);
static BOOL GetProcessLoadedDLLs(HINSTANCE hInstance,
CModuleMap& mapModules);
inline static BOOL GetVersionInfo(HMODULE hModule, DLLVERSIONINFO* pdvi)
{
COXDLLManager dll;
if(!dll.Attach(hModule,FALSE))
return FALSE;
return dll.GetVersionInfo(pdvi);
}
inline static BOOL GetVersionInfo(LPCTSTR lpLibFileName, DLLVERSIONINFO* pdvi)
{
COXDLLManager dll(lpLibFileName);
if(!dll.IsLoaded())
return FALSE;
return dll.GetVersionInfo(pdvi);
}
inline static BOOL GetFileInfo(HMODULE hModule, DLLFILEINFO* pdfi)
{
COXDLLManager dll;
if(!dll.Attach(hModule,FALSE))
return FALSE;
return dll.GetFileInfo(pdfi);
}
inline static BOOL GetFileInfo(LPCTSTR lpLibFileName, DLLFILEINFO* pdfi)
{
COXDLLManager dll(lpLibFileName);
if(!dll.IsLoaded())
return FALSE;
return dll.GetFileInfo(pdfi);
}
inline static BOOL GetSnapshot(HMODULE hModule, DLLSNAPSHOT* pSnapshot)
{
COXDLLManager dll;
if(!dll.Attach(hModule,FALSE))
return FALSE;
return dll.GetSnapshot(pSnapshot);
}
inline static BOOL GetSnapshot(LPCTSTR lpLibFileName, DLLSNAPSHOT* pSnapshot)
{
COXDLLManager dll(lpLibFileName);
if(!dll.IsLoaded())
return FALSE;
return dll.GetSnapshot(pSnapshot);
}
inline static BOOL GetReferenceCount(HMODULE hModule, int& nRefCount)
{
COXDLLManager dll;
if(!dll.Attach(hModule,FALSE))
return FALSE;
return dll.GetReferenceCount(nRefCount);
}
inline static BOOL GetReferenceCount(LPCTSTR lpLibFileName, int& nRefCount)
{
COXDLLManager dll(lpLibFileName);
if(!dll.IsLoaded())
return FALSE;
return dll.GetReferenceCount(nRefCount);
}
inline static BOOL GetDependantProcesses(HMODULE hModule,
CStringArray& arrDependantProcesses)
{
COXDLLManager dll;
if(!dll.Attach(hModule,FALSE))
return FALSE;
return dll.GetDependantProcesses(arrDependantProcesses);
}
inline static BOOL GetDependantProcesses(LPCTSTR lpLibFileName,
CStringArray& arrDependantProcesses)
{
COXDLLManager dll(lpLibFileName);
if(!dll.IsLoaded())
return FALSE;
return dll.GetDependantProcesses(arrDependantProcesses);
}
///////////////////////////////////////
inline BOOL IsLoaded() const {
return ((m_hModule!=NULL)&(m_bIsOwningModule)) ? TRUE : FALSE; }
// counterparts of existing functions
//
HINSTANCE LoadLibrary(LPCTSTR lpLibFileName);
HINSTANCE LoadLibraryEx(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
BOOL FreeLibrary();
inline void FreeLibraryAndExitThread(DWORD dwExitCode)
{
ASSERT(IsLoaded());
::FreeLibraryAndExitThread(m_hModule,dwExitCode);
}
inline HRSRC FindResource(LPCTSTR lpName, LPCTSTR lpType) const
{
ASSERT(IsLoaded());
return ::FindResource(m_hModule,lpName,lpType);
}
inline HRSRC FindResourceEx(LPCTSTR lpName, LPCTSTR lpType, WORD wLanguage) const
{
ASSERT(IsLoaded());
return ::FindResourceEx(m_hModule,lpName,lpType,wLanguage);
}
inline HGLOBAL LoadResource(HRSRC hResInfo) const
{
ASSERT(IsLoaded());
return ::LoadResource(m_hModule,hResInfo);
}
inline BOOL DisableThreadLibraryCalls() const
{
ASSERT(IsLoaded());
return ::DisableThreadLibraryCalls(m_hModule);
}
inline HMODULE GetModuleHandle() const { return m_hModule; }
inline DWORD GetModuleFileName(LPTSTR lpFilename, DWORD nSize) const
{
ASSERT(lpFilename!=NULL);
return ::GetModuleFileName(m_hModule,lpFilename,nSize);
}
inline FARPROC GetProcAddress(LPCSTR lpProcName) const
{
ASSERT(lpProcName!=NULL);
ASSERT(IsLoaded());
return ::GetProcAddress(m_hModule,lpProcName);
}
//////////////////////////////////////////
BOOL Attach(HMODULE hModule, BOOL bUnloadOnDestroy);
inline HMODULE Detach()
{
HMODULE hModule=m_hModule;
Reset();
return hModule;
}
BOOL GetVersionInfo(DLLVERSIONINFO* pdvi) const;
BOOL GetFileInfo(DLLFILEINFO* pdfi) const;
BOOL GetSnapshot(DLLSNAPSHOT* pSnapshot) const;
inline BOOL GetReferenceCount(int& nRefCount) const
{
DLLSNAPSHOT snapShot;
if(GetSnapshot(&snapShot))
{
nRefCount=snapShot.nRefCount;
return TRUE;
}
else
return FALSE;
}
inline BOOL GetDependantProcesses(CStringArray& arrDependantProcesses) const
{
DLLSNAPSHOT snapShot;
if(GetSnapshot(&snapShot))
{
arrDependantProcesses.RemoveAll();
arrDependantProcesses.Append(snapShot.arrDependantProcesses);
return TRUE;
}
else
return FALSE;
}
protected:
inline void Reset()
{
m_hModule=NULL;
m_bWasAlreadyLoaded=FALSE;
m_bIsOwningModule=TRUE;
}
CString GetFileInfoValue(const LPBYTE pFileVersionInfo, WORD nLangID,
WORD nCharset, LPCTSTR lpKeyName) const;
// Implementation
public:
virtual ~COXDLLManager();
};
/////////////////////////////////////////////////////////////////////////////
#endif // _DLLMANAGER_H