diff options
author | Mike Schuchardt <mikes@lunarg.com> | 2022-07-11 20:41:03 +0300 |
---|---|---|
committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2022-07-11 22:38:35 +0300 |
commit | 4de4f256abeadd01a267000950471d83c3867de8 (patch) | |
tree | 744d62145e2b87c4adf3fa393dd56d86ccb76ea4 | |
parent | 9a45e5a4ab79b81e27e1417ca65d53ecfe57ba37 (diff) |
loader: Dynamically load Win8+ functions
Allow loader to run on Windows 7 by dynamically loading function
pointers for Windows 8 and above APIs.
-rw-r--r-- | loader/loader.c | 10 | ||||
-rw-r--r-- | loader/loader_windows.c | 26 | ||||
-rw-r--r-- | loader/loader_windows.h | 2 |
3 files changed, 22 insertions, 16 deletions
diff --git a/loader/loader.c b/loader/loader.c index 8b73343e1..f41d460f8 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -2911,9 +2911,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in #endif #if defined(_WIN32) -#if WINVER >= _WIN32_WINNT_WINBLUE char *package_path = NULL; -#endif #else // Determine how much space is needed to generate the full search path // for the current manifest files. @@ -3001,7 +2999,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in } additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst); relative_location = VK_DRIVERS_INFO_RELATIVE_DIR; -#if defined(_WIN32) && WINVER >= _WIN32_WINNT_WINBLUE +#if defined(_WIN32) package_path = windows_get_app_package_manifest_path(inst); #endif break; @@ -3035,7 +3033,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in // Add the size of any additional search paths defined in the additive environment variable if (NULL != additional_env) { search_path_size += determine_data_file_path_size(additional_env, 0) + 2; -#if defined(_WIN32) && WINVER >= _WIN32_WINNT_WINBLUE +#if defined(_WIN32) } if (NULL != package_path) { search_path_size += determine_data_file_path_size(package_path, 0) + 2; @@ -3092,7 +3090,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in copy_data_file_info(additional_env, NULL, 0, &cur_path_ptr); } -#if defined(_WIN32) && WINVER >= _WIN32_WINNT_WINBLUE +#if defined(_WIN32) if (NULL != package_path) { copy_data_file_info(package_path, NULL, 0, &cur_path_ptr); } @@ -3231,7 +3229,7 @@ out: if (NULL != override_env) { loader_free_getenv(override_env, inst); } -#if defined(_WIN32) && WINVER >= _WIN32_WINNT_WINBLUE +#if defined(_WIN32) if (NULL != package_path) { loader_instance_heap_free(inst, package_path); } diff --git a/loader/loader_windows.c b/loader/loader_windows.c index f99d05df9..89408d2ed 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -51,9 +51,7 @@ #include <dxgi1_6.h> #include "adapters.h" -#if WINVER >= _WIN32_WINNT_WINBLUE #include <appmodel.h> -#endif #if !defined(NDEBUG) #include <crtdbg.h> @@ -1000,15 +998,28 @@ VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const return VK_SUCCESS; } -#if WINVER >= _WIN32_WINNT_WINBLUE 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)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagesByPackageFamily"); + if (!fpGetPackagesByPackageFamily) { + return NULL; + } + typedef LONG(WINAPI * PFN_GetPackagePathByFullName)(PCWSTR, UINT32 *, PWSTR); + PFN_GetPackagePathByFullName fpGetPackagePathByFullName = + (PFN_GetPackagePathByFullName)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 != GetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) || + 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\n"); @@ -1024,7 +1035,7 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst) goto cleanup; } - if (ERROR_SUCCESS != GetPackagesByPackageFamily(familyName, &numPackages, packages, &bufferLength, buffer)) { + 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\n"); goto cleanup; @@ -1033,8 +1044,8 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst) UINT32 pathLength = 0; WCHAR path[MAX_PATH]; memset(path, 0, sizeof(path)); - if (ERROR_INSUFFICIENT_BUFFER != GetPackagePathByFullName(packages[0], &pathLength, NULL) || pathLength > MAX_PATH || - ERROR_SUCCESS != GetPackagePathByFullName(packages[0], &pathLength, 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\n"); goto cleanup; @@ -1061,5 +1072,4 @@ cleanup: loader_instance_heap_free(inst, packages); return ret; } -#endif #endif // _WIN32 diff --git a/loader/loader_windows.h b/loader/loader_windows.h index f1c6fbb1e..80ba6ebe1 100644 --- a/loader/loader_windows.h +++ b/loader/loader_windows.h @@ -113,9 +113,7 @@ VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const // Returns VkLoaderFeatureFlags containing VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING if successful, otherwise 0 VkLoaderFeatureFlags windows_initialize_dxgi(void); -#if WINVER >= _WIN32_WINNT_WINBLUE // Only Available on windows 8 and above // Retrieve a path to an installed app package that contains Vulkan manifests. // When done using the returned string, the caller should free the pointer. char *windows_get_app_package_manifest_path(const struct loader_instance *inst); -#endif #endif // WIN32 |