58 lines
2 KiB
Rust
58 lines
2 KiB
Rust
//! The following directly was copied from [neon][].
|
|
//!
|
|
//! Rust port of [win_delay_load_hook.cc][].
|
|
//!
|
|
//! When the addon tries to load the "node.exe" DLL module, this module gives it the pointer to the
|
|
//! .exe we are running in instead. Typically, that will be the same value. But if the node executable
|
|
//! was renamed, you would not otherwise get the correct DLL.
|
|
//!
|
|
//! [neon]: https://github.com/neon-bindings/neon/blob/5ffa2d282177b63094c46e92b20b8e850d122e65/src/win_delay_load_hook.rs
|
|
//! [win_delay_load_hook.cc]: https://github.com/nodejs/node-gyp/blob/e18a61afc1669d4897e6c5c8a6694f4995a0f4d6/src/win_delay_load_hook.cc
|
|
|
|
use std::ffi::CStr;
|
|
use std::os::raw::c_char;
|
|
|
|
use windows::core::PCSTR;
|
|
use windows::Win32::Foundation::HINSTANCE;
|
|
use windows::Win32::System::LibraryLoader::GetModuleHandleA;
|
|
use windows::Win32::System::WindowsProgramming::{DELAYLOAD_INFO, PDELAYLOAD_FAILURE_DLL_CALLBACK};
|
|
|
|
// Structures hand-copied from
|
|
// https://docs.microsoft.com/en-us/cpp/build/reference/structure-and-constant-definitions
|
|
|
|
const HOST_BINARIES: &[&[u8]] = &[b"node.exe", b"electron.exe"];
|
|
|
|
unsafe extern "C" fn load_exe_hook(event: u32, info: *const DELAYLOAD_INFO) -> HINSTANCE {
|
|
if event != 0x01
|
|
/* dliNotePreLoadLibrary */
|
|
{
|
|
return HINSTANCE::default();
|
|
}
|
|
|
|
let dll_name = unsafe { CStr::from_ptr((*info).TargetDllName.0 as *mut i8) };
|
|
if !HOST_BINARIES
|
|
.iter()
|
|
.any(|&host_name| host_name == dll_name.to_bytes())
|
|
{
|
|
return HINSTANCE::default();
|
|
}
|
|
|
|
match unsafe { GetModuleHandleA(PCSTR::default()) } {
|
|
Ok(h) => h,
|
|
Err(e) => unsafe {
|
|
let location = "win_delay_load_hook.rs\0";
|
|
let err = format!("{}", e);
|
|
crate::sys::napi_fatal_error(
|
|
location.as_ptr() as *const c_char,
|
|
22,
|
|
format!("{}\0", err).as_ptr() as *const c_char,
|
|
err.len(),
|
|
);
|
|
unreachable!();
|
|
},
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
static mut __pfnDliNotifyHook2: *mut PDELAYLOAD_FAILURE_DLL_CALLBACK =
|
|
load_exe_hook as *mut PDELAYLOAD_FAILURE_DLL_CALLBACK;
|