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;
|
||||
}
|
||||
|
||||
static __inline BOOL is_WOW64(void)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
IsWow64Process(GetCurrentProcess(), &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Open an Internet session
|
||||
static HINTERNET GetInternetSession(BOOL bRetry)
|
||||
{
|
||||
|
@ -307,9 +314,9 @@ static HINTERNET GetInternetSession(BOOL bRetry)
|
|||
SetLastError(ERROR_INTERNET_DISCONNECTED);
|
||||
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],
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||
hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
// Set the timeouts
|
||||
pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
|
||||
|
@ -695,9 +702,9 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
|||
goto out;
|
||||
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],
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||
hSession = GetInternetSession(FALSE);
|
||||
if (hSession == NULL)
|
||||
goto out;
|
||||
|
@ -763,7 +770,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
|||
}
|
||||
if (dwStatus != 200) {
|
||||
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;
|
||||
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))
|
||||
|| (!SystemTimeToFileTime(&ServerTime, &FileTime)) )
|
||||
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);
|
||||
// Always store the server response time - the only clock we trust!
|
||||
WriteSetting64(SETTING_LAST_UPDATE, server_time);
|
||||
// Might as well let the user know
|
||||
if (!force_update_check) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -794,7 +802,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
|||
goto out;
|
||||
|
||||
// Make sure the file is NUL terminated
|
||||
buf = (char*)calloc(dwTotalSize+1, 1);
|
||||
buf = (char*)calloc(dwTotalSize + 1, 1);
|
||||
if (buf == NULL)
|
||||
goto out;
|
||||
// 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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DWORD len;
|
||||
|
@ -2023,8 +1992,13 @@ static void InitDialog(HWND hDlg)
|
|||
// 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
|
||||
// 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)) {
|
||||
// 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) &&
|
||||
(ProcessMachine == IMAGE_FILE_MACHINE_I386 || ProcessMachine == IMAGE_FILE_MACHINE_AMD64))
|
||||
uprintf("Notice: Running emulated on %s platform", GetArchName(NativeMachine));
|
||||
|
@ -3354,7 +3328,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
FILE* fd;
|
||||
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 alt_pressed = FALSE, alt_command = FALSE;
|
||||
BOOL alt_pressed = FALSE, alt_command = FALSE, is_WOW64 = FALSE;
|
||||
BYTE *loc_data;
|
||||
DWORD loc_size, u = 0, size = sizeof(u);
|
||||
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);
|
||||
// But if the app is 32 bit and the OS is 64 bit, Sysnative must differ from System32
|
||||
#if (!defined(_WIN64) && !defined(BUILD64))
|
||||
if (is_x64()) {
|
||||
IsWow64Process(GetCurrentProcess(), &is_WOW64);
|
||||
if (is_WOW64) {
|
||||
if (GetSystemWindowsDirectoryU(sysnative_dir, sizeof(sysnative_dir)) == 0) {
|
||||
uprintf("Could not get Windows directory: %s", WindowsErrorString());
|
||||
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_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 */
|
||||
enum WindowsVersion {
|
||||
WINDOWS_UNDEFINED = 0,
|
||||
|
@ -491,26 +537,13 @@ enum WindowsVersion {
|
|||
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 {
|
||||
DWORD Version;
|
||||
DWORD Major;
|
||||
DWORD Minor;
|
||||
DWORD BuildNumber;
|
||||
DWORD Edition;
|
||||
USHORT Arch;
|
||||
char VersionStr[128];
|
||||
} windows_version_t;
|
||||
|
||||
|
@ -564,7 +597,6 @@ extern char app_data_dir[MAX_PATH], *image_path, *fido_url;
|
|||
* Shared prototypes
|
||||
*/
|
||||
extern void GetWindowsVersion(windows_version_t* WindowsVersion);
|
||||
extern BOOL is_x64(void);
|
||||
extern const char* GetAppArchName(void);
|
||||
extern const char* WindowsErrorString(void);
|
||||
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
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 3.23.2023"
|
||||
CAPTION "Rufus 3.23.2024"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -392,8 +392,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,23,2023,0
|
||||
PRODUCTVERSION 3,23,2023,0
|
||||
FILEVERSION 3,23,2024,0
|
||||
PRODUCTVERSION 3,23,2024,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -411,13 +411,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "3.23.2023"
|
||||
VALUE "FileVersion", "3.23.2024"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-3.23.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "3.23.2023"
|
||||
VALUE "ProductVersion", "3.23.2024"
|
||||
END
|
||||
END
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
#if defined(_M_AMD64)
|
||||
return "x64";
|
||||
|
@ -230,7 +214,8 @@ const char* GetAppArchName(void) {
|
|||
#elif defined(_M_ARM)
|
||||
return "arm";
|
||||
#else
|
||||
return "unknown";
|
||||
// Keep in line with what we were doing in 3.x
|
||||
return "none";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -336,20 +321,24 @@ static const char* GetEdition(DWORD ProductType)
|
|||
/*
|
||||
* Modified from smartmontools' os_win32.cpp
|
||||
*/
|
||||
void GetWindowsVersion(windows_version_t* WindowsVersion)
|
||||
void GetWindowsVersion(windows_version_t* windows_version)
|
||||
{
|
||||
OSVERSIONINFOEXA vi, vi2;
|
||||
DWORD dwProductType = 0;
|
||||
const char* w = 0;
|
||||
const char* w64 = "32 bit";
|
||||
const char* w = NULL;
|
||||
const char* arch_name;
|
||||
char *vptr;
|
||||
size_t vlen;
|
||||
DWORD major = 0, minor = 0;
|
||||
USHORT ProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN, NativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
ULONGLONG major_equal, minor_equal;
|
||||
BOOL ws;
|
||||
BOOL ws, is_wow64 = FALSE;
|
||||
|
||||
memset(WindowsVersion, 0, sizeof(windows_version_t));
|
||||
static_strcpy(WindowsVersion->VersionStr, "Windows Undefined");
|
||||
PF_TYPE_DECL(WINAPI, BOOL, IsWow64Process2, (HANDLE, USHORT*, USHORT*));
|
||||
PF_INIT(IsWow64Process2, Kernel32);
|
||||
|
||||
memset(windows_version, 0, sizeof(windows_version_t));
|
||||
static_strcpy(windows_version->VersionStr, "Windows Undefined");
|
||||
|
||||
memset(&vi, 0, sizeof(vi));
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
|
@ -394,8 +383,8 @@ void GetWindowsVersion(windows_version_t* WindowsVersion)
|
|||
|
||||
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
|
||||
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
||||
WindowsVersion->Version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
||||
switch (WindowsVersion->Version) {
|
||||
windows_version->Version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
||||
switch (windows_version->Version) {
|
||||
case WINDOWS_XP: w = "XP";
|
||||
break;
|
||||
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"));
|
||||
break;
|
||||
}
|
||||
WindowsVersion->Version = WINDOWS_11;
|
||||
windows_version->Version = WINDOWS_11;
|
||||
major = 11;
|
||||
// Fall through
|
||||
case WINDOWS_11: w = (ws ? "11" : "Server 2022");
|
||||
break;
|
||||
default:
|
||||
if (WindowsVersion->Version < WINDOWS_XP)
|
||||
WindowsVersion->Version = WINDOWS_UNDEFINED;
|
||||
if (windows_version->Version < WINDOWS_XP)
|
||||
windows_version->Version = WINDOWS_UNDEFINED;
|
||||
else
|
||||
w = "12 or later";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
WindowsVersion->Major = major;
|
||||
WindowsVersion->Minor = minor;
|
||||
windows_version->Major = major;
|
||||
windows_version->Minor = minor;
|
||||
|
||||
if (is_x64())
|
||||
w64 = "64-bit";
|
||||
if ((pfIsWow64Process2 != NULL) && pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) {
|
||||
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);
|
||||
vptr = &WindowsVersion->VersionStr[sizeof("Windows ") - 1];
|
||||
vlen = sizeof(WindowsVersion->VersionStr) - sizeof("Windows ") - 1;
|
||||
vptr = &windows_version->VersionStr[sizeof("Windows ") - 1];
|
||||
vlen = sizeof(windows_version->VersionStr) - 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);
|
||||
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, arch_name);
|
||||
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)
|
||||
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
|
||||
safe_sprintf(vptr, vlen, "%s%s%s, %s",
|
||||
w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), w64);
|
||||
safe_sprintf(vptr, vlen, "%s%s%s %s",
|
||||
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
|
||||
WindowsVersion->BuildNumber = vi.dwBuildNumber;
|
||||
if (WindowsVersion->Version >= WINDOWS_8) {
|
||||
windows_version->BuildNumber = vi.dwBuildNumber;
|
||||
if (windows_version->Version >= WINDOWS_8) {
|
||||
int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");
|
||||
vptr = &WindowsVersion->VersionStr[safe_strlen(WindowsVersion->VersionStr)];
|
||||
vlen = sizeof(WindowsVersion->VersionStr) - safe_strlen(WindowsVersion->VersionStr) - 1;
|
||||
vptr = &windows_version->VersionStr[safe_strlen(windows_version->VersionStr)];
|
||||
vlen = sizeof(windows_version->VersionStr) - safe_strlen(windows_version->VersionStr) - 1;
|
||||
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
|
||||
safe_sprintf(vptr, vlen, " (Build %d)", WindowsVersion->BuildNumber);
|
||||
safe_sprintf(vptr, vlen, " (Build %lu)", windows_version->BuildNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue