2025-11-27 16:46:48 +09:00

376 lines
12 KiB
C++

// ==========================================================================
// Class Implementation : COXVersionInfo
// ==========================================================================
// Source file : verinfo.cpp
// 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.
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h" // standard MFC include
#include "OXVerinfo.h" // class specification
#ifdef WIN32
#include <winver.h>
#else
#include <ver.h>
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(COXVersionInfo, CObject)
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// Definition of static members
const DWORD COXVersionInfo::m_dwFixedFileInfoSignature = 0xFEEF04BDL;
const DWORD COXVersionInfo::m_dwAmericanEnglishTranslation = 0x040904E4L;
LPCTSTR COXVersionInfo::m_pszTranslation = _T("\\VarFileInfo\\Translation");
LPCTSTR COXVersionInfo::m_pszFileInfo = _T("StringFileInfo");
// Data members -------------------------------------------------------------
// protected:
// private:
// Member functions ---------------------------------------------------------
// public:
COXVersionInfo::COXVersionInfo()
{
Empty();
}
BOOL COXVersionInfo::ReadInfo(LPCTSTR pszPathName)
{
LPBYTE pData = NULL;
DWORD hVersion = 0;
DWORD dwVersionSize = 0;
UINT nVersionItemSize = 0;
void* pVersionItemData = NULL;
VS_FIXEDFILEINFO* pFixedFileInfo = NULL;
// Assume failure
Empty();
// Note :
// Several functions changed parameter type from WIN16 to WIN32
// e.g. WIN16 : BOOL VerQueryValue(const void FAR*, LPCSTR, VOID FAR* FAR*, UINT FAR*)
// WIN32 : BOOL VerQueryValue(const LPVOID, LPTSTR, LPVOID*, PUINT)
// Notice that the second parameter changed from pointer to LPCTSTR to
// just pointer to char
// The /Gf option under large model locates string literals in the code segment
// Passing such a string as parameter in WIN16 causes a General Protection Fault
// which points out that the string is not really const !
// Therefore a copy to a temporary buffer will be used in both WIN16 and WIN32
TCHAR szCopyBuffer[512 + 1];
_tcscpy(szCopyBuffer, pszPathName);
dwVersionSize = ::GetFileVersionInfoSize(szCopyBuffer, &hVersion);
if (dwVersionSize == 0)
{
TRACE(_T("COXVersionInfo::ReadInfo : Could not get version info\n"));
return FALSE;
}
pData = new BYTE[dwVersionSize + 1];
_tcscpy(szCopyBuffer, pszPathName);
VERIFY(::GetFileVersionInfo(szCopyBuffer, hVersion, dwVersionSize, pData));
// Get the fixed info first
::VerQueryValue(pData, _T("\\"), &pVersionItemData, &nVersionItemSize);
if (nVersionItemSize != 0)
{
// ... Must have right size
ASSERT(nVersionItemSize == sizeof(VS_FIXEDFILEINFO));
pFixedFileInfo = (VS_FIXEDFILEINFO*)pVersionItemData;
// ... Must have correct header;
ASSERT(pFixedFileInfo->dwSignature == m_dwFixedFileInfoSignature);
m_dwSignature = pFixedFileInfo->dwSignature;
m_dwStrucVersion = pFixedFileInfo->dwStrucVersion;
m_dwFileVersionMS = pFixedFileInfo->dwFileVersionMS;
m_dwFileVersionLS = pFixedFileInfo->dwFileVersionLS;
m_dwProductVersionMS = pFixedFileInfo->dwProductVersionMS;
m_dwProductVersionLS = pFixedFileInfo->dwProductVersionLS;
m_dwFileFlagsMask = pFixedFileInfo->dwFileFlagsMask;
m_dwFileFlags = pFixedFileInfo->dwFileFlags;
m_dwFileOS = pFixedFileInfo->dwFileOS;
m_dwFileType = pFixedFileInfo->dwFileType;
m_dwFileSubtype = pFixedFileInfo->dwFileSubtype;
m_dwFileDateMS = pFixedFileInfo->dwFileDateMS;
m_dwFileDateLS = pFixedFileInfo->dwFileDateLS;
}
else
TRACE(_T("COXVersionInfo::ReadInfo : Could not get fixed version info\n"));
// Get the language - character info
TCHAR szLangChar[512];
_tcscpy(szCopyBuffer, m_pszTranslation);
::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize);
if(nVersionItemSize != 0)
{
::VerLanguageName (*(UINT*)pVersionItemData, szLangChar, 512 - 1);
// ... Swap high and low word (char set and lang id)
m_dwLanguageCountryID = MAKELONG(HIWORD(*(DWORD*)pVersionItemData), LOWORD(*(DWORD*)pVersionItemData));
m_sLanguageCountry = szLangChar;
}
else
TRACE(_T("COXVersionInfo::ReadInfo : Could not get language info, using default\n"));
// Get the variable info
TCHAR szCountryHex[8 + 1];
wsprintf(szCountryHex, _T("%08.8lX"), m_dwLanguageCountryID != 0 ? m_dwLanguageCountryID : m_dwAmericanEnglishTranslation);
CString sFront = CString(_T("\\")) + m_pszFileInfo + _T("\\") + szCountryHex + _T("\\");
CString sSubBlock;
sSubBlock = sFront + _T("Comments");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sComments = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("CompanyName");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sCompanyName = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("FileDescription");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sFileDescription = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("FileVersion");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sFileVersion = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("InternalName");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sInternalName = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("LegalCopyright");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sLegalCopyright = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("LegalTrademarks");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sLegalTrademarks = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("OriginalFilename");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sOriginalFilename = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("PrivateBuild");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sPrivateBuild = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("ProductName");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sProductName = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("ProductVersion");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sProductVersion = (LPCTSTR)(LPTSTR)pVersionItemData;
sSubBlock = sFront + _T("SpecialBuild");
_tcscpy(szCopyBuffer, sSubBlock);
if (::VerQueryValue(pData, szCopyBuffer, &pVersionItemData, &nVersionItemSize))
m_sSpecialBuild = (LPCTSTR)(LPTSTR)pVersionItemData;
m_bValid = TRUE;
delete[] pData;
// Dump(afxDump);
return TRUE;
}
BOOL COXVersionInfo::ContainsValidInfo()
{
return m_bValid;
}
CString COXVersionInfo::GetOSName()
{
if (!ContainsValidInfo())
{
TRACE(_T("COXVersionInfo::GetOSName() : Object does not contain valid info, returning empty string\n"));
return _T("");
}
CString sResult;
DWORD dwFileOS = m_dwFileOS;
// Try all the possible flags and remove them it when a match is found
// The order in which the possible flags are checked is important, because
// they binairy overlap (see winver.h or ver.h)
// GUI Environment
if ((dwFileOS & VOS__PM32) == VOS__PM32)
{
sResult += _T("- 32-bit PM");
dwFileOS &= ~VOS__PM32;
}
if ((dwFileOS & VOS__WINDOWS16) == VOS__WINDOWS16)
{
sResult += _T("- 16-bit Windows");
dwFileOS &= ~VOS__WINDOWS16;
}
if ((dwFileOS & VOS__PM16) == VOS__PM16)
{
sResult += _T("- 16-bit PM");
dwFileOS &= ~VOS__PM16;
}
if ((dwFileOS & VOS__WINDOWS32) == VOS__WINDOWS32)
{
sResult += _T("- Win32");
dwFileOS &= ~VOS__WINDOWS32;
}
// Basic OS
if ((dwFileOS & VOS_OS232) == VOS_OS232)
{
sResult += _T("- 32-bit OS/2");
dwFileOS &= ~VOS_OS232;
}
if ((dwFileOS & VOS_DOS) == VOS_DOS)
{
sResult += _T("- MS-DOS");
dwFileOS &= ~VOS_DOS;
}
if ((dwFileOS & VOS_OS216) == VOS_OS216)
{
sResult += _T("- 16-bit OS/2");
dwFileOS &= ~VOS_OS216;
}
if ((dwFileOS & VOS_NT) == VOS_NT)
{
sResult += _T("- Windows NT");
dwFileOS &= ~VOS_NT;
}
// If the OS still contains flags, it are flag we did not anticipate
if (dwFileOS != 0)
{
sResult += _T("- Unknown");
}
if (!sResult.IsEmpty())
// ... If the result is not empty, remove the leading hyphen
sResult = sResult.Mid(2);
else
// ... If the result is empty, no OS was specified
sResult = _T("None");
return sResult;
}
void COXVersionInfo::Empty()
{
m_dwSignature = 0;
m_dwStrucVersion = 0;
m_dwFileVersionMS = 0;
m_dwFileVersionLS = 0;
m_dwProductVersionMS = 0;
m_dwProductVersionLS = 0;
m_dwFileFlagsMask = 0;
m_dwFileFlags = 0;
m_dwFileOS = 0;
m_dwFileType = 0;
m_dwFileSubtype = 0;
m_dwFileDateMS = 0;
m_dwFileDateLS = 0;
m_dwLanguageCountryID = 0;
m_sLanguageCountry = _T("");
m_sComments = _T("");
m_sCompanyName = _T("");
m_sFileDescription = _T("");
m_sFileVersion = _T("");
m_sInternalName = _T("");
m_sLegalCopyright = _T("");
m_sLegalTrademarks = _T("");
m_sOriginalFilename = _T("");
m_sPrivateBuild = _T("");
m_sProductName = _T("");
m_sProductVersion = _T("");
m_sSpecialBuild = _T("");
m_bValid = FALSE;
}
COXVersionInfo::~COXVersionInfo()
{
}
// Diagnostics ---------------------------------------------------------------
#ifdef _DEBUG
void COXVersionInfo::AssertValid() const
{
CObject::AssertValid();
}
void COXVersionInfo::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << _T("\nm_dwSignature : ") << m_dwSignature;;
dc << _T("\nm_dwStrucVersion : ") << m_dwStrucVersion;
dc << _T("\nm_dwFileVersionMS : ") << m_dwFileVersionMS;
dc << _T("\nm_dwFileVersionLS : ") << m_dwFileVersionLS;
dc << _T("\nm_dwProductVersionMS : ") << m_dwProductVersionMS;
dc << _T("\nm_dwProductVersionLS : ") << m_dwProductVersionLS;
dc << _T("\nm_dwFileFlagsMask : ") << m_dwFileFlagsMask;
dc << _T("\nm_dwFileFlags : ") << m_dwFileFlags;
dc << _T("\nm_dwFileOS : ") << m_dwFileOS;
dc << _T("\nm_dwFileType : ") << m_dwFileType;
dc << _T("\nm_dwFileSubtype : ") << m_dwFileSubtype;
dc << _T("\nm_dwFileDateMS : ") << m_dwFileDateMS;
dc << _T("\nm_dwFileDateLS : ") << m_dwFileDateLS;
dc << _T("\nm_dwLanguageCountryID : ") << m_dwLanguageCountryID;
dc << _T("\nm_sLanguageCountry : ") << m_sLanguageCountry;
dc << _T("\nm_sComments : ") << m_sComments;
dc << _T("\nm_sCompanyName : ") << m_sCompanyName;
dc << _T("\nm_sFileDescription : ") << m_sFileDescription;
dc << _T("\nm_sFileVersion : ") << m_sFileVersion;
dc << _T("\nm_sInternalName : ") << m_sInternalName;
dc << _T("\nm_sLegalCopyright : ") << m_sLegalCopyright;
dc << _T("\nm_sLegalTrademarks : ") << m_sLegalTrademarks;
dc << _T("\nm_sOriginalFilename : ") << m_sOriginalFilename;
dc << _T("\nm_sPrivateBuild : ") << m_sPrivateBuild;
dc << _T("\nm_sProductName : ") << m_sProductName;
dc << _T("\nm_sProductVersion : ") << m_sProductVersion;
dc << _T("\nm_sSpecialBuild; : ") << m_sSpecialBuild;;
dc << _T("\nm_bValid : ") << m_bValid;
}
#endif //_DEBUG
// protected:
// private:
// Message handlers ---------------------------------------------------------
// ==========================================================================