/*
 *
 * Copyright (c) 2014-2022 The Khronos Group Inc.
 * Copyright (c) 2014-2022 Valve Corporation
 * Copyright (c) 2014-2022 LunarG, Inc.
 * Copyright (C) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Jon Ashburn <jon@lunarg.com>
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: Chia-I Wu <olvaffe@gmail.com>
 * Author: Chia-I Wu <olv@lunarg.com>
 * Author: Mark Lobodzinski <mark@LunarG.com>
 * Author: Lenny Komow <lenny@lunarg.com>
 * Author: Charles Giessen <charles@lunarg.com>
 *
 */
// Windows only header file, guard it so that accidental inclusion doesn't cause unknown header include errors
#if defined(_WIN32)

// This needs to be defined first, or else we'll get redefinitions on NTSTATUS values
#define UMDF_USING_NTSTATUS
#include <ntstatus.h>

#include "loader_windows.h"

#include "allocation.h"
#include "loader_environment.h"
#include "loader.h"
#include "log.h"

#include <cfgmgr32.h>
#include <initguid.h>
#include <devpkey.h>
#include <winternl.h>
#include <strsafe.h>
#if defined(__MINGW32__)
#undef strcpy  // fix error with redfined strcpy when building with MinGW-w64
#endif
#include <dxgi1_6.h>
#include "adapters.h"

#if !defined(__MINGW32__)
// not yet available with MinGW-w64 stable
#include <appmodel.h>
#endif

#if !defined(NDEBUG)
#include <crtdbg.h>
#endif

typedef HRESULT(APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
PFN_CreateDXGIFactory1 fpCreateDXGIFactory1;

// Empty function just so windows_initialization can find the current module location
void function_for_finding_the_current_module(void) {}

void windows_initialization(void) {
    char dll_location[MAX_PATH];
    HMODULE module_handle = NULL;

    // Get a module handle to a static function inside of this source
    if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                          (LPCSTR)&function_for_finding_the_current_module, &module_handle) != 0 &&
        GetModuleFileName(module_handle, dll_location, sizeof(dll_location)) != 0) {
        loader_log(NULL, VULKAN_LOADER_INFO_BIT, 0, "Using Vulkan Loader %s", dll_location);
    }

    // This is needed to ensure that newer APIs are available right away
    // and not after the first call that has been statically linked
    LoadLibrary("gdi32.dll");

    wchar_t systemPath[MAX_PATH] = L"";
    GetSystemDirectoryW(systemPath, MAX_PATH);
    StringCchCatW(systemPath, MAX_PATH, L"\\dxgi.dll");
    HMODULE dxgi_module = LoadLibraryW(systemPath);
    fpCreateDXGIFactory1 =
        dxgi_module == NULL ? NULL : (PFN_CreateDXGIFactory1)(void *)GetProcAddress(dxgi_module, "CreateDXGIFactory1");

#if !defined(NDEBUG)
    _set_error_mode(_OUT_TO_STDERR);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
#endif
}

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
    switch (reason) {
        case DLL_PROCESS_ATTACH:
            loader_initialize();
            break;
        case DLL_PROCESS_DETACH:
            if (NULL == reserved) {
                loader_release();
            }
            break;
        default:
            // Do nothing
            break;
    }
    return TRUE;
}

bool windows_add_json_entry(const struct loader_instance *inst,
                            char **reg_data,    // list of JSON files
                            PDWORD total_size,  // size of reg_data
                            LPCSTR key_name,    // key name - used for debug prints - i.e. VulkanDriverName
                            DWORD key_type,     // key data type
                            LPSTR json_path,    // JSON string to add to the list reg_data
                            DWORD json_size,    // size in bytes of json_path
                            VkResult *result) {
    // Check for and ignore duplicates.
    if (*reg_data && strstr(*reg_data, json_path)) {
        // Success. The json_path is already in the list.
        return true;
    }

    if (NULL == *reg_data) {
        *reg_data = loader_instance_heap_alloc(inst, *total_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (NULL == *reg_data) {
            loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                       "windows_add_json_entry: Failed to allocate space for registry data for key %s", json_path);
            *result = VK_ERROR_OUT_OF_HOST_MEMORY;
            return false;
        }
        *reg_data[0] = '\0';
    } else if (strlen(*reg_data) + json_size + 1 > *total_size) {
        void *new_ptr =
            loader_instance_heap_realloc(inst, *reg_data, *total_size, *total_size * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (NULL == new_ptr) {
            loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                       "windows_add_json_entry: Failed to reallocate space for registry value of size %d for key %s",
                       *total_size * 2, json_path);
            *result = VK_ERROR_OUT_OF_HOST_MEMORY;
            return false;
        }
        *reg_data = new_ptr;
        *total_size *= 2;
    }

    for (char *curr_filename = json_path; curr_filename[0] != '\0'; curr_filename += strlen(curr_filename) + 1) {
        if (strlen(*reg_data) == 0) {
            (void)snprintf(*reg_data, json_size + 1, "%s", curr_filename);
        } else {
            (void)snprintf(*reg_data + strlen(*reg_data), json_size + 2, "%c%s", PATH_SEPARATOR, curr_filename);
        }
        loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "%s: Located json file \"%s\" from PnP registry: %s", __FUNCTION__,
                   curr_filename, key_name);

        if (key_type == REG_SZ) {
            break;
        }
    }
    return true;
}

bool windows_get_device_registry_entry(const struct loader_instance *inst, char **reg_data, PDWORD total_size, DEVINST dev_id,
                                       LPCSTR value_name, VkResult *result) {
    HKEY hkrKey = INVALID_HANDLE_VALUE;
    DWORD requiredSize, data_type;
    char *manifest_path = NULL;
    bool found = false;

    assert(reg_data != NULL && "windows_get_device_registry_entry: reg_data is a NULL pointer");
    assert(total_size != NULL && "windows_get_device_registry_entry: total_size is a NULL pointer");

    CONFIGRET status = CM_Open_DevNode_Key(dev_id, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkrKey, CM_REGISTRY_SOFTWARE);
    if (status != CR_SUCCESS) {
        loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                   "windows_get_device_registry_entry: Failed to open registry key for DeviceID(%d)", dev_id);
        *result = VK_ERROR_INCOMPATIBLE_DRIVER;
        return false;
    }

    // query value
    LSTATUS ret = RegQueryValueEx(hkrKey, value_name, NULL, NULL, NULL, &requiredSize);

    if (ret != ERROR_SUCCESS) {
        if (ret == ERROR_FILE_NOT_FOUND) {
            loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                       "windows_get_device_registry_entry: Device ID(%d) Does not contain a value for \"%s\"", dev_id, value_name);
        } else {
            loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                       "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s size", dev_id, value_name);
        }
        goto out;
    }

    manifest_path = loader_instance_heap_alloc(inst, requiredSize, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (manifest_path == NULL) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                   "windows_get_device_registry_entry: Failed to allocate space for DriverName.");
        *result = VK_ERROR_OUT_OF_HOST_MEMORY;
        goto out;
    }

    ret = RegQueryValueEx(hkrKey, value_name, NULL, &data_type, (BYTE *)manifest_path, &requiredSize);

    if (ret != ERROR_SUCCESS) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                   "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s", value_name);
        *result = VK_ERROR_INCOMPATIBLE_DRIVER;
        goto out;
    }

    if (data_type != REG_SZ && data_type != REG_MULTI_SZ) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                   "windows_get_device_registry_entry: Invalid %s data type. Expected REG_SZ or REG_MULTI_SZ.", value_name);
        *result = VK_ERROR_INCOMPATIBLE_DRIVER;
        goto out;
    }

    found = windows_add_json_entry(inst, reg_data, total_size, value_name, data_type, manifest_path, requiredSize, result);

out:
    loader_instance_heap_free(inst, manifest_path);
    RegCloseKey(hkrKey);
    return found;
}

VkResult windows_get_device_registry_files(const struct loader_instance *inst, uint32_t log_target_flag, char **reg_data,
                                           PDWORD reg_data_size, LPCSTR value_name) {
    const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
    const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
#if defined(CM_GETIDLIST_FILTER_PRESENT)
    const ULONG flags = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
#else
    const ULONG flags = 0x300;
#endif

    wchar_t childGuid[MAX_GUID_STRING_LEN + 2];  // +2 for brackets {}
    for (uint32_t i = 0; i < MAX_GUID_STRING_LEN + 2; i++) {
        childGuid[i] = L'\0';
    }
    ULONG childGuidSize = sizeof(childGuid);

    DEVINST devID = 0, childID = 0;
    wchar_t *pDeviceNames = NULL;
    ULONG deviceNamesSize = 0;
    VkResult result = VK_SUCCESS;
    bool found = false;

    assert(reg_data != NULL && "windows_get_device_registry_files: reg_data is NULL");

    // if after obtaining the DeviceNameSize, new device is added start over
    do {
        CM_Get_Device_ID_List_SizeW(&deviceNamesSize, displayGUID, flags);

        loader_instance_heap_free(inst, pDeviceNames);

        pDeviceNames = loader_instance_heap_alloc(inst, deviceNamesSize * sizeof(wchar_t), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (pDeviceNames == NULL) {
            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                       "windows_get_device_registry_files: Failed to allocate space for display device names.");
            result = VK_ERROR_OUT_OF_HOST_MEMORY;
            return result;
        }
    } while (CM_Get_Device_ID_ListW(displayGUID, pDeviceNames, deviceNamesSize, flags) == CR_BUFFER_SMALL);

    if (pDeviceNames) {
        for (wchar_t *deviceName = pDeviceNames; *deviceName; deviceName += wcslen(deviceName) + 1) {
            CONFIGRET status = CM_Locate_DevNodeW(&devID, deviceName, CM_LOCATE_DEVNODE_NORMAL);
            if (CR_SUCCESS != status) {
                loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                           "windows_get_device_registry_files: failed to open DevNode %ls", deviceName);
                continue;
            }
            ULONG ulStatus, ulProblem;
            status = CM_Get_DevNode_Status(&ulStatus, &ulProblem, devID, 0);

            if (CR_SUCCESS != status) {
                loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                           "windows_get_device_registry_files: failed to probe device status %ls", deviceName);
                continue;
            }
            if ((ulStatus & DN_HAS_PROBLEM) && (ulProblem == CM_PROB_NEED_RESTART || ulProblem == DN_NEED_RESTART)) {
                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                           "windows_get_device_registry_files: device %ls is pending reboot, skipping ...", deviceName);
                continue;
            }

            loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0, "windows_get_device_registry_files: opening device %ls",
                       deviceName);

            if (windows_get_device_registry_entry(inst, reg_data, reg_data_size, devID, value_name, &result)) {
                found = true;
                continue;
            } else if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
                break;
            }

            status = CM_Get_Child(&childID, devID, 0);
            if (status != CR_SUCCESS) {
                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                           "windows_get_device_registry_files: unable to open child-device error:%d", status);
                continue;
            }

            do {
                wchar_t buffer[MAX_DEVICE_ID_LEN];
                CM_Get_Device_IDW(childID, buffer, MAX_DEVICE_ID_LEN, 0);

                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                           "windows_get_device_registry_files: Opening child device %d - %ls", childID, buffer);

                status = CM_Get_DevNode_Registry_PropertyW(childID, CM_DRP_CLASSGUID, NULL, &childGuid, &childGuidSize, 0);
                if (status != CR_SUCCESS) {
                    loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                               "windows_get_device_registry_files: unable to obtain GUID for:%d error:%d", childID, status);

                    result = VK_ERROR_INCOMPATIBLE_DRIVER;
                    continue;
                }

                if (wcscmp(childGuid, softwareComponentGUID) != 0) {
                    loader_log(inst, VULKAN_LOADER_DEBUG_BIT | log_target_flag, 0,
                               "windows_get_device_registry_files: GUID for %d is not SoftwareComponent skipping", childID);
                    continue;
                }

                if (windows_get_device_registry_entry(inst, reg_data, reg_data_size, childID, value_name, &result)) {
                    found = true;
                    break;  // check next-display-device
                }

            } while (CM_Get_Sibling(&childID, childID, 0) == CR_SUCCESS);
        }

        loader_instance_heap_free(inst, pDeviceNames);
    }

    if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
        loader_log(inst, log_target_flag, 0, "windows_get_device_registry_files: found no registry files");
        result = VK_ERROR_INCOMPATIBLE_DRIVER;
    }

    return result;
}

VkResult windows_get_registry_files(const struct loader_instance *inst, char *location, bool use_secondary_hive, char **reg_data,
                                    PDWORD reg_data_size) {
    // This list contains all of the allowed ICDs. This allows us to verify that a device is actually present from the vendor
    // specified. This does disallow other vendors, but any new driver should use the device-specific registries anyway.
    const struct {
        const char *filename;
        unsigned int vendor_id;
    } known_drivers[] = {
#if defined(_WIN64)
        {
            .filename = "igvk64.json",
            .vendor_id = 0x8086,
        },
        {
            .filename = "nv-vk64.json",
            .vendor_id = 0x10de,
        },
        {
            .filename = "amd-vulkan64.json",
            .vendor_id = 0x1002,
        },
        {
            .filename = "amdvlk64.json",
            .vendor_id = 0x1002,
        },
#else
        {
            .filename = "igvk32.json",
            .vendor_id = 0x8086,
        },
        {
            .filename = "nv-vk32.json",
            .vendor_id = 0x10de,
        },
        {
            .filename = "amd-vulkan32.json",
            .vendor_id = 0x1002,
        },
        {
            .filename = "amdvlk32.json",
            .vendor_id = 0x1002,
        },
#endif
    };

    LONG rtn_value;
    HKEY hive = DEFAULT_VK_REGISTRY_HIVE, key;
    DWORD access_flags;
    char name[2048];
    char *loc = location;
    char *next;
    DWORD name_size = sizeof(name);
    DWORD value;
    DWORD value_size = sizeof(value);
    VkResult result = VK_SUCCESS;
    bool found = false;
    IDXGIFactory1 *dxgi_factory = NULL;
    bool is_driver = !strcmp(location, VK_DRIVERS_INFO_REGISTRY_LOC);
    uint32_t log_target_flag = is_driver ? VULKAN_LOADER_DRIVER_BIT : VULKAN_LOADER_LAYER_BIT;

    assert(reg_data != NULL && "windows_get_registry_files: reg_data is a NULL pointer");

    if (is_driver) {
        HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&dxgi_factory);
        if (hres != S_OK) {
            loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                       "windows_get_registry_files: Failed to create dxgi factory for ICD registry verification. No ICDs will be "
                       "added from "
                       "legacy registry locations");
            goto out;
        }
    }

    while (*loc) {
        next = loader_get_next_path(loc);
        access_flags = KEY_QUERY_VALUE;
        rtn_value = RegOpenKeyEx(hive, loc, 0, access_flags, &key);
        if (ERROR_SUCCESS == rtn_value) {
            for (DWORD idx = 0;
                 (rtn_value = RegEnumValue(key, idx++, name, &name_size, NULL, NULL, (LPBYTE)&value, &value_size)) == ERROR_SUCCESS;
                 name_size = sizeof(name), value_size = sizeof(value)) {
                if (value_size == sizeof(value) && value == 0) {
                    if (NULL == *reg_data) {
                        *reg_data = loader_instance_heap_alloc(inst, *reg_data_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                        if (NULL == *reg_data) {
                            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                                       "windows_get_registry_files: Failed to allocate space for registry data for key %s", name);
                            RegCloseKey(key);
                            result = VK_ERROR_OUT_OF_HOST_MEMORY;
                            goto out;
                        }
                        *reg_data[0] = '\0';
                    } else if (strlen(*reg_data) + name_size + 1 > *reg_data_size) {
                        void *new_ptr = loader_instance_heap_realloc(inst, *reg_data, *reg_data_size, *reg_data_size * 2,
                                                                     VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                        if (NULL == new_ptr) {
                            loader_log(
                                inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                                "windows_get_registry_files: Failed to reallocate space for registry value of size %d for key %s",
                                *reg_data_size * 2, name);
                            RegCloseKey(key);
                            result = VK_ERROR_OUT_OF_HOST_MEMORY;
                            goto out;
                        }
                        *reg_data = new_ptr;
                        *reg_data_size *= 2;
                    }

                    // We've now found a json file. If this is an ICD, we still need to check if there is actually a device
                    // that matches this ICD
                    loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                               "Located json file \"%s\" from registry \"%s\\%s\"", name,
                               hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR,
                               location);
                    if (is_driver) {
                        uint32_t i = 0;
                        for (i = 0; i < sizeof(known_drivers) / sizeof(known_drivers[0]); ++i) {
                            if (!strcmp(name + strlen(name) - strlen(known_drivers[i].filename), known_drivers[i].filename)) {
                                break;
                            }
                        }
                        if (i == sizeof(known_drivers) / sizeof(known_drivers[0])) {
                            loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                       "Driver %s is not recognized as a known driver. It will be assumed to be active", name);
                        } else {
                            bool found_gpu = false;
                            for (int j = 0;; ++j) {
                                IDXGIAdapter1 *adapter;
                                HRESULT hres = dxgi_factory->lpVtbl->EnumAdapters1(dxgi_factory, j, &adapter);
                                if (hres == DXGI_ERROR_NOT_FOUND) {
                                    break;
                                } else if (hres != S_OK) {
                                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                                               "Failed to enumerate DXGI adapters at index %d. As a result, drivers may be skipped",
                                               j);
                                    continue;
                                }

                                DXGI_ADAPTER_DESC1 description;
                                hres = adapter->lpVtbl->GetDesc1(adapter, &description);
                                if (hres != S_OK) {
                                    loader_log(
                                        inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                        "Failed to get DXGI adapter information at index %d. As a result, drivers may be skipped",
                                        j);
                                    continue;
                                }

                                if (description.VendorId == known_drivers[i].vendor_id) {
                                    found_gpu = true;
                                    break;
                                }
                            }

                            if (!found_gpu) {
                                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                           "Dropping driver %s as no corresponding DXGI adapter was found", name);
                                continue;
                            }
                        }
                    }

                    if (strlen(*reg_data) == 0) {
                        // The list is emtpy. Add the first entry.
                        (void)snprintf(*reg_data, name_size + 1, "%s", name);
                        found = true;
                    } else {
                        // At this point the reg_data variable contains other JSON paths, likely from the PNP/device section
                        // of the registry that we want to have precedence over this non-device specific section of the registry.
                        // To make sure we avoid enumerating old JSON files/drivers that might be present in the non-device specific
                        // area of the registry when a newer device specific JSON file is present, do a check before adding.
                        // Find the file name, without path, of the JSON file found in the non-device specific registry location.
                        // If the same JSON file name is already found in the list, don't add it again.
                        bool foundDuplicate = false;
                        char *pLastSlashName = strrchr(name, '\\');
                        if (pLastSlashName != NULL) {
                            char *foundMatch = strstr(*reg_data, pLastSlashName + 1);
                            if (foundMatch != NULL) {
                                foundDuplicate = true;
                            }
                        }
                        // Only skip if we are adding a driver and a duplicate was found
                        if (!is_driver || (is_driver && foundDuplicate == false)) {
                            // Add the new entry to the list.
                            (void)snprintf(*reg_data + strlen(*reg_data), name_size + 2, "%c%s", PATH_SEPARATOR, name);
                            found = true;
                        } else {
                            loader_log(
                                inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                "Skipping adding of json file \"%s\" from registry \"%s\\%s\" to the list due to duplication", name,
                                hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR,
                                location);
                        }
                    }
                }
            }
            RegCloseKey(key);
        }

        // Advance the location - if the next location is in the secondary hive, then reset the locations and advance the hive
        if (use_secondary_hive && (hive == DEFAULT_VK_REGISTRY_HIVE) && (*next == '\0')) {
            loc = location;
            hive = SECONDARY_VK_REGISTRY_HIVE;
        } else {
            loc = next;
        }
    }

    if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
        loader_log(inst, log_target_flag, 0, "Found no registry files in %s\\%s",
                   (hive == DEFAULT_VK_REGISTRY_HIVE) ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR, location);
        result = VK_ERROR_INCOMPATIBLE_DRIVER;
    }

out:
    if (is_driver && dxgi_factory != NULL) {
        dxgi_factory->lpVtbl->Release(dxgi_factory);
    }

    return result;
}

// Read manifest JSON files using the Windows driver interface
VkResult windows_read_manifest_from_d3d_adapters(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
                                                 const wchar_t *value_name) {
    VkResult result = VK_INCOMPLETE;
    LoaderEnumAdapters2 adapters = {.adapter_count = 0, .adapters = NULL};
    LoaderQueryRegistryInfo *full_info = NULL;
    size_t full_info_size = 0;
    char *json_path = NULL;
    size_t json_path_size = 0;

    HMODULE gdi32_dll = GetModuleHandle("gdi32.dll");
    if (gdi32_dll == NULL) {
        result = VK_ERROR_INCOMPATIBLE_DRIVER;
        goto out;
    }

    PFN_LoaderEnumAdapters2 fpLoaderEnumAdapters2 =
        (PFN_LoaderEnumAdapters2)(void *)GetProcAddress(gdi32_dll, "D3DKMTEnumAdapters2");
    PFN_LoaderQueryAdapterInfo fpLoaderQueryAdapterInfo =
        (PFN_LoaderQueryAdapterInfo)(void *)GetProcAddress(gdi32_dll, "D3DKMTQueryAdapterInfo");
    if (fpLoaderEnumAdapters2 == NULL || fpLoaderQueryAdapterInfo == NULL) {
        result = VK_ERROR_INCOMPATIBLE_DRIVER;
        goto out;
    }

    // Get all of the adapters
    NTSTATUS status = fpLoaderEnumAdapters2(&adapters);
    if (status == STATUS_SUCCESS && adapters.adapter_count > 0) {
        adapters.adapters = loader_instance_heap_alloc(inst, sizeof(*adapters.adapters) * adapters.adapter_count,
                                                       VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
        if (adapters.adapters == NULL) {
            goto out;
        }
        status = fpLoaderEnumAdapters2(&adapters);
    }
    if (status != STATUS_SUCCESS) {
        goto out;
    }

    // If that worked, we need to get the manifest file(s) for each adapter
    for (ULONG i = 0; i < adapters.adapter_count; ++i) {
        // The first query should just check if the field exists and how big it is
        LoaderQueryRegistryInfo filename_info = {
            .query_type = LOADER_QUERY_REGISTRY_ADAPTER_KEY,
            .query_flags =
                {
                    .translate_path = true,
                },
            .value_type = REG_MULTI_SZ,
            .physical_adapter_index = 0,
        };
        wcsncpy(filename_info.value_name, value_name, sizeof(filename_info.value_name) / sizeof(WCHAR));
        LoaderQueryAdapterInfo query_info;
        query_info.handle = adapters.adapters[i].handle;
        query_info.type = LOADER_QUERY_TYPE_REGISTRY;
        query_info.private_data = &filename_info;
        query_info.private_data_size = sizeof(filename_info);
        status = fpLoaderQueryAdapterInfo(&query_info);

        // This error indicates that the type didn't match, so we'll try a REG_SZ
        if (status != STATUS_SUCCESS) {
            filename_info.value_type = REG_SZ;
            status = fpLoaderQueryAdapterInfo(&query_info);
        }

        if (status != STATUS_SUCCESS || filename_info.status != LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
            continue;
        }

        while (status == STATUS_SUCCESS &&
               ((LoaderQueryRegistryInfo *)query_info.private_data)->status == LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
            bool needs_copy = (full_info == NULL);
            size_t full_size = sizeof(LoaderQueryRegistryInfo) + filename_info.output_value_size;
            void *buffer =
                loader_instance_heap_realloc(inst, full_info, full_info_size, full_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
            if (buffer == NULL) {
                result = VK_ERROR_OUT_OF_HOST_MEMORY;
                goto out;
            }
            full_info = buffer;
            full_info_size = full_size;

            if (needs_copy) {
                memcpy(full_info, &filename_info, sizeof(LoaderQueryRegistryInfo));
            }
            query_info.private_data = full_info;
            query_info.private_data_size = (UINT)full_info_size;
            status = fpLoaderQueryAdapterInfo(&query_info);
        }

        if (status != STATUS_SUCCESS || full_info->status != LOADER_QUERY_REGISTRY_STATUS_SUCCESS) {
            goto out;
        }

        // Convert the wide string to a narrow string
        void *buffer = loader_instance_heap_realloc(inst, json_path, json_path_size, full_info->output_value_size,
                                                    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
        if (buffer == NULL) {
            result = VK_ERROR_OUT_OF_HOST_MEMORY;
            goto out;
        }
        json_path = buffer;
        json_path_size = full_info->output_value_size;

        // Iterate over each component string
        for (const wchar_t *curr_path = full_info->output_string; curr_path[0] != '\0'; curr_path += wcslen(curr_path) + 1) {
            WideCharToMultiByte(CP_UTF8, 0, curr_path, -1, json_path, (int)json_path_size, NULL, NULL);

            // Add the string to the output list
            result = VK_SUCCESS;
            windows_add_json_entry(inst, reg_data, reg_data_size, (LPCTSTR)L"EnumAdapters", REG_SZ, json_path,
                                   (DWORD)strlen(json_path) + 1, &result);
            if (result != VK_SUCCESS) {
                goto out;
            }

            // If this is a string and not a multi-string, we don't want to go throught the loop more than once
            if (full_info->value_type == REG_SZ) {
                break;
            }
        }
    }

out:
    loader_instance_heap_free(inst, json_path);
    loader_instance_heap_free(inst, full_info);
    loader_instance_heap_free(inst, adapters.adapters);

    return result;
}

// Look for data files in the registry.
VkResult windows_read_data_files_in_registry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
                                             bool warn_if_not_present, char *registry_location,
                                             struct loader_string_list *out_files) {
    VkResult vk_result = VK_SUCCESS;
    char *search_path = NULL;
    uint32_t log_target_flag = 0;

    if (data_file_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
        log_target_flag = VULKAN_LOADER_DRIVER_BIT;
        loader_log(inst, log_target_flag, 0, "Checking for Driver Manifest files in Registry at %s\\%s",
                   DEFAULT_VK_REGISTRY_HIVE_STR, registry_location);
    } else {
        log_target_flag = VULKAN_LOADER_LAYER_BIT;
        loader_log(inst, log_target_flag, 0, "Checking for Layer Manifest files in Registry at %s\\%s",
                   DEFAULT_VK_REGISTRY_HIVE_STR, registry_location);
    }

    // These calls look at the PNP/Device section of the registry.
    VkResult regHKR_result = VK_SUCCESS;
    DWORD reg_size = 4096;
    if (!strncmp(registry_location, VK_DRIVERS_INFO_REGISTRY_LOC, sizeof(VK_DRIVERS_INFO_REGISTRY_LOC))) {
        // If we're looking for drivers we need to try enumerating adapters
        regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpDriverRegistryWide());
        if (regHKR_result == VK_INCOMPLETE) {
            regHKR_result =
                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpDriverRegistry());
        }
    } else if (!strncmp(registry_location, VK_ELAYERS_INFO_REGISTRY_LOC, sizeof(VK_ELAYERS_INFO_REGISTRY_LOC))) {
        regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpELayerRegistryWide());
        if (regHKR_result == VK_INCOMPLETE) {
            regHKR_result =
                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpELayerRegistry());
        }
    } else if (!strncmp(registry_location, VK_ILAYERS_INFO_REGISTRY_LOC, sizeof(VK_ILAYERS_INFO_REGISTRY_LOC))) {
        regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpILayerRegistryWide());
        if (regHKR_result == VK_INCOMPLETE) {
            regHKR_result =
                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpILayerRegistry());
        }
    }

    if (regHKR_result == VK_ERROR_OUT_OF_HOST_MEMORY) {
        vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
        goto out;
    }

    // This call looks into the Khronos non-device specific section of the registry for layer files.
    bool use_secondary_hive = (data_file_type != LOADER_DATA_FILE_MANIFEST_DRIVER) && (!is_high_integrity());
    VkResult reg_result = windows_get_registry_files(inst, registry_location, use_secondary_hive, &search_path, &reg_size);
    if (reg_result == VK_ERROR_OUT_OF_HOST_MEMORY) {
        vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
        goto out;
    }

    if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
        if (data_file_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                       "windows_read_data_files_in_registry: Registry lookup failed to get ICD manifest files.  Possibly missing "
                       "Vulkan driver?");
            vk_result = VK_ERROR_INCOMPATIBLE_DRIVER;
        } else {
            if (warn_if_not_present) {
                if (data_file_type == LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER ||
                    data_file_type == LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER) {
                    // This is only a warning for layers
                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                               "windows_read_data_files_in_registry: Registry lookup failed to get layer manifest files.");
                } else {
                    // This is only a warning for general data files
                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                               "windows_read_data_files_in_registry: Registry lookup failed to get data files.");
                }
            }
            // Return success for now since it's not critical for layers
            vk_result = VK_SUCCESS;
        }
        goto out;
    }

    // Now, parse the paths and add any manifest files found in them.
    vk_result = add_data_files(inst, search_path, out_files, false);

out:

    loader_instance_heap_free(inst, search_path);

    return vk_result;
}

// This function allocates an array in sorted_devices which must be freed by the caller if not null
VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint32_t *sorted_devices_count,
                                              struct loader_phys_dev_per_icd **sorted_devices) {
    VkResult res = VK_SUCCESS;

    uint32_t sorted_alloc = 0;
    struct loader_icd_term *icd_term = NULL;
    IDXGIFactory6 *dxgi_factory = NULL;
    HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory6, (void **)&dxgi_factory);
    if (hres != S_OK) {
        loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Failed to create DXGI factory 6. Physical devices will not be sorted");
        goto out;
    }
    sorted_alloc = 16;
    *sorted_devices = loader_instance_heap_calloc(inst, sorted_alloc * sizeof(struct loader_phys_dev_per_icd),
                                                  VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    if (*sorted_devices == NULL) {
        res = VK_ERROR_OUT_OF_HOST_MEMORY;
        goto out;
    }

    for (uint32_t i = 0;; ++i) {
        IDXGIAdapter1 *adapter;
        hres = dxgi_factory->lpVtbl->EnumAdapterByGpuPreference(dxgi_factory, i, DXGI_GPU_PREFERENCE_UNSPECIFIED,
                                                                &IID_IDXGIAdapter1, (void **)&adapter);
        if (hres == DXGI_ERROR_NOT_FOUND) {
            break;  // No more adapters
        } else if (hres != S_OK) {
            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
                       "Failed to enumerate adapters by GPU preference at index %u. This adapter will not be sorted", i);
            break;
        }

        DXGI_ADAPTER_DESC1 description;
        hres = adapter->lpVtbl->GetDesc1(adapter, &description);
        if (hres != S_OK) {
            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Failed to get adapter LUID index %u. This adapter will not be sorted", i);
            continue;
        }

        if (sorted_alloc <= i) {
            uint32_t old_size = sorted_alloc * sizeof(struct loader_phys_dev_per_icd);
            *sorted_devices =
                loader_instance_heap_realloc(inst, *sorted_devices, old_size, 2 * old_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
            if (*sorted_devices == NULL) {
                adapter->lpVtbl->Release(adapter);
                res = VK_ERROR_OUT_OF_HOST_MEMORY;
                goto out;
            }
            sorted_alloc *= 2;
        }
        struct loader_phys_dev_per_icd *sorted_array = *sorted_devices;
        sorted_array[*sorted_devices_count].device_count = 0;
        sorted_array[*sorted_devices_count].physical_devices = NULL;

        icd_term = inst->icd_terms;
        for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
            // This is the new behavior, which cannot be run unless the ICD provides EnumerateAdapterPhysicalDevices
            if (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices == NULL) {
                continue;
            }

            uint32_t count = 0;
            VkResult vkres =
                icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, description.AdapterLuid, &count, NULL);
            if (vkres == VK_ERROR_INCOMPATIBLE_DRIVER) {
                continue;  // This driver doesn't support the adapter
            } else if (vkres == VK_ERROR_OUT_OF_HOST_MEMORY) {
                res = VK_ERROR_OUT_OF_HOST_MEMORY;
                goto out;
            } else if (vkres != VK_SUCCESS) {
                loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
                           "Failed to convert DXGI adapter into Vulkan physical device with unexpected error code");
                continue;
            }

            // Get the actual physical devices
            if (0 != count) {
                do {
                    sorted_array[*sorted_devices_count].physical_devices =
                        loader_instance_heap_realloc(inst, sorted_array[*sorted_devices_count].physical_devices,
                                                     sorted_array[*sorted_devices_count].device_count * sizeof(VkPhysicalDevice),
                                                     count * sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                    if (sorted_array[*sorted_devices_count].physical_devices == NULL) {
                        res = VK_ERROR_OUT_OF_HOST_MEMORY;
                        break;
                    }
                    sorted_array[*sorted_devices_count].device_count = count;
                } while ((vkres = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(
                              icd_term->instance, description.AdapterLuid, &count,
                              sorted_array[*sorted_devices_count].physical_devices)) == VK_INCOMPLETE);
            }

            if (vkres != VK_SUCCESS) {
                loader_instance_heap_free(inst, sorted_array[*sorted_devices_count].physical_devices);
                sorted_array[*sorted_devices_count].physical_devices = NULL;
                if (vkres == VK_ERROR_OUT_OF_HOST_MEMORY) {
                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
                    goto out;
                } else {
                    loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Failed to convert DXGI adapter into Vulkan physical device");
                    continue;
                }
            }
            sorted_array[*sorted_devices_count].device_count = count;
            sorted_array[*sorted_devices_count].icd_index = icd_idx;
            sorted_array[*sorted_devices_count].icd_term = icd_term;
            (*sorted_devices_count)++;
        }

        adapter->lpVtbl->Release(adapter);
    }

    dxgi_factory->lpVtbl->Release(dxgi_factory);

out:
    if (*sorted_devices_count == 0 && *sorted_devices != NULL) {
        loader_instance_heap_free(inst, *sorted_devices);
        *sorted_devices = NULL;
    }
    *sorted_devices_count = *sorted_devices_count;
    *sorted_devices = *sorted_devices;
    return res;
}

VkLoaderFeatureFlags windows_initialize_dxgi(void) {
    VkLoaderFeatureFlags feature_flags = 0;
    IDXGIFactory6 *dxgi_factory = NULL;
    HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory6, (void **)&dxgi_factory);
    if (hres == S_OK) {
        feature_flags |= VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING;
        dxgi_factory->lpVtbl->Release(dxgi_factory);
    }
    return feature_flags;
}

// Sort the VkPhysicalDevices that are part of the current group with the list passed in from the sorted list.
// Multiple groups could have devices out of the same sorted list, however, a single group's devices must all come
// from the same sorted list.
void windows_sort_devices_in_group(struct loader_instance *inst, struct VkPhysicalDeviceGroupProperties *group_props,
                                   struct loader_phys_dev_per_icd *icd_sorted_list) {
    uint32_t cur_index = 0;
    for (uint32_t dev = 0; dev < icd_sorted_list->device_count; ++dev) {
        for (uint32_t grp_dev = cur_index; grp_dev < group_props->physicalDeviceCount; ++grp_dev) {
            if (icd_sorted_list->physical_devices[dev] == group_props->physicalDevices[grp_dev]) {
                if (cur_index != grp_dev) {
                    VkPhysicalDevice swap_dev = group_props->physicalDevices[cur_index];
                    group_props->physicalDevices[cur_index] = group_props->physicalDevices[grp_dev];
                    group_props->physicalDevices[grp_dev] = swap_dev;
                }
                cur_index++;
                break;
            }
        }
    }
    if (cur_index == 0) {
        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
                   "windows_sort_devices_in_group:  Never encountered a device in the sorted list group");
    }
}

// This function sorts an array in physical device groups based on the sorted physical device information
VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const uint32_t group_count,
                                             struct loader_physical_device_group_term *sorted_group_term,
                                             const uint32_t sorted_device_count,
                                             struct loader_phys_dev_per_icd *sorted_phys_dev_array) {
    if (0 == group_count || NULL == sorted_group_term) {
        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
                   "windows_sort_physical_device_groups: Called with invalid information (Group count %d, Sorted Info %p)",
                   group_count, sorted_group_term);
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    uint32_t new_index = 0;
    for (uint32_t icd = 0; icd < sorted_device_count; ++icd) {
        for (uint32_t dev = 0; dev < sorted_phys_dev_array[icd].device_count; ++dev) {
            // Find a group associated with a given device
            for (uint32_t group = new_index; group < group_count; ++group) {
                bool device_found = false;
                // Look for the current sorted device in a group and put it in the correct location if it isn't already
                for (uint32_t grp_dev = 0; grp_dev < sorted_group_term[group].group_props.physicalDeviceCount; ++grp_dev) {
                    if (sorted_group_term[group].group_props.physicalDevices[grp_dev] ==
                        sorted_phys_dev_array[icd].physical_devices[dev]) {
                        // First, sort devices inside of group to be in priority order
                        windows_sort_devices_in_group(inst, &sorted_group_term[group].group_props, &sorted_phys_dev_array[icd]);

                        // Second, move the group up in priority if it needs to be
                        if (new_index != group) {
                            struct loader_physical_device_group_term tmp = sorted_group_term[new_index];
                            sorted_group_term[new_index] = sorted_group_term[group];
                            sorted_group_term[group] = tmp;
                        }
                        device_found = true;
                        new_index++;
                        break;
                    }
                }
                if (device_found) {
                    break;
                }
            }
        }
    }
    return VK_SUCCESS;
}

char *windows_get_app_package_manifest_path(const struct loader_instance *inst) {
    // These functions are only available on Windows 8 and above, load them dynamically for compatibility with Windows 7
    typedef LONG(WINAPI * PFN_GetPackagesByPackageFamily)(PCWSTR, UINT32 *, PWSTR *, UINT32 *, WCHAR *);
    PFN_GetPackagesByPackageFamily fpGetPackagesByPackageFamily =
        (PFN_GetPackagesByPackageFamily)(void *)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagesByPackageFamily");
    if (!fpGetPackagesByPackageFamily) {
        return NULL;
    }
    typedef LONG(WINAPI * PFN_GetPackagePathByFullName)(PCWSTR, UINT32 *, PWSTR);
    PFN_GetPackagePathByFullName fpGetPackagePathByFullName =
        (PFN_GetPackagePathByFullName)(void *)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagePathByFullName");
    if (!fpGetPackagePathByFullName) {
        return NULL;
    }

    UINT32 numPackages = 0, bufferLength = 0;
    /* This literal string identifies the Microsoft-published OpenCL and OpenGL Compatibility Pack
     * (so named at the time this is being added), which contains OpenGLOn12 and OpenCLOn12 mapping
     * layers, and will contain VulkanOn12 (aka Dozen) going forward.
     */
    PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
    if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) ||
        numPackages == 0 || bufferLength == 0) {
        loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
                   "windows_get_app_package_manifest_path: Failed to find mapping layers packages by family name");
        return NULL;
    }

    char *ret = NULL;
    WCHAR *buffer = loader_instance_heap_alloc(inst, sizeof(WCHAR) * bufferLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    PWSTR *packages = loader_instance_heap_alloc(inst, sizeof(PWSTR) * numPackages, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    if (!buffer || !packages) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                   "windows_get_app_package_manifest_path: Failed to allocate memory for package names");
        goto cleanup;
    }

    if (ERROR_SUCCESS != fpGetPackagesByPackageFamily(familyName, &numPackages, packages, &bufferLength, buffer)) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                   "windows_get_app_package_manifest_path: Failed to mapping layers package full names");
        goto cleanup;
    }

    UINT32 pathLength = 0;
    WCHAR path[MAX_PATH];
    memset(path, 0, sizeof(path));
    if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagePathByFullName(packages[0], &pathLength, NULL) || pathLength > MAX_PATH ||
        ERROR_SUCCESS != fpGetPackagePathByFullName(packages[0], &pathLength, path)) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                   "windows_get_app_package_manifest_path: Failed to get mapping layers package path");
        goto cleanup;
    }

    int narrowPathLength = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, NULL, NULL);
    if (narrowPathLength == 0) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                   "windows_get_app_package_manifest_path: Failed to convert path from wide to narrow");
        goto cleanup;
    }

    ret = loader_instance_heap_alloc(inst, narrowPathLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    if (!ret) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_app_package_manifest_path: Failed to allocate path");
        goto cleanup;
    }

    narrowPathLength = WideCharToMultiByte(CP_ACP, 0, path, -1, ret, narrowPathLength, NULL, NULL);
    assert((size_t)narrowPathLength == strlen(ret) + 1);

cleanup:
    loader_instance_heap_free(inst, buffer);
    loader_instance_heap_free(inst, packages);
    return ret;
}

VkResult get_settings_path_if_exists_in_registry_key(const struct loader_instance *inst, char **out_path, HKEY key) {
    VkResult result = VK_ERROR_INITIALIZATION_FAILED;

    char name[MAX_STRING_SIZE] = {0};
    DWORD name_size = sizeof(name);

    *out_path = NULL;

    LONG rtn_value = ERROR_SUCCESS;
    for (DWORD idx = 0; rtn_value == ERROR_SUCCESS; idx++) {
        DWORD value = 0;
        DWORD value_size = sizeof(value);
        rtn_value = RegEnumValue(key, idx, name, &name_size, NULL, NULL, (LPBYTE)&value, &value_size);

        if (ERROR_SUCCESS != rtn_value) {
            break;
        }

        uint32_t start_of_path_filename = 0;
        for (uint32_t last_char = name_size; last_char > 0; last_char--) {
            if (name[last_char] == '\\') {
                start_of_path_filename = last_char + 1;
                break;
            }
        }

        // Make sure the path exists first
        if (*out_path && !loader_platform_file_exists(name)) {
            return VK_ERROR_INITIALIZATION_FAILED;
        }

        if (strcmp(VK_LOADER_SETTINGS_FILENAME, &(name[start_of_path_filename])) == 0) {
            *out_path = loader_instance_heap_alloc(inst, name_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
            if (*out_path == NULL) {
                return VK_ERROR_OUT_OF_HOST_MEMORY;
            }
            strcpy(*out_path, name);
            result = VK_SUCCESS;
            break;
        }
    }

    return result;
}

VkResult windows_get_loader_settings_file_path(const struct loader_instance *inst, char **out_path) {
    VkResult result = VK_SUCCESS;
    DWORD access_flags = KEY_QUERY_VALUE;
    HKEY key = NULL;

    *out_path = NULL;

    // if we are running with admin privileges, only check HKEY_LOCAL_MACHINE.
    // Otherwise check HKEY_CURRENT_USER, and if nothing is there, look in HKEY_LOCAL_MACHINE

    if (is_high_integrity()) {
        LONG rtn_value = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
        if (ERROR_SUCCESS != rtn_value) {
            goto out;
        }
        result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
    } else {
        LONG rtn_value = RegOpenKeyEx(HKEY_CURRENT_USER, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
        if (ERROR_SUCCESS == rtn_value) {
            result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
            RegCloseKey(key);
            // Either we got OOM and *must* exit or we successfully found the settings file and can exit
            if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_SUCCESS) {
                goto out;
            }
        }

        rtn_value = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
        if (ERROR_SUCCESS != rtn_value) {
            goto out;
        }

        result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            goto out;
        }
    }

out:
    if (NULL != key) {
        RegCloseKey(key);
    }

    return result;
}

#endif  // _WIN32
