Index: ps/trunk/source/lib/sysdep/os/win/wposix/wutsname.cpp =================================================================== --- ps/trunk/source/lib/sysdep/os/win/wposix/wutsname.cpp (revision 24237) +++ ps/trunk/source/lib/sysdep/os/win/wposix/wutsname.cpp (revision 24238) @@ -1,65 +1,84 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "precompiled.h" -#include "lib/sysdep/os/win/wposix/wutsname.h" +#include "lib/sysdep/os/win/wposix/wutsname.h" #include "lib/sysdep/os/win/wutil.h" // WinScopedPreserveLastError #include "lib/sysdep/os/win/wversion.h" // wversion_Family +#include +#include +/** + * Taken and modified from: https://stackoverflow.com/questions/32115255/c-how-to-detect-windows-10 + */ int uname(struct utsname* un) { - OSVERSIONINFOW vi = { sizeof(OSVERSIONINFOW) }; - GetVersionExW(&vi); + WUTIL_FUNC(pRtlGetVersion, NTSTATUS, (LPOSVERSIONINFOEXW)); + WUTIL_IMPORT_NTDLL(RtlGetVersion , pRtlGetVersion); + + if (!pRtlGetVersion) + return -1; + + OSVERSIONINFOEXW osInfo = { sizeof(OSVERSIONINFOEXW) }; + pRtlGetVersion(&osInfo); + std::ostringstream stream; + + // OS Implementation name + if (osInfo.dwMajorVersion >= 10) + { + stream << "Win" << osInfo.dwMajorVersion; + } + else + stream << wversion_Family() << "\0"; + + sprintf_s(un->sysname, ARRAY_SIZE(un->sysname), "%s", stream.str().c_str()); - // OS implementation name - sprintf_s(un->sysname, ARRAY_SIZE(un->sysname), "%ls", wversion_Family()); - // release info - const wchar_t* vs = vi.szCSDVersion; + // OS Service Pack int sp; - if(swscanf_s(vs, L"Service Pack %d", &sp) == 1) + if (swscanf_s(osInfo.szCSDVersion, L"Service Pack %d", &sp) == 1) sprintf_s(un->release, ARRAY_SIZE(un->release), "SP %d", sp); else un->release[0] = '\0'; - // version - sprintf_s(un->version, ARRAY_SIZE(un->version), "%ls.%lu", wversion_String(), vi.dwBuildNumber & 0xFFFF); + // OS Version. + sprintf_s(un->version, ARRAY_SIZE(un->version), "%lu.%lu.%lu", osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber); // node name { WinScopedPreserveLastError s; // GetComputerName DWORD bufSize = sizeof(un->nodename); WARN_IF_FALSE(GetComputerNameA(un->nodename, &bufSize)); } // hardware type SYSTEM_INFO si; - GetSystemInfo(&si); - if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + GetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) strcpy_s(un->machine, ARRAY_SIZE(un->machine), "x64"); else strcpy_s(un->machine, ARRAY_SIZE(un->machine), "x86"); return 0; } Index: ps/trunk/source/lib/sysdep/os/win/wutil.h =================================================================== --- ps/trunk/source/lib/sysdep/os/win/wutil.h (revision 24237) +++ ps/trunk/source/lib/sysdep/os/win/wutil.h (revision 24238) @@ -1,209 +1,213 @@ /* Copyright (C) 2020 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * various Windows-specific utilities */ #ifndef INCLUDED_WUTIL #define INCLUDED_WUTIL #ifdef _MSC_VER # pragma warning(disable:4091) // hides previous local declaration #endif #include "lib/os_path.h" #include "lib/sysdep/os/win/win.h" template bool wutil_IsValidHandle(H h) { return h != 0 && h != INVALID_HANDLE_VALUE; } //----------------------------------------------------------------------------- // dynamic linking // define a function pointer (optionally prepend 'static') #define WUTIL_FUNC(varName, ret, params)\ ret (WINAPI* varName) params // rationale: // - splitting up WUTIL_FUNC and WUTIL_IMPORT is a bit verbose in // the common case of a local function pointer definition, // but allows one-time initialization of static variables. // - differentiating between procName and varName allows searching // for the actual definition of the function pointer in the code. // - a cast would require passing in ret/params. // - writing a type-punned pointer breaks strict-aliasing rules. #define WUTIL_IMPORT(hModule, procName, varName)\ STMT(\ const FARPROC f = GetProcAddress(hModule, #procName);\ memcpy(&varName, &f, sizeof(FARPROC));\ ) // note: Kernel32 is guaranteed to be loaded, so we don't // need to LoadLibrary and FreeLibrary. #define WUTIL_IMPORT_KERNEL32(procName, varName)\ WUTIL_IMPORT(GetModuleHandleW(L"kernel32.dll"), procName, varName) +// note: ntdll is guaranteed to be loaded, so we don't +// need to LoadLibrary and FreeLibrary. +#define WUTIL_IMPORT_NTDLL(procName, varName)\ + WUTIL_IMPORT(GetModuleHandleW(L"ntdll.dll"), procName, varName) //----------------------------------------------------------------------------- // safe allocator extern void* wutil_Allocate(size_t size); extern void wutil_Free(void* p); //----------------------------------------------------------------------------- // locks // critical sections used by win-specific code enum WinLockId { WDBG_SYM_CS, // protects (non-reentrant) dbghelp.dll WDIR_WATCH_CS, NUM_CS }; extern void wutil_Lock(WinLockId id); extern void wutil_Unlock(WinLockId id); // used in a desperate attempt to avoid deadlock in wseh. extern bool wutil_IsLocked(WinLockId id); class WinScopedLock { public: WinScopedLock(WinLockId id) : m_id(id) { wutil_Lock(m_id); } ~WinScopedLock() { wutil_Unlock(m_id); } private: WinLockId m_id; }; //----------------------------------------------------------------------------- // errors /** * some WinAPI functions SetLastError(0) on success, which is bad because * it can hide previous errors. this class takes care of restoring the * previous value. **/ class WinScopedPreserveLastError { public: WinScopedPreserveLastError() : m_lastError(GetLastError()) { SetLastError(0); } ~WinScopedPreserveLastError() { if(m_lastError != 0 && GetLastError() == 0) SetLastError(m_lastError); } private: DWORD m_lastError; }; /** * @return the Status equivalent of GetLastError(), or ERR::FAIL if * there's no equivalent. * SetLastError(0) should be called before the Windows function to * make sure no stale errors are returned. **/ extern Status StatusFromWin(); //----------------------------------------------------------------------------- // command line extern int wutil_argc(); extern wchar_t** wutil_argv(); extern bool wutil_HasCommandLineArgument(const wchar_t* arg); //----------------------------------------------------------------------------- // directories extern const OsPath& wutil_SystemPath(); extern const OsPath& wutil_ExecutablePath(); extern const OsPath& wutil_LocalAppdataPath(); extern const OsPath& wutil_RoamingAppdataPath(); extern const OsPath& wutil_PersonalPath(); //----------------------------------------------------------------------------- // Wow64 extern bool wutil_IsWow64(); class WinScopedDisableWow64Redirection { public: WinScopedDisableWow64Redirection(); ~WinScopedDisableWow64Redirection(); private: void* m_wasRedirectionEnabled; }; //----------------------------------------------------------------------------- LIB_API Status wutil_SetPrivilege(const wchar_t* privilege, bool enable); /** * @return module handle of lib code (that of the main EXE if * linked statically, otherwise the DLL). * this is necessary for the error dialog. **/ extern HMODULE wutil_LibModuleHandle(); /** * @return handle to the first window owned by the current process, or * 0 if none exist (e.g. it hasn't yet created one). * * enumerates all top-level windows and stops if PID matches. * once this function returns a non-NULL handle, it will always * return that cached value. **/ extern HWND wutil_AppWindow(); #endif // #ifndef INCLUDED_WUTIL Index: ps/trunk/source/lib/sysdep/os/win/wversion.cpp =================================================================== --- ps/trunk/source/lib/sysdep/os/win/wversion.cpp (revision 24237) +++ ps/trunk/source/lib/sysdep/os/win/wversion.cpp (revision 24238) @@ -1,108 +1,108 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "precompiled.h" #include "lib/sysdep/os/win/wversion.h" #include "lib/sysdep/os/win/win.h" #include "lib/sysdep/os/win/winit.h" #include WINIT_REGISTER_EARLY_INIT(wversion_Init); static wchar_t windowsVersionString[20]; static size_t windowsVersion; // see WVERSION_* -const wchar_t* wversion_Family() +const char* wversion_Family() { ENSURE(windowsVersion != 0); switch(windowsVersion) { case WVERSION_2K: - return L"Win2k"; + return "Win2k"; case WVERSION_XP: - return L"WinXP"; + return "WinXP"; case WVERSION_XP64: - return L"WinXP64"; + return "WinXP64"; case WVERSION_VISTA: - return L"Vista"; + return "Vista"; case WVERSION_7: - return L"Win7"; + return "Win7"; case WVERSION_8: - return L"Win8"; + return "Win8"; case WVERSION_8_1: - return L"Win8.1"; + return "Win8.1"; case WVERSION_10: - return L"Win10"; + return "Win10"; default: - return L"Windows"; + return "Windows"; } } const wchar_t* wversion_String() { ENSURE(windowsVersionString[0] != '\0'); return windowsVersionString; } size_t wversion_Number() { ENSURE(windowsVersion != 0); return windowsVersion; } static Status wversion_Init() { // note: don't use GetVersion[Ex] because it gives the version of the // emulated OS when running an app with compatibility shims enabled. HKEY hKey; if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { DWORD size = sizeof(windowsVersionString); (void)RegQueryValueExW(hKey, L"CurrentVersion", 0, 0, (LPBYTE)windowsVersionString, &size); unsigned major = 0, minor = 0; // ICC 11.1.082 generates incorrect code for the following: // const int ret = swscanf_s(windowsVersionString, L"%u.%u", &major, &minor); std::wstringstream ss(windowsVersionString); ss >> major; wchar_t dot; ss >> dot; ENSURE(dot == '.'); ss >> minor; ENSURE(4 <= major && major <= 0xFF); ENSURE(minor <= 0xFF); windowsVersion = (major << 8) | minor; RegCloseKey(hKey); } else DEBUG_WARN_ERR(ERR::LOGIC); return INFO::OK; } Index: ps/trunk/source/lib/sysdep/os/win/wversion.h =================================================================== --- ps/trunk/source/lib/sysdep/os/win/wversion.h (revision 24237) +++ ps/trunk/source/lib/sysdep/os/win/wversion.h (revision 24238) @@ -1,51 +1,51 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef INCLUDED_WVERSION #define INCLUDED_WVERSION /** * @return CurrentVersion string from registry **/ extern const wchar_t* wversion_String(); // (same format as WINVER) const size_t WVERSION_2K = 0x0500; const size_t WVERSION_XP = 0x0501; const size_t WVERSION_XP64 = 0x0502; const size_t WVERSION_VISTA = 0x0600; const size_t WVERSION_7 = 0x0601; const size_t WVERSION_8 = 0x0602; const size_t WVERSION_8_1 = 0x0603; const size_t WVERSION_10 = 0x0604; /** * @return one of the above WVERSION* values **/ LIB_API size_t wversion_Number(); /** * @return short textual representation of the version **/ -extern const wchar_t* wversion_Family(); +extern const char* wversion_Family(); #endif // #ifndef INCLUDED_WVERSION