From 0f0267bb655757e687d80edd3db27098b6b0b73e Mon Sep 17 00:00:00 2001 From: Lenny Komow Date: Fri, 4 Nov 2016 10:38:39 -0600 Subject: winsdk: Parameterize ConfigureRT program Change-Id: I2f869d5a71fb6c5411aa2ab6a3b133c37fb52a09 --- windowsRuntimeInstaller/InstallerRT.nsi | 2 +- windowsRuntimeInstaller/configure_runtime.c | 135 +++++++++++++++++++++------- 2 files changed, 102 insertions(+), 35 deletions(-) (limited to 'windowsRuntimeInstaller') diff --git a/windowsRuntimeInstaller/InstallerRT.nsi b/windowsRuntimeInstaller/InstallerRT.nsi index 08d0e57c..5b13a6d0 100644 --- a/windowsRuntimeInstaller/InstallerRT.nsi +++ b/windowsRuntimeInstaller/InstallerRT.nsi @@ -250,7 +250,7 @@ VIAddVersionKey "LegalCopyright" "" Function ${un}ConfigLayersAndVulkanDLL # Execute the configuration program - nsExec::ExecToStack 'ConfigureRT.exe --abi-major ${VERSION_ABI_MAJOR}' + nsExec::ExecToStack 'ConfigureRT.exe --abi-major ${VERSION_ABI_MAJOR} --api-name ${APINAME}' Delete "$TEMP\VulkanRT\configure_rt.log" Rename "configure_rt.log" "$TEMP\VulkanRT\configure_rt.log" pop $0 diff --git a/windowsRuntimeInstaller/configure_runtime.c b/windowsRuntimeInstaller/configure_runtime.c index a8460a16..2041f426 100644 --- a/windowsRuntimeInstaller/configure_runtime.c +++ b/windowsRuntimeInstaller/configure_runtime.c @@ -77,6 +77,7 @@ struct SDKVersion }; const char* FLAG_ABI_MAJOR = "--abi-major"; +const char* FLAG_API_NAME = "--api-name"; const char* PATH_SYSTEM32 = "\\SYSTEM32\\"; const char* PATH_SYSWOW64 = "\\SysWOW64\\"; @@ -88,8 +89,9 @@ inline size_t min_s(size_t a, size_t b) { return a > b ? a : b; } // log (input) - Logging file stream // install_path (input) - The installation path of the SDK which provides the layers // platform (input) - The platform to set the installation for (x64 or x86) +// api_name (input) - The api name to use when working with registries // Returns: Zero on success, an error code on failure -int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform); +int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform, const char* api_name); // Compare two sdk versions // @@ -98,6 +100,7 @@ int compare_versions(const struct SDKVersion* a, const struct SDKVersion* b); // Locate all of the SDK installations // +// api_name (input) - The api name to use when working with registries // install_paths (output) - A poiner to an array of the installations paths // install_versions (output) - A pointer to an array of the SDK versions // count (output) - A pointer to the number of items in each array @@ -107,7 +110,8 @@ int compare_versions(const struct SDKVersion* a, const struct SDKVersion* b); // call free_installations(), even if this function returned an error code. The orders of // install_paths and install_versions match, so (*install_paths)[2] is guaranteed to match // (*install_versions)[2] -int find_installations(char*** install_paths, struct SDKVersion** install_versions, size_t* count); +int find_installations(const char* api_name, char*** install_paths, struct SDKVersion** install_versions, + size_t* count); // Free the memory allocated by find_installations() void free_installations(char** install_paths, struct SDKVersion* install_versions, size_t count); @@ -118,8 +122,9 @@ void free_installations(char** install_paths, struct SDKVersion* install_version // argc (input) - The argument count // argv (input) - An array of argument strings // abi_major (output) - The major abi version from the arguments +// api_name (output) - The api name to use when working with registries and system files // Returns: Zero on success, an error code on failure -int parse_arguments(FILE* log, int argc, char** argv, long* abi_major); +int parse_arguments(FILE* log, int argc, char** argv, long* abi_major, const char** api_name); // Read the version from a string // @@ -142,16 +147,20 @@ int read_version_from_filename(const char* filename, struct SDKVersion* version) // install_paths (input) - An array of every vulkan installation path // count (input) - The number of vulkan installations // platform (input) - The platform (x64 or x86) of the registry to use (both exist on x64) +// api_name (input) - The api name to use when working with registries // Returns: Zero on success, an error code on failure -int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform); +int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform, + const char* api_name); // Update all explicity layers in the windows registry // // log (input) - Logging file stream // platform (input) - The platform of the OS (both registries will be modified if this is x64) // version (input) - The version that should be set to current (if it exists) +// api_name (input) - The api name to use when working with registries // Returns: Zero on success, an error code on failure -int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version); +int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version, + const char* api_name); // Update a single vulkan system file (vulkan.dll or vulkaninfo.exe) // @@ -171,8 +180,9 @@ int update_system_file(FILE* log, const char* name, const char* extension, const // log (input) - Loging file stream // abi_major (input) - The ABI major version of the files that should be used // platform (input) - The platform for the current OS +// api_name (input) - The api name to use when working with system files // latest_runtime_version (output) - The version that the runtime files were updated to -int update_windows_directories(FILE* log, long abi_major, enum Platform platform, +int update_windows_directories(FILE* log, long abi_major, enum Platform platform, const char* api_name, struct SDKVersion* latest_runtime_version); int main(int argc, char** argv) @@ -189,24 +199,28 @@ int main(int argc, char** argv) // Parse the arguments to get the abi version and the number of bits of the OS long abi_major; - CHECK_ERROR_HANDLED(parse_arguments(log, argc, argv, &abi_major), { fclose(log); }); + const char* api_name; + CHECK_ERROR_HANDLED(parse_arguments(log, argc, argv, &abi_major, &api_name), { fclose(log); }); + + fprintf(log, "API Name: %s\n", api_name); // This makes System32 and SysWOW64 not do any redirection (well, until 128-bit is a thing) Wow64DisableWow64FsRedirection(NULL); // Update System32 (on all systems) and SysWOW64 on 64-bit system struct SDKVersion latest_runtime_version; - CHECK_ERROR_HANDLED(update_windows_directories(log, abi_major, platform, &latest_runtime_version), - { fclose(log); }); + CHECK_ERROR_HANDLED(update_windows_directories(log, abi_major, platform, api_name, + &latest_runtime_version), { fclose(log); }); // Update the explicit layers that are set in the windows registry - CHECK_ERROR_HANDLED(update_registry_layers(log, platform, &latest_runtime_version), { fclose(log); }); + CHECK_ERROR_HANDLED(update_registry_layers(log, platform, &latest_runtime_version, api_name), + { fclose(log); }); fclose(log); return 0; } -int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform) +int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform, const char* api_name) { switch(platform) { @@ -217,6 +231,11 @@ int add_explicit_layers(FILE* log, const char* install_path, enum Platform platf fprintf(log, "Updating x86 explicit layers to path: %s\n", install_path); break; } + + const char* registry_pattern = "SOFTWARE\\Khronos\\%s\\ExplicitLayers"; + int registry_size = snprintf(NULL, 0, registry_pattern, api_name) + 1; + char* registry_key = malloc(registry_size); + snprintf(registry_key, registry_size, registry_pattern, api_name); // If this is a 32 bit system, we allow redirection to point this at the 32-bit registries. // If not, we add the flag KEY_WOW64_64KEY, to disable redirection for this node. @@ -227,8 +246,9 @@ int add_explicit_layers(FILE* log, const char* install_path, enum Platform platf } // Create (if needed) and open the explicit layer key - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers", - 0, NULL, REG_OPTION_NON_VOLATILE, flags, NULL, &hKey, NULL) != ERROR_SUCCESS) { + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry_key, 0, NULL, REG_OPTION_NON_VOLATILE, flags, + NULL, &hKey, NULL) != ERROR_SUCCESS) { + free(registry_key); return 20; } @@ -249,6 +269,7 @@ int add_explicit_layers(FILE* log, const char* install_path, enum Platform platf const char* layer_pattern = platform == PLATFORM_X64 ? "%s\\Bin\\%s" : "%s\\Bin32\\%s"; int layer_size = snprintf(NULL, 0, layer_pattern, install_path, find_data.cFileName) + 1; if(layer_size < 0) { + free(registry_key); return 40; } char* layer = malloc(layer_size); @@ -260,11 +281,13 @@ int add_explicit_layers(FILE* log, const char* install_path, enum Platform platf LSTATUS err = RegSetValueEx(hKey, layer, zero, REG_DWORD, (BYTE*) &zero, sizeof(DWORD)); free(layer); if(err != ERROR_SUCCESS) { + free(registry_key); return 50; } } RegCloseKey(hKey); + free(registry_key); return 0; } @@ -293,7 +316,7 @@ int compare_versions(const struct SDKVersion* a, const struct SDKVersion* b) return strncmp(a->extended, b->extended, SDK_VERSION_BUFFER_SIZE); } -int find_installations(char*** install_paths, struct SDKVersion** install_versions, size_t* count) +int find_installations(const char* api_name, char*** install_paths, struct SDKVersion** install_versions, size_t* count) { *install_paths = malloc(sizeof(char*) * 64); *install_versions = malloc(sizeof(struct SDKVersion) * 64); @@ -307,6 +330,11 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio return 90; } + size_t api_len = strlen(api_name); + char* sdk_id = malloc(api_len + 4); + strcpy(sdk_id, api_name); + strcpy(sdk_id + api_len, "SDK"); + DWORD keyCount, keyLen; RegQueryInfoKey(hKey, NULL, NULL, NULL, &keyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL); for(int i = 0; i < keyCount; ++i) { @@ -314,7 +342,7 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio DWORD nameSize = COPY_BUFFER_SIZE; RegEnumKeyEx(hKey, i, name, &nameSize, NULL, NULL, NULL, NULL); - if(strncmp("VulkanSDK", name, 9)) { + if(strncmp(sdk_id, name, api_len + 3)) { continue; } @@ -351,10 +379,12 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio if(!(found_installation && found_version)) { RegCloseKey(hKey); + free(sdk_id); return 100; } } RegCloseKey(hKey); + free(sdk_id); return 0; } @@ -368,9 +398,10 @@ void free_installations(char** install_paths, struct SDKVersion* install_version free(install_versions); } -int parse_arguments(FILE* log, int argc, char** argv, long* abi_major) +int parse_arguments(FILE* log, int argc, char** argv, long* abi_major, const char** api_name) { *abi_major = 0; + *api_name = "Vulkan"; // Parse arguments for(int i = 0; i < argc; ++i) { @@ -385,6 +416,13 @@ int parse_arguments(FILE* log, int argc, char** argv, long* abi_major) return 120; } } + if(!strcmp(argv[i], FLAG_API_NAME)) { + if(i + 1 == argc) { + fprintf(log, "ERROR: No value given for flag %s.\n", FLAG_API_NAME); + return 124; + } + *api_name = argv[++i]; + } } // Check that we have everything we need @@ -466,7 +504,8 @@ int read_version_from_filename(const char* filename, struct SDKVersion* version) return 0; } -int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform) +int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform, + const char* api_name) { switch(platform) { @@ -477,6 +516,11 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, fprintf(log, "Removing x86 explicit layers from registry\n"); break; } + + const char* pattern = "SOFTWARE\\Khronos\\%s\\ExplicitLayers"; + int registry_size = snprintf(NULL, 0, pattern, api_name) + 1; + char* registry_key = malloc(registry_size); + snprintf(registry_key, registry_size, pattern, api_name); bool removed_one; do { @@ -489,8 +533,9 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, } // Create (if needed) and open the explicit layer key - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers", - 0, NULL, REG_OPTION_NON_VOLATILE, flags, NULL, &hKey, NULL) != ERROR_SUCCESS) { + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry_key, 0, NULL, REG_OPTION_NON_VOLATILE, flags, + NULL, &hKey, NULL) != ERROR_SUCCESS) { + free(registry_key); return 160; } @@ -507,6 +552,7 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, fprintf(log, "Removing explicit layer entry: %s\n", name); LSTATUS err = RegDeleteValue(hKey, name); if(err != ERROR_SUCCESS) { + free(registry_key); return 170; } removed_one = true; @@ -520,16 +566,18 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, RegCloseKey(hKey); } while(removed_one); - + + free(registry_key); return 0; } -int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version) +int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version, + const char* api_name) { char** install_paths; struct SDKVersion* install_versions; size_t count; - CHECK_ERROR_HANDLED(find_installations(&install_paths, &install_versions, &count), + CHECK_ERROR_HANDLED(find_installations(api_name, &install_paths, &install_versions, &count), { free_installations(install_paths, install_versions, count); }); for(size_t i = 0; i < count; ++i) { fprintf(log, "Found installation of %ld.%ld.%ld.%ld in: %s\n", install_versions[i].major, @@ -537,11 +585,11 @@ int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVe } fprintf(log, "\n"); if(platform == PLATFORM_X64) { - CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X64), + CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X64, api_name), { free_installations(install_paths, install_versions, count); }); fprintf(log, "\n"); } - CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X86), + CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X86, api_name), { free_installations(install_paths, install_versions, count); }); fprintf(log, "\n"); @@ -553,11 +601,11 @@ int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVe for(size_t i = 0; i < count; ++i) { if(compare_versions(install_versions + i, version) == 0) { if(platform == PLATFORM_X64) { - CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X64), + CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X64, api_name), { free_installations(install_paths, install_versions, count); }); fprintf(log, "\n"); } - CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X86), + CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X86, api_name), { free_installations(install_paths, install_versions, count); }); break; } @@ -658,8 +706,19 @@ int update_system_file(FILE* log, const char* name, const char* extension, const return 0; } -int update_windows_directories(FILE* log, long abi_major, enum Platform platform, struct SDKVersion* latest_runtime_version) +int update_windows_directories(FILE* log, long abi_major, enum Platform platform, const char* api_name, + struct SDKVersion* latest_runtime_version) { + size_t api_len = strlen(api_name); + char* vulkan_name = malloc(api_len + 1); + char* vulkan_info_name = malloc(api_len + 5); + for(size_t i = 0; i < api_len; ++i) { + vulkan_name[i] = tolower(api_name[i]); + } + vulkan_name[api_len] = '\0'; + strcpy(vulkan_info_name, vulkan_name); + strcpy(vulkan_info_name + api_len, "info"); + struct SDKVersion version; unsigned windows_path_size = GetWindowsDirectory(NULL, 0); // Size includes null terminator char* system_path = malloc(windows_path_size + @@ -668,33 +727,41 @@ int update_windows_directories(FILE* log, long abi_major, enum Platform platform strcpy(system_path + windows_path_size - 1, PATH_SYSTEM32); fprintf(log, "Updating system directory: %s\n", system_path); - CHECK_ERROR_HANDLED(update_system_file(log, "vulkan", ".dll", system_path, abi_major, true, + CHECK_ERROR_HANDLED(update_system_file(log, vulkan_name, ".dll", system_path, abi_major, true, latest_runtime_version), { free(system_path); }); - CHECK_ERROR_HANDLED(update_system_file(log, "vulkaninfo", ".exe", system_path, abi_major, false, - &version), { free(system_path); }); + CHECK_ERROR_HANDLED(update_system_file(log, vulkan_info_name, ".exe", system_path, abi_major, false, + &version), { free(system_path); free(vulkan_info_name); free(vulkan_name);}); if(compare_versions(latest_runtime_version, &version) != 0) { free(system_path); + free(vulkan_info_name); + free(vulkan_name); return 220; } if(platform == PLATFORM_X64) { strcpy(system_path + windows_path_size - 1, PATH_SYSWOW64); fprintf(log, "\nUpdating system directory: %s\n", system_path); - CHECK_ERROR_HANDLED(update_system_file(log, "vulkan", ".dll", system_path, abi_major, - true, &version), { free(system_path); }); + CHECK_ERROR_HANDLED(update_system_file(log, vulkan_name, ".dll", system_path, abi_major, + true, &version), { free(system_path); free(vulkan_info_name); free(vulkan_name); }); if(compare_versions(latest_runtime_version, &version) != 0) { free(system_path); + free(vulkan_info_name); + free(vulkan_name); return 230; } - CHECK_ERROR_HANDLED(update_system_file(log, "vulkaninfo", ".exe", system_path, abi_major, - false, &version), { free(system_path); }); + CHECK_ERROR_HANDLED(update_system_file(log, vulkan_info_name, ".exe", system_path, abi_major, + false, &version), { free(system_path); free(vulkan_info_name); free(vulkan_name); }); if(compare_versions(latest_runtime_version, &version) != 0) { free(system_path); + free(vulkan_info_name); + free(vulkan_name); return 240; } } free(system_path); + free(vulkan_info_name); + free(vulkan_name); fprintf(log, "\nUpdate of system directories succeeded.\n\n"); return 0; } -- cgit v1.2.3