Subject: Fix [651e828a52]: Wrong Windows version reported for Windows 8.1

From: "jan.nijtmans" <[email-masked]>
Date: Mon, 3 Feb 2014 14:43:52 +0000

---
 unix/tclUnixInit.c | 29 ++++++++++++++++++++++-------
 win/tclWinInit.c   | 18 ++++++++++++++----
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c
index 0b98cf9..423e97e 100644
--- a/unix/tclUnixInit.c
+++ b/unix/tclUnixInit.c
@@ -33,7 +33,10 @@
 #endif
 
 #ifdef __CYGWIN__
-DLLIMPORT extern __stdcall unsigned char GetVersionExA(void *);
+DLLIMPORT extern __stdcall unsigned char GetVersionExW(void *);
+DLLIMPORT extern __stdcall void *LoadLibraryW(const void *);
+DLLIMPORT extern __stdcall void FreeLibrary(void *);
+DLLIMPORT extern __stdcall void *GetProcAddress(void *, const char *);
 DLLIMPORT extern __stdcall void GetSystemInfo(void *);
 
 #define NUMPLATFORMS 4
@@ -66,14 +69,14 @@ typedef struct _SYSTEM_INFO {
   int      wProcessorRevision;
 } SYSTEM_INFO;
 
-typedef struct _OSVERSIONINFOA {
+typedef struct _OSVERSIONINFOW {
   DWORD dwOSVersionInfoSize;
   DWORD dwMajorVersion;
   DWORD dwMinorVersion;
   DWORD dwBuildNumber;
   DWORD dwPlatformId;
-  char szCSDVersion[128];
-} OSVERSIONINFOA;
+  wchar_t szCSDVersion[128];
+} OSVERSIONINFOW;
 #endif
 
 #ifdef HAVE_COREFOUNDATION
@@ -811,7 +814,8 @@ TclpSetVariables(
 {
 #ifdef __CYGWIN__
     SYSTEM_INFO sysInfo;
-    OSVERSIONINFOA osInfo;
+    static OSVERSIONINFOW osInfo;
+    static int osInfoInitialized = 0;
     char buffer[TCL_INTEGER_SPACE * 2];
 #elif !defined(NO_UNAME)
     struct utsname name;
@@ -924,8 +928,19 @@ TclpSetVariables(
     unameOK = 0;
 #ifdef __CYGWIN__
 	unameOK = 1;
-    osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
-    GetVersionExA(&osInfo);
+    if (!osInfoInitialized) {
+      HANDLE handle = LoadLibraryW(L"NTDLL");
+      int(*getversion)(void *) = (int(*)(void *))GetProcAddress(handle, "RtlGetVersion");
+      osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+      if (!getversion || getversion(&osInfo)) {
+        GetVersionExW(&osInfo);
+      }
+      if (handle) {
+        FreeLibrary(handle);
+      }
+      osInfoInitialized = 1;
+    }
+
     GetSystemInfo(&sysInfo);
 
     if (osInfo.dwPlatformId < NUMPLATFORMS) {
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index 81d762f..08ef1ed 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -563,7 +563,8 @@ TclpSetVariables(
 	SYSTEM_INFO info;
 	OemId oemId;
     } sys;
-    OSVERSIONINFOW osInfo;
+    static OSVERSIONINFOW osInfo;
+    static int osInfoInitialized = 0;
     Tcl_DString ds;
     WCHAR szUserName[UNLEN+1];
     DWORD cchUserNameLen = UNLEN;
@@ -571,9 +572,18 @@ TclpSetVariables(
     Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
 	    TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
 
-    osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
-    GetVersionExW(&osInfo);
-
+    if (!osInfoInitialized) {
+      HANDLE handle = LoadLibraryW(L"NTDLL");
+      int(*getversion)(void *) = (int(*)(void *))GetProcAddress(handle, "RtlGetVersion");
+      osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+      if (!getversion || getversion(&osInfo)) {
+        GetVersionExW(&osInfo);
+      }
+      if (handle) {
+        FreeLibrary(handle);
+      }
+      osInfoInitialized = 1;
+    }
     GetSystemInfo(&sys.info);
 
     /*
-- 
cgit v0.12