Skip to content

Commit 6196475

Browse files
committed
Improve delayload comments
1 parent 8e547f4 commit 6196475

File tree

2 files changed

+37
-27
lines changed

2 files changed

+37
-27
lines changed

build.rs

+34-26
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,43 @@ fn main() {
2828
let target = env::var("TARGET").unwrap();
2929
println!("cargo:rustc-env=TARGET={target}");
3030

31+
// Set linker options specific to Windows MSVC.
3132
let target_os = env::var("CARGO_CFG_TARGET_OS");
3233
let target_env = env::var("CARGO_CFG_TARGET_ENV");
33-
if Ok("windows") == target_os.as_deref() && Ok("msvc") == target_env.as_deref() {
34-
// # Only search system32 for DLLs
35-
//
36-
// This applies to DLLs loaded at load time. However, this setting is ignored
37-
// before Windows 10 RS1.
38-
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");
34+
if target_os.as_deref() != Ok("windows") && target_env.as_deref() != Ok("msvc") {
35+
return;
36+
}
3937

40-
// # Delay load
41-
//
42-
// Delay load dlls that are not "known DLLs".
43-
// Known DLLs are always loaded from the system directory whereas other DLLs
44-
// are loaded from the application directory. By delay loading the latter
45-
// we can ensure they are instead loaded from the system directory.
46-
//
47-
// This will work on all supported Windows versions but it relies on
48-
// using `SetDefaultDllDirectories` before any libraries are loaded.
49-
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
50-
for dll in delay_load_dlls {
51-
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
52-
}
53-
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");
38+
// # Only search system32 for DLLs
39+
//
40+
// This applies to DLLs loaded at load time. However, this setting is ignored
41+
// before Windows 10 RS1 (aka 1601).
42+
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
43+
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");
5444

55-
// # Turn linker warnings into errors
56-
//
57-
// Rust hides linker warnings meaning mistakes may go unnoticed.
58-
// Turning them into errors forces them to be displayed (and the build to fail).
59-
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
60-
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
45+
// # Delay load
46+
//
47+
// Delay load dlls that are not "known DLLs"[1].
48+
// Known DLLs are always loaded from the system directory whereas other DLLs
49+
// are loaded from the application directory. By delay loading the latter
50+
// we can ensure they are instead loaded from the system directory.
51+
// [1]: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching
52+
//
53+
// This will work on all supported Windows versions but it relies on
54+
// us using `SetDefaultDllDirectories` before any libraries are loaded.
55+
// See also: src/bin/rustup-init.rs
56+
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
57+
for dll in delay_load_dlls {
58+
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
6159
}
60+
// When using delayload, it's necessary to also link delayimp.lib
61+
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
62+
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");
63+
64+
// # Turn linker warnings into errors
65+
//
66+
// Rust hides linker warnings meaning mistakes may go unnoticed.
67+
// Turning them into errors forces them to be displayed (and the build to fail).
68+
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
69+
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
6270
}

src/bin/rustup-init.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,14 @@ fn do_recursion_guard() -> Result<()> {
169169

170170
/// Windows pre-main security mitigations.
171171
///
172-
/// This is attempts to defend against malicious DLLs that may sit alongside
172+
/// This attempts to defend against malicious DLLs that may sit alongside
173173
/// rustup-init in the user's download folder.
174174
#[cfg(windows)]
175175
pub fn pre_rustup_main_init() {
176176
use winapi::um::libloaderapi::{SetDefaultDllDirectories, LOAD_LIBRARY_SEARCH_SYSTEM32};
177177
// Default to loading delay loaded DLLs from the system directory.
178+
// For DLLs loaded at load time, this relies on the `delayload` linker flag.
179+
// This is only necessary prior to Windows 10 RS1. See build.rs for details.
178180
unsafe {
179181
let result = SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
180182
// SetDefaultDllDirectories should never fail if given valid arguments.

0 commit comments

Comments
 (0)