From aaf1e0b25bbeedc18869073e1a51719e2e86cc93 Mon Sep 17 00:00:00 2001 From: Matthew Wozniak <106494504+wozniak@users.noreply.github.com> Date: Tue, 9 Jan 2024 20:11:22 -0500 Subject: [PATCH] add ability to open dlls with platform-specific flags (#18370) --- lib/std/dynamic_library.zig | 18 +++++++++++++++--- lib/std/os/windows.zig | 28 ++++++++++++++++++++++++++++ lib/std/os/windows/kernel32.zig | 1 + 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 956a48a338..42a2c6ddbd 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -320,16 +320,28 @@ pub const WindowsDynLib = struct { dll: windows.HMODULE, pub fn open(path: []const u8) !WindowsDynLib { + return openEx(path, .none); + } + + pub fn openEx(path: []const u8, flags: windows.LoadLibraryFlags) !WindowsDynLib { const path_w = try windows.sliceToPrefixedFileW(null, path); - return openW(path_w.span().ptr); + return openExW(path_w.span().ptr, flags); } pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib { + return openExZ(path_c, .none); + } + + pub fn openExZ(path_c: [*:0]const u8, flags: windows.LoadLibraryFlags) !WindowsDynLib { const path_w = try windows.cStrToPrefixedFileW(null, path_c); - return openW(path_w.span().ptr); + return openExW(path_w.span().ptr, flags); } pub fn openW(path_w: [*:0]const u16) !WindowsDynLib { + return openExW(path_w, .none); + } + + pub fn openExW(path_w: [*:0]const u16, flags: windows.LoadLibraryFlags) !WindowsDynLib { var offset: usize = 0; if (path_w[0] == '\\' and path_w[1] == '?' and path_w[2] == '?' and path_w[3] == '\\') { // + 4 to skip over the \??\ @@ -337,7 +349,7 @@ pub const WindowsDynLib = struct { } return WindowsDynLib{ - .dll = try windows.LoadLibraryW(path_w + offset), + .dll = try windows.LoadLibraryExW(path_w + offset, flags), }; } diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index dee6381d91..451310c44d 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1802,6 +1802,34 @@ pub fn LoadLibraryW(lpLibFileName: [*:0]const u16) LoadLibraryError!HMODULE { }; } +pub const LoadLibraryFlags = enum(DWORD) { + none = 0, + dont_resolve_dll_references = 0x00000001, + load_ignore_code_authz_level = 0x00000010, + load_library_as_datafile = 0x00000002, + load_library_as_datafile_exclusive = 0x00000040, + load_library_as_image_resource = 0x00000020, + load_library_search_application_dir = 0x00000200, + load_library_search_default_dirs = 0x00001000, + load_library_search_dll_load_dir = 0x00000100, + load_library_search_system32 = 0x00000800, + load_library_search_user_dirs = 0x00000400, + load_with_altered_search_path = 0x00000008, + load_library_require_signed_target = 0x00000080, + load_library_safe_current_dirs = 0x00002000, +}; + +pub fn LoadLibraryExW(lpLibFileName: [*:0]const u16, dwFlags: LoadLibraryFlags) LoadLibraryError!HMODULE { + return kernel32.LoadLibraryExW(lpLibFileName, null, @intFromEnum(dwFlags)) orelse { + switch (kernel32.GetLastError()) { + .FILE_NOT_FOUND => return error.FileNotFound, + .PATH_NOT_FOUND => return error.FileNotFound, + .MOD_NOT_FOUND => return error.FileNotFound, + else => |err| return unexpectedError(err), + } + }; +} + pub fn FreeLibrary(hModule: HMODULE) void { assert(kernel32.FreeLibrary(hModule) != 0); } diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index ab43fd894d..a1ca655ed1 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -387,6 +387,7 @@ pub extern "kernel32" fn WriteFileEx( ) callconv(WINAPI) BOOL; pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*:0]const u16) callconv(WINAPI) ?HMODULE; +pub extern "kernel32" fn LoadLibraryExW(lpLibFileName: [*:0]const u16, hFile: ?HANDLE, dwFlags: DWORD) callconv(WINAPI) ?HMODULE; pub extern "kernel32" fn GetProcAddress(hModule: HMODULE, lpProcName: [*:0]const u8) callconv(WINAPI) ?FARPROC;