Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47109 Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- v5: Write an absolute path to the library in the JSON file, clean up error handling, and remove incorrect error handling in Unregister.
dlls/winevulkan/Makefile.in | 2 +- dlls/winevulkan/make_vulkan | 3 + dlls/winevulkan/vulkan.c | 104 ++++++++++++++++++++++++++++++++ dlls/winevulkan/winevulkan.spec | 2 + loader/wine.inf.in | 1 + 5 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in index e0bca6fad7..2ffff40c3a 100644 --- a/dlls/winevulkan/Makefile.in +++ b/dlls/winevulkan/Makefile.in @@ -1,6 +1,6 @@ MODULE = winevulkan.dll IMPORTLIB = winevulkan -IMPORTS = user32 gdi32 +IMPORTS = user32 gdi32 advapi32
C_SRCS = \ vulkan.c \ diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index e0b94a06cb..bccfa6a6d6 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -2509,6 +2509,9 @@ class VkGenerator(object): else: f.write("@ stub {0}\n".format(func.name))
+ f.write("@ stdcall -private DllRegisterServer()\n") + f.write("@ stdcall -private DllUnregisterServer()\n") + def generate_vulkan_loader_spec(self, f): self._generate_copyright(f, spec_file=True)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 59472bcef8..257416ab14 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -21,6 +21,7 @@
#include "windef.h" #include "winbase.h" +#include "winreg.h" #include "winuser.h"
#include "vulkan_private.h" @@ -50,6 +51,7 @@ static void *wine_vk_find_struct_(void *s, VkStructureType t)
static void *wine_vk_get_global_proc_addr(const char *name);
+static HINSTANCE hinstance; static const struct vulkan_funcs *vk_funcs; static VkResult (*p_vkEnumerateInstanceVersion)(uint32_t *version);
@@ -1268,6 +1270,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) switch (reason) { case DLL_PROCESS_ATTACH: + hinstance = hinst; DisableThreadLibraryCalls(hinst); return wine_vk_init(); } @@ -1307,3 +1310,104 @@ void *native_vkGetInstanceProcAddrWINE(VkInstance instance, const char *name) { return vk_funcs->p_vkGetInstanceProcAddr(instance, name); } + + +static const WCHAR winevulkan_jsonW[] = {'\','w','i','n','e','v','u','l','k','a','n','.','j','s','o','n',0}; +static const WCHAR vulkan_driversW[] = {'S','o','f','t','w','a','r','e','\','K','h','r','o','n','o','s','\', + 'V','u','l','k','a','n','\','D','r','i','v','e','r','s',0}; +static BOOL writestr(HANDLE handle, const char *str) +{ + DWORD written; + return WriteFile(handle, str, strlen(str), &written, NULL); +} + +HRESULT WINAPI DllRegisterServer(void) +{ + WCHAR json_path[MAX_PATH]; + char dll_path[MAX_PATH], dll_path_escaped[MAX_PATH*2], vk_version[20]; + UINT i, j; + HANDLE file; + HKEY key; + DWORD zero = 0; + + /* Create the JSON manifest and registry key to register this ICD with the official Vulkan loader. */ + TRACE("\n"); + GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path)); + lstrcatW(json_path, winevulkan_jsonW); + file = CreateFileW(json_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + { + ERR("Unable to create JSON manifest.\n"); + return E_UNEXPECTED; + } + + if (!GetModuleFileNameA(hinstance, dll_path, ARRAY_SIZE(dll_path))) + { + ERR("Unable to get DLL path.\n"); + CloseHandle(file); + return E_UNEXPECTED; + } + /* Backslashes in the path need to be escaped for JSON */ + for (i = 0, j = 0; i < strlen(dll_path) + 1; i++, j++) + { + if (dll_path[i] == '\') + dll_path_escaped[j++] = '\'; + + dll_path_escaped[j] = dll_path[i]; + } + + snprintf(vk_version, sizeof(vk_version), "%u.%u.%u", + VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE), + VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE), + VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE)); + + writestr(file, "{\r\n"); + writestr(file, " "file_format_version": "1.0.0",\r\n"); + writestr(file, " "ICD": {\r\n"); + writestr(file, " "library_path": ""); + writestr(file, dll_path_escaped); + writestr(file, "",\r\n"); + writestr(file, " "api_version": ""); + writestr(file, vk_version); + writestr(file, ""\r\n"); + writestr(file, " }\r\n"); + writestr(file, "}\r\n"); + CloseHandle(file); + + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, NULL, 0, KEY_SET_VALUE, + NULL, &key, NULL) != ERROR_SUCCESS) + { + ERR("Unable to create registry key.\n"); + return E_UNEXPECTED; + } + + if (RegSetValueExW(key, json_path, 0, REG_DWORD, (const BYTE *)&zero, sizeof(zero)) != ERROR_SUCCESS) + { + ERR("Unable to set registry value.\n"); + RegCloseKey(key); + return E_UNEXPECTED; + } + + RegCloseKey(key); + return S_OK; +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + WCHAR json_path[MAX_PATH]; + HKEY key; + + /* Remove the JSON manifest and registry key */ + TRACE("\n"); + GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path)); + lstrcatW(json_path, winevulkan_jsonW); + DeleteFileW(json_path); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, KEY_SET_VALUE, &key) == ERROR_SUCCESS) + { + RegDeleteValueW(key, json_path); + RegCloseKey(key); + } + + return S_OK; +} diff --git a/dlls/winevulkan/winevulkan.spec b/dlls/winevulkan/winevulkan.spec index c02af5aeaa..e024a43586 100644 --- a/dlls/winevulkan/winevulkan.spec +++ b/dlls/winevulkan/winevulkan.spec @@ -239,3 +239,5 @@ @ stdcall -private wine_vkUpdateDescriptorSets(ptr long ptr long ptr) @ stdcall -private wine_vkWaitForFences(ptr long ptr long int64) @ stdcall -private wine_vkWaitSemaphores(ptr ptr int64) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 6e0cb21253..d0b156eb77 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -2569,6 +2569,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,windowscodecs.dll,1 11,,winegstreamer.dll,1 11,,wineqtdecoder.dll,1 +11,,winevulkan.dll,1 11,,wintrust.dll,1 11,,iexplore.exe,1
On 3/24/20 2:52 PM, Brendan Shanks wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47109 Signed-off-by: Brendan Shanks bshanks@codeweavers.com
v5: Write an absolute path to the library in the JSON file, clean up error handling, and remove incorrect error handling in Unregister.
dlls/winevulkan/Makefile.in | 2 +- dlls/winevulkan/make_vulkan | 3 + dlls/winevulkan/vulkan.c | 104 ++++++++++++++++++++++++++++++++ dlls/winevulkan/winevulkan.spec | 2 + loader/wine.inf.in | 1 + 5 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in index e0bca6fad7..2ffff40c3a 100644 --- a/dlls/winevulkan/Makefile.in +++ b/dlls/winevulkan/Makefile.in @@ -1,6 +1,6 @@ MODULE = winevulkan.dll IMPORTLIB = winevulkan -IMPORTS = user32 gdi32 +IMPORTS = user32 gdi32 advapi32
C_SRCS = \ vulkan.c \ diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index e0b94a06cb..bccfa6a6d6 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -2509,6 +2509,9 @@ class VkGenerator(object): else: f.write("@ stub {0}\n".format(func.name))
f.write("@ stdcall -private DllRegisterServer()\n")
f.write("@ stdcall -private DllUnregisterServer()\n")
def generate_vulkan_loader_spec(self, f): self._generate_copyright(f, spec_file=True)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 59472bcef8..257416ab14 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -21,6 +21,7 @@
#include "windef.h" #include "winbase.h" +#include "winreg.h" #include "winuser.h"
#include "vulkan_private.h" @@ -50,6 +51,7 @@ static void *wine_vk_find_struct_(void *s, VkStructureType t)
static void *wine_vk_get_global_proc_addr(const char *name);
+static HINSTANCE hinstance; static const struct vulkan_funcs *vk_funcs; static VkResult (*p_vkEnumerateInstanceVersion)(uint32_t *version);
@@ -1268,6 +1270,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) switch (reason) { case DLL_PROCESS_ATTACH:
hinstance = hinst; DisableThreadLibraryCalls(hinst); return wine_vk_init(); }
@@ -1307,3 +1310,104 @@ void *native_vkGetInstanceProcAddrWINE(VkInstance instance, const char *name) { return vk_funcs->p_vkGetInstanceProcAddr(instance, name); }
+static const WCHAR winevulkan_jsonW[] = {'\','w','i','n','e','v','u','l','k','a','n','.','j','s','o','n',0}; +static const WCHAR vulkan_driversW[] = {'S','o','f','t','w','a','r','e','\','K','h','r','o','n','o','s','\',
'V','u','l','k','a','n','\\','D','r','i','v','e','r','s',0};
+static BOOL writestr(HANDLE handle, const char *str) +{
- DWORD written;
- return WriteFile(handle, str, strlen(str), &written, NULL);
+}
If the concern here is about duplication for the calling-strings, maybe it would be preferable to use a macro rather than a helper function. I agree with your reasoning from discussion on v3 of the patch that it's more elegant to keep the icd file contents groups together.
Although maybe it would be preferable to setup a single multiline-string and use sprintf or something? That seems simplest from a readability standpoint.
Thanks,
Liam Middlebrook
+HRESULT WINAPI DllRegisterServer(void) +{
- WCHAR json_path[MAX_PATH];
- char dll_path[MAX_PATH], dll_path_escaped[MAX_PATH*2], vk_version[20];
- UINT i, j;
- HANDLE file;
- HKEY key;
- DWORD zero = 0;
- /* Create the JSON manifest and registry key to register this ICD with the official Vulkan loader. */
- TRACE("\n");
- GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path));
- lstrcatW(json_path, winevulkan_jsonW);
- file = CreateFileW(json_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (file == INVALID_HANDLE_VALUE)
- {
ERR("Unable to create JSON manifest.\n");
return E_UNEXPECTED;
- }
- if (!GetModuleFileNameA(hinstance, dll_path, ARRAY_SIZE(dll_path)))
- {
ERR("Unable to get DLL path.\n");
CloseHandle(file);
return E_UNEXPECTED;
- }
- /* Backslashes in the path need to be escaped for JSON */
- for (i = 0, j = 0; i < strlen(dll_path) + 1; i++, j++)
- {
if (dll_path[i] == '\\')
dll_path_escaped[j++] = '\\';
dll_path_escaped[j] = dll_path[i];
- }
- snprintf(vk_version, sizeof(vk_version), "%u.%u.%u",
VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE),
VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE),
VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));
- writestr(file, "{\r\n");
- writestr(file, " "file_format_version": "1.0.0",\r\n");
- writestr(file, " "ICD": {\r\n");
- writestr(file, " "library_path": "");
- writestr(file, dll_path_escaped);
- writestr(file, "",\r\n");
- writestr(file, " "api_version": "");
- writestr(file, vk_version);
- writestr(file, ""\r\n");
- writestr(file, " }\r\n");
- writestr(file, "}\r\n");
- CloseHandle(file);
- if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, NULL, 0, KEY_SET_VALUE,
NULL, &key, NULL) != ERROR_SUCCESS)
- {
ERR("Unable to create registry key.\n");
return E_UNEXPECTED;
- }
- if (RegSetValueExW(key, json_path, 0, REG_DWORD, (const BYTE *)&zero, sizeof(zero)) != ERROR_SUCCESS)
- {
ERR("Unable to set registry value.\n");
RegCloseKey(key);
return E_UNEXPECTED;
- }
- RegCloseKey(key);
- return S_OK;
+}
+HRESULT WINAPI DllUnregisterServer(void) +{
- WCHAR json_path[MAX_PATH];
- HKEY key;
- /* Remove the JSON manifest and registry key */
- TRACE("\n");
- GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path));
- lstrcatW(json_path, winevulkan_jsonW);
- DeleteFileW(json_path);
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, KEY_SET_VALUE, &key) == ERROR_SUCCESS)
- {
RegDeleteValueW(key, json_path);
RegCloseKey(key);
- }
- return S_OK;
+} diff --git a/dlls/winevulkan/winevulkan.spec b/dlls/winevulkan/winevulkan.spec index c02af5aeaa..e024a43586 100644 --- a/dlls/winevulkan/winevulkan.spec +++ b/dlls/winevulkan/winevulkan.spec @@ -239,3 +239,5 @@ @ stdcall -private wine_vkUpdateDescriptorSets(ptr long ptr long ptr) @ stdcall -private wine_vkWaitForFences(ptr long ptr long int64) @ stdcall -private wine_vkWaitSemaphores(ptr ptr int64) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 6e0cb21253..d0b156eb77 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -2569,6 +2569,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,windowscodecs.dll,1 11,,winegstreamer.dll,1 11,,wineqtdecoder.dll,1 +11,,winevulkan.dll,1 11,,wintrust.dll,1 11,,iexplore.exe,1
----------------------------------------------------------------------------------- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. -----------------------------------------------------------------------------------