|
|
//+----------------------------------------------------------------------------
//
// File: getmodulever.cpp
//
// Module: CMSETUP.LIB, CMUTIL.DLL
//
// Synopsis: Implementation of the GetModuleVersionAndLCID function.
//
// Copyright (c) 1998-2001 Microsoft Corporation
//
// Author: quintinb Created Header 08/19/99
//
//+----------------------------------------------------------------------------
#include "cmutil.h"
//+----------------------------------------------------------------------------
//
// Function: GetModuleVersionAndLCID
//
// Synopsis: Gets the version information and LCID from the specified module
//
// Arguments: LPTSTR pszFile - Full path to the file to get the version number of
// LPDWORD pdwVersion - version number (Hiword Major, Loword Minor)
// LPDWORD pdwBuild - build number (Hiword Major, Loword Minor)
// LPDWORD pdwLCID - returns the Locale ID that the module was localized too
//
// Returns: HRESULT -- S_OK if successful, an error code otherwise
//
// History: quintinb -- Code borrowed from Yoshifumi "Vogue" Inoue
// from (private\admin\wsh\host\verutil.cpp).
// Rewritten to match our coding style. 9/14/98
// 17-Oct-2000 SumitC cleanup, fixed leaks, moved to common\source
//
// Notes: There are 2 versions of this function, which take ANSI and Unicode
// versions of the pszFile argument.
//
//+----------------------------------------------------------------------------
HRESULT GetModuleVersionAndLCID (LPSTR pszFile, LPDWORD pdwVersion, LPDWORD pdwBuild, LPDWORD pdwLCID) { HRESULT hr = S_OK; HANDLE hHeap = NULL; LPVOID pData = NULL; DWORD dwHandle; DWORD dwLen; if ((NULL == pdwVersion) || (NULL == pdwBuild) || (NULL == pdwLCID) || (NULL == pszFile) || (TEXT('\0') == pszFile)) { hr = E_POINTER; goto Cleanup; }
*pdwVersion = 0; *pdwBuild = 0; *pdwLCID = 0;
dwLen = GetFileVersionInfoSizeA(pszFile, &dwHandle); if (0 == dwLen) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Cleanup; } hHeap = GetProcessHeap(); if (NULL == hHeap) { hr = E_POINTER; CMASSERTMSG(FALSE, TEXT("GetModuleVersionAndLCID -- couldn't get a handle to the process heap.")); goto Cleanup; } pData = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwLen);
if (!pData) { hr = E_OUTOFMEMORY; CMASSERTMSG(FALSE, TEXT("GetModuleVersionAndLCID -- couldn't alloc on the process heap.")); goto Cleanup; }
if (!GetFileVersionInfoA(pszFile, dwHandle, dwLen, pData)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Cleanup; }
VS_FIXEDFILEINFO* pVerInfo; LPVOID pInfo; UINT nLen;
if (!VerQueryValueA(pData, "\\", &pInfo, &nLen)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Cleanup; }
pVerInfo = (VS_FIXEDFILEINFO*) pInfo;
*pdwVersion = pVerInfo->dwProductVersionMS; *pdwBuild = pVerInfo->dwProductVersionLS;
//
// Now get the language the binary was compiled for
//
typedef struct _LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } LangAndCodePage;
nLen = 0; LangAndCodePage* pTranslate = NULL;
if (!VerQueryValueA(pData, "\\VarFileInfo\\Translation", (PVOID*)&pTranslate, &nLen)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Cleanup; }
//
// Let's assert that we only got one LangAndCodePage struct back. We technically
// could get more than one back but we certainly aren't expecting more than one. If we
// get more than one, use the first one as the language of the dll.
//
MYDBGASSERT(1 == (nLen/sizeof(LangAndCodePage)));
if ((nLen/sizeof(LangAndCodePage)) >= 1) { *pdwLCID = pTranslate[0].wLanguage; }
Cleanup: if (hHeap) { HeapFree(hHeap, 0, pData); }
return hr; }
//+----------------------------------------------------------------------------
// This is the Unicode version of GetModuleVersionAndLCID (the first arg is LPWSTR)
// and it just calls the Ansi version above.
//+----------------------------------------------------------------------------
HRESULT GetModuleVersionAndLCID (LPWSTR pszFile, LPDWORD pdwVersion, LPDWORD pdwBuild, LPDWORD pdwLCID) { CHAR pszAnsiFileName[MAX_PATH + 1];
if (WideCharToMultiByte(CP_ACP, 0, pszFile, -1, pszAnsiFileName, MAX_PATH, NULL, NULL)) { return GetModuleVersionAndLCID(pszAnsiFileName, pdwVersion, pdwBuild, pdwLCID); }
return E_INVALIDARG; }
|