mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
5.4 KiB
195 lines
5.4 KiB
////////////////////////////////////////////////////////////////
|
|
// 1998 Microsoft Systems Journal
|
|
// If this code works, it was written by Paul DiLascia.
|
|
// If not, I don't know who wrote it.
|
|
//
|
|
// CModuleVersion provides an easy way to get version info
|
|
// for a module.(DLL or EXE).
|
|
//
|
|
// This code appeard in April 1998 edition of Microsoft Systems
|
|
// Journal.
|
|
//
|
|
// 27-July-1998 -- Adapted by James A. McLaughiln (Schlumberger
|
|
// Technology Corp.) for Smart Cards. Merged with the concepts from
|
|
// CFileVersion class contributed by Manuel Laflamme on a posting to
|
|
// www.codeguru.com. If these mods don't work, then you can blame me.
|
|
|
|
#include "StdAfx.h"
|
|
#include "slbModVer.h"
|
|
|
|
CModuleVersion::CModuleVersion()
|
|
: m_pVersionInfo(NULL)
|
|
{
|
|
}
|
|
|
|
//////////////////
|
|
// Destroy: delete version info
|
|
//
|
|
CModuleVersion::~CModuleVersion()
|
|
{
|
|
delete [] m_pVersionInfo;
|
|
}
|
|
|
|
BOOL CModuleVersion::GetFileVersionInfo(LPCTSTR modulename)
|
|
{
|
|
// get module handle
|
|
HMODULE hModule = ::GetModuleHandle(modulename);
|
|
if (hModule==NULL && modulename!=NULL)
|
|
return FALSE;
|
|
|
|
return GetFileVersionInfo(hModule);
|
|
}
|
|
|
|
//////////////////
|
|
// Get file version info for a given module
|
|
// Allocates storage for all info, fills "this" with
|
|
// VS_FIXEDFILEINFO, and sets codepage.
|
|
//
|
|
BOOL CModuleVersion::GetFileVersionInfo(HMODULE hModule)
|
|
{
|
|
m_translation.charset = 1252; // default = ANSI code page
|
|
memset((VS_FIXEDFILEINFO*)this, 0, sizeof(VS_FIXEDFILEINFO));
|
|
|
|
// get module file name
|
|
TCHAR filename[_MAX_PATH];
|
|
DWORD len = GetModuleFileName(hModule, filename,
|
|
sizeof(filename)/sizeof(filename[0]));
|
|
if (len <= 0)
|
|
return FALSE;
|
|
|
|
// read file version info
|
|
DWORD dwDummyHandle; // will always be set to zero
|
|
len = GetFileVersionInfoSize(filename, &dwDummyHandle);
|
|
if (len <= 0)
|
|
return FALSE;
|
|
|
|
m_pVersionInfo = new BYTE[len]; // allocate version info
|
|
if (!::GetFileVersionInfo(filename, 0, len, m_pVersionInfo))
|
|
return FALSE;
|
|
|
|
// copy fixed info to myself, which am derived from VS_FIXEDFILEINFO
|
|
if (!GetFixedInfo(*(VS_FIXEDFILEINFO*)this))
|
|
return FALSE;
|
|
|
|
// Get translation info
|
|
LPVOID lpvi;
|
|
UINT iLen;
|
|
if (VerQueryValue(m_pVersionInfo,
|
|
TEXT("\\VarFileInfo\\Translation"), &lpvi, &iLen) && iLen >= 4) {
|
|
m_translation = *(TRANSLATION*)lpvi;
|
|
TRACE(TEXT("code page = %d\n"), m_translation.charset);
|
|
}
|
|
|
|
return dwSignature == VS_FFI_SIGNATURE;
|
|
}
|
|
|
|
//////////////////
|
|
// Get string file info.
|
|
// Key name is something like "CompanyName".
|
|
// returns the value as a CString.
|
|
//
|
|
CString CModuleVersion::GetValue(LPCTSTR lpKeyName)
|
|
{
|
|
CString sVal;
|
|
if (m_pVersionInfo) {
|
|
|
|
// To get a string value must pass query in the form
|
|
//
|
|
// "\StringFileInfo\<langID><codepage>\keyname"
|
|
//
|
|
// where <lang-codepage> is the languageID concatenated with the
|
|
// code page, in hex. Wow.
|
|
//
|
|
CString query;
|
|
query.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),
|
|
m_translation.langID,
|
|
m_translation.charset,
|
|
lpKeyName);
|
|
|
|
LPCTSTR pVal;
|
|
UINT iLenVal;
|
|
if (VerQueryValue(m_pVersionInfo, (LPTSTR)(LPCTSTR)query,
|
|
(LPVOID*)&pVal, &iLenVal)) {
|
|
|
|
sVal = pVal;
|
|
}
|
|
}
|
|
return sVal;
|
|
}
|
|
|
|
// typedef for DllGetVersion proc
|
|
typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
|
|
|
|
/////////////////
|
|
// Get DLL Version by calling DLL's DllGetVersion proc
|
|
//
|
|
BOOL CModuleVersion::DllGetVersion(LPCTSTR modulename, DLLVERSIONINFO& dvi)
|
|
{
|
|
HINSTANCE hinst = LoadLibrary(modulename);
|
|
if (!hinst)
|
|
return FALSE;
|
|
|
|
// Must use GetProcAddress because the DLL might not implement
|
|
// DllGetVersion. Depending upon the DLL, the lack of implementation of the
|
|
// function may be a version marker in itself.
|
|
//
|
|
DLLGETVERSIONPROC pDllGetVersion =
|
|
(DLLGETVERSIONPROC)GetProcAddress(hinst, reinterpret_cast<const char *>(_T("DllGetVersion")));
|
|
|
|
if (!pDllGetVersion)
|
|
return FALSE;
|
|
|
|
memset(&dvi, 0, sizeof(dvi)); // clear
|
|
dvi.cbSize = sizeof(dvi); // set size for Windows
|
|
|
|
return SUCCEEDED((*pDllGetVersion)(&dvi));
|
|
}
|
|
|
|
BOOL CModuleVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi)
|
|
{
|
|
// Must furst call GetFileVersionInfo or constructor with arg
|
|
ASSERT(m_pVersionInfo != NULL);
|
|
if ( m_pVersionInfo == NULL )
|
|
return FALSE;
|
|
|
|
UINT nQuerySize;
|
|
VS_FIXEDFILEINFO* pVsffi;
|
|
if ( ::VerQueryValue((void **)m_pVersionInfo, _T("\\"),
|
|
(void**)&pVsffi, &nQuerySize) )
|
|
{
|
|
vsffi = *pVsffi;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
CString CModuleVersion::GetFixedFileVersion()
|
|
{
|
|
CString strVersion;
|
|
VS_FIXEDFILEINFO vsffi;
|
|
|
|
if (GetFixedInfo(vsffi))
|
|
{
|
|
strVersion.Format (_T("%u,%u,%u,%u"),HIWORD(dwFileVersionMS),
|
|
LOWORD(dwFileVersionMS),
|
|
HIWORD(dwFileVersionLS),
|
|
LOWORD(dwFileVersionLS));
|
|
}
|
|
return strVersion;
|
|
}
|
|
|
|
CString CModuleVersion::GetFixedProductVersion()
|
|
{
|
|
CString strVersion;
|
|
VS_FIXEDFILEINFO vsffi;
|
|
|
|
if (GetFixedInfo(vsffi))
|
|
{
|
|
strVersion.Format (_T("%u,%u,%u,%u"), HIWORD(dwProductVersionMS),
|
|
LOWORD(dwProductVersionMS),
|
|
HIWORD(dwProductVersionLS),
|
|
LOWORD(dwProductVersionLS));
|
|
}
|
|
return strVersion;
|
|
}
|