Skip to content

Commit 1cf586c

Browse files
authored
Merge pull request #15 from TerranMechworks/queue-user-apc
Use QueueUserAPC instead of CreateThread for DllMain
2 parents 9ca0e2d + 09a465e commit 1cf586c

2 files changed

Lines changed: 22 additions & 20 deletions

File tree

crates/zipfixup/Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ region = "3.0.2"
2525
version = "0.62.0"
2626
default-features = false
2727
features = [
28-
"Win32_System_Diagnostics_Debug", # OutputDebugStringA/OutputDebugStringW
29-
"Win32_System_LibraryLoader", # DisableThreadLibraryCalls
30-
"Win32_System_SystemServices", # DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH
28+
"std",
29+
# OutputDebugStringA/OutputDebugStringW
30+
"Win32_System_Diagnostics_Debug",
31+
# DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH
32+
"Win32_System_SystemServices",
33+
# GetCurrentThread/QueueUserAPC
34+
"Win32_System_Threading",
3135
]
3236

3337
[build-dependencies]

crates/zipfixup/src/dll_main.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,37 @@
22
//! executable that loaded the DLL.
33
use crate::{Result, output};
44
use std::sync::Mutex;
5-
use windows::Win32::Foundation::{HMODULE, TRUE};
6-
use windows::Win32::System::LibraryLoader::DisableThreadLibraryCalls;
7-
use windows::Win32::System::SystemServices::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH};
5+
use windows::Win32::Foundation::{FALSE, GetLastError, HMODULE, TRUE};
6+
use windows::Win32::System::SystemServices::DLL_PROCESS_ATTACH;
7+
use windows::Win32::System::Threading::{GetCurrentThread, QueueUserAPC};
88

99
const VERSION: &str = env!("CARGO_PKG_VERSION");
1010

1111
#[unsafe(no_mangle)]
1212
#[allow(non_snake_case)]
1313
extern "system" fn DllMain(
14-
hlibmodule: HMODULE,
14+
_hlibmodule: HMODULE,
1515
call_reason: u32,
1616
_reserved: *mut std::ffi::c_void,
1717
) -> windows::core::BOOL {
1818
match call_reason {
1919
DLL_PROCESS_ATTACH => {
2020
output!("DLL_PROCESS_ATTACH");
21-
// disable DLL_THREAD_ATTACH/DLL_THREAD_DETACH notifications, since
22-
// we don't need them, and may help with spawning threads
23-
let _ = unsafe { DisableThreadLibraryCalls(hlibmodule) };
24-
// it's unclear what is allowed to be done in DllMain.
25-
// theoretically, even spawning a thread is not "recommended":
26-
// https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
27-
// https://devblogs.microsoft.com/oldnewthing/20070904-00/?p=25283
28-
// however, we don't synchronize on the thread, so it's ok?
29-
let _ = std::thread::spawn(load_fixup);
21+
let hthread = unsafe { GetCurrentThread() };
22+
let res = unsafe { QueueUserAPC(Some(load_fixup), hthread, 0) };
23+
if res == 0 {
24+
let e = unsafe { GetLastError() }.0;
25+
output!("QueueUserAPC failed: {e:08x}");
26+
FALSE
27+
} else {
28+
TRUE
29+
}
3030
}
31-
DLL_PROCESS_DETACH => (),
32-
_ => (),
31+
_ => TRUE,
3332
}
34-
TRUE
3533
}
3634

37-
fn load_fixup() {
35+
unsafe extern "system" fn load_fixup(_data: usize) {
3836
if let Err(e) = load_fixup_inner() {
3937
output!("FATAL error when loading fixup: {:?}", e);
4038
}

0 commit comments

Comments
 (0)