377 lines
10 KiB
C++
377 lines
10 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1996-2000 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// VerInfo.cpp
|
|
//
|
|
// Abstract:
|
|
// Implementation of the CVersionInfo class.
|
|
//
|
|
// Author:
|
|
// David Potter (davidp) October 11, 1996
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "VerInfo.h"
|
|
#include "ExcOper.h"
|
|
#include "TraceTag.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Global Variables
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef _DEBUG
|
|
CTraceTag g_tagVersionInfo(_T("Misc"), _T("CVersionInfo"), 0);
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CVersionInfo
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::CVersionInfo
|
|
//
|
|
// Routine Description:
|
|
// Default constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CVersionInfo::CVersionInfo(void)
|
|
{
|
|
m_pbVerInfo = NULL;
|
|
|
|
} //*** CVersionInfo::CVersionInfo()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::~CVersionInfo
|
|
//
|
|
// Routine Description:
|
|
// Destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CVersionInfo::~CVersionInfo(void)
|
|
{
|
|
delete [] m_pbVerInfo;
|
|
|
|
} //*** CVersionInfo::~CVersionInfo()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::Init
|
|
//
|
|
// Routine Description:
|
|
// Initialize the class instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Exceptions Thrown:
|
|
// CNTException Errors from GetModuleFileName(),
|
|
// GetFileVersionInfoSize(), and
|
|
// GetFileVersionInfo().
|
|
// Any exceptions thrown by new[]().
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CVersionInfo::Init(void)
|
|
{
|
|
TCHAR szExeName[MAX_PATH];
|
|
DWORD dwVerHandle;
|
|
DWORD cbVerInfo;
|
|
|
|
ASSERT(m_pbVerInfo == NULL);
|
|
|
|
// Get the name of the file from which to read version information.
|
|
if (!::GetModuleFileName(
|
|
AfxGetInstanceHandle(),
|
|
szExeName,
|
|
sizeof(szExeName) / sizeof(TCHAR)
|
|
))
|
|
ThrowStaticException(::GetLastError());
|
|
|
|
// Trace(...)
|
|
|
|
try
|
|
{
|
|
// Get the size of the version information
|
|
cbVerInfo = ::GetFileVersionInfoSize(szExeName, &dwVerHandle);
|
|
if (cbVerInfo == 0)
|
|
ThrowStaticException(::GetLastError());
|
|
|
|
// Allocate the version info buffer.
|
|
m_pbVerInfo = new BYTE[cbVerInfo];
|
|
if ( m_pbVerInfo == NULL )
|
|
{
|
|
AfxThrowMemoryException();
|
|
} // if: error allocating the version info buffer
|
|
|
|
// Read the version info from the file.
|
|
if (!::GetFileVersionInfo(szExeName, dwVerHandle, cbVerInfo, PbVerInfo()))
|
|
ThrowStaticException(::GetLastError());
|
|
} // try
|
|
catch (CException *)
|
|
{
|
|
delete [] m_pbVerInfo;
|
|
m_pbVerInfo = NULL;
|
|
throw;
|
|
} // catch: CException
|
|
|
|
} //*** CVersionInfo::Init()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::PszQueryValue
|
|
//
|
|
// Routine Description:
|
|
// Read a string value from the version resource.
|
|
//
|
|
// Arguments:
|
|
// pszValueName [IN] Name of value to get.
|
|
//
|
|
// Return Value:
|
|
// Pointer to value string buffer.
|
|
// The string pointed to belongs to CVersionInfo and
|
|
// is valid until the object is destructed.
|
|
//
|
|
// Exceptions Thrown:
|
|
// CNTException Errors from VerQueryValue().
|
|
// Any exceptions thrown by CString::Format().
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LPCTSTR CVersionInfo::PszQueryValue(IN LPCTSTR pszValueName)
|
|
{
|
|
CString strValueName;
|
|
LPDWORD pdwTranslation;
|
|
LPTSTR pszReturn;
|
|
UINT cbReturn;
|
|
UINT cchReturn;
|
|
|
|
ASSERT(pszValueName != NULL);
|
|
ASSERT(PbVerInfo() != NULL);
|
|
|
|
// Get the LangID and CharSetID.
|
|
strValueName = _T("\\VarFileInfo\\Translation");
|
|
if (!::VerQueryValue(
|
|
PbVerInfo(),
|
|
(LPTSTR) (LPCTSTR) strValueName,
|
|
(LPVOID *) &pdwTranslation,
|
|
&cbReturn
|
|
)
|
|
|| (cbReturn == 0))
|
|
{
|
|
pszReturn = NULL;
|
|
} // if: error getting LangID and CharSetID
|
|
else
|
|
{
|
|
// Construct the name of the value to read.
|
|
strValueName.Format(
|
|
_T("\\StringFileInfo\\%04X%04X\\%s"),
|
|
LOWORD(*pdwTranslation), // LangID
|
|
HIWORD(*pdwTranslation), // CharSetID
|
|
pszValueName
|
|
);
|
|
Trace(g_tagVersionInfo, _T("Querying '%s'"), strValueName);
|
|
|
|
// Read the value.
|
|
if (!::VerQueryValue(
|
|
PbVerInfo(),
|
|
(LPTSTR) (LPCTSTR) strValueName,
|
|
(LPVOID *) &pszReturn,
|
|
&cchReturn
|
|
)
|
|
|| (cchReturn == 0))
|
|
pszReturn = NULL;
|
|
} // else:
|
|
|
|
#ifdef _DEBUG
|
|
if (pszReturn != NULL)
|
|
Trace(g_tagVersionInfo, _T("PszQueryValue(%s) = '%s'"), pszValueName, pszReturn);
|
|
else
|
|
Trace(g_tagVersionInfo, _T("PszQueryValue(%s) = Not Available"), pszValueName);
|
|
#endif
|
|
|
|
return pszReturn;
|
|
|
|
} //*** CVersionInfo::PszQueryValue()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::BQueryValue
|
|
//
|
|
// Routine Description:
|
|
// Read a value from the version resource.
|
|
//
|
|
// Arguments:
|
|
// pszValueName [IN] Name of value to get.
|
|
// rdwValue [OUT] DWORD in which to return the value.
|
|
//
|
|
// Return Value:
|
|
// TRUE = success, FALSE = failure
|
|
//
|
|
// Exceptions Thrown:
|
|
// None.
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CVersionInfo::BQueryValue(
|
|
IN LPCTSTR pszValueName,
|
|
OUT DWORD & rdwValue
|
|
)
|
|
{
|
|
BOOL bSuccess;
|
|
UINT cbReturn;
|
|
DWORD * pdwValue;
|
|
|
|
ASSERT(pszValueName != NULL);
|
|
ASSERT(PbVerInfo() != NULL);
|
|
|
|
// Read the value.
|
|
if (!::VerQueryValue(
|
|
PbVerInfo(),
|
|
(LPTSTR) pszValueName,
|
|
(LPVOID *) &pdwValue,
|
|
&cbReturn
|
|
)
|
|
|| (cbReturn == 0))
|
|
bSuccess = FALSE;
|
|
else
|
|
{
|
|
rdwValue = *pdwValue;
|
|
bSuccess = TRUE;
|
|
} // else: value read successfully
|
|
|
|
#ifdef _DEBUG
|
|
if (bSuccess)
|
|
Trace(g_tagVersionInfo, _T("BQueryValue(%s) = '%lx'"), pszValueName, rdwValue);
|
|
else
|
|
Trace(g_tagVersionInfo, _T("BQueryValue(%s) = Not Available"), pszValueName);
|
|
#endif
|
|
|
|
return bSuccess;
|
|
|
|
} //*** CVersionInfo::BQueryValue()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::PffiQueryValue
|
|
//
|
|
// Routine Description:
|
|
// Read the VS_FIXEDFILEINFO information from the version resource.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// pffi Pointer to a VS_FIXEDFILEINFO structure. The buffer
|
|
// pointerd to belongs to CVersionInfo and is valid
|
|
// until the object is destructed.
|
|
//
|
|
// Exceptions Thrown:
|
|
// CNTException Errors from VerQueryValue().
|
|
// Any exceptions thrown by CString::Format().
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
const VS_FIXEDFILEINFO * CVersionInfo::PffiQueryValue(void)
|
|
{
|
|
VS_FIXEDFILEINFO * pffi;
|
|
UINT cbReturn;
|
|
|
|
ASSERT(PbVerInfo() != NULL);
|
|
|
|
// Read the FixedFileInfo.
|
|
if (!::VerQueryValue(PbVerInfo(), _T("\\"), (LPVOID *) &pffi, &cbReturn)
|
|
|| (cbReturn == 0))
|
|
pffi = NULL;
|
|
|
|
#ifdef _DEBUG
|
|
if (pffi != NULL)
|
|
Trace(g_tagVersionInfo, _T("PffiQueryValue() version = %d.%d.%d.%d"),
|
|
HIWORD(pffi->dwFileVersionMS),
|
|
LOWORD(pffi->dwFileVersionMS),
|
|
HIWORD(pffi->dwFileVersionLS),
|
|
LOWORD(pffi->dwFileVersionLS));
|
|
else
|
|
Trace(g_tagVersionInfo, _T("PffiQueryValue() = Not Available"));
|
|
#endif
|
|
|
|
return pffi;
|
|
|
|
} //*** CVersionInfo::PffiQueryValue()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CVersionInfo::QueryFileVersionDisplayString
|
|
//
|
|
// Routine Description:
|
|
// Read the file version as a display string from the version resource.
|
|
//
|
|
// Arguments:
|
|
// rstrValue [OUT] String in which to return the version display string.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Exceptions Thrown:
|
|
// CNTException ERROR_RESOURCE_TYPE_NOT_FOUND.
|
|
// Any exceptions thrown by CString::Format().
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CVersionInfo::QueryFileVersionDisplayString(OUT CString & rstrValue)
|
|
{
|
|
const VS_FIXEDFILEINFO * pffi;
|
|
|
|
// Get the file version information.
|
|
pffi = PffiQueryValue();
|
|
if (pffi == NULL)
|
|
ThrowStaticException((SC) ERROR_RESOURCE_TYPE_NOT_FOUND);
|
|
|
|
// Format the display string.
|
|
rstrValue.Format(
|
|
IDS_VERSION_NUMBER_FORMAT,
|
|
HIWORD(pffi->dwFileVersionMS),
|
|
LOWORD(pffi->dwFileVersionMS),
|
|
HIWORD(pffi->dwFileVersionLS),
|
|
LOWORD(pffi->dwFileVersionLS)
|
|
);
|
|
|
|
Trace(g_tagVersionInfo, _T("QueryFileVersionDisplayString() = %s"), rstrValue);
|
|
|
|
} //*** CVersionInfo::QueryFileVersionDisplayString()
|