winsdk: Parameterize ConfigureRT program
authorLenny Komow <lenny@lunarg.com>
Fri, 4 Nov 2016 16:38:39 +0000 (10:38 -0600)
committerLenny Komow <lenny@lunarg.com>
Tue, 8 Nov 2016 16:07:28 +0000 (09:07 -0700)
Change-Id: I2f869d5a71fb6c5411aa2ab6a3b133c37fb52a09

windowsRuntimeInstaller/InstallerRT.nsi
windowsRuntimeInstaller/configure_runtime.c

index 08d0e57..5b13a6d 100644 (file)
@@ -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
index a8460a1..2041f42 100644 (file)
@@ -77,6 +77,7 @@ struct SDKVersion
 };\r
 \r
 const char* FLAG_ABI_MAJOR = "--abi-major";\r
+const char* FLAG_API_NAME = "--api-name";\r
 const char* PATH_SYSTEM32 = "\\SYSTEM32\\";\r
 const char* PATH_SYSWOW64 = "\\SysWOW64\\";\r
 \r
@@ -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\r
 // install_path (input) - The installation path of the SDK which provides the layers\r
 // platform (input) - The platform to set the installation for (x64 or x86)\r
+// api_name (input) - The api name to use when working with registries\r
 // Returns: Zero on success, an error code on failure\r
-int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform);\r
+int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform, const char* api_name);\r
 \r
 // Compare two sdk versions\r
 //\r
@@ -98,6 +100,7 @@ int compare_versions(const struct SDKVersion* a, const struct SDKVersion* b);
 \r
 // Locate all of the SDK installations\r
 //\r
+// api_name (input) - The api name to use when working with registries\r
 // install_paths (output) - A poiner to an array of the installations paths\r
 // install_versions (output) - A pointer to an array of the SDK versions\r
 // count (output) - A pointer to the number of items in each array\r
@@ -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\r
 // install_paths and install_versions match, so (*install_paths)[2] is guaranteed to match\r
 // (*install_versions)[2]\r
-int find_installations(char*** install_paths, struct SDKVersion** install_versions, size_t* count);\r
+int find_installations(const char* api_name, char*** install_paths, struct SDKVersion** install_versions,\r
+    size_t* count);\r
 \r
 // Free the memory allocated by find_installations()\r
 void free_installations(char** install_paths, struct SDKVersion* install_versions, size_t count);\r
@@ -118,8 +122,9 @@ void free_installations(char** install_paths, struct SDKVersion* install_version
 // argc (input) - The argument count\r
 // argv (input) - An array of argument strings\r
 // abi_major (output) - The major abi version from the arguments\r
+// api_name (output) - The api name to use when working with registries and system files\r
 // Returns: Zero on success, an error code on failure\r
-int parse_arguments(FILE* log, int argc, char** argv, long* abi_major);\r
+int parse_arguments(FILE* log, int argc, char** argv, long* abi_major, const char** api_name);\r
 \r
 // Read the version from a string\r
 //\r
@@ -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\r
 // count (input) - The number of vulkan installations\r
 // platform (input) - The platform (x64 or x86) of the registry to use (both exist on x64)\r
+// api_name (input) - The api name to use when working with registries\r
 // Returns: Zero on success, an error code on failure\r
-int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform);\r
+int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform,\r
+    const char* api_name);\r
 \r
 // Update all explicity layers in the windows registry\r
 //\r
 // log (input) - Logging file stream\r
 // platform (input) - The platform of the OS (both registries will be modified if this is x64)\r
 // version (input) - The version that should be set to current (if it exists)\r
+// api_name (input) - The api name to use when working with registries\r
 // Returns: Zero on success, an error code on failure\r
-int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version);\r
+int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version,\r
+    const char* api_name);\r
 \r
 // Update a single vulkan system file (vulkan.dll or vulkaninfo.exe)\r
 //\r
@@ -171,8 +180,9 @@ int update_system_file(FILE* log, const char* name, const char* extension, const
 // log (input) - Loging file stream\r
 // abi_major (input) - The ABI major version of the files that should be used\r
 // platform (input) - The platform for the current OS\r
+// api_name (input) - The api name to use when working with system files\r
 // latest_runtime_version (output) - The version that the runtime files were updated to\r
-int update_windows_directories(FILE* log, long abi_major, enum Platform platform,\r
+int update_windows_directories(FILE* log, long abi_major, enum Platform platform, const char* api_name,\r
     struct SDKVersion* latest_runtime_version);\r
 \r
 int main(int argc, char** argv)\r
@@ -189,24 +199,28 @@ int main(int argc, char** argv)
 \r
     // Parse the arguments to get the abi version and the number of bits of the OS\r
     long abi_major;\r
-    CHECK_ERROR_HANDLED(parse_arguments(log, argc, argv, &abi_major), { fclose(log); });\r
+    const char* api_name;\r
+    CHECK_ERROR_HANDLED(parse_arguments(log, argc, argv, &abi_major, &api_name), { fclose(log); });\r
+    \r
+    fprintf(log, "API Name: %s\n", api_name);\r
     \r
     // This makes System32 and SysWOW64 not do any redirection (well, until 128-bit is a thing)\r
     Wow64DisableWow64FsRedirection(NULL);\r
     \r
     // Update System32 (on all systems) and SysWOW64 on 64-bit system\r
     struct SDKVersion latest_runtime_version;\r
-    CHECK_ERROR_HANDLED(update_windows_directories(log, abi_major, platform, &latest_runtime_version),\r
-        { fclose(log); });\r
+    CHECK_ERROR_HANDLED(update_windows_directories(log, abi_major, platform, api_name,\r
+        &latest_runtime_version), { fclose(log); });\r
 \r
     // Update the explicit layers that are set in the windows registry\r
-    CHECK_ERROR_HANDLED(update_registry_layers(log, platform, &latest_runtime_version), { fclose(log); });\r
+    CHECK_ERROR_HANDLED(update_registry_layers(log, platform, &latest_runtime_version, api_name),\r
+        { fclose(log); });\r
 \r
     fclose(log);\r
     return 0;\r
 }\r
 \r
-int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform)\r
+int add_explicit_layers(FILE* log, const char* install_path, enum Platform platform, const char* api_name)\r
 {\r
     switch(platform)\r
     {\r
@@ -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);\r
         break;\r
     }\r
+    \r
+    const char* registry_pattern = "SOFTWARE\\Khronos\\%s\\ExplicitLayers";\r
+    int registry_size = snprintf(NULL, 0, registry_pattern, api_name) + 1;\r
+    char* registry_key = malloc(registry_size);\r
+    snprintf(registry_key, registry_size, registry_pattern, api_name);\r
 \r
     // If this is a 32 bit system, we allow redirection to point this at the 32-bit registries.\r
     // If not, we add the flag KEY_WOW64_64KEY, to disable redirection for this node.\r
@@ -227,8 +246,9 @@ int add_explicit_layers(FILE* log, const char* install_path, enum Platform platf
     }\r
     \r
     // Create (if needed) and open the explicit layer key\r
-    if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers",\r
-        0, NULL, REG_OPTION_NON_VOLATILE, flags, NULL, &hKey, NULL) != ERROR_SUCCESS) {\r
+    if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry_key, 0, NULL, REG_OPTION_NON_VOLATILE, flags,\r
+         NULL, &hKey, NULL) != ERROR_SUCCESS) {\r
+        free(registry_key);\r
         return 20;\r
     }\r
 \r
@@ -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";\r
         int layer_size = snprintf(NULL, 0, layer_pattern, install_path, find_data.cFileName) + 1;\r
         if(layer_size < 0) {\r
+            free(registry_key);\r
             return 40;\r
         }\r
         char* layer = malloc(layer_size);\r
@@ -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));\r
         free(layer);\r
         if(err != ERROR_SUCCESS) {\r
+            free(registry_key);\r
             return 50;\r
         }\r
     }\r
 \r
     RegCloseKey(hKey);\r
+    free(registry_key);\r
     return 0;\r
 }\r
 \r
@@ -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);\r
 }\r
 \r
-int find_installations(char*** install_paths, struct SDKVersion** install_versions, size_t* count)\r
+int find_installations(const char* api_name, char*** install_paths, struct SDKVersion** install_versions, size_t* count)\r
 {\r
     *install_paths = malloc(sizeof(char*) * 64);\r
     *install_versions = malloc(sizeof(struct SDKVersion) * 64);\r
@@ -307,6 +330,11 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio
         return 90;\r
     }\r
     \r
+    size_t api_len = strlen(api_name);\r
+    char* sdk_id = malloc(api_len + 4);\r
+    strcpy(sdk_id, api_name);\r
+    strcpy(sdk_id + api_len, "SDK");\r
+    \r
     DWORD keyCount, keyLen;\r
     RegQueryInfoKey(hKey, NULL, NULL, NULL, &keyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL);\r
     for(int i = 0; i < keyCount; ++i) {\r
@@ -314,7 +342,7 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio
         DWORD nameSize = COPY_BUFFER_SIZE;\r
         RegEnumKeyEx(hKey, i, name, &nameSize, NULL, NULL, NULL, NULL);\r
         \r
-        if(strncmp("VulkanSDK", name, 9)) {\r
+        if(strncmp(sdk_id, name, api_len + 3)) {\r
             continue;\r
         }\r
         \r
@@ -351,10 +379,12 @@ int find_installations(char*** install_paths, struct SDKVersion** install_versio
         \r
         if(!(found_installation && found_version)) {\r
             RegCloseKey(hKey);\r
+            free(sdk_id);\r
             return 100;\r
         }\r
     }\r
     RegCloseKey(hKey);\r
+    free(sdk_id);\r
     \r
     return 0;\r
 }\r
@@ -368,9 +398,10 @@ void free_installations(char** install_paths, struct SDKVersion* install_version
     free(install_versions);\r
 }\r
 \r
-int parse_arguments(FILE* log, int argc, char** argv, long* abi_major)\r
+int parse_arguments(FILE* log, int argc, char** argv, long* abi_major, const char** api_name)\r
 {\r
     *abi_major = 0;\r
+    *api_name = "Vulkan";\r
 \r
     // Parse arguments\r
     for(int i = 0; i < argc; ++i) {\r
@@ -385,6 +416,13 @@ int parse_arguments(FILE* log, int argc, char** argv, long* abi_major)
                 return 120;\r
             }\r
         }\r
+        if(!strcmp(argv[i], FLAG_API_NAME)) {\r
+            if(i + 1 == argc) {\r
+                fprintf(log, "ERROR: No value given for flag %s.\n", FLAG_API_NAME);\r
+                return 124;\r
+            }\r
+            *api_name = argv[++i];\r
+        }\r
     }\r
     \r
     // Check that we have everything we need\r
@@ -466,7 +504,8 @@ int read_version_from_filename(const char* filename, struct SDKVersion* version)
     return 0;\r
 }\r
 \r
-int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform)\r
+int remove_explicit_layers(FILE* log, const char** install_paths, size_t count, enum Platform platform,\r
+    const char* api_name)\r
 {\r
     switch(platform)\r
     {\r
@@ -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");\r
         break;\r
     }\r
+    \r
+    const char* pattern = "SOFTWARE\\Khronos\\%s\\ExplicitLayers";\r
+    int registry_size = snprintf(NULL, 0, pattern, api_name) + 1;\r
+    char* registry_key = malloc(registry_size);\r
+    snprintf(registry_key, registry_size, pattern, api_name);\r
 \r
     bool removed_one;\r
     do {\r
@@ -489,8 +533,9 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count,
         }\r
 \r
         // Create (if needed) and open the explicit layer key\r
-        if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers",\r
-            0, NULL, REG_OPTION_NON_VOLATILE, flags, NULL, &hKey, NULL) != ERROR_SUCCESS) {\r
+        if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry_key, 0, NULL, REG_OPTION_NON_VOLATILE, flags,\r
+            NULL, &hKey, NULL) != ERROR_SUCCESS) {\r
+            free(registry_key);\r
             return 160;\r
         }\r
 \r
@@ -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);\r
                     LSTATUS err = RegDeleteValue(hKey, name);\r
                     if(err != ERROR_SUCCESS) {\r
+                        free(registry_key);\r
                         return 170;\r
                     }\r
                     removed_one = true;\r
@@ -520,16 +566,18 @@ int remove_explicit_layers(FILE* log, const char** install_paths, size_t count,
 \r
         RegCloseKey(hKey);\r
     } while(removed_one);\r
-\r
+    \r
+    free(registry_key);\r
     return 0;\r
 }\r
 \r
-int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version)\r
+int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVersion* version,\r
+    const char* api_name)\r
 {\r
     char** install_paths;\r
     struct SDKVersion* install_versions;\r
     size_t count;\r
-    CHECK_ERROR_HANDLED(find_installations(&install_paths, &install_versions, &count),\r
+    CHECK_ERROR_HANDLED(find_installations(api_name, &install_paths, &install_versions, &count),\r
         { free_installations(install_paths, install_versions, count); });\r
     for(size_t i = 0; i < count; ++i) {\r
         fprintf(log, "Found installation of %ld.%ld.%ld.%ld in: %s\n", install_versions[i].major,\r
@@ -537,11 +585,11 @@ int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVe
     }\r
     fprintf(log, "\n");\r
     if(platform == PLATFORM_X64) {\r
-        CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X64),\r
+        CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X64, api_name),\r
             { free_installations(install_paths, install_versions, count); });\r
         fprintf(log, "\n");\r
     }\r
-    CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X86),\r
+    CHECK_ERROR_HANDLED(remove_explicit_layers(log, install_paths, count, PLATFORM_X86, api_name),\r
         { free_installations(install_paths, install_versions, count); });\r
     fprintf(log, "\n");\r
 \r
@@ -553,11 +601,11 @@ int update_registry_layers(FILE* log, enum Platform platform, const struct SDKVe
     for(size_t i = 0; i < count; ++i) {\r
         if(compare_versions(install_versions + i, version) == 0) {\r
             if(platform == PLATFORM_X64) {\r
-                CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X64),\r
+                CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X64, api_name),\r
                     { free_installations(install_paths, install_versions, count); });\r
                 fprintf(log, "\n");\r
             }\r
-            CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X86),\r
+            CHECK_ERROR_HANDLED(add_explicit_layers(log, install_paths[i], PLATFORM_X86, api_name),\r
                 { free_installations(install_paths, install_versions, count); });\r
             break;\r
         }\r
@@ -658,8 +706,19 @@ int update_system_file(FILE* log, const char* name, const char* extension, const
     return 0;\r
 }\r
 \r
-int update_windows_directories(FILE* log, long abi_major, enum Platform platform, struct SDKVersion* latest_runtime_version)\r
+int update_windows_directories(FILE* log, long abi_major, enum Platform platform, const char* api_name,\r
+    struct SDKVersion* latest_runtime_version)\r
 {\r
+    size_t api_len = strlen(api_name);\r
+    char* vulkan_name = malloc(api_len + 1);\r
+    char* vulkan_info_name = malloc(api_len + 5);\r
+    for(size_t i = 0; i < api_len; ++i) {\r
+        vulkan_name[i] = tolower(api_name[i]);\r
+    }\r
+    vulkan_name[api_len] = '\0';\r
+    strcpy(vulkan_info_name, vulkan_name);\r
+    strcpy(vulkan_info_name + api_len, "info");\r
+    \r
     struct SDKVersion version;\r
     unsigned windows_path_size = GetWindowsDirectory(NULL, 0); // Size includes null terminator\r
     char* system_path = malloc(windows_path_size +\r
@@ -668,33 +727,41 @@ int update_windows_directories(FILE* log, long abi_major, enum Platform platform
 \r
     strcpy(system_path + windows_path_size - 1, PATH_SYSTEM32);\r
     fprintf(log, "Updating system directory: %s\n", system_path);\r
-    CHECK_ERROR_HANDLED(update_system_file(log, "vulkan", ".dll", system_path, abi_major, true,\r
+    CHECK_ERROR_HANDLED(update_system_file(log, vulkan_name, ".dll", system_path, abi_major, true,\r
         latest_runtime_version), { free(system_path); });\r
-    CHECK_ERROR_HANDLED(update_system_file(log, "vulkaninfo", ".exe", system_path, abi_major, false,\r
-        &version), { free(system_path); });\r
+    CHECK_ERROR_HANDLED(update_system_file(log, vulkan_info_name, ".exe", system_path, abi_major, false,\r
+        &version), { free(system_path); free(vulkan_info_name); free(vulkan_name);});\r
     if(compare_versions(latest_runtime_version, &version) != 0) {\r
         free(system_path);\r
+        free(vulkan_info_name);\r
+        free(vulkan_name);\r
         return 220;\r
     }\r
 \r
     if(platform == PLATFORM_X64) {\r
         strcpy(system_path + windows_path_size - 1, PATH_SYSWOW64);\r
         fprintf(log, "\nUpdating system directory: %s\n", system_path);\r
-        CHECK_ERROR_HANDLED(update_system_file(log, "vulkan", ".dll", system_path, abi_major,\r
-            true, &version), { free(system_path); });\r
+        CHECK_ERROR_HANDLED(update_system_file(log, vulkan_name, ".dll", system_path, abi_major,\r
+            true, &version), { free(system_path); free(vulkan_info_name); free(vulkan_name); });\r
         if(compare_versions(latest_runtime_version, &version) != 0) {\r
             free(system_path);\r
+            free(vulkan_info_name);\r
+            free(vulkan_name);\r
             return 230;\r
         }\r
-        CHECK_ERROR_HANDLED(update_system_file(log, "vulkaninfo", ".exe", system_path, abi_major,\r
-            false, &version), { free(system_path); });\r
+        CHECK_ERROR_HANDLED(update_system_file(log, vulkan_info_name, ".exe", system_path, abi_major,\r
+            false, &version), { free(system_path); free(vulkan_info_name); free(vulkan_name); });\r
         if(compare_versions(latest_runtime_version, &version) != 0) {\r
             free(system_path);\r
+            free(vulkan_info_name);\r
+            free(vulkan_name);\r
             return 240;\r
         }\r
     }\r
 \r
     free(system_path);\r
+    free(vulkan_info_name);\r
+    free(vulkan_name);\r
     fprintf(log, "\nUpdate of system directories succeeded.\n\n");\r
     return 0;\r
 }\r