diff --git a/Common/OSVersion.cpp b/Common/OSVersion.cpp index adc2f1d310..3ee3aab8c5 100644 --- a/Common/OSVersion.cpp +++ b/Common/OSVersion.cpp @@ -11,6 +11,16 @@ #include "OSVersion.h" #include "Common/CommonWindows.h" +struct WindowsReleaseInfo +{ + int major; + int minor; + int spMajor; + int spMinor; + int build; + bool greater = false; +}; + bool GetVersionFromKernel32(uint32_t &major, uint32_t &minor, uint32_t &build) { #if PPSSPP_PLATFORM(UWP) return false; @@ -37,23 +47,7 @@ bool GetVersionFromKernel32(uint32_t &major, uint32_t &minor, uint32_t &build) { } bool DoesVersionMatchWindows(uint32_t major, uint32_t minor, uint32_t spMajor, uint32_t spMinor, bool greater) { -#if PPSSPP_PLATFORM(UWP) - if (greater) - return true; - else - return major >= 7; -#else - if (spMajor == 0 && spMinor == 0) { - // "Applications not manifested for Windows 10 will return the Windows 8 OS version value (6.2)." - // Try to use kernel32.dll instead, for Windows 10+. Doesn't do SP versions. - uint32_t actualMajor, actualMinor, actualBuild; - if (GetVersionFromKernel32(actualMajor, actualMinor, actualBuild)) { - if (greater) - return actualMajor > major || (major == actualMajor && actualMinor >= minor); - return major == actualMajor && minor == actualMinor; - } - } - +#if !PPSSPP_PLATFORM(UWP) uint64_t conditionMask = 0; OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); @@ -67,31 +61,64 @@ bool DoesVersionMatchWindows(uint32_t major, uint32_t minor, uint32_t spMajor, u VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, op); VER_SET_CONDITION(conditionMask, VER_MINORVERSION, op); - VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, op); - VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, op); + uint32_t typeMask = VER_MAJORVERSION | VER_MINORVERSION; - const uint32_t typeMask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; + if (spMajor > 0) { + VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, op); + typeMask |= VER_SERVICEPACKMAJOR; + } + if (spMinor > 0) { + VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, op); + typeMask |= VER_SERVICEPACKMINOR; + } return VerifyVersionInfo(&osvi, typeMask, conditionMask) != FALSE; + +#else + return false; #endif } +bool DoesVersionMatchWindows(WindowsReleaseInfo release) { + if (release.spMajor == 0 && release.spMinor == 0) { + // Compare Info + int major = release.major; + int minor = release.minor; + int build = release.build; + bool greater = release.greater; + + OSVERSIONINFOEX osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + GetVersionEx((LPOSVERSIONINFO)&osvi); + + // OS Info + uint32_t osMajor = osvi.dwMajorVersion; + uint32_t osMinor = osvi.dwMinorVersion; + uint32_t osBuild = osvi.dwBuildNumber; + +#if !PPSSPP_PLATFORM(UWP) + // "Applications not manifested for Windows 10 will return the Windows 8 OS version value (6.2)." + // Try to use kernel32.dll instead, for Windows 10+. + GetVersionFromKernel32(osMajor, osMinor, osBuild); +#endif + + if (major == osMajor) { + // To detect Windows 11 we must check build number + if (osMinor >= minor && osBuild >= build) { + return true; + } + } + } + return DoesVersionMatchWindows(release.major, release.minor, release.spMajor, release.spMinor, release.greater); +} + bool IsVistaOrHigher() { #if PPSSPP_PLATFORM(UWP) return true; #else - OSVERSIONINFOEX osvi; - DWORDLONG dwlConditionMask = 0; - int op = VER_GREATER_EQUAL; - ZeroMemory(&osvi, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = 6; // Vista is 6.0 - osvi.dwMinorVersion = 0; - - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); - - return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE; + // Vista is 6.0 + return DoesVersionMatchWindows(6, 0, 0, 0, true); #endif } @@ -99,44 +126,38 @@ bool IsWin7OrHigher() { #if PPSSPP_PLATFORM(UWP) return true; #else - OSVERSIONINFOEX osvi; - DWORDLONG dwlConditionMask = 0; - int op = VER_GREATER_EQUAL; - ZeroMemory(&osvi, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = 6; // Win7 is 6.1 - osvi.dwMinorVersion = 1; - - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); - - return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE; + // Win7 is 6.1 + return DoesVersionMatchWindows(6, 0, 0, 0, true); #endif } std::string GetWindowsVersion() { - const bool IsWindowsXPSP2 = DoesVersionMatchWindows(5, 1, 2, 0, false); - const bool IsWindowsXPSP3 = DoesVersionMatchWindows(5, 1, 3, 0, false); - const bool IsWindowsVista = DoesVersionMatchWindows(6, 0, 0, 0, false); - const bool IsWindowsVistaSP1 = DoesVersionMatchWindows(6, 0, 1, 0, false); - const bool IsWindowsVistaSP2 = DoesVersionMatchWindows(6, 0, 2, 0, false); - const bool IsWindows7 = DoesVersionMatchWindows(6, 1, 0, 0, false); - const bool IsWindows7SP1 = DoesVersionMatchWindows(6, 1, 1, 0, false); - const bool IsWindows8 = DoesVersionMatchWindows(6, 2, 0, 0, false); - const bool IsWindows8_1 = DoesVersionMatchWindows(6, 3, 0, 0, false); - const bool IsWindows10 = DoesVersionMatchWindows(10, 0, 0, 0, false); + std::vector> windowsReleases = { + /* { "Preview text", { major, minor, spMajor, spMinor, build, greater } }, */ + { "Microsoft Windows XP, Service Pack 2", { 5, 1, 2, 0 } }, + { "Microsoft Windows XP, Service Pack 3", { 5, 1, 3, 0 } }, + { "Microsoft Windows Vista", { 6, 0, 0, 0 } }, + { "Microsoft Windows Vista, Service Pack 1", { 6, 0, 1, 0 } }, + { "Microsoft Windows Vista, Service Pack 2", { 6, 0, 2, 0 } }, + { "Microsoft Windows 7", { 6, 1, 0, 0 } }, + { "Microsoft Windows 7, Service Pack 1", { 6, 1, 1, 0 } }, + { "Microsoft Windows 8", { 6, 2, 0, 0 } }, + { "Microsoft Windows 8.1", { 6, 3, 0, 0 } }, + { "Microsoft Windows 10", { 10, 0, 0, 0 } }, + { "Microsoft Windows 11", { 10, 0, 0, 0, 22000 } }, + }; - if (IsWindowsXPSP2) return "Microsoft Windows XP, Service Pack 2"; - if (IsWindowsXPSP3) return "Microsoft Windows XP, Service Pack 3"; - if (IsWindowsVista) return "Microsoft Windows Vista"; - if (IsWindowsVistaSP1) return "Microsoft Windows Vista, Service Pack 1"; - if (IsWindowsVistaSP2) return "Microsoft Windows Vista, Service Pack 2"; - if (IsWindows7) return "Microsoft Windows 7"; - if (IsWindows7SP1) return "Microsoft Windows 7, Service Pack 1"; - if (IsWindows8) return "Microsoft Windows 8"; - if (IsWindows8_1) return "Microsoft Windows 8.1"; - if (IsWindows10) return "Microsoft Windows 10"; - return "Unsupported version of Microsoft Windows."; + // Start from higher to lower + for (auto release = rbegin(windowsReleases); release != rend(windowsReleases); ++release) { + std::string previewText = release->first; + WindowsReleaseInfo releaseInfo = release->second; + bool buildMatch = DoesVersionMatchWindows(releaseInfo); + if (buildMatch) { + return previewText; + } + } + + return "Unknown version of Microsoft Windows."; } std::string GetWindowsSystemArchitecture() { diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 95ac55f4eb..52d3757566 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -25,6 +25,7 @@ #include "Common/System/Display.h" #include "Common/System/NativeApp.h" #include "Common/System/Request.h" +#include #include "Core/System.h" #include "Core/Loaders.h" @@ -348,7 +349,7 @@ std::string System_GetProperty(SystemProperty prop) { static bool hasCheckedGPUDriverVersion = false; switch (prop) { case SYSPROP_NAME: - return "Windows 10 Universal"; + return GetWindowsVersion(); case SYSPROP_LANGREGION: return langRegion; case SYSPROP_CLIPBOARD_TEXT: