13
13
#include < inttypes.h>
14
14
#include < assert.h>
15
15
16
+ const char *ZIG_WINDOWS_KIT_REG_KEY = " SOFTWARE\\ Microsoft\\ Windows Kits\\ Installed Roots" ;
17
+
16
18
struct ZigWindowsSDKPrivate {
17
19
ZigWindowsSDK base;
18
20
};
@@ -182,48 +184,42 @@ static ZigFindWindowsSdkError find_10_version(ZigWindowsSDKPrivate *priv) {
182
184
if (priv->base .path10_ptr == nullptr )
183
185
return ZigFindWindowsSdkErrorNone;
184
186
185
- char sdk_lib_dir[4096 ];
186
- int n = snprintf (sdk_lib_dir, 4096 , " %s\\ Lib\\ *" , priv->base .path10_ptr );
187
- if (n < 0 || n >= 4096 ) {
188
- return ZigFindWindowsSdkErrorPathTooLong;
189
- }
190
-
191
- // enumerate files in sdk path looking for latest version
192
- WIN32_FIND_DATA ffd;
193
- HANDLE hFind = FindFirstFileA (sdk_lib_dir, &ffd);
194
- if (hFind == INVALID_HANDLE_VALUE) {
195
- return ZigFindWindowsSdkErrorNotFound;
196
- }
197
- int v0 = 0 , v1 = 0 , v2 = 0 , v3 = 0 ;
198
- for (;;) {
199
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
200
- int c0 = 0 , c1 = 0 , c2 = 0 , c3 = 0 ;
201
- sscanf (ffd.cFileName , " %d.%d.%d.%d" , &c0, &c1, &c2, &c3);
202
- if (c0 == 10 && c1 == 0 && c2 == 10240 && c3 == 0 ) {
203
- // Microsoft released 26624 as 10240 accidentally.
204
- // https://developer.microsoft.com/en-us/windows/downloads/sdk-archive
205
- c2 = 26624 ;
206
- }
207
-
208
- if ( (c0 > v0)
209
- || (c0 == v0 && c1 > v1)
210
- || (c0 == v0 && c1 == v1 && c2 > v2)
211
- || (c0 == v0 && c1 == v1 && c2 == v2 && c3 > v3) ) {
212
- v0 = c0, v1 = c1, v2 = c2, v3 = c3;
213
- free ((void *)priv->base .version10_ptr );
214
- priv->base .version10_ptr = strdup (ffd.cFileName );
215
- if (priv->base .version10_ptr == nullptr ) {
216
- FindClose (hFind);
217
- return ZigFindWindowsSdkErrorOutOfMemory;
218
- }
219
- }
220
- }
221
- if (FindNextFile (hFind, &ffd) == 0 ) {
222
- FindClose (hFind);
223
- break ;
224
- }
225
- }
226
- priv->base .version10_len = strlen (priv->base .version10_ptr );
187
+ char reg_query[MAX_PATH] = { 0 };
188
+ int n = snprintf (reg_query, MAX_PATH, " %s\\ %s.0\\ Installed Options" , ZIG_WINDOWS_KIT_REG_KEY, priv->base .version10_ptr );
189
+ if (n < 0 || n >= MAX_PATH) {
190
+ return ZigFindWindowsSdkErrorPathTooLong;
191
+ }
192
+
193
+ HKEY options_key;
194
+ HRESULT rc;
195
+ rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_query, 0 ,
196
+ KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &options_key);
197
+ if (rc != ERROR_SUCCESS) {
198
+ return ZigFindWindowsSdkErrorNotFound;
199
+ }
200
+
201
+ char *option_name = nullptr ;
202
+ switch (native_arch) {
203
+ case NativeArchArm:
204
+ option_name = " OptionId.DesktopCPParm" ;
205
+ break ;
206
+ case NativeArchx86_64:
207
+ option_name = " OptionId.DesktopCPPx64" ;
208
+ break ;
209
+ case NativeArchi386:
210
+ option_name = " OptionId.DesktopCPPx86" ;
211
+ break ;
212
+ default :
213
+ return ZigFindWindowsSdkErrorNotFound;
214
+ }
215
+
216
+ DWORD val_sz = sizeof (DWORD);
217
+ DWORD reg_val = 0 ;
218
+ DWORD type = REG_DWORD;
219
+ rc = RegQueryValueEx (options_key, option_name, NULL , &type, (LPBYTE)®_val, &val_sz);
220
+ if (rc != ERROR_SUCCESS || reg_val != 1 ) {
221
+ return ZigFindWindowsSdkErrorNotFound;
222
+ }
227
223
return ZigFindWindowsSdkErrorNone;
228
224
}
229
225
@@ -274,23 +270,32 @@ ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
274
270
return ZigFindWindowsSdkErrorOutOfMemory;
275
271
}
276
272
277
- HKEY key;
278
- HRESULT rc;
279
- rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, " SOFTWARE\\ Microsoft\\ Windows Kits\\ Installed Roots" , 0 ,
280
- KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &key);
281
- if (rc != ERROR_SUCCESS) {
282
- zig_free_windows_sdk (&priv->base );
283
- return ZigFindWindowsSdkErrorNotFound;
284
- }
273
+ HRESULT rc;
274
+
275
+ // note(dimenus): If this key doesn't exist, neither the Win 8 SDK nor the Win 10 SDK is installed
276
+ HKEY roots_key;
277
+ rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, ZIG_WINDOWS_KIT_REG_KEY, 0 ,
278
+ KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &roots_key);
279
+ if (rc != ERROR_SUCCESS) {
280
+ zig_free_windows_sdk (&priv->base );
281
+ return ZigFindWindowsSdkErrorNotFound;
282
+ }
285
283
286
284
{
285
+ HKEY v10_key;
286
+ rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, " SOFTWARE\\ Microsoft\\ Microsoft SDKs\\ Windows\\ v10.0" , 0 ,
287
+ KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &v10_key);
288
+ if (rc != ERROR_SUCCESS) {
289
+ goto find_win10_sdk_done;
290
+ }
291
+
287
292
DWORD tmp_buf_len = MAX_PATH;
288
293
priv->base .path10_ptr = (const char *)calloc (tmp_buf_len, 1 );
289
294
if (priv->base .path10_ptr == nullptr ) {
290
295
zig_free_windows_sdk (&priv->base );
291
296
return ZigFindWindowsSdkErrorOutOfMemory;
292
297
}
293
- rc = RegQueryValueEx (key , " KitsRoot10 " , NULL , NULL , (LPBYTE)priv->base .path10_ptr , &tmp_buf_len);
298
+ rc = RegQueryValueEx (v10_key , " InstallationFolder " , NULL , NULL , (LPBYTE)priv->base .path10_ptr , &tmp_buf_len);
294
299
if (rc == ERROR_SUCCESS) {
295
300
priv->base .path10_len = tmp_buf_len - 1 ;
296
301
if (priv->base .path10_ptr [priv->base .path10_len - 1 ] == ' \\ ' ) {
@@ -300,15 +305,27 @@ ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
300
305
free ((void *)priv->base .path10_ptr );
301
306
priv->base .path10_ptr = nullptr ;
302
307
}
308
+
309
+ priv->base .version10_ptr = (const char *)calloc (tmp_buf_len, 1 );
310
+ rc = RegQueryValueEx (v10_key, " ProductVersion" , NULL , NULL , (LPBYTE)priv->base .version10_ptr , &tmp_buf_len);
311
+ if (rc == ERROR_SUCCESS) {
312
+ size_t orig_len = priv->base .version10_len ;
313
+ snprintf ((char *)priv->base .version10_ptr , MAX_PATH, " %s.0" , priv->base .version10_ptr );
314
+ priv->base .version10_len = tmp_buf_len - 1 + 2 ; // note(dimenus): Microsoft doesn't include the .0 in the ProductVersion key....
315
+ } else {
316
+ free ((void *)priv->base .version10_ptr );
317
+ priv->base .version10_ptr = nullptr ;
318
+ }
303
319
}
320
+ find_win10_sdk_done:
304
321
{
305
322
DWORD tmp_buf_len = MAX_PATH;
306
323
priv->base .path81_ptr = (const char *)calloc (tmp_buf_len, 1 );
307
324
if (priv->base .path81_ptr == nullptr ) {
308
325
zig_free_windows_sdk (&priv->base );
309
326
return ZigFindWindowsSdkErrorOutOfMemory;
310
327
}
311
- rc = RegQueryValueEx (key , " KitsRoot81" , NULL , NULL , (LPBYTE)priv->base .path81_ptr , &tmp_buf_len);
328
+ rc = RegQueryValueEx (roots_key , " KitsRoot81" , NULL , NULL , (LPBYTE)priv->base .path81_ptr , &tmp_buf_len);
312
329
if (rc == ERROR_SUCCESS) {
313
330
priv->base .path81_len = tmp_buf_len - 1 ;
314
331
if (priv->base .path81_ptr [priv->base .path81_len - 1 ] == ' \\ ' ) {
0 commit comments