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.

201 lines
5.7 KiB

  1. ////////////////////////////////////////////////////////////////
  2. // 1998 Microsoft Systems Journal
  3. // If this code works, it was written by Paul DiLascia.
  4. // If not, I don't know who wrote it.
  5. //
  6. // CModuleVersion provides an easy way to get version info
  7. // for a module.(DLL or EXE).
  8. //
  9. // This code appeard in April 1998 edition of Microsoft Systems
  10. // Journal.
  11. //
  12. // 27-July-1998 -- Adapted by James A. McLaughiln (Schlumberger
  13. // Technology Corp.) for Smart Cards. Merged with the concepts from
  14. // CFileVersion class contributed by Manuel Laflamme on a posting to
  15. // www.codeguru.com. If these mods don't work, then you can blame me.
  16. #include "StdAfx.h"
  17. #include "slbModVer.h"
  18. CModuleVersion::CModuleVersion()
  19. : m_pVersionInfo(NULL)
  20. {
  21. }
  22. //////////////////
  23. // Destroy: delete version info
  24. //
  25. CModuleVersion::~CModuleVersion()
  26. {
  27. delete [] m_pVersionInfo;
  28. }
  29. BOOL CModuleVersion::GetFileVersionInfo(LPCTSTR modulename)
  30. {
  31. // get module handle
  32. HMODULE hModule = ::GetModuleHandle(modulename);
  33. if (hModule==NULL && modulename!=NULL)
  34. return FALSE;
  35. return GetFileVersionInfo(hModule);
  36. }
  37. //////////////////
  38. // Get file version info for a given module
  39. // Allocates storage for all info, fills "this" with
  40. // VS_FIXEDFILEINFO, and sets codepage.
  41. //
  42. BOOL CModuleVersion::GetFileVersionInfo(HMODULE hModule)
  43. {
  44. m_translation.charset = 1252; // default = ANSI code page
  45. memset((VS_FIXEDFILEINFO*)this, 0, sizeof(VS_FIXEDFILEINFO));
  46. // get module file name
  47. TCHAR filename[_MAX_PATH+1];// Space for null termination
  48. DWORD len = GetModuleFileName(hModule, filename,
  49. sizeof(filename)/sizeof(filename[0]));
  50. if (len <= 0)
  51. return FALSE;
  52. // Zero terminate buffer.
  53. if(len <=_MAX_PATH)
  54. filename[len] = 0;
  55. else
  56. filename[_MAX_PATH] = 0;
  57. // read file version info
  58. DWORD dwDummyHandle; // will always be set to zero
  59. len = GetFileVersionInfoSize(filename, &dwDummyHandle);
  60. if (len <= 0)
  61. return FALSE;
  62. m_pVersionInfo = new BYTE[len]; // allocate version info
  63. if (!::GetFileVersionInfo(filename, 0, len, m_pVersionInfo))
  64. return FALSE;
  65. // copy fixed info to myself, which am derived from VS_FIXEDFILEINFO
  66. if (!GetFixedInfo(*(VS_FIXEDFILEINFO*)this))
  67. return FALSE;
  68. // Get translation info
  69. LPVOID lpvi;
  70. UINT iLen;
  71. if (VerQueryValue(m_pVersionInfo,
  72. TEXT("\\VarFileInfo\\Translation"), &lpvi, &iLen) && iLen >= 4) {
  73. m_translation = *(TRANSLATION*)lpvi;
  74. TRACE(TEXT("code page = %d\n"), m_translation.charset);
  75. }
  76. return dwSignature == VS_FFI_SIGNATURE;
  77. }
  78. //////////////////
  79. // Get string file info.
  80. // Key name is something like "CompanyName".
  81. // returns the value as a CString.
  82. //
  83. CString CModuleVersion::GetValue(LPCTSTR lpKeyName)
  84. {
  85. CString sVal;
  86. if (m_pVersionInfo) {
  87. // To get a string value must pass query in the form
  88. //
  89. // "\StringFileInfo\<langID><codepage>\keyname"
  90. //
  91. // where <lang-codepage> is the languageID concatenated with the
  92. // code page, in hex. Wow.
  93. //
  94. CString query;
  95. query.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),
  96. m_translation.langID,
  97. m_translation.charset,
  98. lpKeyName);
  99. LPCTSTR pVal;
  100. UINT iLenVal;
  101. if (VerQueryValue(m_pVersionInfo, (LPTSTR)(LPCTSTR)query,
  102. (LPVOID*)&pVal, &iLenVal)) {
  103. sVal = pVal;
  104. }
  105. }
  106. return sVal;
  107. }
  108. // typedef for DllGetVersion proc
  109. typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
  110. /////////////////
  111. // Get DLL Version by calling DLL's DllGetVersion proc
  112. //
  113. BOOL CModuleVersion::DllGetVersion(LPCTSTR modulename, DLLVERSIONINFO& dvi)
  114. {
  115. HINSTANCE hinst = LoadLibrary(modulename);
  116. if (!hinst)
  117. return FALSE;
  118. // Must use GetProcAddress because the DLL might not implement
  119. // DllGetVersion. Depending upon the DLL, the lack of implementation of the
  120. // function may be a version marker in itself.
  121. //
  122. DLLGETVERSIONPROC pDllGetVersion =
  123. (DLLGETVERSIONPROC)GetProcAddress(hinst, reinterpret_cast<const char *>(_T("DllGetVersion")));
  124. if (!pDllGetVersion)
  125. return FALSE;
  126. memset(&dvi, 0, sizeof(dvi)); // clear
  127. dvi.cbSize = sizeof(dvi); // set size for Windows
  128. return SUCCEEDED((*pDllGetVersion)(&dvi));
  129. }
  130. BOOL CModuleVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi)
  131. {
  132. // Must furst call GetFileVersionInfo or constructor with arg
  133. ASSERT(m_pVersionInfo != NULL);
  134. if ( m_pVersionInfo == NULL )
  135. return FALSE;
  136. UINT nQuerySize;
  137. VS_FIXEDFILEINFO* pVsffi;
  138. if ( ::VerQueryValue((void **)m_pVersionInfo, _T("\\"),
  139. (void**)&pVsffi, &nQuerySize) )
  140. {
  141. vsffi = *pVsffi;
  142. return TRUE;
  143. }
  144. return FALSE;
  145. }
  146. CString CModuleVersion::GetFixedFileVersion()
  147. {
  148. CString strVersion;
  149. VS_FIXEDFILEINFO vsffi;
  150. if (GetFixedInfo(vsffi))
  151. {
  152. strVersion.Format (_T("%u,%u,%u,%u"),HIWORD(dwFileVersionMS),
  153. LOWORD(dwFileVersionMS),
  154. HIWORD(dwFileVersionLS),
  155. LOWORD(dwFileVersionLS));
  156. }
  157. return strVersion;
  158. }
  159. CString CModuleVersion::GetFixedProductVersion()
  160. {
  161. CString strVersion;
  162. VS_FIXEDFILEINFO vsffi;
  163. if (GetFixedInfo(vsffi))
  164. {
  165. strVersion.Format (_T("%u,%u,%u,%u"), HIWORD(dwProductVersionMS),
  166. LOWORD(dwProductVersionMS),
  167. HIWORD(dwProductVersionLS),
  168. LOWORD(dwProductVersionLS));
  169. }
  170. return strVersion;
  171. }