Browse Source

Windows: Fix CMAKE_HOST_SYSTEM_VERSION on Windows >= 8.1 (#15674)

The GetVersionEx API is deprecated, so try RtlGetVersion first.

Co-Author: Christian Maaser
Brad King 10 years ago
parent
commit
d4736d53cd
1 changed files with 46 additions and 10 deletions
  1. 46 10
      Source/cmGlobalGenerator.cxx

+ 46 - 10
Source/cmGlobalGenerator.cxx

@@ -14,6 +14,20 @@
 #if defined(_MSC_VER) && _MSC_VER >= 1800
 # define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 #endif
+typedef struct {
+  ULONG  dwOSVersionInfoSize;
+  ULONG  dwMajorVersion;
+  ULONG  dwMinorVersion;
+  ULONG  dwBuildNumber;
+  ULONG  dwPlatformId;
+  WCHAR  szCSDVersion[128];
+  USHORT wServicePackMajor;
+  USHORT wServicePackMinor;
+  USHORT wSuiteMask;
+  UCHAR  wProductType;
+  UCHAR  wReserved;
+} CMRTL_OSVERSIONINFOEXW;
+
 #endif
 
 #include "cmGlobalGenerator.h"
@@ -437,23 +451,45 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
   if (!mf->GetDefinition("CMAKE_SYSTEM"))
     {
 #if defined(_WIN32) && !defined(__CYGWIN__)
-    /* Windows version number data.  */
-    OSVERSIONINFO osvi;
-    ZeroMemory(&osvi, sizeof(osvi));
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    CMRTL_OSVERSIONINFOEXW osviex;
+    ZeroMemory(&osviex, sizeof(osviex));
+    osviex.dwOSVersionInfoSize = sizeof(osviex);
+
+    typedef LONG (FAR WINAPI *cmRtlGetVersion)(CMRTL_OSVERSIONINFOEXW*);
+    cmRtlGetVersion rtlGetVersion = reinterpret_cast<cmRtlGetVersion>(
+      GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"));
+    if (rtlGetVersion && rtlGetVersion(&osviex) == 0)
+      {
+      std::ostringstream windowsVersionString;
+      windowsVersionString << osviex.dwMajorVersion << "."
+                           << osviex.dwMinorVersion << "."
+                           << osviex.dwBuildNumber;
+      windowsVersionString.str();
+      mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
+                        windowsVersionString.str().c_str());
+      }
+    else
+      {
+      // RtlGetVersion failed, so use the deprecated GetVersionEx function.
+      /* Windows version number data.  */
+      OSVERSIONINFO osvi;
+      ZeroMemory(&osvi, sizeof(osvi));
+      osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (push)
 # pragma warning (disable:4996)
 #endif
-    GetVersionEx (&osvi);
+      GetVersionEx (&osvi);
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (pop)
 #endif
-    std::ostringstream windowsVersionString;
-    windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
-    windowsVersionString.str();
-    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
-                      windowsVersionString.str().c_str());
+      std::ostringstream windowsVersionString;
+      windowsVersionString << osvi.dwMajorVersion << "."
+                           << osvi.dwMinorVersion;
+      windowsVersionString.str();
+      mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
+                        windowsVersionString.str().c_str());
+      }
 #endif
     // Read the DetermineSystem file
     std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");