mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-24 19:54:25 -04:00
[misc] improve Windows version detection
* Also update README.txt * Closes #220
This commit is contained in:
parent
c6da7311b0
commit
86d5f02a20
6 changed files with 132 additions and 75 deletions
150
src/stdfn.c
150
src/stdfn.c
|
@ -29,53 +29,119 @@
|
|||
#include "resource.h"
|
||||
#include "localization.h"
|
||||
|
||||
// Must be in the same order as enum WindowsVersion
|
||||
static const char* WindowsVersionName[WINDOWS_MAX] = {
|
||||
"Undefined",
|
||||
"Windows 2000 or earlier (unsupported)",
|
||||
"Windows XP",
|
||||
"Windows 2003 (or XP x64)",
|
||||
"Windows Vista",
|
||||
"Windows 7",
|
||||
"Windows 8 or later",
|
||||
};
|
||||
int nWindowsVersion = WINDOWS_UNDEFINED;
|
||||
char WindowsVersionStr[128] = "Windows ";
|
||||
|
||||
enum WindowsVersion nWindowsVersion = WINDOWS_UNDEFINED;
|
||||
|
||||
/*
|
||||
* Detect Windows version
|
||||
*/
|
||||
enum WindowsVersion DetectWindowsVersion(void)
|
||||
static BOOL is_x64(void)
|
||||
{
|
||||
OSVERSIONINFO OSVersion;
|
||||
|
||||
memset(&OSVersion, 0, sizeof(OSVERSIONINFO));
|
||||
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (GetVersionEx(&OSVersion) == 0)
|
||||
return WINDOWS_UNDEFINED;
|
||||
if (OSVersion.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
return WINDOWS_UNSUPPORTED;
|
||||
// See the Remarks section from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833.aspx
|
||||
if ((OSVersion.dwMajorVersion < 5) || ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 0)))
|
||||
return WINDOWS_UNSUPPORTED; // Win2k or earlier
|
||||
if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 1))
|
||||
return WINDOWS_XP;
|
||||
if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 2))
|
||||
return WINDOWS_2003;
|
||||
if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 0))
|
||||
return WINDOWS_VISTA;
|
||||
if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 1))
|
||||
return WINDOWS_7;
|
||||
if ((OSVersion.dwMajorVersion > 6) || ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion >= 2)))
|
||||
return WINDOWS_8_OR_LATER;
|
||||
return WINDOWS_UNSUPPORTED;
|
||||
BOOL ret = FALSE;
|
||||
BOOL (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL;
|
||||
// Detect if we're running a 32 or 64 bit system
|
||||
if (sizeof(uintptr_t) < 8) {
|
||||
pIsWow64Process = (BOOL (__stdcall *)(HANDLE, PBOOL))
|
||||
GetProcAddress(GetModuleHandleA("KERNEL32"), "IsWow64Process");
|
||||
if (pIsWow64Process != NULL) {
|
||||
(*pIsWow64Process)(GetCurrentProcess(), &ret);
|
||||
}
|
||||
} else {
|
||||
ret = TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* PrintWindowsVersion(enum WindowsVersion version)
|
||||
// From smartmontools os_win32.cpp
|
||||
void GetWindowsVersion(void)
|
||||
{
|
||||
if ((version < 0) || (version >= WINDOWS_MAX))
|
||||
version = WINDOWS_UNDEFINED;
|
||||
return WindowsVersionName[version];
|
||||
OSVERSIONINFOEXA vi, vi2;
|
||||
const char* w = 0;
|
||||
const char* w64 = "32 bit";
|
||||
char* vptr;
|
||||
size_t vlen;
|
||||
unsigned major, minor;
|
||||
ULONGLONG major_equal, minor_equal;
|
||||
BOOL ws;
|
||||
|
||||
nWindowsVersion = WINDOWS_UNDEFINED;
|
||||
safe_strcpy(WindowsVersionStr, sizeof(WindowsVersionStr), "Windows Undefined");
|
||||
|
||||
memset(&vi, 0, sizeof(vi));
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
|
||||
memset(&vi, 0, sizeof(vi));
|
||||
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
|
||||
return;
|
||||
}
|
||||
|
||||
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
||||
|
||||
if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {
|
||||
// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
|
||||
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
|
||||
|
||||
major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
for (major = vi.dwMajorVersion; major <= 9; major++) {
|
||||
memset(&vi2, 0, sizeof(vi2));
|
||||
vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;
|
||||
if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
|
||||
continue;
|
||||
if (vi.dwMajorVersion < major) {
|
||||
vi.dwMajorVersion = major; vi.dwMinorVersion = 0;
|
||||
}
|
||||
|
||||
minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
|
||||
for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
|
||||
memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);
|
||||
vi2.dwMinorVersion = minor;
|
||||
if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
|
||||
continue;
|
||||
vi.dwMinorVersion = minor;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
|
||||
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
||||
nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
||||
switch (nWindowsVersion) {
|
||||
case 0x50: w = "2000";
|
||||
break;
|
||||
case 0x51: w = "XP";
|
||||
break;
|
||||
case 0x52: w = (!GetSystemMetrics(89)?"2003":"2003_R2");
|
||||
break;
|
||||
case 0x60: w = (ws?"Vista":"2008");
|
||||
break;
|
||||
case 0x61: w = (ws?"7":"2008_R2");
|
||||
break;
|
||||
case 0x62: w = (ws?"8":"2012");
|
||||
break;
|
||||
case 0x63: w = (ws?"8.1":"2012_R2");
|
||||
break;
|
||||
default:
|
||||
nWindowsVersion = WINDOWS_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_x64())
|
||||
w64 = "64-bit";
|
||||
|
||||
vptr = &WindowsVersionStr[sizeof("Windows ") - 1];
|
||||
vlen = sizeof(WindowsVersionStr) - sizeof("Windows ") - 1;
|
||||
if (!w)
|
||||
safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId==VER_PLATFORM_WIN32_NT?"NT":"??"),
|
||||
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
|
||||
else if (vi.wServicePackMinor)
|
||||
safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);
|
||||
else if (vi.wServicePackMajor)
|
||||
safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
|
||||
else
|
||||
safe_sprintf(vptr, vlen, "%s %s", w, w64);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue