add ability to open dlls with platform-specific flags (#18370)

This commit is contained in:
Matthew Wozniak 2024-01-09 20:11:22 -05:00 committed by GitHub
parent 4a1a5ee47b
commit aaf1e0b25b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 3 deletions

View File

@ -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),
};
}

View File

@ -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);
}

View File

@ -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;