winsdk: Parameterize ConfigureRT program
Change-Id: I2f869d5a71fb6c5411aa2ab6a3b133c37fb52a09
diff --git a/windowsRuntimeInstaller/InstallerRT.nsi b/windowsRuntimeInstaller/InstallerRT.nsi
index 08d0e57..5b13a6d 100644
--- a/windowsRuntimeInstaller/InstallerRT.nsi
+++ b/windowsRuntimeInstaller/InstallerRT.nsi
@@ -250,7 +250,7 @@
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 a8460a1..2041f42 100644
--- a/windowsRuntimeInstaller/configure_runtime.c
+++ b/windowsRuntimeInstaller/configure_runtime.c
@@ -77,6 +77,7 @@
};
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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if(!(found_installation && found_version)) {
RegCloseKey(hKey);
+ free(sdk_id);
return 100;
}
}
RegCloseKey(hKey);
+ free(sdk_id);
return 0;
}
@@ -368,9 +398,10 @@
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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;
}