{
HMODULE w32skrnl;
LPVOID (WINAPI *GetThunkBuff)(VOID);
- OSVERSIONINFOA version;
LPVOID buf_ptr;
+ DWORD raw_version;
+ USHORT build_num;
+ BOOL build_num_valid;
a->debug("resolving DPMI function via GetThunkBuff() function from w32skrnl.dll...");
w32skrnl = GetModuleHandleA("w32skrnl.dll");
return 0;
}
- version.dwOSVersionInfoSize = sizeof(version);
- if (!GetVersionExA(&version))
- {
- a->debug("failed: cannot detect version.");
- errno = EINVAL;
- return 0;
- }
+ raw_version = GetVersion();
+ build_num = (raw_version >> 16) & 0x3FFF;
+ build_num_valid = ((raw_version & 0xC0000000) == 0x80000000 && (raw_version & 0xff) < 4);
- /* Versions before 1.1 (1.1.88) are not supported. */
- if (version.dwMajorVersion < 1 || (version.dwMajorVersion == 1 && version.dwMinorVersion < 1))
+ /* Builds older than 88 (match version 1.1) are not supported. */
+ if (build_num_valid && build_num < 88)
{
a->debug("failed: found old incompatible version.");
errno = ENOENT;
}
/*
- * Versions 1.1 (1.1.88) - 1.15 (1.15.103) have DPMI function at offset 0xa0.
- * Versions 1.15a (1.15.111) - 1.30c (1.30.172) have DPMI function at offset 0xa4.
+ * Builds 88-103 (match versions 1.1-1.15) have DPMI function at offset 0xa0.
+ * Builds 111-172 (match versions 1.15a-1.30c) have DPMI function at offset 0xa4.
+ * If build number is unavailable then expects the latest version.
*/
- if (version.dwMajorVersion > 1 ||
- (version.dwMajorVersion == 1 && version.dwMinorVersion > 15) ||
- (version.dwMajorVersion == 1 && version.dwMinorVersion == 15 && version.dwBuildNumber >= 111))
- physmem->w32skrnl_dpmi_lcall_ptr = (LPVOID)((BYTE *)buf_ptr + 0xa4);
- else
- physmem->w32skrnl_dpmi_lcall_ptr = (LPVOID)((BYTE *)buf_ptr + 0xa0);
+ physmem->w32skrnl_dpmi_lcall_ptr = (LPVOID)((BYTE *)buf_ptr + ((build_num_valid && build_num < 111) ? 0xa0 : 0xa4));
a->debug("success.");
return 1;
BOOL
win32_is_non_nt_system(void)
{
- OSVERSIONINFOA version;
+#if defined(_M_IX86) || defined(__i386__)
+ /* Highest bit set indicates the non-NT system. */
+ return GetVersion() >> 31;
+#else
+ /* Non-i386 systems are not pre-NT compatible. */
+ return FALSE;
+#endif
+}
+
+static BOOL
+win32_is_nt40_system(void)
+{
+#if defined(_M_IX86) || defined(__i386__)
+ /* Check for Windows NT 4.0. Highest two bits are zero for NT and in lowest 8 bits is major os version. */
+ DWORD raw_version = GetVersion();
+ return (raw_version >> 30) == 0 && (raw_version & 0xff) >= 4;
+#else
+ /* Modern non-i386 systems have at least version 5.2 (XP x64). */
+ return TRUE;
+#endif
+}
+
+static BOOL
+win32_is_win2k_system(void)
+{
+#if defined(_M_IX86) || defined(__i386__)
+ /* Check for Windows 2000 (NT 5.0). Highest two bits are zero for NT and in lowest 8 bits is major os version. */
+ DWORD raw_version = GetVersion();
+ return (raw_version >> 30) == 0 && (raw_version & 0xff) >= 5;
+#else
+ /* Modern non-i386 systems have at least version 5.2 (XP x64). */
+ return TRUE;
+#endif
+}
+
+BOOL
+win32_is_vista_system(void)
+{
+#if defined(_M_IX86) || defined(__i386__)
+ /* Check for Windows Vista (NT 6.0). Highest two bits are zero for NT and in lowest 8 bits is major os version. */
+ DWORD raw_version = GetVersion();
+ return (raw_version >> 30) == 0 && (raw_version & 0xff) >= 6;
+#else
+ /* Check for Windows Vista (NT 6.0). */
+ OSVERSIONINFO version;
version.dwOSVersionInfoSize = sizeof(version);
- return GetVersionExA(&version) && version.dwPlatformId < VER_PLATFORM_WIN32_NT;
+ if (!GetVersionEx(&version) ||
+ version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+ version.dwMajorVersion >= 6)
+ return FALSE;
+ else
+ return TRUE;
+#endif
}
+#ifndef _WIN64
+static BOOL
+win32_is_win8_system(void)
+{
+#if defined(_M_IX86) || defined(__i386__)
+ /* Check for Windows 8 (NT 6.2). Highest two bits are zero for NT and in lowest 16 bits are minor<<8 + major os version. */
+ DWORD raw_version = GetVersion();
+ if ((raw_version >> 30) != 0 ||
+ (raw_version & 0xff) < 6 ||
+ ((raw_version & 0xff) == 6 && ((raw_version >> 8) & 0xff) < 2))
+ return FALSE;
+ else
+ return TRUE;
+#else
+ /* Check for Windows 8 (NT 6.2). */
+ OSVERSIONINFO version;
+ version.dwOSVersionInfoSize = sizeof(version);
+ if (!GetVersionEx(&version) ||
+ version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+ version.dwMajorVersion < 6 ||
+ (version.dwMajorVersion == 6 && version.dwMinorVersion < 2))
+ return FALSE;
+ else
+ return TRUE;
+#endif
+}
+#endif
+
BOOL
win32_is_32bit_on_64bit_system(void)
{
#ifdef _WIN64
return FALSE;
#else
- OSVERSIONINFOA version;
-
- /* Check for Windows 8 (NT 6.2). */
- version.dwOSVersionInfoSize = sizeof(version);
- if (!GetVersionExA(&version) ||
- version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
- version.dwMajorVersion < 6 ||
- (version.dwMajorVersion == 6 && version.dwMinorVersion < 2))
- return FALSE;
-
- return win32_is_32bit_on_64bit_system();
+ return win32_is_win8_system() && win32_is_32bit_on_64bit_system();
#endif
}
win32_change_error_mode(UINT new_mode)
{
SetThreadErrorModeProt MySetThreadErrorMode = NULL;
- OSVERSIONINFOA version;
HMODULE kernel32;
HMODULE ntdll;
DWORD old_mode;
* On Windows NT 4.0+ systems fallback to thread HardErrorMode API.
* It depends on architecture specific offset for HardErrorMode field in TEB.
*/
- version.dwOSVersionInfoSize = sizeof(version);
- if (GetVersionExA(&version) &&
- version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
- version.dwMajorVersion >= 4)
+ if (win32_is_nt40_system())
{
ULONG *hard_error_mode_ptr = (ULONG *)((BYTE *)NtCurrentTeb() + TEB_HARD_ERROR_MODE_OFFSET);
old_mode = *hard_error_mode_ptr;
SECURITY_DESCRIPTOR_CONTROL bits_mask;
SECURITY_DESCRIPTOR_CONTROL bits_set;
SECURITY_DESCRIPTOR_CONTROL control;
- OSVERSIONINFO version;
HMODULE advapi32;
DWORD revision;
* older versions of advapi32.dll library, so resolve it at runtime.
*/
- version.dwOSVersionInfoSize = sizeof(version);
- if (!GetVersionEx(&version) ||
- version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
- version.dwMajorVersion < 5)
+ if (!win32_is_win2k_system())
return TRUE;
if (!GetSecurityDescriptorControl(security_descriptor, &control, &revision))
{
BOOL revert_only_privilege;
LUID luid_debug_privilege;
- OSVERSIONINFO version;
DWORD process_right;
HANDLE revert_token;
HANDLE process;
* PROCESS_QUERY_LIMITED_INFORMATION right on older systems than
* Windows Vista (NT 6.0).
*/
- version.dwOSVersionInfoSize = sizeof(version);
- if (GetVersionEx(&version) &&
- version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
- version.dwMajorVersion >= 6)
+ if (win32_is_vista_system())
process_right = PROCESS_QUERY_LIMITED_INFORMATION;
else
process_right = PROCESS_QUERY_INFORMATION;