From 7eb14b991ca43a74ecefe65dd98dedd93b18ee22 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Sat, 5 Apr 2025 00:19:14 +0200 Subject: [PATCH] Only try kernelbase if the full symbol lookup failed --- src/sys/windows.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 4661128..9a553fb 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -106,13 +106,23 @@ pub fn init() -> apperr::Result { return Err(get_last_error()); } - let mut kernel32 = LibraryLoader::GetModuleHandleW(w!("kernel32.dll")); - if kernel32.is_null() { - // `kernel32.dll` doesn't exist on OneCore variants of Windows. - // NOTE: `kernelbase.dll` is NOT a stable API to rely on. In our case it's the best option though. - kernel32 = LibraryLoader::GetModuleHandleW(w!("kernelbase.dll")); + unsafe fn load_read_func(module: *const u16) -> apperr::Result { + unsafe { get_module(module).and_then(|m| get_proc_address(m, c"ReadConsoleInputExW")) } } - STATE.read_console_input_ex = get_proc_address(kernel32, c"ReadConsoleInputExW")?; + + // `kernel32.dll` doesn't exist on OneCore variants of Windows. + // NOTE: `kernelbase.dll` is NOT a stable API to rely on. In our case it's the best option though. + // + // This is written as two nested `match` statements so that we can return the error from the first + // `load_read_func` call if it fails. The kernel32.dll lookup may contain some valid information, + // while the kernelbase.dll lookup may not, since it's not a stable API. + STATE.read_console_input_ex = match load_read_func(w!("kernel32.dll")) { + Ok(func) => func, + Err(err) => match load_read_func(w!("kernelbase.dll")) { + Ok(func) => func, + Err(_) => return Err(err), + }, + }; Ok(Deinit) } @@ -464,6 +474,10 @@ pub unsafe fn virtual_commit(base: *mut u8, size: usize) -> apperr::Result<()> { } } +unsafe fn get_module(name: *const u16) -> apperr::Result { + unsafe { check_ptr_return(LibraryLoader::GetModuleHandleW(name)) } +} + unsafe fn load_library(name: *const u16) -> apperr::Result { unsafe { check_ptr_return(LibraryLoader::LoadLibraryExW(