Skip to content

Commit

Permalink
Fix platform version for Windows 10/11 using RtlGetVersion()
Browse files Browse the repository at this point in the history
We've added a new show_platform example to check the reported
platform by the base::get_platform() function.
  • Loading branch information
dacap committed Feb 20, 2024
1 parent 763ce04 commit 58723a9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
27 changes: 24 additions & 3 deletions base/platform.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// LAF Base Library
// Copyright (c) 2021 Igara Studio S.A.
// Copyright (c) 2021-2024 Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
Expand All @@ -12,6 +12,8 @@

#if LAF_WINDOWS
#include <windows.h>

typedef LONG (WINAPI* RtlGetVersion_Func)(OSVERSIONINFOEX*);
#elif LAF_LINUX // Unix-like system
#include <sys/utsname.h>
#endif
Expand All @@ -29,9 +31,28 @@ Platform get_platform()

OSVERSIONINFOEX osv;
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
::GetVersionEx((OSVERSIONINFO*)&osv);

p.osVer = Version(osv.dwMajorVersion, osv.dwMinorVersion, 0, 0);
// It looks like GetVersionEx() returns 6.2 for all Windows versions
// after Windows 8 and RtlGetVersion() returns the correct version
// and build number for Windows 10 and 11.
static const auto fnRtlGetVersion = reinterpret_cast<RtlGetVersion_Func>(
GetProcAddress(GetModuleHandle(L"ntdll.dll"),
"RtlGetVersion"));
if (!fnRtlGetVersion ||
!fnRtlGetVersion(&osv) ||
!osv.dwMajorVersion) {
OSVERSIONINFOEX osv;
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
// Ignore deprecated function warning
#pragma warning(push)
#pragma warning(disable : 4996)
GetVersionEx((OSVERSIONINFO*)&osv);
#pragma warning(pop)
}

p.osVer = Version(osv.dwMajorVersion,
osv.dwMinorVersion,
osv.dwBuildNumber, 0);
switch (osv.wProductType) {
case VER_NT_DOMAIN_CONTROLLER:
case VER_NT_SERVER:
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ if(LAF_BACKEND STREQUAL "skia")
laf_add_example(multiple_windows GUI)
laf_add_example(panviewport GUI)
laf_add_example(shader GUI)
laf_add_example(show_platform CONSOLE)
endif()
50 changes: 50 additions & 0 deletions examples/show_platform.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// LAF Library
// Copyright (c) 2024 Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#include "base/platform.h"

#include <cstdio>

int app_main(int argc, char* argv[])
{
base::Platform p = base::get_platform();
switch (p.os) {
#if LAF_WINDOWS
case base::Platform::OS::Windows:
std::printf(
"Windows v%s%s%s",
p.osVer.str().c_str(),
p.isWow64 ? " WoW64": "",
(p.wineVer ? (std::string(" WINE v") + p.wineVer).c_str(): ""));
break;
#endif
case base::Platform::OS::macOS:
std::printf(
"macOS v%s",
p.osVer.str().c_str());
break;
#if LAF_LINUX
case base::Platform::OS::Linux:
std::printf("Linux %s", p.distroName.c_str());
if (!p.distroVer.empty())
std::printf(" %s", p.distroVer.c_str());
break;
#endif
}
switch (p.arch) {
case base::Platform::Arch::x86:
std::printf(" (x86)");
break;
case base::Platform::Arch::x64:
std::printf(" (x64)");
break;
case base::Platform::Arch::arm64:
std::printf(" (arm64)");
break;
}
std::printf("\n");
return 0;
}

0 comments on commit 58723a9

Please sign in to comment.