15db71995Sopenharmony_ci/* 25db71995Sopenharmony_ci * Copyright (c) 2021-2022 The Khronos Group Inc. 35db71995Sopenharmony_ci * Copyright (c) 2021-2022 Valve Corporation 45db71995Sopenharmony_ci * Copyright (c) 2021-2022 LunarG, Inc. 55db71995Sopenharmony_ci * 65db71995Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 75db71995Sopenharmony_ci * of this software and/or associated documentation files (the "Materials"), to 85db71995Sopenharmony_ci * deal in the Materials without restriction, including without limitation the 95db71995Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 105db71995Sopenharmony_ci * sell copies of the Materials, and to permit persons to whom the Materials are 115db71995Sopenharmony_ci * furnished to do so, subject to the following conditions: 125db71995Sopenharmony_ci * 135db71995Sopenharmony_ci * The above copyright notice(s) and this permission notice shall be included in 145db71995Sopenharmony_ci * all copies or substantial portions of the Materials. 155db71995Sopenharmony_ci * 165db71995Sopenharmony_ci * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175db71995Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185db71995Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 195db71995Sopenharmony_ci * 205db71995Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 215db71995Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 225db71995Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 235db71995Sopenharmony_ci * USE OR OTHER DEALINGS IN THE MATERIALS. 245db71995Sopenharmony_ci * 255db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com> 265db71995Sopenharmony_ci */ 275db71995Sopenharmony_ci 285db71995Sopenharmony_ci#pragma once 295db71995Sopenharmony_ci 305db71995Sopenharmony_ci#include "test_util.h" 315db71995Sopenharmony_ci 325db71995Sopenharmony_ci#include <unordered_set> 335db71995Sopenharmony_ci#include <stdlib.h> 345db71995Sopenharmony_ci 355db71995Sopenharmony_ci#if defined(WIN32) 365db71995Sopenharmony_ci#include <strsafe.h> 375db71995Sopenharmony_ci#include <cfgmgr32.h> 385db71995Sopenharmony_ci#include <initguid.h> 395db71995Sopenharmony_ci#include <devpkey.h> 405db71995Sopenharmony_ci#include <winternl.h> 415db71995Sopenharmony_ci#include <appmodel.h> 425db71995Sopenharmony_ci 435db71995Sopenharmony_ci#define CINTERFACE 445db71995Sopenharmony_ci#include <dxgi1_6.h> 455db71995Sopenharmony_ci#include <adapters.h> 465db71995Sopenharmony_ci#endif 475db71995Sopenharmony_ci 485db71995Sopenharmony_cienum class ManifestCategory { implicit_layer, explicit_layer, icd, settings }; 495db71995Sopenharmony_cienum class GpuType { unspecified, integrated, discrete, external }; 505db71995Sopenharmony_ci 515db71995Sopenharmony_ci#if defined(WIN32) 525db71995Sopenharmony_ci#define VK_VARIANT_REG_STR "" 535db71995Sopenharmony_ci#define VK_VARIANT_REG_STR_W L"" 545db71995Sopenharmony_ci 555db71995Sopenharmony_ci#define VK_DRIVERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\Drivers" 565db71995Sopenharmony_ci#define VK_ELAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\ExplicitLayers" 575db71995Sopenharmony_ci#define VK_ILAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\ImplicitLayers" 585db71995Sopenharmony_ci#define VK_SETTINGS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\LoaderSettings" 595db71995Sopenharmony_ci 605db71995Sopenharmony_cistruct RegistryEntry { 615db71995Sopenharmony_ci RegistryEntry() = default; 625db71995Sopenharmony_ci RegistryEntry(std::string const& name) noexcept : name(name) {} 635db71995Sopenharmony_ci RegistryEntry(std::string const& name, DWORD value) noexcept : name(name), value(value) {} 645db71995Sopenharmony_ci std::string name; 655db71995Sopenharmony_ci DWORD value{}; 665db71995Sopenharmony_ci}; 675db71995Sopenharmony_ci 685db71995Sopenharmony_cistruct HKeyHandle { 695db71995Sopenharmony_ci explicit HKeyHandle(const size_t value, const std::string& key_path) noexcept : key(HKEY{}), path(key_path) { 705db71995Sopenharmony_ci key = reinterpret_cast<HKEY>(value); 715db71995Sopenharmony_ci } 725db71995Sopenharmony_ci 735db71995Sopenharmony_ci HKEY get() const noexcept { return key; } 745db71995Sopenharmony_ci 755db71995Sopenharmony_ci HKEY key{}; 765db71995Sopenharmony_ci std::string path; 775db71995Sopenharmony_ci}; 785db71995Sopenharmony_ci 795db71995Sopenharmony_cistatic const char* pnp_registry_path = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}"; 805db71995Sopenharmony_ci 815db71995Sopenharmony_ci// Needed for DXGI mocking 825db71995Sopenharmony_cistruct KnownDriverData { 835db71995Sopenharmony_ci const char* filename = nullptr; 845db71995Sopenharmony_ci int vendor_id = 0; 855db71995Sopenharmony_ci}; 865db71995Sopenharmony_cistatic std::array<KnownDriverData, 4> known_driver_list = { 875db71995Sopenharmony_ci#if defined(_WIN64) 885db71995Sopenharmony_ci KnownDriverData{"igvk64.json", 0x8086}, KnownDriverData{"nv-vk64.json", 0x10de}, KnownDriverData{"amd-vulkan64.json", 0x1002}, 895db71995Sopenharmony_ci KnownDriverData{"amdvlk64.json", 0x1002} 905db71995Sopenharmony_ci#else 915db71995Sopenharmony_ci KnownDriverData{"igvk32.json", 0x8086}, KnownDriverData{"nv-vk32.json", 0x10de}, KnownDriverData{"amd-vulkan32.json", 0x1002}, 925db71995Sopenharmony_ci KnownDriverData{"amdvlk32.json", 0x1002} 935db71995Sopenharmony_ci#endif 945db71995Sopenharmony_ci}; 955db71995Sopenharmony_ci 965db71995Sopenharmony_cistruct DXGIAdapter { 975db71995Sopenharmony_ci GpuType gpu_preference = GpuType::unspecified; 985db71995Sopenharmony_ci DXGI_ADAPTER_DESC1 desc1{}; 995db71995Sopenharmony_ci uint32_t adapter_index = 0; 1005db71995Sopenharmony_ci IDXGIAdapter1 adapter_instance{}; 1015db71995Sopenharmony_ci IDXGIAdapter1Vtbl adapter_vtbl_instance{}; 1025db71995Sopenharmony_ci}; 1035db71995Sopenharmony_ci 1045db71995Sopenharmony_cistruct D3DKMT_Adapter { 1055db71995Sopenharmony_ci D3DKMT_Adapter& add_driver_manifest_path(fs::path const& src); 1065db71995Sopenharmony_ci D3DKMT_Adapter& add_implicit_layer_manifest_path(fs::path const& src); 1075db71995Sopenharmony_ci D3DKMT_Adapter& add_explicit_layer_manifest_path(fs::path const& src); 1085db71995Sopenharmony_ci 1095db71995Sopenharmony_ci UINT hAdapter; 1105db71995Sopenharmony_ci LUID adapter_luid; 1115db71995Sopenharmony_ci std::vector<std::wstring> driver_paths; 1125db71995Sopenharmony_ci std::vector<std::wstring> implicit_layer_paths; 1135db71995Sopenharmony_ci std::vector<std::wstring> explicit_layer_paths; 1145db71995Sopenharmony_ci 1155db71995Sopenharmony_ci private: 1165db71995Sopenharmony_ci D3DKMT_Adapter& add_path(fs::path src, std::vector<std::wstring>& dest); 1175db71995Sopenharmony_ci}; 1185db71995Sopenharmony_ci 1195db71995Sopenharmony_ci#elif COMMON_UNIX_PLATFORMS 1205db71995Sopenharmony_ci 1215db71995Sopenharmony_cistruct DirEntry { 1225db71995Sopenharmony_ci DIR* directory = nullptr; 1235db71995Sopenharmony_ci std::string folder_path; 1245db71995Sopenharmony_ci std::vector<struct dirent*> contents; 1255db71995Sopenharmony_ci // the current item being read by an app (incremented by readdir, reset to zero by opendir & closedir) 1265db71995Sopenharmony_ci size_t current_index = 0; 1275db71995Sopenharmony_ci bool is_fake_path = false; // true when this entry is for folder redirection 1285db71995Sopenharmony_ci}; 1295db71995Sopenharmony_ci 1305db71995Sopenharmony_ci#endif 1315db71995Sopenharmony_ci 1325db71995Sopenharmony_cistruct FrameworkEnvironment; // forward declaration 1335db71995Sopenharmony_ci 1345db71995Sopenharmony_ci// Necessary to have inline definitions as shim is a dll and thus functions 1355db71995Sopenharmony_ci// defined in the .cpp wont be found by the rest of the application 1365db71995Sopenharmony_cistruct PlatformShim { 1375db71995Sopenharmony_ci PlatformShim() = default; 1385db71995Sopenharmony_ci PlatformShim(std::vector<fs::FolderManager>* folders) : folders(folders) {} 1395db71995Sopenharmony_ci 1405db71995Sopenharmony_ci // Used to get info about which drivers & layers have been added to folders 1415db71995Sopenharmony_ci std::vector<fs::FolderManager>* folders; 1425db71995Sopenharmony_ci 1435db71995Sopenharmony_ci // Test Framework interface 1445db71995Sopenharmony_ci void reset(); 1455db71995Sopenharmony_ci 1465db71995Sopenharmony_ci void redirect_all_paths(fs::path const& path); 1475db71995Sopenharmony_ci void redirect_category(fs::path const& new_path, ManifestCategory category); 1485db71995Sopenharmony_ci 1495db71995Sopenharmony_ci // fake paths are paths that the loader normally looks in but actually point to locations inside the test framework 1505db71995Sopenharmony_ci void set_fake_path(ManifestCategory category, fs::path const& path); 1515db71995Sopenharmony_ci 1525db71995Sopenharmony_ci // known paths are real paths but since the test framework guarantee's the order files are found in, files in these paths 1535db71995Sopenharmony_ci // need to be ordered correctly 1545db71995Sopenharmony_ci void add_known_path(fs::path const& path); 1555db71995Sopenharmony_ci 1565db71995Sopenharmony_ci void add_manifest(ManifestCategory category, fs::path const& path); 1575db71995Sopenharmony_ci void add_unsecured_manifest(ManifestCategory category, fs::path const& path); 1585db71995Sopenharmony_ci 1595db71995Sopenharmony_ci// platform specific shim interface 1605db71995Sopenharmony_ci#if defined(WIN32) 1615db71995Sopenharmony_ci // Control Platform Elevation Level 1625db71995Sopenharmony_ci void set_elevated_privilege(bool elev) { elevation_level = (elev) ? SECURITY_MANDATORY_HIGH_RID : SECURITY_MANDATORY_LOW_RID; } 1635db71995Sopenharmony_ci unsigned long elevation_level = SECURITY_MANDATORY_LOW_RID; 1645db71995Sopenharmony_ci 1655db71995Sopenharmony_ci void add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1); 1665db71995Sopenharmony_ci void add_d3dkmt_adapter(D3DKMT_Adapter const& adapter); 1675db71995Sopenharmony_ci void set_app_package_path(fs::path const& path); 1685db71995Sopenharmony_ci 1695db71995Sopenharmony_ci std::unordered_map<uint32_t, DXGIAdapter> dxgi_adapters; 1705db71995Sopenharmony_ci 1715db71995Sopenharmony_ci std::vector<D3DKMT_Adapter> d3dkmt_adapters; 1725db71995Sopenharmony_ci 1735db71995Sopenharmony_ci // TODO: 1745db71995Sopenharmony_ci void add_CM_Device_ID(std::wstring const& id, fs::path const& icd_path, fs::path const& layer_path); 1755db71995Sopenharmony_ci std::wstring CM_device_ID_list = {L'\0'}; 1765db71995Sopenharmony_ci std::vector<RegistryEntry> CM_device_ID_registry_keys; 1775db71995Sopenharmony_ci 1785db71995Sopenharmony_ci uint32_t random_base_path = 0; 1795db71995Sopenharmony_ci 1805db71995Sopenharmony_ci std::vector<fs::path> icd_paths; 1815db71995Sopenharmony_ci 1825db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_current_user_explicit_layers; 1835db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_current_user_implicit_layers; 1845db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_local_machine_explicit_layers; 1855db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_local_machine_implicit_layers; 1865db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_local_machine_drivers; 1875db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_local_machine_settings; 1885db71995Sopenharmony_ci std::vector<RegistryEntry> hkey_current_user_settings; 1895db71995Sopenharmony_ci 1905db71995Sopenharmony_ci std::wstring app_package_path; 1915db71995Sopenharmony_ci 1925db71995Sopenharmony_ci // When a key is created, return the index of the 1935db71995Sopenharmony_ci size_t created_key_count = 0; 1945db71995Sopenharmony_ci std::vector<HKeyHandle> created_keys; 1955db71995Sopenharmony_ci 1965db71995Sopenharmony_ci#elif COMMON_UNIX_PLATFORMS 1975db71995Sopenharmony_ci bool is_fake_path(fs::path const& path); 1985db71995Sopenharmony_ci fs::path const& get_real_path_from_fake_path(fs::path const& path); 1995db71995Sopenharmony_ci 2005db71995Sopenharmony_ci void redirect_path(fs::path const& path, fs::path const& new_path); 2015db71995Sopenharmony_ci void remove_redirect(fs::path const& path); 2025db71995Sopenharmony_ci 2035db71995Sopenharmony_ci bool is_known_path(fs::path const& path); 2045db71995Sopenharmony_ci void remove_known_path(fs::path const& path); 2055db71995Sopenharmony_ci 2065db71995Sopenharmony_ci void redirect_dlopen_name(fs::path const& filename, fs::path const& actual_path); 2075db71995Sopenharmony_ci bool is_dlopen_redirect_name(fs::path const& filename); 2085db71995Sopenharmony_ci 2095db71995Sopenharmony_ci fs::path query_default_redirect_path(ManifestCategory category); 2105db71995Sopenharmony_ci 2115db71995Sopenharmony_ci std::unordered_map<std::string, fs::path> redirection_map; 2125db71995Sopenharmony_ci std::unordered_map<std::string, fs::path> dlopen_redirection_map; 2135db71995Sopenharmony_ci std::unordered_set<std::string> known_path_set; 2145db71995Sopenharmony_ci 2155db71995Sopenharmony_ci void set_elevated_privilege(bool elev) { use_fake_elevation = elev; } 2165db71995Sopenharmony_ci bool use_fake_elevation = false; 2175db71995Sopenharmony_ci 2185db71995Sopenharmony_ci std::vector<DirEntry> dir_entries; 2195db71995Sopenharmony_ci 2205db71995Sopenharmony_ci#if defined(__APPLE__) 2215db71995Sopenharmony_ci std::string bundle_contents; 2225db71995Sopenharmony_ci#endif 2235db71995Sopenharmony_ci#endif 2245db71995Sopenharmony_ci bool is_during_destruction = false; 2255db71995Sopenharmony_ci}; 2265db71995Sopenharmony_ci 2275db71995Sopenharmony_cistd::vector<std::string> parse_env_var_list(std::string const& var); 2285db71995Sopenharmony_cistd::string category_path_name(ManifestCategory category); 2295db71995Sopenharmony_ci 2305db71995Sopenharmony_cistd::vector<std::string> get_folder_contents(std::vector<fs::FolderManager>* folders, std::string folder_name) noexcept; 2315db71995Sopenharmony_ci 2325db71995Sopenharmony_ciextern "C" { 2335db71995Sopenharmony_ci// dynamically link on windows and macos 2345db71995Sopenharmony_ci#if defined(WIN32) || defined(__APPLE__) 2355db71995Sopenharmony_ciusing PFN_get_platform_shim = PlatformShim* (*)(std::vector<fs::FolderManager>* folders); 2365db71995Sopenharmony_ci#define GET_PLATFORM_SHIM_STR "get_platform_shim" 2375db71995Sopenharmony_ci 2385db71995Sopenharmony_ci#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) 2395db71995Sopenharmony_ci// statically link on linux 2405db71995Sopenharmony_ciPlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders); 2415db71995Sopenharmony_ci#endif 2425db71995Sopenharmony_ci} 243