diff options
author | Bailey Kuo <formosa@google.com> | 2024-05-09 22:57:45 +0000 |
---|---|---|
committer | Bailey Kuo <formosa@google.com> | 2024-05-09 22:57:46 +0000 |
commit | 217ec159fb6cba3bd843920c42ef0874be0c1e21 (patch) | |
tree | 734d83833658f5aa7d1866714069a4f0a2663010 | |
parent | e89358719876bdc86a4b4a129280c3f817b2a708 (diff) | |
download | libloading-master.tar.gz |
This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/libloading
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
Test: TreeHugger
Change-Id: I65f97d9a3417d2ebbec9e24b8c2f1d04b5cab9e6
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .github/workflows/libloading.yml | 2 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | Cargo.toml | 17 | ||||
-rw-r--r-- | Cargo.toml.orig | 17 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | src/changelog.rs | 27 | ||||
-rw-r--r-- | src/error.rs | 8 | ||||
-rw-r--r-- | src/lib.rs | 6 | ||||
-rw-r--r-- | src/os/unix/mod.rs | 186 | ||||
-rw-r--r-- | src/os/windows/mod.rs | 121 |
11 files changed, 217 insertions, 179 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 37498d8..9802472 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "006afa9d614a2a5bd2ce666b657a3fb83ce2d090" + "sha1": "dc8664fd23a34b16e240c1bd48acbe3596cb8eef" }, "path_in_vcs": "" }
\ No newline at end of file diff --git a/.github/workflows/libloading.yml b/.github/workflows/libloading.yml index 3382da1..9fbcb6e 100644 --- a/.github/workflows/libloading.yml +++ b/.github/workflows/libloading.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - rust_toolchain: [nightly, stable, 1.48.0] + rust_toolchain: [nightly, stable, 1.56.0] os: [ubuntu-latest, windows-latest, macOS-latest] timeout-minutes: 20 steps: @@ -25,7 +25,7 @@ rust_library { host_supported: true, crate_name: "libloading", cargo_env_compat: true, - cargo_pkg_version: "0.8.1", + cargo_pkg_version: "0.8.3", srcs: ["src/lib.rs"], edition: "2015", rustlibs: ["libcfg_if"], @@ -10,9 +10,9 @@ # See Cargo.toml.orig for the original contents. [package] -rust-version = "1.48.0" +rust-version = "1.56.0" name = "libloading" -version = "0.8.1" +version = "0.8.3" authors = ["Simonas Kazlauskas <libloading@kazlauskas.me>"] description = "Bindings around the platform's dynamic library loading primitives with greatly improved memory safety." documentation = "https://docs.rs/libloading/" @@ -43,10 +43,9 @@ version = "1.1" [target."cfg(unix)".dependencies.cfg-if] version = "1" -[target."cfg(windows)".dependencies.windows-sys] -version = "0.48" -features = [ - "Win32_Foundation", - "Win32_System_Diagnostics_Debug", - "Win32_System_LibraryLoader", -] +[target."cfg(windows)".dependencies.windows-targets] +version = ">=0.48, <0.53" + +[target."cfg(windows)".dev-dependencies.windows-sys] +version = "0.52" +features = ["Win32_Foundation"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 84d1755..fbe57ee 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -3,7 +3,7 @@ name = "libloading" # When bumping # * Don’t forget to add an entry to `src/changelog.rs` # * If bumping to an incompatible version, adjust the documentation in `src/lib.rs` -version = "0.8.1" +version = "0.8.3" authors = ["Simonas Kazlauskas <libloading@kazlauskas.me>"] license = "ISC" repository = "https://github.com/nagisa/rust_libloading/" @@ -12,15 +12,14 @@ readme = "README.mkd" description = "Bindings around the platform's dynamic library loading primitives with greatly improved memory safety." keywords = ["dlopen", "load", "shared", "dylib"] categories = ["api-bindings"] -rust-version = "1.48.0" +rust-version = "1.56.0" -[target.'cfg(windows)'.dependencies.windows-sys] -version = "0.48" -features = [ - "Win32_Foundation", - "Win32_System_Diagnostics_Debug", - "Win32_System_LibraryLoader", -] +[target.'cfg(windows)'.dependencies.windows-targets] +version = ">=0.48, <0.53" + +[target.'cfg(windows)'.dev-dependencies.windows-sys] +version = "0.52" +features = ["Win32_Foundation"] [target.'cfg(unix)'.dependencies.cfg-if] version = "1" @@ -8,13 +8,13 @@ third_party { license_type: NOTICE last_upgrade_date { year: 2024 - month: 2 - day: 2 + month: 5 + day: 9 } homepage: "https://crates.io/crates/libloading" identifier { type: "Archive" - value: "https://static.crates.io/crates/libloading/libloading-0.8.1.crate" - version: "0.8.1" + value: "https://static.crates.io/crates/libloading/libloading-0.8.3.crate" + version: "0.8.3" } } diff --git a/src/changelog.rs b/src/changelog.rs index 536834b..58101ae 100644 --- a/src/changelog.rs +++ b/src/changelog.rs @@ -1,10 +1,37 @@ //! The change log. +/// Release 0.8.3 (2024-03-05) +/// +/// ## Non-breaking changes +/// +/// A `dev-dependency` on `windows-sys` that was unconditionally introduced in +/// [0.8.2](r0_8_2) has been made conditional. +pub mod r0_8_3 {} + +/// Release 0.8.2 (2024-03-01) +/// +/// ## (Potentially) breaking changes +/// +/// MSRV has been increased to 1.56.0. Since both rustc versions are ancient, this has been deemed +/// to not be breaking enough to warrant a semver-breaking release of libloading. If you're stick +/// with a version of rustc older than 1.56.0, lock `libloading` dependency to `0.8.1`. +/// +/// ## Non-breaking changes +/// +/// * The crate switches the dependency on `windows-sys` to a `windows-target` one for Windows +/// bindings. In order to enable this `libloading` defines any bindings necessary for its operation +/// internally, just like has been done for `unix` targets. This should result in leaner dependency +/// trees. +/// * `os::unix::with_dlerror` has been exposed for the users who need to invoke `dl*` family of +/// functions manually. +pub mod r0_8_2 {} + /// Release 0.8.1 (2023-09-30) /// /// ## Non-breaking changes /// /// * Support for GNU Hurd. +pub mod r0_8_1 {} /// Release 0.8.0 (2023-04-11) /// diff --git a/src/error.rs b/src/error.rs index bd70ec3..ff4891c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use std::ffi::CString; +use std::ffi::{CString, CStr}; /// A `dlerror` error. pub struct DlDescription(pub(crate) CString); @@ -9,6 +9,12 @@ impl std::fmt::Debug for DlDescription { } } +impl From<&CStr> for DlDescription { + fn from(value: &CStr) -> Self { + Self(value.into()) + } +} + /// A Windows API error. pub struct WindowsError(pub(crate) std::io::Error); @@ -41,15 +41,13 @@ pub mod changelog; pub mod os; mod util; - mod error; -pub use self::error::Error; - #[cfg(any(unix, windows, libloading_docs))] mod safe; + +pub use self::error::Error; #[cfg(any(unix, windows, libloading_docs))] pub use self::safe::{Library, Symbol}; - use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::ffi::{OsStr, OsString}; diff --git a/src/os/unix/mod.rs b/src/os/unix/mod.rs index df7efda..6347e02 100644 --- a/src/os/unix/mod.rs +++ b/src/os/unix/mod.rs @@ -16,18 +16,33 @@ use util::{cstr_cow_from_bytes, ensure_compatible_types}; mod consts; -// dl* family of functions did not have enough thought put into it. -// -// Whole error handling scheme is done via setting and querying some global state, therefore it is -// not safe to use dynamic library loading in MT-capable environment at all. Only in POSIX 2008+TC1 -// a thread-local state was allowed for `dlerror`, making the dl* family of functions MT-safe. -// -// In practice (as of 2020-04-01) most of the widely used targets use a thread-local for error -// state and have been doing so for a long time. Regardless the comments in this function shall -// remain as a documentation for the future generations. -fn with_dlerror<T, F>(wrap: fn(crate::error::DlDescription) -> crate::Error, closure: F) --> Result<T, Option<crate::Error>> -where F: FnOnce() -> Option<T> { +/// Run code and handle errors reported by `dlerror`. +/// +/// This function first executes the `closure` function containing calls to the functions that +/// report their errors via `dlerror`. This closure may return either `None` or `Some(*)` to +/// further affect operation of this function. +/// +/// In case the `closure` returns `None`, `with_dlerror` inspects the `dlerror`. `dlerror` may +/// decide to not provide any error description, in which case `Err(None)` is returned to the +/// caller. Otherwise the `error` callback is invoked to allow inspection and conversion of the +/// error message. The conversion result is returned as `Err(Some(Error))`. +/// +/// If the operations that report their errors via `dlerror` were all successful, `closure` should +/// return `Some(T)` instead. In this case `dlerror` is not inspected at all. +/// +/// # Notes +/// +/// The whole `dlerror` handling scheme is done via setting and querying some global state. For +/// that reason it is not safe to use dynamic library loading in MT-capable environment at all. +/// Only in POSIX 2008+TC1 a thread-local state was allowed for `dlerror`, making the dl* family of +/// functions possibly MT-safe, depending on the implementation of `dlerror`. +/// +/// In practice (as of 2020-04-01) most of the widely used targets use a thread-local for error +/// state and have been doing so for a long time. +pub fn with_dlerror<T, F, Error>(closure: F, error: fn(&CStr) -> Error) -> Result<T, Option<Error>> +where + F: FnOnce() -> Option<T>, +{ // We used to guard all uses of dl* functions with our own mutex. This made them safe to use in // MT programs provided the only way a program used dl* was via this library. However, it also // had a number of downsides or cases where it failed to handle the problems. For instance, @@ -53,8 +68,8 @@ where F: FnOnce() -> Option<T> { // or a bug in implementation of dl* family of functions. closure().ok_or_else(|| unsafe { // This code will only get executed if the `closure` returns `None`. - let error = dlerror(); - if error.is_null() { + let dlerror_str = dlerror(); + if dlerror_str.is_null() { // In non-dlsym case this may happen when there’re bugs in our bindings or there’s // non-libloading user of libdl; possibly in another thread. None @@ -64,8 +79,7 @@ where F: FnOnce() -> Option<T> { // ownership over the message? // TODO: should do locale-aware conversion here. OTOH Rust doesn’t seem to work well in // any system that uses non-utf8 locale, so I doubt there’s a problem here. - let message = CStr::from_ptr(error).into(); - Some(wrap(crate::error::DlDescription(message))) + Some(error(CStr::from_ptr(dlerror_str))) // Since we do a copy of the error string above, maybe we should call dlerror again to // let libdl know it may free its copy of the string now? } @@ -74,7 +88,7 @@ where F: FnOnce() -> Option<T> { /// A platform-specific counterpart of the cross-platform [`Library`](crate::Library). pub struct Library { - handle: *mut raw::c_void + handle: *mut raw::c_void, } unsafe impl Send for Library {} @@ -164,30 +178,38 @@ impl Library { /// termination routines contained within the library is safe as well. These routines may be /// executed when the library is unloaded. pub unsafe fn open<P>(filename: Option<P>, flags: raw::c_int) -> Result<Library, crate::Error> - where P: AsRef<OsStr> { + where + P: AsRef<OsStr>, + { let filename = match filename { None => None, Some(ref f) => Some(cstr_cow_from_bytes(f.as_ref().as_bytes())?), }; - with_dlerror(|desc| crate::Error::DlOpen { desc }, move || { - let result = dlopen(match filename { - None => ptr::null(), - Some(ref f) => f.as_ptr() - }, flags); - // ensure filename lives until dlopen completes - drop(filename); - if result.is_null() { - None - } else { - Some(Library { - handle: result - }) - } - }).map_err(|e| e.unwrap_or(crate::Error::DlOpenUnknown)) + with_dlerror( + move || { + let result = dlopen( + match filename { + None => ptr::null(), + Some(ref f) => f.as_ptr(), + }, + flags, + ); + // ensure filename lives until dlopen completes + drop(filename); + if result.is_null() { + None + } else { + Some(Library { handle: result }) + } + }, + |desc| crate::Error::DlOpen { desc: desc.into() }, + ) + .map_err(|e| e.unwrap_or(crate::Error::DlOpenUnknown)) } unsafe fn get_impl<T, F>(&self, symbol: &[u8], on_null: F) -> Result<Symbol<T>, crate::Error> - where F: FnOnce() -> Result<Symbol<T>, crate::Error> + where + F: FnOnce() -> Result<Symbol<T>, crate::Error>, { ensure_compatible_types::<T, *mut raw::c_void>()?; let symbol = cstr_cow_from_bytes(symbol)?; @@ -197,23 +219,26 @@ impl Library { // // We try to leave as little space as possible for this to occur, but we can’t exactly // fully prevent it. - match with_dlerror(|desc| crate::Error::DlSym { desc }, || { - dlerror(); - let symbol = dlsym(self.handle, symbol.as_ptr()); - if symbol.is_null() { - None - } else { - Some(Symbol { - pointer: symbol, - pd: marker::PhantomData - }) - } - }) { + let result = with_dlerror( + || { + dlerror(); + let symbol = dlsym(self.handle, symbol.as_ptr()); + if symbol.is_null() { + None + } else { + Some(Symbol { + pointer: symbol, + pd: marker::PhantomData, + }) + } + }, + |desc| crate::Error::DlSym { desc: desc.into() }, + ); + match result { Err(None) => on_null(), Err(Some(e)) => Err(e), - Ok(x) => Ok(x) + Ok(x) => Ok(x), } - } /// Get a pointer to a function or static variable by symbol name. @@ -284,10 +309,12 @@ impl Library { /// variables that work on e.g. Linux may have unintended behaviour on other targets. #[inline(always)] pub unsafe fn get_singlethreaded<T>(&self, symbol: &[u8]) -> Result<Symbol<T>, crate::Error> { - self.get_impl(symbol, || Ok(Symbol { - pointer: ptr::null_mut(), - pd: marker::PhantomData - })) + self.get_impl(symbol, || { + Ok(Symbol { + pointer: ptr::null_mut(), + pd: marker::PhantomData, + }) + }) } /// Convert the `Library` to a raw handle. @@ -308,9 +335,7 @@ impl Library { /// pointer previously returned by `Library::into_raw` call. It must be valid to call `dlclose` /// with this pointer as an argument. pub unsafe fn from_raw(handle: *mut raw::c_void) -> Library { - Library { - handle - } + Library { handle } } /// Unload the library. @@ -324,13 +349,17 @@ impl Library { /// /// The underlying data structures may still get leaked if an error does occur. pub fn close(self) -> Result<(), crate::Error> { - let result = with_dlerror(|desc| crate::Error::DlClose { desc }, || { - if unsafe { dlclose(self.handle) } == 0 { - Some(()) - } else { - None - } - }).map_err(|e| e.unwrap_or(crate::Error::DlCloseUnknown)); + let result = with_dlerror( + || { + if unsafe { dlclose(self.handle) } == 0 { + Some(()) + } else { + None + } + }, + |desc| crate::Error::DlClose { desc: desc.into() }, + ) + .map_err(|e| e.unwrap_or(crate::Error::DlCloseUnknown)); // While the library is not free'd yet in case of an error, there is no reason to try // dropping it again, because all that will do is try calling `dlclose` again. only // this time it would ignore the return result, which we already seen failing… @@ -359,7 +388,7 @@ impl fmt::Debug for Library { /// `Symbol` does not outlive the `Library` it comes from. pub struct Symbol<T> { pointer: *mut raw::c_void, - pd: marker::PhantomData<T> + pd: marker::PhantomData<T>, } impl<T> Symbol<T> { @@ -409,13 +438,18 @@ impl<T> fmt::Debug for Symbol<T> { if dladdr(self.pointer, info.as_mut_ptr()) != 0 { let info = info.assume_init(); if info.dli_sname.is_null() { - f.write_str(&format!("Symbol@{:p} from {:?}", - self.pointer, - CStr::from_ptr(info.dli_fname))) + f.write_str(&format!( + "Symbol@{:p} from {:?}", + self.pointer, + CStr::from_ptr(info.dli_fname) + )) } else { - f.write_str(&format!("Symbol {:?}@{:p} from {:?}", - CStr::from_ptr(info.dli_sname), self.pointer, - CStr::from_ptr(info.dli_fname))) + f.write_str(&format!( + "Symbol {:?}@{:p} from {:?}", + CStr::from_ptr(info.dli_sname), + self.pointer, + CStr::from_ptr(info.dli_fname) + )) } } else { f.write_str(&format!("Symbol@{:p}", self.pointer)) @@ -425,9 +459,9 @@ impl<T> fmt::Debug for Symbol<T> { } // Platform specific things -#[cfg_attr(any(target_os = "linux", target_os = "android"), link(name="dl"))] -#[cfg_attr(any(target_os = "freebsd", target_os = "dragonfly"), link(name="c"))] -extern { +#[cfg_attr(any(target_os = "linux", target_os = "android"), link(name = "dl"))] +#[cfg_attr(any(target_os = "freebsd", target_os = "dragonfly"), link(name = "c"))] +extern "C" { fn dlopen(filename: *const raw::c_char, flags: raw::c_int) -> *mut raw::c_void; fn dlclose(handle: *mut raw::c_void) -> raw::c_int; fn dlsym(handle: *mut raw::c_void, symbol: *const raw::c_char) -> *mut raw::c_void; @@ -437,8 +471,8 @@ extern { #[repr(C)] struct DlInfo { - dli_fname: *const raw::c_char, - dli_fbase: *mut raw::c_void, - dli_sname: *const raw::c_char, - dli_saddr: *mut raw::c_void + dli_fname: *const raw::c_char, + dli_fbase: *mut raw::c_void, + dli_sname: *const raw::c_char, + dli_saddr: *mut raw::c_void, } diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index ff96ef8..172801e 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1,59 +1,18 @@ // A hack for docs.rs to build documentation that has both windows and linux documentation in the // same rustdoc build visible. #[cfg(all(libloading_docs, not(windows)))] -mod windows_imports { - pub(super) enum HMODULE {} - pub(super) enum FARPROC {} - #[allow(non_camel_case_types)] - pub(super) enum THREAD_ERROR_MODE {} - #[allow(non_camel_case_types)] - pub(super) struct LOAD_LIBRARY_FLAGS; - - pub(super) mod consts { - use super::LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_IGNORE_CODE_AUTHZ_LEVEL: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_AS_DATAFILE: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_AS_IMAGE_RESOURCE: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SEARCH_APPLICATION_DIR: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SEARCH_SYSTEM32: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SEARCH_USER_DIRS: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_WITH_ALTERED_SEARCH_PATH: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_REQUIRE_SIGNED_TARGET: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - pub(crate) const LOAD_LIBRARY_SAFE_CURRENT_DIRS: LOAD_LIBRARY_FLAGS = LOAD_LIBRARY_FLAGS; - } -} +mod windows_imports {} #[cfg(any(not(libloading_docs), windows))] mod windows_imports { - extern crate windows_sys; - pub(super) use self::windows_sys::Win32::Foundation::{GetLastError, FARPROC, HMODULE}; - pub(super) use self::windows_sys::Win32::System::Diagnostics::Debug as debug_api; - pub(super) use self::windows_sys::Win32::System::Diagnostics::Debug::SEM_FAILCRITICALERRORS; - pub(super) use self::windows_sys::Win32::System::Diagnostics::Debug::THREAD_ERROR_MODE; - - pub(super) use self::windows_sys::Win32::System::LibraryLoader as library_loader; - pub(super) use self::windows_sys::Win32::System::LibraryLoader::LOAD_LIBRARY_FLAGS; - + use super::{DWORD, BOOL, HANDLE, HMODULE, FARPROC}; pub(super) use std::os::windows::ffi::{OsStrExt, OsStringExt}; - - pub(super) mod consts { - pub(crate) use super::windows_sys::Win32::System::LibraryLoader::{ - LOAD_IGNORE_CODE_AUTHZ_LEVEL, - LOAD_LIBRARY_AS_DATAFILE, - LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE, - LOAD_LIBRARY_AS_IMAGE_RESOURCE, - LOAD_LIBRARY_SEARCH_APPLICATION_DIR, - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, - LOAD_LIBRARY_SEARCH_SYSTEM32, - LOAD_LIBRARY_SEARCH_USER_DIRS, - LOAD_WITH_ALTERED_SEARCH_PATH, - LOAD_LIBRARY_REQUIRE_SIGNED_TARGET, - LOAD_LIBRARY_SAFE_CURRENT_DIRS, - }; - } + windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> DWORD); + windows_targets::link!("kernel32.dll" "system" fn SetThreadErrorMode(new_mode: DWORD, old_mode: *mut DWORD) -> BOOL); + windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleExW(flags: u32, module_name: *const u16, module: *mut HMODULE) -> BOOL); + windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(module: HMODULE) -> BOOL); + windows_targets::link!("kernel32.dll" "system" fn LoadLibraryExW(filename: *const u16, file: HANDLE, flags: DWORD) -> HMODULE); + windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(module: HMODULE, filename: *mut u16, size: DWORD) -> DWORD); + windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(module: HMODULE, procname: *const u8) -> FARPROC); } use self::windows_imports::*; @@ -124,7 +83,7 @@ impl Library { unsafe { let mut handle: HMODULE = 0; with_get_last_error(|source| crate::Error::GetModuleHandleExW { source }, || { - let result = library_loader::GetModuleHandleExW(0, std::ptr::null_mut(), &mut handle); + let result = GetModuleHandleExW(0, std::ptr::null_mut(), &mut handle); if result == 0 { None } else { @@ -159,7 +118,7 @@ impl Library { with_get_last_error(|source| crate::Error::GetModuleHandleExW { source }, || { // Make sure no winapi calls as a result of drop happen inside this closure, because // otherwise that might change the return value of the GetLastError. - let result = library_loader::GetModuleHandleExW(0, wide_filename.as_ptr(), &mut handle); + let result = GetModuleHandleExW(0, wide_filename.as_ptr(), &mut handle); if result == 0 { None } else { @@ -199,7 +158,7 @@ impl Library { let ret = with_get_last_error(|source| crate::Error::LoadLibraryExW { source }, || { // Make sure no winapi calls as a result of drop happen inside this closure, because // otherwise that might change the return value of the GetLastError. - let handle = library_loader::LoadLibraryExW(wide_filename.as_ptr(), 0, flags); + let handle = LoadLibraryExW(wide_filename.as_ptr(), 0, flags); if handle == 0 { None } else { @@ -226,7 +185,7 @@ impl Library { ensure_compatible_types::<T, FARPROC>()?; let symbol = cstr_cow_from_bytes(symbol)?; with_get_last_error(|source| crate::Error::GetProcAddress { source }, || { - let symbol = library_loader::GetProcAddress(self.0, symbol.as_ptr().cast()); + let symbol = GetProcAddress(self.0, symbol.as_ptr().cast()); if symbol.is_none() { None } else { @@ -247,7 +206,7 @@ impl Library { ensure_compatible_types::<T, FARPROC>()?; with_get_last_error(|source| crate::Error::GetProcAddress { source }, || { let ordinal = ordinal as usize as *const _; - let symbol = library_loader::GetProcAddress(self.0, ordinal); + let symbol = GetProcAddress(self.0, ordinal); if symbol.is_none() { None } else { @@ -285,7 +244,7 @@ impl Library { /// The underlying data structures may still get leaked if an error does occur. pub fn close(self) -> Result<(), crate::Error> { let result = with_get_last_error(|source| crate::Error::FreeLibrary { source }, || { - if unsafe { library_loader::FreeLibrary(self.0) == 0 } { + if unsafe { FreeLibrary(self.0) == 0 } { None } else { Some(()) @@ -301,7 +260,7 @@ impl Library { impl Drop for Library { fn drop(&mut self) { - unsafe { library_loader::FreeLibrary(self.0); } + unsafe { FreeLibrary(self.0); } } } @@ -311,7 +270,7 @@ impl fmt::Debug for Library { // FIXME: use Maybeuninit::uninit_array when stable let mut buf = mem::MaybeUninit::<[mem::MaybeUninit<u16>; 1024]>::uninit().assume_init(); - let len = library_loader::GetModuleFileNameW(self.0, + let len = GetModuleFileNameW(self.0, buf[..].as_mut_ptr().cast(), 1024) as usize; if len == 0 { f.write_str(&format!("Library@{:#x}", self.0)) @@ -381,14 +340,14 @@ impl<T> fmt::Debug for Symbol<T> { } } -struct ErrorModeGuard(THREAD_ERROR_MODE); +struct ErrorModeGuard(DWORD); impl ErrorModeGuard { #[allow(clippy::if_same_then_else)] fn new() -> Option<ErrorModeGuard> { unsafe { let mut previous_mode = 0; - if debug_api::SetThreadErrorMode(SEM_FAILCRITICALERRORS, &mut previous_mode) == 0 { + if SetThreadErrorMode(SEM_FAILCRITICALERRORS, &mut previous_mode) == 0 { // How in the world is it possible for what is essentially a simple variable swap // to fail? For now we just ignore the error -- the worst that can happen here is // the previous mode staying on and user seeing a dialog error on older Windows @@ -406,7 +365,7 @@ impl ErrorModeGuard { impl Drop for ErrorModeGuard { fn drop(&mut self) { unsafe { - debug_api::SetThreadErrorMode(self.0, ptr::null_mut()); + SetThreadErrorMode(self.0, ptr::null_mut()); } } } @@ -424,13 +383,29 @@ where F: FnOnce() -> Option<T> { }) } + +#[allow(clippy::upper_case_acronyms)] +type BOOL = i32; +#[allow(clippy::upper_case_acronyms)] +type DWORD = u32; +#[allow(clippy::upper_case_acronyms)] +type HANDLE = isize; +#[allow(clippy::upper_case_acronyms)] +type HMODULE = isize; +#[allow(clippy::upper_case_acronyms)] +type FARPROC = Option<unsafe extern "system" fn() -> isize>; +#[allow(non_camel_case_types)] +type LOAD_LIBRARY_FLAGS = DWORD; + +const SEM_FAILCRITICALERRORS: DWORD = 1; + /// Do not check AppLocker rules or apply Software Restriction Policies for the DLL. /// /// This action applies only to the DLL being loaded and not to its dependencies. This value is /// recommended for use in setup programs that must run extracted DLLs during installation. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_IGNORE_CODE_AUTHZ_LEVEL: LOAD_LIBRARY_FLAGS = consts::LOAD_IGNORE_CODE_AUTHZ_LEVEL; +pub const LOAD_IGNORE_CODE_AUTHZ_LEVEL: LOAD_LIBRARY_FLAGS = 0x00000010; /// Map the file into the calling process’ virtual address space as if it were a data file. /// @@ -440,7 +415,7 @@ pub const LOAD_IGNORE_CODE_AUTHZ_LEVEL: LOAD_LIBRARY_FLAGS = consts::LOAD_IGNORE /// messages or resources from it. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_AS_DATAFILE: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_AS_DATAFILE; +pub const LOAD_LIBRARY_AS_DATAFILE: LOAD_LIBRARY_FLAGS = 0x00000002; /// Map the file into the calling process’ virtual address space as if it were a data file. /// @@ -449,7 +424,7 @@ pub const LOAD_LIBRARY_AS_DATAFILE: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_AS /// while it is in use. However, the DLL can still be opened by other processes. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE; +pub const LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: LOAD_LIBRARY_FLAGS = 0x00000040; /// Map the file into the process’ virtual address space as an image file. /// @@ -461,7 +436,7 @@ pub const LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: LOAD_LIBRARY_FLAGS = consts::LOAD_ /// [`LOAD_LIBRARY_AS_DATAFILE`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_AS_IMAGE_RESOURCE: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_AS_IMAGE_RESOURCE; +pub const LOAD_LIBRARY_AS_IMAGE_RESOURCE: LOAD_LIBRARY_FLAGS = 0x00000020; /// Search the application's installation directory for the DLL and its dependencies. /// @@ -469,7 +444,7 @@ pub const LOAD_LIBRARY_AS_IMAGE_RESOURCE: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBR /// [`LOAD_WITH_ALTERED_SEARCH_PATH`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SEARCH_APPLICATION_DIR: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SEARCH_APPLICATION_DIR; +pub const LOAD_LIBRARY_SEARCH_APPLICATION_DIR: LOAD_LIBRARY_FLAGS = 0x00000200; /// Search default directories when looking for the DLL and its dependencies. /// @@ -479,7 +454,7 @@ pub const LOAD_LIBRARY_SEARCH_APPLICATION_DIR: LOAD_LIBRARY_FLAGS = consts::LOAD /// [`LOAD_WITH_ALTERED_SEARCH_PATH`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; +pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = 0x00001000; /// Directory that contains the DLL is temporarily added to the beginning of the list of /// directories that are searched for the DLL’s dependencies. @@ -490,7 +465,7 @@ pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = consts::LOAD_LI /// with [`LOAD_WITH_ALTERED_SEARCH_PATH`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR; +pub const LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: LOAD_LIBRARY_FLAGS = 0x00000100; /// Search `%windows%\system32` for the DLL and its dependencies. /// @@ -498,7 +473,7 @@ pub const LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: LOAD_LIBRARY_FLAGS = consts::LOAD_LI /// [`LOAD_WITH_ALTERED_SEARCH_PATH`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SEARCH_SYSTEM32: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SEARCH_SYSTEM32; +pub const LOAD_LIBRARY_SEARCH_SYSTEM32: LOAD_LIBRARY_FLAGS = 0x00000800; /// Directories added using the `AddDllDirectory` or the `SetDllDirectory` function are searched /// for the DLL and its dependencies. @@ -508,7 +483,7 @@ pub const LOAD_LIBRARY_SEARCH_SYSTEM32: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRAR /// combined with [`LOAD_WITH_ALTERED_SEARCH_PATH`]. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SEARCH_USER_DIRS: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SEARCH_USER_DIRS; +pub const LOAD_LIBRARY_SEARCH_USER_DIRS: LOAD_LIBRARY_FLAGS = 0x00000400; /// If `filename` specifies an absolute path, the system uses the alternate file search strategy /// discussed in the [Remarks section] to find associated executable modules that the specified @@ -523,15 +498,15 @@ pub const LOAD_LIBRARY_SEARCH_USER_DIRS: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRA /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). /// /// [Remarks]: https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#remarks -pub const LOAD_WITH_ALTERED_SEARCH_PATH: LOAD_LIBRARY_FLAGS = consts::LOAD_WITH_ALTERED_SEARCH_PATH; +pub const LOAD_WITH_ALTERED_SEARCH_PATH: LOAD_LIBRARY_FLAGS = 0x00000008; /// Specifies that the digital signature of the binary image must be checked at load time. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_REQUIRE_SIGNED_TARGET: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_REQUIRE_SIGNED_TARGET; +pub const LOAD_LIBRARY_REQUIRE_SIGNED_TARGET: LOAD_LIBRARY_FLAGS = 0x00000080; /// Allow loading a DLL for execution from the current directory only if it is under a directory in /// the Safe load list. /// /// See [flag documentation on MSDN](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw#parameters). -pub const LOAD_LIBRARY_SAFE_CURRENT_DIRS: LOAD_LIBRARY_FLAGS = consts::LOAD_LIBRARY_SAFE_CURRENT_DIRS; +pub const LOAD_LIBRARY_SAFE_CURRENT_DIRS: LOAD_LIBRARY_FLAGS = 0x00002000; |