From 8c1430dbeb05014306cb709d8362b60e2fa2928d Mon Sep 17 00:00:00 2001 From: Peter Bain Date: Thu, 7 Mar 2019 11:30:36 -0500 Subject: [PATCH] Get Windows version information from registry if major version is 10. Print the release ID for unrecognized OS versions. Fixes https://github.com/eclipse/omr/issues/3644 Signed-off-by: Peter Bain --- port/win32/omrsysinfo.c | 84 ++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/port/win32/omrsysinfo.c b/port/win32/omrsysinfo.c index 502827bdc0..c50505cf12 100644 --- a/port/win32/omrsysinfo.c +++ b/port/win32/omrsysinfo.c @@ -169,7 +169,7 @@ omrsysinfo_get_env(struct OMRPortLibrary *portLibrary, const char *envVar, char const char * omrsysinfo_get_OS_type(struct OMRPortLibrary *portLibrary) { - +BOOLEAN isServerMajorVersion10 = FALSE; /* WIN32_WINNT version constants : @@ -190,18 +190,22 @@ WIN32_WINNT version constants : if (NULL == PPG_si_osType) { char *defaultTypeName = "Windows"; -#if !defined(_WIN32_WINNT_WINBLUE) || !(_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) +#if !defined(_WIN32_WINNT_WINBLUE) || (_WIN32_WINNT_MAXVER < _WIN32_WINNT_WINBLUE) + /* Windows 8 or earlier */ OSVERSIONINFOEX versionInfo; #endif PPG_si_osType = defaultTypeName; /* by default, use the "unrecognized version" string */ PPG_si_osTypeOnHeap = NULL; #if defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) + /* Windows 8.1 or later */ /* OS Versions: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx */ if (IsWindowsServer()) { #if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WIN10) if (IsWindows10OrGreater()) { - PPG_si_osType = "Windows Server 2016"; + /* Starting with major version 10, use the registry to get the version */ + PPG_si_osType = defaultTypeName; + isServerMajorVersion10 = TRUE; } else #endif /* defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WIN10) */ if (IsWindows8Point1OrGreater()) { @@ -218,6 +222,7 @@ WIN32_WINNT version constants : } else { #if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WIN10) if (IsWindows10OrGreater()) { + /* May need to check ReleaseId when next Windows version is released */ PPG_si_osType = "Windows 10"; } else #endif /* defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WIN10) */ @@ -262,9 +267,9 @@ WIN32_WINNT version constants : break; } break; - default: - PPG_si_osType = defaultTypeName; - break; + default: + PPG_si_osType = defaultTypeName; + break; } break; } @@ -329,14 +334,9 @@ WIN32_WINNT version constants : } break; default: { - switch (versionInfo.dwMinorVersion) { - case 0: - PPG_si_osType = "Windows Server 2016"; - break; - default: - PPG_si_osType = defaultTypeName; - break; - } + /* Starting with major version 10, use the registry to get the version */ + PPG_si_osType = defaultTypeName; + isServerMajorVersion10 = TRUE; } break; } @@ -349,25 +349,57 @@ WIN32_WINNT version constants : } #endif /* defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) */ - +#define PRODUCT_NAME_KEY "ProductName" +#define RELEASE_ID_KEY "ReleaseId" +#define WINDOWS_SERVER_PREFIX "Windows Server version " if (defaultTypeName == PPG_si_osType) { HKEY hKey; - if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey)) { - DWORD nameSize = 0; - /* query the first time to get the content size of the value. */ - if (ERROR_SUCCESS == RegQueryValueExA(hKey, "ProductName", NULL, NULL, NULL, &nameSize)) { - char *productNameBuffer = portLibrary->mem_allocate_memory(portLibrary, nameSize, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); - if (NULL != productNameBuffer) { - /* query the second time to get the value */ - if (ERROR_SUCCESS == RegQueryValueExA(hKey, "ProductName", NULL, NULL, (LPBYTE)productNameBuffer, &nameSize)) { - PPG_si_osType = PPG_si_osTypeOnHeap = productNameBuffer; - } else { - portLibrary->mem_free_memory(portLibrary, productNameBuffer); + if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey)) { + DWORD valueSize = 0; + if (isServerMajorVersion10 + && (ERROR_SUCCESS == RegQueryValueExA(hKey, RELEASE_ID_KEY, NULL, NULL, NULL, &valueSize))) { + char ridBuffer[5]; /* the ReleaseId string format is YYMM */ + if (sizeof(ridBuffer) >= valueSize) { + if (ERROR_SUCCESS == RegQueryValueExA(hKey, RELEASE_ID_KEY, NULL, NULL, (LPBYTE)ridBuffer, &valueSize)) { + if (0 == strcmp(ridBuffer, "1607")) { + PPG_si_osType = "Windows Server 2016"; + } else if (0 == strcmp(ridBuffer, "1809")) { + PPG_si_osType = "Windows Server 2019"; + } else { + size_t bufferSize = sizeof(WINDOWS_SERVER_PREFIX) + valueSize + 1; + char *productNameBuffer = portLibrary->mem_allocate_memory(portLibrary, + valueSize, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); + if (NULL != productNameBuffer) { + /* Print the version string using the format used by Microsoft */ + portLibrary->str_printf(portLibrary, productNameBuffer, bufferSize, + "%s%s", WINDOWS_SERVER_PREFIX, ridBuffer); + PPG_si_osTypeOnHeap = productNameBuffer; + PPG_si_osType = PPG_si_osTypeOnHeap; + } + } + } + } + } + if (defaultTypeName == PPG_si_osType) { + /* query the first time to get the content size of the value. */ + if (ERROR_SUCCESS == RegQueryValueExA(hKey, PRODUCT_NAME_KEY, NULL, NULL, NULL, &valueSize)) { + char *productNameBuffer = portLibrary->mem_allocate_memory(portLibrary, valueSize, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); + if (NULL != productNameBuffer) { + /* query the second time to get the value */ + if (ERROR_SUCCESS == RegQueryValueExA(hKey, PRODUCT_NAME_KEY, NULL, NULL, (LPBYTE)productNameBuffer, &valueSize)) { + PPG_si_osType = PPG_si_osTypeOnHeap = productNameBuffer; + } else { + portLibrary->mem_free_memory(portLibrary, productNameBuffer); + } } } } } } +#undef PRODUCT_NAME_KEY +#undef RELEASE_ID_KEY +#undef WINDOWS_SERVER_PREFIX if (defaultTypeName == PPG_si_osType) { #if defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) Trc_PRT_sysinfo_failed_to_get_os_type();