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