mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[misc] further Windows version and arch detection improvements
* Now also populate the underlying Windows arch in the version struct * Also fix MinGW warnings
This commit is contained in:
parent
4dd40bba2f
commit
a6451c6fc7
5 changed files with 127 additions and 108 deletions
24
src/net.c
24
src/net.c
|
@ -265,6 +265,13 @@ static char* GetShortName(const char* url)
|
||||||
return short_name;
|
return short_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline BOOL is_WOW64(void)
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
IsWow64Process(GetCurrentProcess(), &ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Open an Internet session
|
// Open an Internet session
|
||||||
static HINTERNET GetInternetSession(BOOL bRetry)
|
static HINTERNET GetInternetSession(BOOL bRetry)
|
||||||
{
|
{
|
||||||
|
@ -307,9 +314,9 @@ static HINTERNET GetInternetSession(BOOL bRetry)
|
||||||
SetLastError(ERROR_INTERNET_DISCONNECTED);
|
SetLastError(ERROR_INTERNET_DISCONNECTED);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)",
|
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)",
|
||||||
rufus_version[0], rufus_version[1], rufus_version[2],
|
rufus_version[0], rufus_version[1], rufus_version[2],
|
||||||
WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
|
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||||
hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||||
// Set the timeouts
|
// Set the timeouts
|
||||||
pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
|
pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
|
||||||
|
@ -695,9 +702,9 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
hostname[sizeof(hostname)-1] = 0;
|
hostname[sizeof(hostname)-1] = 0;
|
||||||
|
|
||||||
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)",
|
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)",
|
||||||
rufus_version[0], rufus_version[1], rufus_version[2],
|
rufus_version[0], rufus_version[1], rufus_version[2],
|
||||||
WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
|
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||||
hSession = GetInternetSession(FALSE);
|
hSession = GetInternetSession(FALSE);
|
||||||
if (hSession == NULL)
|
if (hSession == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -763,7 +770,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
||||||
}
|
}
|
||||||
if (dwStatus != 200) {
|
if (dwStatus != 200) {
|
||||||
vuprintf("Could not find a %s version file on server %s", channel[k], server_url);
|
vuprintf("Could not find a %s version file on server %s", channel[k], server_url);
|
||||||
if ((releases_only) || (k+1 >= ARRAYSIZE(channel)))
|
if ((releases_only) || (k + 1 >= ARRAYSIZE(channel)))
|
||||||
goto out;
|
goto out;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -777,14 +784,15 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
||||||
if ( (!pfHttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL))
|
if ( (!pfHttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL))
|
||||||
|| (!SystemTimeToFileTime(&ServerTime, &FileTime)) )
|
|| (!SystemTimeToFileTime(&ServerTime, &FileTime)) )
|
||||||
goto out;
|
goto out;
|
||||||
server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
|
server_time = ((((int64_t)FileTime.dwHighDateTime) << 32) + FileTime.dwLowDateTime) / 10000000;
|
||||||
vvuprintf("Server time: %" PRId64, server_time);
|
vvuprintf("Server time: %" PRId64, server_time);
|
||||||
// Always store the server response time - the only clock we trust!
|
// Always store the server response time - the only clock we trust!
|
||||||
WriteSetting64(SETTING_LAST_UPDATE, server_time);
|
WriteSetting64(SETTING_LAST_UPDATE, server_time);
|
||||||
// Might as well let the user know
|
// Might as well let the user know
|
||||||
if (!force_update_check) {
|
if (!force_update_check) {
|
||||||
if ((local_time > server_time + 600) || (local_time < server_time - 600)) {
|
if ((local_time > server_time + 600) || (local_time < server_time - 600)) {
|
||||||
uprintf("IMPORTANT: Your local clock is more than 10 minutes in the %s. Unless you fix this, " APPLICATION_NAME " may not be able to check for updates...",
|
uprintf("IMPORTANT: Your local clock is more than 10 minutes in the %s. Unless you fix this, "
|
||||||
|
APPLICATION_NAME " may not be able to check for updates...",
|
||||||
(local_time > server_time + 600)?"future":"past");
|
(local_time > server_time + 600)?"future":"past");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -794,7 +802,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
// Make sure the file is NUL terminated
|
// Make sure the file is NUL terminated
|
||||||
buf = (char*)calloc(dwTotalSize+1, 1);
|
buf = (char*)calloc(dwTotalSize + 1, 1);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
// This is a version file - we should be able to gulp it down in one go
|
// This is a version file - we should be able to gulp it down in one go
|
||||||
|
|
43
src/rufus.c
43
src/rufus.c
|
@ -1891,37 +1891,6 @@ static __inline const char* IsAlphaOrBeta(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline DWORD GetApplicationArch(void)
|
|
||||||
{
|
|
||||||
#if defined(_M_AMD64)
|
|
||||||
return IMAGE_FILE_MACHINE_AMD64;
|
|
||||||
#elif defined(_M_IX86)
|
|
||||||
return IMAGE_FILE_MACHINE_I386;
|
|
||||||
#elif defined(_M_ARM64)
|
|
||||||
return IMAGE_FILE_MACHINE_ARM64;
|
|
||||||
#elif defined(_M_ARM)
|
|
||||||
return IMAGE_FILE_MACHINE_ARM;
|
|
||||||
#else
|
|
||||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* GetArchName(USHORT uArch)
|
|
||||||
{
|
|
||||||
switch (uArch) {
|
|
||||||
case IMAGE_FILE_MACHINE_AMD64:
|
|
||||||
return "x64";
|
|
||||||
case IMAGE_FILE_MACHINE_I386:
|
|
||||||
return "x86";
|
|
||||||
case IMAGE_FILE_MACHINE_ARM64:
|
|
||||||
return "Arm64";
|
|
||||||
case IMAGE_FILE_MACHINE_ARM:
|
|
||||||
return "Arm";
|
|
||||||
default:
|
|
||||||
return "(Unknown Arch)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InitDialog(HWND hDlg)
|
static void InitDialog(HWND hDlg)
|
||||||
{
|
{
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
@ -2023,8 +1992,13 @@ static void InitDialog(HWND hDlg)
|
||||||
// Oh, and https://devblogs.microsoft.com/oldnewthing/20220209-00/?p=106239 is *WRONG*:
|
// Oh, and https://devblogs.microsoft.com/oldnewthing/20220209-00/?p=106239 is *WRONG*:
|
||||||
// GetNativeSystemInfo() will not tell you what the native system architecture is when
|
// GetNativeSystemInfo() will not tell you what the native system architecture is when
|
||||||
// running x86 code on ARM64. Instead you have to use IsWow64Process2(), which is only
|
// running x86 code on ARM64. Instead you have to use IsWow64Process2(), which is only
|
||||||
// available on Windows 10 1511 or later...
|
// available on Windows 10 1709 or later...
|
||||||
if ((pfIsWow64Process2 != NULL) && pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) {
|
if ((pfIsWow64Process2 != NULL) && pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) {
|
||||||
|
// x64 running emulated on ARM64 returns IMAGE_FILE_MACHINE_UNKNOWN for ProcessMachine
|
||||||
|
// because Microsoft does not consider it a WOW64 process. So we need to fix
|
||||||
|
// ProcessMachine ourselves to *ACTUALLY* return the bloody process machine...
|
||||||
|
if (ProcessMachine == IMAGE_FILE_MACHINE_UNKNOWN)
|
||||||
|
ProcessMachine = GetApplicationArch();
|
||||||
if ((NativeMachine == IMAGE_FILE_MACHINE_ARM || NativeMachine == IMAGE_FILE_MACHINE_ARM64) &&
|
if ((NativeMachine == IMAGE_FILE_MACHINE_ARM || NativeMachine == IMAGE_FILE_MACHINE_ARM64) &&
|
||||||
(ProcessMachine == IMAGE_FILE_MACHINE_I386 || ProcessMachine == IMAGE_FILE_MACHINE_AMD64))
|
(ProcessMachine == IMAGE_FILE_MACHINE_I386 || ProcessMachine == IMAGE_FILE_MACHINE_AMD64))
|
||||||
uprintf("Notice: Running emulated on %s platform", GetArchName(NativeMachine));
|
uprintf("Notice: Running emulated on %s platform", GetArchName(NativeMachine));
|
||||||
|
@ -3354,7 +3328,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE;
|
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE;
|
||||||
BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = IsRegistryNode(REGKEY_HKCU, vs_reg);
|
BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = IsRegistryNode(REGKEY_HKCU, vs_reg);
|
||||||
BOOL alt_pressed = FALSE, alt_command = FALSE;
|
BOOL alt_pressed = FALSE, alt_command = FALSE, is_WOW64 = FALSE;
|
||||||
BYTE *loc_data;
|
BYTE *loc_data;
|
||||||
DWORD loc_size, u = 0, size = sizeof(u);
|
DWORD loc_size, u = 0, size = sizeof(u);
|
||||||
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb";
|
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb";
|
||||||
|
@ -3440,7 +3414,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
static_strcpy(sysnative_dir, system_dir);
|
static_strcpy(sysnative_dir, system_dir);
|
||||||
// But if the app is 32 bit and the OS is 64 bit, Sysnative must differ from System32
|
// But if the app is 32 bit and the OS is 64 bit, Sysnative must differ from System32
|
||||||
#if (!defined(_WIN64) && !defined(BUILD64))
|
#if (!defined(_WIN64) && !defined(BUILD64))
|
||||||
if (is_x64()) {
|
IsWow64Process(GetCurrentProcess(), &is_WOW64);
|
||||||
|
if (is_WOW64) {
|
||||||
if (GetSystemWindowsDirectoryU(sysnative_dir, sizeof(sysnative_dir)) == 0) {
|
if (GetSystemWindowsDirectoryU(sysnative_dir, sizeof(sysnative_dir)) == 0) {
|
||||||
uprintf("Could not get Windows directory: %s", WindowsErrorString());
|
uprintf("Could not get Windows directory: %s", WindowsErrorString());
|
||||||
static_strcpy(sysnative_dir, "C:\\Windows");
|
static_strcpy(sysnative_dir, "C:\\Windows");
|
||||||
|
|
62
src/rufus.h
62
src/rufus.h
|
@ -476,6 +476,52 @@ typedef enum TASKBAR_PROGRESS_FLAGS
|
||||||
TASKBAR_PAUSED = 0x8
|
TASKBAR_PAUSED = 0x8
|
||||||
} TASKBAR_PROGRESS_FLAGS;
|
} TASKBAR_PROGRESS_FLAGS;
|
||||||
|
|
||||||
|
/* We can't use the Microsoft enums as we want to have RISC-V */
|
||||||
|
enum ArchType {
|
||||||
|
ARCH_UNKNOWN = 0,
|
||||||
|
ARCH_X86_32,
|
||||||
|
ARCH_X86_64,
|
||||||
|
ARCH_ARM_32,
|
||||||
|
ARCH_ARM_64,
|
||||||
|
ARCH_IA_64,
|
||||||
|
ARCH_RISCV_32,
|
||||||
|
ARCH_RISCV_64,
|
||||||
|
ARCH_RISCV_128,
|
||||||
|
ARCH_EBC,
|
||||||
|
ARCH_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
static __inline USHORT GetApplicationArch(void)
|
||||||
|
{
|
||||||
|
#if defined(_M_AMD64)
|
||||||
|
return IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
return IMAGE_FILE_MACHINE_I386;
|
||||||
|
#elif defined(_M_ARM64)
|
||||||
|
return IMAGE_FILE_MACHINE_ARM64;
|
||||||
|
#elif defined(_M_ARM)
|
||||||
|
return IMAGE_FILE_MACHINE_ARM;
|
||||||
|
#else
|
||||||
|
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char* GetArchName(USHORT uArch)
|
||||||
|
{
|
||||||
|
switch (uArch) {
|
||||||
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
|
return "x64";
|
||||||
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
|
return "x86";
|
||||||
|
case IMAGE_FILE_MACHINE_ARM64:
|
||||||
|
return "Arm64";
|
||||||
|
case IMAGE_FILE_MACHINE_ARM:
|
||||||
|
return "Arm";
|
||||||
|
default:
|
||||||
|
return "(Unknown Arch)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Windows versions */
|
/* Windows versions */
|
||||||
enum WindowsVersion {
|
enum WindowsVersion {
|
||||||
WINDOWS_UNDEFINED = 0,
|
WINDOWS_UNDEFINED = 0,
|
||||||
|
@ -491,26 +537,13 @@ enum WindowsVersion {
|
||||||
WINDOWS_MAX = 0xFFFF,
|
WINDOWS_MAX = 0xFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ArchType {
|
|
||||||
ARCH_UNKNOWN = 0,
|
|
||||||
ARCH_X86_32,
|
|
||||||
ARCH_X86_64,
|
|
||||||
ARCH_ARM_32,
|
|
||||||
ARCH_ARM_64,
|
|
||||||
ARCH_IA_64,
|
|
||||||
ARCH_RISCV_32,
|
|
||||||
ARCH_RISCV_64,
|
|
||||||
ARCH_RISCV_128,
|
|
||||||
ARCH_EBC,
|
|
||||||
ARCH_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD Version;
|
DWORD Version;
|
||||||
DWORD Major;
|
DWORD Major;
|
||||||
DWORD Minor;
|
DWORD Minor;
|
||||||
DWORD BuildNumber;
|
DWORD BuildNumber;
|
||||||
DWORD Edition;
|
DWORD Edition;
|
||||||
|
USHORT Arch;
|
||||||
char VersionStr[128];
|
char VersionStr[128];
|
||||||
} windows_version_t;
|
} windows_version_t;
|
||||||
|
|
||||||
|
@ -564,7 +597,6 @@ extern char app_data_dir[MAX_PATH], *image_path, *fido_url;
|
||||||
* Shared prototypes
|
* Shared prototypes
|
||||||
*/
|
*/
|
||||||
extern void GetWindowsVersion(windows_version_t* WindowsVersion);
|
extern void GetWindowsVersion(windows_version_t* WindowsVersion);
|
||||||
extern BOOL is_x64(void);
|
|
||||||
extern const char* GetAppArchName(void);
|
extern const char* GetAppArchName(void);
|
||||||
extern const char* WindowsErrorString(void);
|
extern const char* WindowsErrorString(void);
|
||||||
extern void DumpBufferHex(void *buf, size_t size);
|
extern void DumpBufferHex(void *buf, size_t size);
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 3.23.2023"
|
CAPTION "Rufus 3.23.2024"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -392,8 +392,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,23,2023,0
|
FILEVERSION 3,23,2024,0
|
||||||
PRODUCTVERSION 3,23,2023,0
|
PRODUCTVERSION 3,23,2024,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -411,13 +411,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "3.23.2023"
|
VALUE "FileVersion", "3.23.2024"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-3.23.exe"
|
VALUE "OriginalFilename", "rufus-3.23.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.23.2023"
|
VALUE "ProductVersion", "3.23.2024"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
96
src/stdfn.c
96
src/stdfn.c
|
@ -204,22 +204,6 @@ uint32_t htab_hash(char* str, htab_table* htab)
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL is_x64(void)
|
|
||||||
{
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, IsWow64Process, (HANDLE, PBOOL));
|
|
||||||
// Detect if we're running a 32 or 64 bit system
|
|
||||||
if (sizeof(uintptr_t) < 8) {
|
|
||||||
PF_INIT(IsWow64Process, Kernel32);
|
|
||||||
if (pfIsWow64Process != NULL) {
|
|
||||||
(*pfIsWow64Process)(GetCurrentProcess(), &ret);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* GetAppArchName(void) {
|
const char* GetAppArchName(void) {
|
||||||
#if defined(_M_AMD64)
|
#if defined(_M_AMD64)
|
||||||
return "x64";
|
return "x64";
|
||||||
|
@ -230,7 +214,8 @@ const char* GetAppArchName(void) {
|
||||||
#elif defined(_M_ARM)
|
#elif defined(_M_ARM)
|
||||||
return "arm";
|
return "arm";
|
||||||
#else
|
#else
|
||||||
return "unknown";
|
// Keep in line with what we were doing in 3.x
|
||||||
|
return "none";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,20 +321,24 @@ static const char* GetEdition(DWORD ProductType)
|
||||||
/*
|
/*
|
||||||
* Modified from smartmontools' os_win32.cpp
|
* Modified from smartmontools' os_win32.cpp
|
||||||
*/
|
*/
|
||||||
void GetWindowsVersion(windows_version_t* WindowsVersion)
|
void GetWindowsVersion(windows_version_t* windows_version)
|
||||||
{
|
{
|
||||||
OSVERSIONINFOEXA vi, vi2;
|
OSVERSIONINFOEXA vi, vi2;
|
||||||
DWORD dwProductType = 0;
|
DWORD dwProductType = 0;
|
||||||
const char* w = 0;
|
const char* w = NULL;
|
||||||
const char* w64 = "32 bit";
|
const char* arch_name;
|
||||||
char *vptr;
|
char *vptr;
|
||||||
size_t vlen;
|
size_t vlen;
|
||||||
DWORD major = 0, minor = 0;
|
DWORD major = 0, minor = 0;
|
||||||
|
USHORT ProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN, NativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
||||||
ULONGLONG major_equal, minor_equal;
|
ULONGLONG major_equal, minor_equal;
|
||||||
BOOL ws;
|
BOOL ws, is_wow64 = FALSE;
|
||||||
|
|
||||||
memset(WindowsVersion, 0, sizeof(windows_version_t));
|
PF_TYPE_DECL(WINAPI, BOOL, IsWow64Process2, (HANDLE, USHORT*, USHORT*));
|
||||||
static_strcpy(WindowsVersion->VersionStr, "Windows Undefined");
|
PF_INIT(IsWow64Process2, Kernel32);
|
||||||
|
|
||||||
|
memset(windows_version, 0, sizeof(windows_version_t));
|
||||||
|
static_strcpy(windows_version->VersionStr, "Windows Undefined");
|
||||||
|
|
||||||
memset(&vi, 0, sizeof(vi));
|
memset(&vi, 0, sizeof(vi));
|
||||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||||
|
@ -394,8 +383,8 @@ void GetWindowsVersion(windows_version_t* WindowsVersion)
|
||||||
|
|
||||||
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
|
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
|
||||||
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
||||||
WindowsVersion->Version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
windows_version->Version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
||||||
switch (WindowsVersion->Version) {
|
switch (windows_version->Version) {
|
||||||
case WINDOWS_XP: w = "XP";
|
case WINDOWS_XP: w = "XP";
|
||||||
break;
|
break;
|
||||||
case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2"));
|
case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2"));
|
||||||
|
@ -416,52 +405,67 @@ void GetWindowsVersion(windows_version_t* WindowsVersion)
|
||||||
w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));
|
w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
WindowsVersion->Version = WINDOWS_11;
|
windows_version->Version = WINDOWS_11;
|
||||||
major = 11;
|
major = 11;
|
||||||
// Fall through
|
// Fall through
|
||||||
case WINDOWS_11: w = (ws ? "11" : "Server 2022");
|
case WINDOWS_11: w = (ws ? "11" : "Server 2022");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (WindowsVersion->Version < WINDOWS_XP)
|
if (windows_version->Version < WINDOWS_XP)
|
||||||
WindowsVersion->Version = WINDOWS_UNDEFINED;
|
windows_version->Version = WINDOWS_UNDEFINED;
|
||||||
else
|
else
|
||||||
w = "12 or later";
|
w = "12 or later";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowsVersion->Major = major;
|
windows_version->Major = major;
|
||||||
WindowsVersion->Minor = minor;
|
windows_version->Minor = minor;
|
||||||
|
|
||||||
if (is_x64())
|
if ((pfIsWow64Process2 != NULL) && pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) {
|
||||||
w64 = "64-bit";
|
windows_version->Arch = NativeMachine;
|
||||||
|
} else {
|
||||||
|
// Assume same arch as the app
|
||||||
|
windows_version->Arch = GetApplicationArch();
|
||||||
|
// Fix the Arch if we have a 32-bit app running under WOW64
|
||||||
|
if ((sizeof(uintptr_t) < 8) && IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) {
|
||||||
|
if (windows_version->Arch == IMAGE_FILE_MACHINE_I386)
|
||||||
|
windows_version->Arch = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
else if (windows_version->Arch == IMAGE_FILE_MACHINE_ARM)
|
||||||
|
windows_version->Arch = IMAGE_FILE_MACHINE_ARM64;
|
||||||
|
else // I sure wanna be made aware of this scenario...
|
||||||
|
assert(FALSE);
|
||||||
|
}
|
||||||
|
uprintf("Note: Underlying Windows architecture was guessed and may be incorrect...");
|
||||||
|
}
|
||||||
|
arch_name = GetArchName(windows_version->Arch);
|
||||||
|
|
||||||
GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);
|
GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);
|
||||||
vptr = &WindowsVersion->VersionStr[sizeof("Windows ") - 1];
|
vptr = &windows_version->VersionStr[sizeof("Windows ") - 1];
|
||||||
vlen = sizeof(WindowsVersion->VersionStr) - sizeof("Windows ") - 1;
|
vlen = sizeof(windows_version->VersionStr) - sizeof("Windows ") - 1;
|
||||||
if (!w)
|
if (!w)
|
||||||
safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"),
|
safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"),
|
||||||
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
|
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, arch_name);
|
||||||
else if (vi.wServicePackMinor)
|
else if (vi.wServicePackMinor)
|
||||||
safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);
|
safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch_name);
|
||||||
else if (vi.wServicePackMajor)
|
else if (vi.wServicePackMajor)
|
||||||
safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
|
safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, arch_name);
|
||||||
else
|
else
|
||||||
safe_sprintf(vptr, vlen, "%s%s%s, %s",
|
safe_sprintf(vptr, vlen, "%s%s%s %s",
|
||||||
w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), w64);
|
w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), arch_name);
|
||||||
|
|
||||||
WindowsVersion->Edition = (int)dwProductType;
|
windows_version->Edition = (int)dwProductType;
|
||||||
|
|
||||||
// Add the build number (including UBR if available) for Windows 8.0 and later
|
// Add the build number (including UBR if available) for Windows 8.0 and later
|
||||||
WindowsVersion->BuildNumber = vi.dwBuildNumber;
|
windows_version->BuildNumber = vi.dwBuildNumber;
|
||||||
if (WindowsVersion->Version >= WINDOWS_8) {
|
if (windows_version->Version >= WINDOWS_8) {
|
||||||
int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");
|
int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");
|
||||||
vptr = &WindowsVersion->VersionStr[safe_strlen(WindowsVersion->VersionStr)];
|
vptr = &windows_version->VersionStr[safe_strlen(windows_version->VersionStr)];
|
||||||
vlen = sizeof(WindowsVersion->VersionStr) - safe_strlen(WindowsVersion->VersionStr) - 1;
|
vlen = sizeof(windows_version->VersionStr) - safe_strlen(windows_version->VersionStr) - 1;
|
||||||
if (nUbr > 0)
|
if (nUbr > 0)
|
||||||
safe_sprintf(vptr, vlen, " (Build %d.%d)", WindowsVersion->BuildNumber, nUbr);
|
safe_sprintf(vptr, vlen, " (Build %lu.%d)", windows_version->BuildNumber, nUbr);
|
||||||
else
|
else
|
||||||
safe_sprintf(vptr, vlen, " (Build %d)", WindowsVersion->BuildNumber);
|
safe_sprintf(vptr, vlen, " (Build %lu)", windows_version->BuildNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue