//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Implementation of class TModuleVersionInfo, version resource parser &
/// accessor class
//----------------------------------------------------------------------------
#include <owl/pch.h>
#include <owl/module.h>
#include <stdio.h>
#include <owl/except.rh>
namespace owl {
OWL_DIAGINFO;
static tchar viRootStr[] = _T("\\");
static tchar viTransStr[] = _T("\\VarFileInfo\\Translation");
static tchar viSubBlockQueryFmt[] = _T("\\StringFileInfo\\%08lx\\%s");
static tchar viFileDescStr[] = _T("FileDescription");
static tchar viFileVersionStr[] = _T("FileVersion");
static tchar viInternalNameStr[] = _T("InternalName");
static tchar viLegalCopyrightStr[] = _T("LegalCopyright");
static tchar viOriginalFilenameStr[] = _T("OriginalFilename");
static tchar viProductNameStr[] = _T("ProductName");
static tchar viProductVersionStr[] = _T("ProductVersion");
static tchar viSpecialBuildStr[] = _T("SpecialBuild");
//
/// Constructs a TModuleVersionInfo given a module or instance handle
//
TModuleVersionInfo::TModuleVersionInfo(TModule::THandle hModule)
:
Buff(0),
Lang(0),
FixedInfo(0)
{
TTmpBuffer<tchar> modFName(_MAX_PATH);
::GetModuleFileName(hModule, modFName, _MAX_PATH);
#if !defined(UNICODE)
::OemToAnsi(modFName, modFName);
#endif
Init(modFName);
}
//
/// Constructs a TModuleVersionInfo given a module filename
/// String version. Throws TXModuleVersionInfo on errors. [VH 2005-04-03]
//
TModuleVersionInfo::TModuleVersionInfo(const tstring& modFName)
:
Buff(0),
Lang(0),
FixedInfo(0)
{
Init(modFName.c_str ());
}
//
// Internal initialization fills in the data members
// Now returns void and throws exceptions. [VH 2005-04-03]
//
void
TModuleVersionInfo::Init(LPCTSTR modFName)
{
try {
uint32 fvHandle;
#if defined WINELIB
uint32 infoSize = TVersion::GetFileVersionInfoSize((LPTSTR)modFName, (unsigned int *)&fvHandle);
#else
uint32 infoSize = TVersion::GetFileVersionInfoSize((LPTSTR)modFName, &fvHandle);
#endif
if (!infoSize)
throw 1; // Caught below.
TAPointer<uint8> buf(new uint8[uint(infoSize)]);
if (!TVersion::GetFileVersionInfo((LPTSTR)modFName, fvHandle, infoSize, buf))
throw 2; // Caught below.
// Copy string to buffer so if the -dc compiler switch (Put constant
// strings in code segments) is on, VerQueryValue will work under Win16.
// This works around a problem in Microsoft's ver.dll which writes to the
// string pointed to by subBlockName.
//
uint vInfoLen; // not really used, but must be passed
tchar* subBlockName = viRootStr;
if (!TVersion::VerQueryValue(buf, subBlockName, (void **)&FixedInfo, &vInfoLen))
throw 3; // Caught below.
subBlockName = viTransStr;
uint32 * trans;
if (!TVersion::VerQueryValue(buf, subBlockName, (void **)&trans, &vInfoLen))
throw 4; // Caught below.
// Assign language and buffer.
//
// Swap the words so sprintf will print the lang-charset in the correct format.
Lang = MkUint32(HiUint16(*trans), LoUint16(*trans));
Buff = buf.Relinquish (); // Take ownership.
}
catch (...) {
// Rethrow dedicated exception.
//
LPCTSTR msg = 0;
TSystemMessage last_error;
if (last_error.SysError())
msg = last_error.SysMessage ().c_str();
TXModuleVersionInfo::Raise(msg);
}
}
//
// Clean up the new'd buffer
//
TModuleVersionInfo::~TModuleVersionInfo()
{
delete[] Buff;
}
//
/// Queries any given "\\StringFileInfo\\lang-charset\\<str>" version. Info string lang
/// indicates the language translation, may be 0 to signify file default.
//
bool
TModuleVersionInfo::GetInfoString(LPCTSTR str, LPCTSTR& value, uint lang)
{
PRECONDITION(Buff);
uint vSize;
TTmpBuffer<tchar> subBlockName(MAX_PATH);
_stprintf(subBlockName, viSubBlockQueryFmt, lang ? uint32(lang) : Lang, str);
return TVersion::VerQueryValue(Buff, subBlockName, (void**)&value, &vSize);
}
//
// Commonly used, predefined info string queries. Pass requested language thru,
// may be 0 to signify default.
//
//
/// Retrieves the file description information in the requested language id.
//
bool TModuleVersionInfo::GetFileDescription(LPCTSTR& fileDesc, uint lang)
{
return GetInfoString(viFileDescStr, fileDesc, lang);
}
//
/// Retrieves the file version information in the requested language id.
//
bool
TModuleVersionInfo::GetFileVersion(LPCTSTR& fileVersion, uint lang)
{
return GetInfoString(viFileVersionStr, fileVersion, lang);
}
//
/// Retrieves the internal name of the module.
//
bool
TModuleVersionInfo::GetInternalName(LPCTSTR& internalName, uint lang)
{
return GetInfoString(viInternalNameStr, internalName, lang);
}
//
/// Retrieves the copyright message.
//
bool
TModuleVersionInfo::GetLegalCopyright(LPCTSTR& copyright, uint lang)
{
return GetInfoString(viLegalCopyrightStr, copyright, lang);
}
//
/// Retrieves the original filename.
//
bool
TModuleVersionInfo::GetOriginalFilename(LPCTSTR& originalFilename, uint lang)
{
return GetInfoString(viOriginalFilenameStr, originalFilename, lang);
}
//
/// Retrieves the product name this module is associated with.
//
bool
TModuleVersionInfo::GetProductName(LPCTSTR& prodName, uint lang)
{
return GetInfoString(viProductNameStr, prodName, lang);
}
//
/// Retrieves the version of the product.
//
bool
TModuleVersionInfo::GetProductVersion(LPCTSTR& prodVersion, uint lang)
{
return GetInfoString(viProductVersionStr, prodVersion, lang);
}
//
/// Retrieves the special build number.
//
bool
TModuleVersionInfo::GetSpecialBuild(LPCTSTR& specialBuild, uint lang)
{
// !CQ could check VS_FF_SPECIALBUILD flag first...
return GetInfoString(viSpecialBuildStr, specialBuild, lang);
}
//
/// Local error handler for string query methods. [VH 2005-04-03]
//
static struct TEH
{
bool operator=(bool r)
{if (!r) TXModuleVersionInfo().Throw (); return r;}
}
E;
//
// Query any given "\StringFileInfo\lang-charset\<str>" version info string.
// lang indicates the language translation, may be 0 to signify file default.
// String version. Throws exception on failure. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetInfoString(const tstring& str, uint lang)
{LPCTSTR v = _T(""); E = GetInfoString(str.c_str (), v, lang); return v;}
//
// Commonly used, predefined info string queries. Pass requested language thru,
// may be 0 to signify default.
/// Retrieves the file description information in the requested language id.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetFileDescription(uint lang)
{LPCTSTR v = _T(""); E = GetFileDescription(v, lang); return v;}
//
/// Retrieves the file version information in the requested language id.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetFileVersion(uint lang)
{LPCTSTR v = _T(""); E = GetFileVersion(v, lang); return v;}
//
/// Retrieves the internal name of the module.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetInternalName(uint lang)
{LPCTSTR v = _T(""); E = GetInternalName(v, lang); return v;}
//
/// Retrieves the copyright message.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetLegalCopyright(uint lang)
{LPCTSTR v = _T(""); E = GetLegalCopyright(v, lang); return v;}
//
/// Retrieves the original filename.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetOriginalFilename(uint lang)
{LPCTSTR v = _T(""); E = GetOriginalFilename(v, lang); return v;}
//
/// Retrieves the product name this module is associated with.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetProductName(uint lang)
{LPCTSTR v = _T(""); E = GetProductName(v, lang); return v;}
//
/// Retrieves the version of the product.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetProductVersion(uint lang)
{LPCTSTR v = _T(""); E = GetProductVersion(v, lang); return v;}
//
/// Retrieves the special build number.
/// String version. [VH 2005-04-03]
//
tstring TModuleVersionInfo::GetSpecialBuild(uint lang)
{LPCTSTR v = _T(""); E = GetSpecialBuild(v, lang); return v;}
//
/// Gets the language name string associated with a language/charset code
//
tstring
TModuleVersionInfo::GetLanguageName(uint lang)
{
TTmpBuffer<tchar> langStr(128);
TVersion::VerLanguageName(uint(lang), langStr, 128);
return tstring((tchar*)langStr);
}
//
/// Returns values of TFileType if GetFileType() returned DevDriver or Font.
/// If GetFileType() returned VirtDriver, this function returns the virtual
/// device identifier included in the virtual device control block.
//
uint32 TModuleVersionInfo::GetFileSubType() const
{
PRECONDITION(FixedInfo);
uint32 fileSubType = FixedInfo->dwFileSubtype;
switch (GetFileType()) {
case TypeUnknown:
case App:
case DLL:
break;
case DevDriver:
switch (FixedInfo->dwFileSubtype) {
case VFT2_UNKNOWN:
fileSubType = UnknownDevDriver;
break;
case VFT2_DRV_PRINTER:
fileSubType = PtrDriver;
break;
case VFT2_DRV_KEYBOARD:
fileSubType = KybdDriver;
break;
case VFT2_DRV_LANGUAGE:
fileSubType = LangDriver;
break;
case VFT2_DRV_DISPLAY:
fileSubType = DisplayDriver;
break;
case VFT2_DRV_MOUSE:
fileSubType = MouseDriver;
break;
case VFT2_DRV_NETWORK:
fileSubType = NtwkDriver;
break;
case VFT2_DRV_SYSTEM:
fileSubType = SysDriver;
break;
case VFT2_DRV_INSTALLABLE:
fileSubType = InstallableDriver;
break;
default: //case VFT2_DRV_SOUND:
fileSubType = SoundDriver;
}
break;
case Font:
switch (FixedInfo->dwFileSubtype) {
case VFT2_UNKNOWN:
fileSubType = UnknownFont;
break;
case VFT2_FONT_RASTER:
fileSubType = RasterFont;
break;
case VFT2_FONT_VECTOR:
fileSubType = VectorFont;
break;
default: //case VFT2_FONT_TRUETYPE:
fileSubType = TrueTypeFont;
}
break;
case VirtDevice:
case StaticLib:
break;
}
return fileSubType;
}
//
/// Retrieves the file date.
//
FILETIME TModuleVersionInfo::GetFileDate() const
{
PRECONDITION(FixedInfo);
FILETIME ft = {FixedInfo->dwFileDateLS, FixedInfo->dwFileDateMS};
return ft;
}
//----------------------------------------------------------------------------
//
// Exception class [VH 2005-04-03]
//
//
/// Create the exception.
//
TXModuleVersionInfo::TXModuleVersionInfo(const tstring& name)
:
TXOwl(MakeMessage(IDS_INVALIDMODULE, name))
{
}
//
/// Creates a copy of the exception
//
TXModuleVersionInfo*
TXModuleVersionInfo::Clone()
{
return new TXModuleVersionInfo(*this);
}
//
/// Throws the exception
//
void
TXModuleVersionInfo::Throw()
{
throw *this;
}
//
/// Throws the exception
//
void
TXModuleVersionInfo::Raise(const tstring& name)
{
TXModuleVersionInfo(name).Throw();
}
} // OWL namespace
/* ========================================================================== */
↑ V522 There might be dereferencing of a potential null pointer 'msg'.