1 /*
2 * Copyright (c) 2017-2022 The Khronos Group Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * OpenCL is a trademark of Apple Inc. used under license by Khronos.
17 */
18
19 #include <icd.h>
20 #include "icd_windows_apppackage.h"
21
22 typedef _Check_return_ LONG(WINAPI *PFN_GetPackagesByPackageFamily)(
23 _In_ PCWSTR packageFamilyName,
24 _Inout_ UINT32* count,
25 _Out_writes_opt_(*count) PWSTR* packageFullNames,
26 _Inout_ UINT32* bufferLength,
27 _Out_writes_opt_(*bufferLength) WCHAR* buffer
28 );
29
30 typedef LONG (WINAPI *PFN_GetPackagePathByFullName)(
31 _In_ PCWSTR packageFullName,
32 _Inout_ UINT32* pathLength,
33 _Out_writes_opt_(*pathLength) PWSTR path
34 );
35
khrIcdOsVendorsEnumerateAppPackage(void)36 bool khrIcdOsVendorsEnumerateAppPackage(void)
37 {
38 bool ret = false;
39 WCHAR *buffer = NULL;
40 PWSTR *packages = NULL;
41
42 HMODULE h = LoadLibraryA("kernel32.dll");
43 if (h == NULL)
44 return ret;
45
46 PFN_GetPackagesByPackageFamily pGetPackagesByPackageFamily =
47 (PFN_GetPackagesByPackageFamily)GetProcAddress(h, "GetPackagesByPackageFamily");
48 if (!pGetPackagesByPackageFamily)
49 {
50 KHR_ICD_TRACE("GetProcAddress failed for GetPackagesByPackageFamily\n");
51 goto cleanup;
52 }
53
54 PFN_GetPackagePathByFullName pGetPackagePathByFullName =
55 (PFN_GetPackagePathByFullName)GetProcAddress(h, "GetPackagePathByFullName");
56 if (!pGetPackagePathByFullName)
57 {
58 KHR_ICD_TRACE("GetProcAddress failed for GetPackagePathByFullName\n");
59 goto cleanup;
60 }
61
62 UINT32 numPackages = 0, bufferLength = 0;
63 PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
64 if (ERROR_INSUFFICIENT_BUFFER != pGetPackagesByPackageFamily(familyName,
65 &numPackages, NULL,
66 &bufferLength, NULL) ||
67 numPackages == 0 || bufferLength == 0)
68 {
69 KHR_ICD_TRACE("Failed to find mapping layers packages by family name\n");
70 goto cleanup;
71 }
72
73 buffer = malloc(sizeof(WCHAR) * bufferLength);
74 packages = malloc(sizeof(PWSTR) * numPackages);
75 if (!buffer || !packages)
76 {
77 KHR_ICD_TRACE("Failed to allocate memory for package names\n");
78 goto cleanup;
79 }
80
81 if (ERROR_SUCCESS != pGetPackagesByPackageFamily(familyName,
82 &numPackages, packages,
83 &bufferLength, buffer))
84 {
85 KHR_ICD_TRACE("Failed to get mapping layers package full names\n");
86 goto cleanup;
87 }
88
89 UINT32 pathLength = 0;
90 WCHAR path[MAX_PATH];
91 if (ERROR_INSUFFICIENT_BUFFER != pGetPackagePathByFullName(packages[0], &pathLength, NULL) ||
92 pathLength > MAX_PATH ||
93 ERROR_SUCCESS != pGetPackagePathByFullName(packages[0], &pathLength, path))
94 {
95 KHR_ICD_TRACE("Failed to get mapping layers package path length\n");
96 goto cleanup;
97 }
98
99 #if defined(_M_AMD64)
100 #define PLATFORM_PATH L"x64"
101 #elif defined(_M_ARM)
102 #define PLATFORM_PATH L"arm"
103 #elif defined(_M_ARM64)
104 #define PLATFORM_PATH L"arm64"
105 #elif defined(_M_IX86)
106 #define PLATFORM_PATH L"x86"
107 #endif
108
109 wchar_t dllPath[MAX_PATH];
110 wcscpy_s(dllPath, MAX_PATH, path);
111 wcscat_s(dllPath, MAX_PATH, L"\\" PLATFORM_PATH L"\\OpenCLOn12.dll");
112
113 char narrowDllPath[MAX_PATH];
114 WideCharToMultiByte(CP_UTF8, 0, dllPath, -1, narrowDllPath, MAX_PATH, NULL, NULL);
115
116 ret = adapterAdd(narrowDllPath, ZeroLuid);
117
118 cleanup:
119 FreeLibrary(h);
120 free(buffer);
121 free(packages);
122 return ret;
123 }
124