Source code of Windows XP (NT5)
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.

179 lines
5.7 KiB

  1. /*======================================================================================//
  2. | //
  3. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  4. | //
  5. |File Name: version.cpp //
  6. | //
  7. |Description: //
  8. | //
  9. |Created: Paul Skoglund 09-1998 //
  10. | //
  11. |Rev History: //
  12. | //
  13. |=======================================================================================*/
  14. #include "StdAfx.h"
  15. #include "winver.h"
  16. #include "version.h"
  17. #include "resource.h"
  18. #define ARRAY_SIZE(_X_) (sizeof(_X_)/sizeof(_X_[0]) )
  19. CVersion::CVersion(HINSTANCE hInst) : m_hInst(hInst), m_bInitializedOK(FALSE)
  20. {
  21. memset(&szFileVersion, 0, sizeof(szFileVersion) );
  22. memset(&szProductVersion, 0, sizeof(szProductVersion) );
  23. memset(&szFileFlags, 0, sizeof(szFileFlags) );
  24. m_bDebug = m_bPatched = m_bPreRelease = m_bPrivateBuild = m_bSpecialBuild = FALSE;
  25. TCHAR szFileName[_MAX_PATH + 1] = { 0 };
  26. DWORD dwBogus = 0;
  27. DWORD dwSize = 0;
  28. LPVOID hMem = NULL;
  29. if ( GetModuleFileName(hInst, szFileName, ARRAY_SIZE(szFileName)) &&
  30. (dwSize = GetFileVersionInfoSize(szFileName, &dwBogus)) &&
  31. (hMem = new BYTE[dwSize]) )
  32. {
  33. if (GetFileVersionInfo(szFileName, NULL, dwSize, hMem) )
  34. {
  35. UINT uLen = 0;
  36. VS_FIXEDFILEINFO *ptr_vs_fixed_info;
  37. if (VerQueryValue( hMem, _T("\\"), (void **) &ptr_vs_fixed_info, &uLen) )
  38. {
  39. m_bInitializedOK = ParseFixedInfo(*ptr_vs_fixed_info, uLen);
  40. }
  41. LoadStringFileInfo(hMem);
  42. delete [] hMem;
  43. }
  44. }
  45. }
  46. BOOL CVersion::LoadStringFileInfo(LPVOID hMem)
  47. {
  48. #ifndef UNICODE
  49. #error "what code-page to use? window-multilingual? 0x04e4"
  50. #endif
  51. UINT uLen;
  52. TCHAR buf[128];
  53. TCHAR *info;
  54. // it is my understanding that the string below are identified with the same english string under each language
  55. // $$ confirm? yes/no
  56. struct
  57. {
  58. TCHAR *name;
  59. tstring *target;
  60. } table[] = {
  61. { _T("CompanyName"), &strCompanyName }, { _T("FileDescription"), &strFileDescription },
  62. { _T("FileVersion"), &strFileVersion }, { _T("InternalName"), &strInternalName },
  63. { _T("LegalCopyright"), &strLegalCopyright}, { _T("OriginalFilename"),&strOriginalFilename },
  64. { _T("ProductName"), &strProductName }, { _T("ProductVersion"), &strProductVersion },
  65. { _T("Comments"), &strComments }, { _T("LegalTrademarks"), &strLegalTrademarks },
  66. { _T("PrivateBuild"), &strPrivateBuild }, { _T("SpecialBuild"), &strSpecialBuild }
  67. };
  68. buf[ARRAY_SIZE(buf) - 1] = 0; //insure null termination
  69. for (int i = 0; i < ARRAY_SIZE(table); i++)
  70. {
  71. // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
  72. _sntprintf(buf, ARRAY_SIZE(buf) -1 , _T("\\StringFileInfo\\%04hx04b0\\%s"), GetUserDefaultLangID(), table[i].name);
  73. if (VerQueryValue( hMem, buf, (void **) &info, &uLen) )
  74. {
  75. *(table[i].target) = info;
  76. }
  77. }
  78. return TRUE;
  79. }
  80. BOOL CVersion::ParseFixedInfo(VS_FIXEDFILEINFO &info, UINT uLen)
  81. {
  82. ASSERT( uLen == sizeof(VS_FIXEDFILEINFO) );
  83. if(uLen != sizeof(VS_FIXEDFILEINFO) )
  84. return FALSE;
  85. _stprintf(szFileVersion, _T("%hu.%hu.%hu.%hu"),
  86. HIWORD(info.dwFileVersionMS),
  87. LOWORD(info.dwFileVersionMS),
  88. HIWORD(info.dwFileVersionLS),
  89. LOWORD(info.dwFileVersionLS));
  90. _stprintf(szProductVersion, _T("%hu.%hu.%hu.%hu"),
  91. HIWORD(info.dwProductVersionMS),
  92. LOWORD(info.dwProductVersionMS),
  93. HIWORD(info.dwProductVersionLS),
  94. LOWORD(info.dwProductVersionLS));
  95. if ((info.dwFileFlagsMask & VS_FF_DEBUG) &&
  96. (info.dwFileFlags & VS_FF_DEBUG) )
  97. {
  98. m_bDebug = TRUE;
  99. }
  100. if ((info.dwFileFlagsMask & VS_FF_PRERELEASE) &&
  101. (info.dwFileFlags & VS_FF_PRERELEASE) )
  102. {
  103. m_bPreRelease = TRUE;
  104. }
  105. if ((info.dwFileFlagsMask & VS_FF_PATCHED ) &&
  106. (info.dwFileFlags & VS_FF_PATCHED ) )
  107. {
  108. m_bPatched = TRUE;
  109. }
  110. if ((info.dwFileFlagsMask & VS_FF_PRIVATEBUILD ) &&
  111. (info.dwFileFlags & VS_FF_PRIVATEBUILD ) )
  112. {
  113. m_bPrivateBuild = TRUE;
  114. }
  115. if ((info.dwFileFlagsMask & VS_FF_SPECIALBUILD ) &&
  116. (info.dwFileFlags & VS_FF_SPECIALBUILD) )
  117. {
  118. m_bSpecialBuild = TRUE;
  119. }
  120. TCHAR *start = szFileFlags;
  121. int len = 0;
  122. int remaining_len = ARRAY_SIZE(szFileFlags) - 1; // length in characters not bytes!
  123. int flags[] = {VS_FF_PATCHED, VS_FF_DEBUG, VS_FF_PRERELEASE, 0 };
  124. int ids[] = {IDS_PATCHED, IDS_DEBUG, IDS_BETA, 0 };
  125. ASSERT(ARRAY_SIZE(flags) == ARRAY_SIZE(ids));
  126. for (int i = 0; flags[i], ids[i]; i++)
  127. {
  128. if ((info.dwFileFlagsMask & flags[i]) &&
  129. (info.dwFileFlags & flags[i]) && remaining_len > 1)
  130. {
  131. if (remaining_len)
  132. {
  133. remaining_len--;
  134. *start = _T(' ');
  135. start++;
  136. }
  137. // $$ if 4th parameter, maxbuffer = 0, LoadString doesn't return zero as advertised
  138. // reported to MS 9/29/1998
  139. len = ::LoadString(m_hInst, ids[i], start, remaining_len);
  140. start += len;
  141. remaining_len -= len;
  142. }
  143. }
  144. return TRUE;
  145. }