Skip to content

Commit 1aaa794

Browse files
committed
[core] improve Windows version reporting
* Detect Windows 11 and report build number
1 parent bab1864 commit 1aaa794

File tree

5 files changed

+127
-33
lines changed

5 files changed

+127
-33
lines changed

examples/wdi-simple.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#endif
88

99
VS_VERSION_INFO VERSIONINFO
10-
FILEVERSION 1,4,755,0
11-
PRODUCTVERSION 1,4,755,0
10+
FILEVERSION 1,4,756,0
11+
PRODUCTVERSION 1,4,756,0
1212
FILEFLAGSMASK 0x17L
1313
#ifdef _DEBUG
1414
FILEFLAGS 0x1L
@@ -25,13 +25,13 @@ BEGIN
2525
BEGIN
2626
VALUE "CompanyName", "akeo.ie"
2727
VALUE "FileDescription", "WDI-Simple"
28-
VALUE "FileVersion", "1.3.755"
28+
VALUE "FileVersion", "1.3.756"
2929
VALUE "InternalName", "WDI-Simple"
3030
VALUE "LegalCopyright", "� 2010-2018 Pete Batard (LGPL v3)"
3131
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/lesser.html"
3232
VALUE "OriginalFilename", "wdi-simple.exe"
3333
VALUE "ProductName", "WDI-Simple"
34-
VALUE "ProductVersion", "1.3.755"
34+
VALUE "ProductVersion", "1.3.756"
3535
VALUE "Comments", "http://libwdi.akeo.ie"
3636
END
3737
END

examples/zadig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#define FIELD_ORANGE RGB(255,240,200)
6060
#define ARROW_GREEN RGB(92,228,65)
6161
#define ARROW_ORANGE RGB(253,143,56)
62-
#define APP_VERSION "Zadig 2.6.755"
62+
#define APP_VERSION "Zadig 2.6.756"
6363

6464
// These are used to flag end users about the driver they are going to replace
6565
enum driver_type {

examples/zadig.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ END
246246
//
247247

248248
VS_VERSION_INFO VERSIONINFO
249-
FILEVERSION 2,6,755,0
250-
PRODUCTVERSION 2,6,755,0
249+
FILEVERSION 2,6,756,0
250+
PRODUCTVERSION 2,6,756,0
251251
FILEFLAGSMASK 0x17L
252252
#ifdef _DEBUG
253253
FILEFLAGS 0x1L
@@ -264,13 +264,13 @@ BEGIN
264264
BEGIN
265265
VALUE "CompanyName", "akeo.ie"
266266
VALUE "FileDescription", "Zadig"
267-
VALUE "FileVersion", "2.6.755"
267+
VALUE "FileVersion", "2.6.756"
268268
VALUE "InternalName", "Zadig"
269269
VALUE "LegalCopyright", "� 2010-2018 Pete Batard (GPL v3)"
270270
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
271271
VALUE "OriginalFilename", "zadig.exe"
272272
VALUE "ProductName", "Zadig"
273-
VALUE "ProductVersion", "2.6.755"
273+
VALUE "ProductVersion", "2.6.756"
274274
VALUE "Comments", "http://libwdi.akeo.ie"
275275
END
276276
END

libwdi/libwdi.c

Lines changed: 114 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static const char* inf_template[WDI_NB_DRIVERS-1] = {"winusb.inf.in", "libusb0.i
5959
static const char* cat_template[WDI_NB_DRIVERS-1] = {"winusb.cat.in", "libusb0.cat.in", "libusbk.cat.in", "usbser.cat.in"};
6060
static const char* ms_compat_id[WDI_NB_DRIVERS-1] = {"MS_COMP_WINUSB", "MS_COMP_LIBUSB0", "MS_COMP_LIBUSBK", "MS_COMP_USBSER"};
6161
int nWindowsVersion = WINDOWS_UNDEFINED;
62+
int nWindowsBuildNumber = -1;
6263
char WindowsVersionStr[128] = "Windows ";
6364

6465
// Detect Windows version
@@ -76,27 +77,101 @@ BOOL is_x64(void)
7677
return ret;
7778
}
7879

79-
// From smartmontools os_win32.cpp
80+
static const char* GetEdition(DWORD ProductType)
81+
{
82+
// From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo
83+
// These values can be found in the winnt.h header.
84+
switch (ProductType) {
85+
case 0x00000000: return ""; // Undefined
86+
case 0x00000001: return "Ultimate";
87+
case 0x00000002: return "Home Basic";
88+
case 0x00000003: return "Home Premium";
89+
case 0x00000004: return "Enterprise";
90+
case 0x00000005: return "Home Basic N";
91+
case 0x00000006: return "Business";
92+
case 0x00000007: return "Standard Server";
93+
case 0x00000008: return "Datacenter Server";
94+
case 0x00000009: return "Smallbusiness Server";
95+
case 0x0000000A: return "Enterprise Server";
96+
case 0x0000000B: return "Starter";
97+
case 0x00000010: return "Business N";
98+
case 0x00000011: return "Web Server";
99+
case 0x00000012: return "Cluster Server";
100+
case 0x00000013: return "Home Server";
101+
case 0x0000001A: return "Home Premium N";
102+
case 0x0000001B: return "Enterprise N";
103+
case 0x0000001C: return "Ultimate N";
104+
case 0x00000022: return "Home Premium Server";
105+
case 0x0000002F: return "Starter N";
106+
case 0x00000030: return "Pro";
107+
case 0x00000031: return "Pro N";
108+
case 0x00000042: return "Starter E";
109+
case 0x00000043: return "Home Basic E";
110+
case 0x00000044: return "Premium E";
111+
case 0x00000045: return "Pro E";
112+
case 0x00000046: return "Enterprise E";
113+
case 0x00000047: return "Ultimate E";
114+
case 0x00000048: return "Enterprise Eval";
115+
case 0x00000054: return "Enterprise N Eval";
116+
case 0x00000057: return "Thin PC";
117+
case 0x0000006F: return "Core Connected";
118+
case 0x00000070: return "Pro Student";
119+
case 0x00000071: return "Core Connected N";
120+
case 0x00000072: return "Pro Student N";
121+
case 0x00000073: return "Core Connected Single Language";
122+
case 0x00000074: return "Core Connected China";
123+
case 0x00000079: return "Edu";
124+
case 0x0000007A: return "Edu N";
125+
case 0x0000007D: return "Enterprise S";
126+
case 0x0000007E: return "Enterprise S N";
127+
case 0x0000007F: return "Pro S";
128+
case 0x00000080: return "Pro S N";
129+
case 0x00000081: return "Enterprise S Eval";
130+
case 0x00000082: return "Enterprise S N Eval";
131+
case 0x0000008A: return "Pro Single Language";
132+
case 0x0000008B: return "Pro China";
133+
case 0x0000008C: return "Enterprise Subscription";
134+
case 0x0000008D: return "Enterprise Subscription N";
135+
case 0x00000095: return "Utility VM";
136+
case 0x000000A1: return "Pro Workstation";
137+
case 0x000000A2: return "Pro Workstation N";
138+
case 0x000000A4: return "Pro for Education";
139+
case 0x000000A5: return "Pro for Education N";
140+
case 0x000000AB: return "Enterprise G"; // I swear Microsoft are just making up editions...
141+
case 0x000000AC: return "Enterprise G N";
142+
case 0x000000B6: return "Core OS";
143+
case 0x000000B7: return "Cloud E";
144+
case 0x000000B8: return "Cloud E N";
145+
case 0x000000BD: return "Lite";
146+
case 0xABCDABCD: return "(Unlicensed)";
147+
default: return "(Unknown Edition)";
148+
}
149+
}
150+
151+
/*
152+
* Modified from smartmontools' os_win32.cpp
153+
*/
80154
void GetWindowsVersion(void)
81155
{
82156
OSVERSIONINFOEXA vi, vi2;
157+
DWORD dwProductType;
83158
const char* w = 0;
84159
const char* w64 = "32 bit";
85-
char *vptr, build_number[10] = "";
160+
char* vptr;
86161
size_t vlen;
87162
unsigned major, minor;
88163
ULONGLONG major_equal, minor_equal;
89164
BOOL ws;
90165

91166
nWindowsVersion = WINDOWS_UNDEFINED;
92-
safe_strcpy(WindowsVersionStr, sizeof(WindowsVersionStr), "Windows Undefined");
167+
static_strcpy(WindowsVersionStr, "Windows Undefined");
93168

94169
memset(&vi, 0, sizeof(vi));
95170
vi.dwOSVersionInfoSize = sizeof(vi);
96-
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
171+
if (!GetVersionExA((OSVERSIONINFOA*)&vi)) {
97172
memset(&vi, 0, sizeof(vi));
98173
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
99-
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
174+
if (!GetVersionExA((OSVERSIONINFOA*)&vi))
100175
return;
101176
}
102177

@@ -136,22 +211,30 @@ void GetWindowsVersion(void)
136211
ws = (vi.wProductType <= VER_NT_WORKSTATION);
137212
nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
138213
switch (nWindowsVersion) {
139-
case 0x61: w = (ws ? "7" : "2008_R2");
214+
case 0x51: w = "XP";
215+
break;
216+
case 0x52: w = (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2");
140217
break;
141-
case 0x62: w = (ws ? "8" : "2012");
218+
case 0x60: w = (ws ? "Vista" : "Server 2008");
142219
break;
143-
case 0x63: w = (ws ? "8.1" : "2012_R2");
220+
case 0x61: w = (ws ? "7" : "Server 2008_R2");
221+
break;
222+
case 0x62: w = (ws ? "8" : "Server 2012");
223+
break;
224+
case 0x63: w = (ws ? "8.1" : "Server 2012_R2");
144225
break;
145226
case 0x64: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)");
146227
break;
147228
// Starting with Windows 10 Preview 2, the major is the same as the public-facing version
148-
case 0xA0: w = (ws ? "10" : "Server 10");
229+
case 0xA0: w = (ws ? ((vi.dwBuildNumber < 20000) ? "10" : "11") : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));
230+
break;
231+
case 0xB0: w = (ws ? "11" : "Server 2022");
149232
break;
150233
default:
151-
if (nWindowsVersion < 0x61)
234+
if (nWindowsVersion < 0x51)
152235
nWindowsVersion = WINDOWS_UNSUPPORTED;
153236
else
154-
w = "11 or later";
237+
w = "12 or later";
155238
break;
156239
}
157240
}
@@ -160,6 +243,7 @@ void GetWindowsVersion(void)
160243
if (is_x64())
161244
w64 = "64-bit";
162245

246+
GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);
163247
vptr = &WindowsVersionStr[sizeof("Windows ") - 1];
164248
vlen = sizeof(WindowsVersionStr) - sizeof("Windows ") - 1;
165249
if (!w)
@@ -170,19 +254,29 @@ void GetWindowsVersion(void)
170254
else if (vi.wServicePackMajor)
171255
safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
172256
else
173-
safe_sprintf(vptr, vlen, "%s %s", w, w64);
257+
safe_sprintf(vptr, vlen, "%s%s%s, %s",
258+
w, (dwProductType != PRODUCT_UNDEFINED) ? " " : "", GetEdition(dwProductType), w64);
174259

175-
// Add the build number for Windows 8.0 and later
260+
// Add the build number (including UBR if available) for Windows 8.0 and later
261+
nWindowsBuildNumber = vi.dwBuildNumber;
176262
if (nWindowsVersion >= 0x62) {
177-
ReadRegistryStr(REGKEY_HKLM, "Microsoft\\Windows NT\\CurrentVersion\\CurrentBuildNumber", build_number, sizeof(build_number));
178-
if (build_number[0] != 0) {
179-
safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), " (Build ");
180-
safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), build_number);
181-
safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), ")");
182-
}
263+
HKEY hCurrentVersion;
264+
DWORD dwType = REG_DWORD, dwSize = sizeof(DWORD), dwUbr = 0;
265+
if (RegOpenKeyExA(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion",
266+
0, KEY_READ, &hCurrentVersion) == ERROR_SUCCESS) {
267+
RegQueryValueExA(hCurrentVersion, "UBR", NULL, &dwType, (LPBYTE)&dwUbr, &dwSize);
268+
RegCloseKey(hCurrentVersion);
269+
}
270+
271+
vptr = &WindowsVersionStr[safe_strlen(WindowsVersionStr)];
272+
vlen = sizeof(WindowsVersionStr) - safe_strlen(WindowsVersionStr) - 1;
273+
if (dwUbr != 0)
274+
safe_sprintf(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, (int)dwUbr);
275+
else
276+
safe_sprintf(vptr, vlen, " (Build %d)", nWindowsBuildNumber);
183277
}
184-
185278
}
279+
186280
/*
187281
* Converts a windows error to human readable string
188282
* uses retval as errorcode, or, if 0, use GetLastError()

libwdi/libwdi.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ END
5050
//
5151

5252
VS_VERSION_INFO VERSIONINFO
53-
FILEVERSION 1,4,755,0
54-
PRODUCTVERSION 1,4,755,0
53+
FILEVERSION 1,4,756,0
54+
PRODUCTVERSION 1,4,756,0
5555
FILEFLAGSMASK 0x17L
5656
#ifdef _DEBUG
5757
FILEFLAGS 0x1L
@@ -68,13 +68,13 @@ BEGIN
6868
BEGIN
6969
VALUE "CompanyName", "akeo.ie"
7070
VALUE "FileDescription", "libwdi: Windows Driver Installer Library"
71-
VALUE "FileVersion", "1.3.755"
71+
VALUE "FileVersion", "1.3.756"
7272
VALUE "InternalName", "libwdi"
7373
VALUE "LegalCopyright", "� 2010-2017 Pete Batard (LGPL v3)"
7474
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/lesser.html"
7575
VALUE "OriginalFilename", "libwdi"
7676
VALUE "ProductName", "libwdi"
77-
VALUE "ProductVersion", "1.3.755"
77+
VALUE "ProductVersion", "1.3.756"
7878
VALUE "Comments", "http://libwdi.akeo.ie"
7979
END
8080
END

0 commit comments

Comments
 (0)