From fa7cd77d7d16dca7ddd18a647b2316c63c7ec12f Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 7 Dec 2017 13:49:07 -0500 Subject: [PATCH] win32: improve version reporting under System Information --- CHANGES.md | 1 + frontend/drivers/platform_win32.c | 122 ++++++++++++++++++++++++++---- menu/menu_displaylist.c | 2 +- 3 files changed, 109 insertions(+), 16 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8a96ac498c..ddb34e00e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ - WINDOWS: Raw input driver now supports new lightgun code. - WINDOWS: Use configured OSD/text message color on GDI driver. - WINDOWS/XINPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names +- WINDOWS: Improve version reporting under System Information. # 1.6.9 - COMMON: Small memory leak. diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 2988b75c4e..b523c487a0 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- @@ -25,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -130,40 +132,110 @@ static void gfx_set_dwm(void) static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) { - uint32_t version = GetVersion(); + char buildStr[11] = {0}; + bool server = false; + const char *arch = ""; + bool serverR2 = false; - *major = (DWORD)(LOBYTE(LOWORD(version))); - *minor = (DWORD)(HIBYTE(LOWORD(version))); +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Windows 2000 and later */ + SYSTEM_INFO si = {0}; + OSVERSIONINFOEX vi = {0}; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - switch (*major) + server = vi.wProductType != VER_NT_WORKSTATION; + + serverR2 = GetSystemMetrics(SM_SERVERR2); + + GetSystemInfo(&si); + + switch (si.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + arch = "x64"; + break; + case PROCESSOR_ARCHITECTURE_INTEL: + arch = "x86"; + break; + case PROCESSOR_ARCHITECTURE_ARM: + arch = "ARM"; + break; + default: + break; + } +#else + OSVERSIONINFO vi = {0}; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); +#endif + + /* Available from NT 3.5 and Win95 */ + GetVersionEx((OSVERSIONINFO*)&vi); + + if (major) + *major = vi.dwMajorVersion; + + if (minor) + *minor = vi.dwMinorVersion; + + if (vi.dwMajorVersion == 4 && vi.dwMinorVersion == 0) + snprintf(buildStr, sizeof(buildStr), "%lu", (DWORD)(LOWORD(vi.dwBuildNumber))); /* Windows 95 build number is in the low-order word only */ + else + snprintf(buildStr, sizeof(buildStr), "%lu", vi.dwBuildNumber); + + switch (vi.dwMajorVersion) { case 10: - strlcpy(s, "Windows 10", len); + if (server) + strlcpy(s, "Windows Server 2016", len); + else + strlcpy(s, "Windows 10", len); break; case 6: - switch (*minor) + switch (vi.dwMinorVersion) { case 3: - strlcpy(s, "Windows 8.1", len); + if (server) + strlcpy(s, "Windows Server 2012 R2", len); + else + strlcpy(s, "Windows 8.1", len); break; case 2: - strlcpy(s, "Windows 8", len); + if (server) + strlcpy(s, "Windows Server 2012", len); + else + strlcpy(s, "Windows 8", len); break; case 1: - strlcpy(s, "Windows 7/2008 R2", len); + if (server) + strlcpy(s, "Windows Server 2008 R2", len); + else + strlcpy(s, "Windows 7", len); break; case 0: - strlcpy(s, "Windows Vista/2008", len); + if (server) + strlcpy(s, "Windows Server 2008", len); + else + strlcpy(s, "Windows Vista", len); break; default: break; } break; case 5: - switch (*minor) + switch (vi.dwMinorVersion) { case 2: - strlcpy(s, "Windows 2003", len); + if (server) + if (serverR2) + strlcpy(s, "Windows Server 2003 R2", len); + else + strlcpy(s, "Windows Server 2003", len); + else + { + /* Yes, XP Pro x64 is a higher version number than XP x86 */ + if (string_is_equal(arch, "x64")) + strlcpy(s, "Windows XP", len); + } break; case 1: strlcpy(s, "Windows XP", len); @@ -174,10 +246,15 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) } break; case 4: - switch (*minor) + switch (vi.dwMinorVersion) { case 0: - strlcpy(s, "Windows NT 4.0", len); + if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) + strlcpy(s, "Windows 95", len); + else if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) + strlcpy(s, "Windows NT 4.0", len); + else + strlcpy(s, "Unknown", len); break; case 90: strlcpy(s, "Windows ME", len); @@ -188,9 +265,24 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) } break; default: - sprintf(s, "Windows %i.%i", *major, *minor); + snprintf(s, len, "Windows %i.%i", *major, *minor); break; } + + if (!string_is_empty(arch)) + { + strlcat(s, " ", len); + strlcat(s, arch, len); + } + + strlcat(s, " Build ", len); + strlcat(s, buildStr, len); + + if (!string_is_empty(vi.szCSDVersion)) + { + strlcat(s, " ", len); + strlcat(s, vi.szCSDVersion, len); + } } static void frontend_win32_init(void *data) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 051f17d62a..a7da756206 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -805,7 +805,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) if (frontend->get_os) { frontend->get_os(tmp2, sizeof(tmp2), &major, &minor); - snprintf(tmp, sizeof(tmp), "%s : %s %d.%d", + snprintf(tmp, sizeof(tmp), "%s : %s (v%d.%d)", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS), frontend->get_os ? tmp2 : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),