| /** | |
| * This file has no copyright assigned and is placed in the Public Domain. | |
| * This file is part of the mingw-w64 runtime package. | |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. | |
| */ | |
| #include <windows.h> | |
| static unsigned int get_osplatform_helper(void) | |
| { | |
| OSVERSIONINFOA osvi; | |
| #ifdef __i386__ | |
| HMODULE kernel32; | |
| WINBOOL (WINAPI *kernel32_GetVersionExA)(LPOSVERSIONINFOA); | |
| DWORD raw_ver; | |
| WORD maj_ver; | |
| BOOL is_nt; | |
| #endif | |
| osvi.dwOSVersionInfoSize = sizeof(osvi); | |
| #ifdef __i386__ | |
| /* GetVersionExA is not available on older WinNT and Win32s versions. When | |
| * it is available, it returns a full 32-bit platform ID (2^32 possible values). | |
| * GetVersion uses its highest bit to identify whether the system is WinNT | |
| * and its low 8 bits to return the major OS system version (Win9x starts | |
| * at 4). So load GetVersionExA dynamically, and on failure fall back to | |
| * GetVersion. | |
| */ | |
| kernel32 = GetModuleHandleA("kernel32.dll"); | |
| kernel32_GetVersionExA = kernel32 ? GetProcAddress(kernel32, "GetVersionExA") : NULL; | |
| if (kernel32_GetVersionExA && kernel32_GetVersionExA(&osvi)) | |
| return osvi.dwPlatformId; | |
| raw_ver = GetVersion(); | |
| maj_ver = raw_ver & 0xff; | |
| is_nt = !(raw_ver >> 31); | |
| if (is_nt) | |
| return VER_PLATFORM_WIN32_NT; | |
| else if (maj_ver >= 4) | |
| return VER_PLATFORM_WIN32_WINDOWS; | |
| else | |
| return VER_PLATFORM_WIN32s; | |
| #else | |
| /* On non-i386 platforms, GetVersionExA is always available. | |
| * In case of failure, return value 2 (WinNT) which is a sane default. | |
| * Value 0 (Win32s) is not a sane default as Win32s is i386-only. | |
| */ | |
| if (GetVersionExA(&osvi)) | |
| return osvi.dwPlatformId; | |
| else | |
| return VER_PLATFORM_WIN32_NT; | |
| #endif | |
| } | |
| #ifndef GET_OSPLATFORM_HELPER_ONLY | |
| #undef _osplatform | |
| static unsigned int _osplatform; | |
| unsigned int* __cdecl __p__osplatform(void); | |
| unsigned int* __cdecl __p__osplatform(void) | |
| { | |
| static long init = 0; | |
| if (!init) | |
| { | |
| (void)InterlockedExchange((long*)&_osplatform, get_osplatform_helper()); | |
| (void)InterlockedExchange(&init, 1); | |
| } | |
| return &_osplatform; | |
| } | |
| unsigned int* (__cdecl *__MINGW_IMP_SYMBOL(__p__osplatform))(void) = __p__osplatform; | |
| #endif |