Drop the code for supporting XP/Vista

This commit is contained in:
Simonas Kazlauskas
2021-02-06 16:36:56 +02:00
parent 2dc3cb5983
commit 4182c7e7e8
3 changed files with 19 additions and 45 deletions
-1
View File
@@ -16,7 +16,6 @@ categories = ["api-bindings"]
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
features = [
"winerror",
"errhandlingapi",
"libloaderapi",
]
+7
View File
@@ -25,6 +25,13 @@
/// neither `RTLD_LOCAL` nor [`RTLD_GLOBAL`] are specified. Setting the `RTLD_LOCAL` flag makes
/// the behaviour more consistent across platforms.
///
/// ### Dropped support for Windows XP/Vista
///
/// The (broken) support for Windows XP and Windows Vista environments was removed. This was
/// prompted primarily by a similar policy change in the [Rust
/// project](https://github.com/rust-lang/compiler-team/issues/378) but also as an acknowledgement
/// to the fact that `libloading` never worked in these environments anyway.
///
/// [issue #86]: https://github.com/nagisa/rust_libloading/issues/86
/// [`Library::new`]: crate::Library::new
/// [windows_open]: crate::os::windows::Library::load_with_flags
+12 -44
View File
@@ -28,7 +28,6 @@ mod windows_imports {
extern crate winapi;
pub(super) use self::winapi::shared::minwindef::{WORD, DWORD, HMODULE, FARPROC};
pub(super) use self::winapi::shared::ntdef::WCHAR;
pub(super) use self::winapi::shared::winerror;
pub(super) use self::winapi::um::{errhandlingapi, libloaderapi};
pub(super) use std::os::windows::ffi::{OsStrExt, OsStringExt};
pub(super) const SEM_FAILCE: DWORD = 1;
@@ -55,7 +54,6 @@ use self::windows_imports::*;
use util::{ensure_compatible_types, cstr_cow_from_bytes};
use std::ffi::{OsStr, OsString};
use std::{fmt, io, marker, mem, ptr};
use std::sync::atomic::{AtomicBool, Ordering};
/// A platform-specific counterpart of the cross-platform [`Library`](crate::Library).
pub struct Library(HMODULE);
@@ -373,49 +371,23 @@ impl<T> fmt::Debug for Symbol<T> {
}
}
static USE_ERRORMODE: AtomicBool = AtomicBool::new(false);
struct ErrorModeGuard(DWORD);
impl ErrorModeGuard {
#[allow(clippy::if_same_then_else)]
fn new() -> Option<ErrorModeGuard> {
unsafe {
if !USE_ERRORMODE.load(Ordering::Acquire) {
let mut previous_mode = 0;
let success = errhandlingapi::SetThreadErrorMode(SEM_FAILCE, &mut previous_mode) != 0;
if !success && errhandlingapi::GetLastError() == winerror::ERROR_CALL_NOT_IMPLEMENTED {
USE_ERRORMODE.store(true, Ordering::Release);
} else if !success {
// SetThreadErrorMode failed with some other error? 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
// machines.
return None;
} else if previous_mode == SEM_FAILCE {
return None;
} else {
return Some(ErrorModeGuard(previous_mode));
}
}
match errhandlingapi::SetErrorMode(SEM_FAILCE) {
SEM_FAILCE => {
// This is important to reduce racy-ness when this library is used on multiple
// threads. In particular this helps with following race condition:
//
// T1: SetErrorMode(SEM_FAILCE)
// T2: SetErrorMode(SEM_FAILCE)
// T1: SetErrorMode(old_mode) # not SEM_FAILCE
// T2: SetErrorMode(SEM_FAILCE) # restores to SEM_FAILCE on drop
//
// This is still somewhat racy in a sense that T1 might restore the error
// mode before T2 finishes loading the library, but that is less of a
// concern it will only end up in end user seeing a dialog.
//
// Also, SetErrorMode itself is probably not an atomic operation.
None
}
a => Some(ErrorModeGuard(a))
let mut previous_mode = 0;
if errhandlingapi::SetThreadErrorMode(SEM_FAILCE, &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
// machines.
None
} else if previous_mode == SEM_FAILCE {
None
} else {
Some(ErrorModeGuard(previous_mode))
}
}
}
@@ -424,11 +396,7 @@ impl ErrorModeGuard {
impl Drop for ErrorModeGuard {
fn drop(&mut self) {
unsafe {
if !USE_ERRORMODE.load(Ordering::Relaxed) {
errhandlingapi::SetThreadErrorMode(self.0, ptr::null_mut());
} else {
errhandlingapi::SetErrorMode(self.0);
}
errhandlingapi::SetThreadErrorMode(self.0, ptr::null_mut());
}
}
}