Commit aaf1e0b25b

Matthew Wozniak <106494504+wozniak@users.noreply.github.com>
2024-01-10 02:11:22
add ability to open dlls with platform-specific flags (#18370)
1 parent 4a1a5ee
Changed files (3)
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;
 
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);
 }
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),
         };
     }