Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.8 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: getmodulever.cpp
  4. //
  5. // Module: CMSETUP.LIB, CMUTIL.DLL
  6. //
  7. // Synopsis: Implementation of the GetModuleVersionAndLCID function.
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation
  10. //
  11. // Author: quintinb Created Header 08/19/99
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmutil.h"
  15. //+----------------------------------------------------------------------------
  16. //
  17. // Function: GetModuleVersionAndLCID
  18. //
  19. // Synopsis: Gets the version information and LCID from the specified module
  20. //
  21. // Arguments: LPTSTR pszFile - Full path to the file to get the version number of
  22. // LPDWORD pdwVersion - version number (Hiword Major, Loword Minor)
  23. // LPDWORD pdwBuild - build number (Hiword Major, Loword Minor)
  24. // LPDWORD pdwLCID - returns the Locale ID that the module was localized too
  25. //
  26. // Returns: HRESULT -- S_OK if successful, an error code otherwise
  27. //
  28. // History: quintinb -- Code borrowed from Yoshifumi "Vogue" Inoue
  29. // from (private\admin\wsh\host\verutil.cpp).
  30. // Rewritten to match our coding style. 9/14/98
  31. // 17-Oct-2000 SumitC cleanup, fixed leaks, moved to common\source
  32. //
  33. // Notes: There are 2 versions of this function, which take ANSI and Unicode
  34. // versions of the pszFile argument.
  35. //
  36. //+----------------------------------------------------------------------------
  37. HRESULT GetModuleVersionAndLCID (LPSTR pszFile, LPDWORD pdwVersion, LPDWORD pdwBuild, LPDWORD pdwLCID)
  38. {
  39. HRESULT hr = S_OK;
  40. HANDLE hHeap = NULL;
  41. LPVOID pData = NULL;
  42. DWORD dwHandle;
  43. DWORD dwLen;
  44. if ((NULL == pdwVersion) || (NULL == pdwBuild) || (NULL == pdwLCID) ||
  45. (NULL == pszFile) || (TEXT('\0') == pszFile))
  46. {
  47. hr = E_POINTER;
  48. goto Cleanup;
  49. }
  50. *pdwVersion = 0;
  51. *pdwBuild = 0;
  52. *pdwLCID = 0;
  53. dwLen = GetFileVersionInfoSizeA(pszFile, &dwHandle);
  54. if (0 == dwLen)
  55. {
  56. hr = HRESULT_FROM_WIN32(GetLastError());
  57. goto Cleanup;
  58. }
  59. hHeap = GetProcessHeap();
  60. if (NULL == hHeap)
  61. {
  62. hr = E_POINTER;
  63. CMASSERTMSG(FALSE, TEXT("GetModuleVersionAndLCID -- couldn't get a handle to the process heap."));
  64. goto Cleanup;
  65. }
  66. pData = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwLen);
  67. if (!pData)
  68. {
  69. hr = E_OUTOFMEMORY;
  70. CMASSERTMSG(FALSE, TEXT("GetModuleVersionAndLCID -- couldn't alloc on the process heap."));
  71. goto Cleanup;
  72. }
  73. if (!GetFileVersionInfoA(pszFile, dwHandle, dwLen, pData))
  74. {
  75. hr = HRESULT_FROM_WIN32(GetLastError());
  76. goto Cleanup;
  77. }
  78. VS_FIXEDFILEINFO* pVerInfo;
  79. LPVOID pInfo;
  80. UINT nLen;
  81. if (!VerQueryValueA(pData, "\\", &pInfo, &nLen))
  82. {
  83. hr = HRESULT_FROM_WIN32(GetLastError());
  84. goto Cleanup;
  85. }
  86. pVerInfo = (VS_FIXEDFILEINFO*) pInfo;
  87. *pdwVersion = pVerInfo->dwProductVersionMS;
  88. *pdwBuild = pVerInfo->dwProductVersionLS;
  89. //
  90. // Now get the language the binary was compiled for
  91. //
  92. typedef struct _LANGANDCODEPAGE
  93. {
  94. WORD wLanguage;
  95. WORD wCodePage;
  96. } LangAndCodePage;
  97. nLen = 0;
  98. LangAndCodePage* pTranslate = NULL;
  99. if (!VerQueryValueA(pData, "\\VarFileInfo\\Translation", (PVOID*)&pTranslate, &nLen))
  100. {
  101. hr = HRESULT_FROM_WIN32(GetLastError());
  102. goto Cleanup;
  103. }
  104. //
  105. // Let's assert that we only got one LangAndCodePage struct back. We technically
  106. // could get more than one back but we certainly aren't expecting more than one. If we
  107. // get more than one, use the first one as the language of the dll.
  108. //
  109. MYDBGASSERT(1 == (nLen/sizeof(LangAndCodePage)));
  110. if ((nLen/sizeof(LangAndCodePage)) >= 1)
  111. {
  112. *pdwLCID = pTranslate[0].wLanguage;
  113. }
  114. Cleanup:
  115. if (hHeap)
  116. {
  117. HeapFree(hHeap, 0, pData);
  118. }
  119. return hr;
  120. }
  121. //+----------------------------------------------------------------------------
  122. // This is the Unicode version of GetModuleVersionAndLCID (the first arg is LPWSTR)
  123. // and it just calls the Ansi version above.
  124. //+----------------------------------------------------------------------------
  125. HRESULT GetModuleVersionAndLCID (LPWSTR pszFile, LPDWORD pdwVersion, LPDWORD pdwBuild, LPDWORD pdwLCID)
  126. {
  127. CHAR pszAnsiFileName[MAX_PATH + 1];
  128. if (WideCharToMultiByte(CP_ACP, 0, pszFile, -1, pszAnsiFileName, MAX_PATH, NULL, NULL))
  129. {
  130. return GetModuleVersionAndLCID(pszAnsiFileName, pdwVersion, pdwBuild, pdwLCID);
  131. }
  132. return E_INVALIDARG;
  133. }