147 lines
3.4 KiB
C++
147 lines
3.4 KiB
C++
// FileVersion.cpp: implementation of the CFileVersion class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "FileVersion.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CFileVersion::CFileVersion()
|
|
{
|
|
m_lpVersionData = NULL;
|
|
m_dwLangCharset = 0;
|
|
}
|
|
|
|
CFileVersion::~CFileVersion()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void CFileVersion::Close()
|
|
{
|
|
delete[] m_lpVersionData;
|
|
m_lpVersionData = NULL;
|
|
m_dwLangCharset = 0;
|
|
}
|
|
|
|
BOOL CFileVersion::Open(LPCTSTR lpszModuleName)
|
|
{
|
|
ASSERT(_tcslen(lpszModuleName) > 0);
|
|
ASSERT(m_lpVersionData == NULL);
|
|
|
|
// Get the version information size for allocate the buffer
|
|
DWORD dwHandle;
|
|
DWORD dwDataSize = ::GetFileVersionInfoSize((LPTSTR)lpszModuleName, &dwHandle);
|
|
if ( dwDataSize == 0 )
|
|
return FALSE;
|
|
|
|
// Allocate buffer and retrieve version information
|
|
m_lpVersionData = new BYTE[dwDataSize];
|
|
if (!::GetFileVersionInfo((LPTSTR)lpszModuleName, dwHandle, dwDataSize,
|
|
(void**)m_lpVersionData) )
|
|
{
|
|
Close();
|
|
return FALSE;
|
|
}
|
|
|
|
// Retrieve the first language and character-set identifier
|
|
UINT nQuerySize;
|
|
DWORD* pTransTable;
|
|
if (!::VerQueryValue(m_lpVersionData, _T("\\VarFileInfo\\Translation"),
|
|
(void **)&pTransTable, &nQuerySize) )
|
|
{
|
|
Close();
|
|
return FALSE;
|
|
}
|
|
|
|
// Swap the words to have lang-charset in the correct format
|
|
m_dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0]));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
CString CFileVersion::QueryValue(LPCTSTR lpszValueName,
|
|
DWORD dwLangCharset /* = 0*/)
|
|
{
|
|
// Must call Open() first
|
|
// ASSERT(m_lpVersionData != NULL);
|
|
if ( m_lpVersionData == NULL )
|
|
return (CString)_T("");
|
|
|
|
// If no lang-charset specified use default
|
|
if ( dwLangCharset == 0 )
|
|
dwLangCharset = m_dwLangCharset;
|
|
|
|
// Query version information value
|
|
UINT nQuerySize;
|
|
LPVOID lpData;
|
|
CString strValue, strBlockName;
|
|
strBlockName.Format(_T("\\StringFileInfo\\%08lx\\%s"),
|
|
dwLangCharset, lpszValueName);
|
|
if ( ::VerQueryValue((void **)m_lpVersionData, strBlockName.GetBuffer(0),
|
|
&lpData, &nQuerySize) )
|
|
strValue = (LPCTSTR)lpData;
|
|
|
|
strBlockName.ReleaseBuffer();
|
|
|
|
return strValue;
|
|
}
|
|
|
|
BOOL CFileVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi)
|
|
{
|
|
// Must call Open() first
|
|
ASSERT(m_lpVersionData != NULL);
|
|
if ( m_lpVersionData == NULL )
|
|
return FALSE;
|
|
|
|
UINT nQuerySize;
|
|
VS_FIXEDFILEINFO* pVsffi;
|
|
if ( ::VerQueryValue((void **)m_lpVersionData, _T("\\"),
|
|
(void**)&pVsffi, &nQuerySize) )
|
|
{
|
|
vsffi = *pVsffi;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
CString CFileVersion::GetFixedFileVersion()
|
|
{
|
|
CString strVersion;
|
|
VS_FIXEDFILEINFO vsffi;
|
|
|
|
if ( GetFixedInfo(vsffi) )
|
|
{
|
|
strVersion.Format(_T("%u,%u,%u,%u"),HIWORD(vsffi.dwFileVersionMS),
|
|
LOWORD(vsffi.dwFileVersionMS),
|
|
HIWORD(vsffi.dwFileVersionLS),
|
|
LOWORD(vsffi.dwFileVersionLS));
|
|
}
|
|
return strVersion;
|
|
}
|
|
|
|
CString CFileVersion::GetFixedProductVersion()
|
|
{
|
|
CString strVersion;
|
|
VS_FIXEDFILEINFO vsffi;
|
|
|
|
if ( GetFixedInfo(vsffi) )
|
|
{
|
|
strVersion.Format(_T("%u,%u,%u,%u"), HIWORD(vsffi.dwProductVersionMS),
|
|
LOWORD(vsffi.dwProductVersionMS),
|
|
HIWORD(vsffi.dwProductVersionLS),
|
|
LOWORD(vsffi.dwProductVersionLS));
|
|
}
|
|
return strVersion;
|
|
}
|