Skip to content

Replace remaining winapi usage with windows-sys #3802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 8 additions & 30 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,43 +104,21 @@ zstd = "0.13"
cc = "1"
winreg = "0.52"

[target."cfg(windows)".dependencies.winapi]
features = [
"combaseapi",
"errhandlingapi",
"fileapi",
"handleapi",
"ioapiset",
"jobapi",
"jobapi2",
"minwindef",
"processthreadsapi",
"psapi",
"shlobj",
"shtypes",
"synchapi",
"sysinfoapi",
"tlhelp32",
"userenv",
"winbase",
"winerror",
"winioctl",
"winnt",
"winuser",
]
version = "0.3"

[target."cfg(windows)".dependencies.windows-sys]
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_Storage_FileSystem",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_IO",
"Win32_System_Ioctl",
"Win32_System_JobObjects",
"Win32_System_Kernel",
"Win32_System_LibraryLoader",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
"Win32_Security",
"Win32_System_Kernel",
"Win32_System_IO",
"Win32_System_Ioctl",
]
version = "0.52.0"

Expand Down
4 changes: 3 additions & 1 deletion src/bin/rustup-init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ fn do_recursion_guard() -> Result<()> {
/// rustup-init in the user's download folder.
#[cfg(windows)]
pub fn pre_rustup_main_init() {
use winapi::um::libloaderapi::{SetDefaultDllDirectories, LOAD_LIBRARY_SEARCH_SYSTEM32};
use windows_sys::Win32::System::LibraryLoader::{
SetDefaultDllDirectories, LOAD_LIBRARY_SEARCH_SYSTEM32,
};
// Default to loading delay loaded DLLs from the system directory.
// For DLLs loaded at load time, this relies on the `delayload` linker flag.
// This is only necessary prior to Windows 10 RS1. See build.rs for details.
Expand Down
2 changes: 1 addition & 1 deletion src/cli/download_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ impl DownloadTracker {
let percent = (self.total_downloaded as f64 / content_len as f64) * 100.;
let remaining = content_len - self.total_downloaded;
let eta_h = Duration::from_secs(if speed == 0 {
std::u64::MAX
u64::MAX
} else {
(remaining / speed) as u64
});
Expand Down
19 changes: 8 additions & 11 deletions src/cli/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,9 @@ mod imp {
use std::mem;
use std::ptr;

use winapi::shared::minwindef::*;
use winapi::um::handleapi::*;
use winapi::um::jobapi2::*;
use winapi::um::processthreadsapi::*;
use winapi::um::winnt::HANDLE;
use winapi::um::winnt::*;
use windows_sys::Win32::Foundation::*;
use windows_sys::Win32::System::JobObjects::*;
use windows_sys::Win32::System::Threading::*;

pub(crate) struct Setup {
job: Handle,
Expand All @@ -70,7 +67,7 @@ mod imp {
// we're otherwise part of someone else's job object in this case.

let job = CreateJobObjectW(ptr::null_mut(), ptr::null());
if job.is_null() {
if job == 0 {
return None;
}
let job = Handle { inner: job };
Expand All @@ -85,8 +82,8 @@ mod imp {
let r = SetInformationJobObject(
job.inner,
JobObjectExtendedLimitInformation,
&mut info as *mut _ as LPVOID,
mem::size_of_val(&info) as DWORD,
&mut info as *mut _ as *const std::ffi::c_void,
mem::size_of_val(&info) as u32,
);
if r == 0 {
return None;
Expand Down Expand Up @@ -114,8 +111,8 @@ mod imp {
let r = SetInformationJobObject(
self.job.inner,
JobObjectExtendedLimitInformation,
&mut info as *mut _ as LPVOID,
mem::size_of_val(&info) as DWORD,
&mut info as *mut _ as *const std::ffi::c_void,
mem::size_of_val(&info) as u32,
);
if r == 0 {
info!("failed to configure job object to defaults: {}", last_err());
Expand Down
40 changes: 19 additions & 21 deletions src/cli/self_update/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,15 +294,14 @@ pub fn complete_windows_uninstall() -> Result<utils::ExitCode> {
pub(crate) fn wait_for_parent() -> Result<()> {
use std::io;
use std::mem;
use winapi::shared::minwindef::DWORD;
use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE};
use winapi::um::processthreadsapi::{GetCurrentProcessId, OpenProcess};
use winapi::um::synchapi::WaitForSingleObject;
use winapi::um::tlhelp32::{
use windows_sys::Win32::Foundation::{CloseHandle, INVALID_HANDLE_VALUE, WAIT_OBJECT_0};
use windows_sys::Win32::Storage::FileSystem::SYNCHRONIZE;
use windows_sys::Win32::System::Diagnostics::ToolHelp::{
CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS,
};
use winapi::um::winbase::{INFINITE, WAIT_OBJECT_0};
use winapi::um::winnt::SYNCHRONIZE;
use windows_sys::Win32::System::Threading::{
GetCurrentProcessId, OpenProcess, WaitForSingleObject, INFINITE,
};

unsafe {
// Take a snapshot of system processes, one of which is ours
Expand All @@ -318,7 +317,7 @@ pub(crate) fn wait_for_parent() -> Result<()> {
});

let mut entry: PROCESSENTRY32 = mem::zeroed();
entry.dwSize = mem::size_of::<PROCESSENTRY32>() as DWORD;
entry.dwSize = mem::size_of::<PROCESSENTRY32>() as u32;

// Iterate over system processes looking for ours
let success = Process32First(*snapshot, &mut entry);
Expand All @@ -343,7 +342,7 @@ pub(crate) fn wait_for_parent() -> Result<()> {

// Get a handle to the parent process
let parent = OpenProcess(SYNCHRONIZE, 0, parent_id);
if parent.is_null() {
if parent == 0 {
// This just means the parent has already exited.
return Ok(());
}
Expand Down Expand Up @@ -371,8 +370,8 @@ pub(crate) fn do_add_to_path() -> Result<()> {

fn _apply_new_path(new_path: Option<Vec<u16>>) -> Result<()> {
use std::ptr;
use winapi::shared::minwindef::*;
use winapi::um::winuser::{
use windows_sys::Win32::Foundation::*;
use windows_sys::Win32::UI::WindowsAndMessaging::{
SendMessageTimeoutA, HWND_BROADCAST, SMTO_ABORTIFHUNG, WM_SETTINGCHANGE,
};

Expand Down Expand Up @@ -645,12 +644,11 @@ pub(crate) fn delete_rustup_and_cargo_home() -> Result<()> {
use std::ptr;
use std::thread;
use std::time::Duration;
use winapi::shared::minwindef::DWORD;
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE};
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
use winapi::um::winbase::FILE_FLAG_DELETE_ON_CLOSE;
use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, GENERIC_READ};
use windows_sys::Win32::Foundation::{CloseHandle, GENERIC_READ, INVALID_HANDLE_VALUE};
use windows_sys::Win32::Security::SECURITY_ATTRIBUTES;
use windows_sys::Win32::Storage::FileSystem::{
CreateFileW, FILE_FLAG_DELETE_ON_CLOSE, FILE_SHARE_DELETE, FILE_SHARE_READ, OPEN_EXISTING,
};

// CARGO_HOME, hopefully empty except for bin/rustup.exe
let cargo_home = utils::cargo_home()?;
Expand All @@ -671,8 +669,8 @@ pub(crate) fn delete_rustup_and_cargo_home() -> Result<()> {
let gc_exe_win: Vec<_> = gc_exe.as_os_str().encode_wide().chain(Some(0)).collect();

// Make the sub-process opened by gc exe inherit its attribute.
let mut sa = SECURITY_ATTRIBUTES {
nLength: mem::size_of::<SECURITY_ATTRIBUTES>() as DWORD,
let sa = SECURITY_ATTRIBUTES {
nLength: mem::size_of::<SECURITY_ATTRIBUTES>() as u32,
lpSecurityDescriptor: ptr::null_mut(),
bInheritHandle: 1,
};
Expand All @@ -684,10 +682,10 @@ pub(crate) fn delete_rustup_and_cargo_home() -> Result<()> {
gc_exe_win.as_ptr(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_DELETE,
&mut sa,
&sa,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
ptr::null_mut(),
0,
);

if gc_handle == INVALID_HANDLE_VALUE {
Expand Down
6 changes: 3 additions & 3 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ pub(crate) fn run_command_for_dir<S: AsRef<OsStr> + Debug>(

#[cfg(windows)]
fn exec(cmd: &mut Command) -> io::Result<ExitCode> {
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use windows_sys::Win32::Foundation::{BOOL, FALSE, TRUE};
use windows_sys::Win32::System::Console::SetConsoleCtrlHandler;

unsafe extern "system" fn ctrlc_handler(_: DWORD) -> BOOL {
unsafe extern "system" fn ctrlc_handler(_: u32) -> BOOL {
// Do nothing. Let the child process handle it.
TRUE
}
Expand Down
23 changes: 9 additions & 14 deletions src/dist/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,10 @@ impl TargetTriple {
/// it is only available on Windows 10 1511+, so we use `GetProcAddress`
/// to maintain backward compatibility with older Windows versions.
fn arch_primary() -> Option<&'static str> {
use winapi::shared::minwindef::BOOL;
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winnt::HANDLE;
use windows_sys::core::s;
use windows_sys::Win32::Foundation::{BOOL, HANDLE};
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};
use windows_sys::Win32::System::Threading::GetCurrentProcess;

const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64;
const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
Expand All @@ -320,16 +320,11 @@ impl TargetTriple {
*mut u16,
)
-> BOOL = unsafe {
let module = GetModuleHandleA(b"kernel32.dll\0" as *const u8 as *const i8);
if module.is_null() {
let module = GetModuleHandleA(s!("kernel32.dll"));
if module == 0 {
return None;
}
let process =
GetProcAddress(module, b"IsWow64Process2\0" as *const u8 as *const i8);
if process.is_null() {
return None;
}
mem::transmute(process)
mem::transmute(GetProcAddress(module, s!("IsWow64Process2"))?)
};

let mut _machine = 0;
Expand All @@ -352,7 +347,7 @@ impl TargetTriple {
/// Get the host architecture using `GetNativeSystemInfo`.
/// Does not support detecting aarch64.
fn arch_fallback() -> Option<&'static str> {
use winapi::um::sysinfoapi::GetNativeSystemInfo;
use windows_sys::Win32::System::SystemInformation::GetNativeSystemInfo;

const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
Expand All @@ -363,7 +358,7 @@ impl TargetTriple {
GetNativeSystemInfo(&mut sys_info);
}

match unsafe { sys_info.u.s() }.wProcessorArchitecture {
match unsafe { sys_info.Anonymous.Anonymous }.wProcessorArchitecture {
PROCESSOR_ARCHITECTURE_AMD64 => Some("x86_64"),
PROCESSOR_ARCHITECTURE_INTEL => Some("i686"),
_ => None,
Expand Down
37 changes: 18 additions & 19 deletions src/utils/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,25 +156,24 @@ pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
use std::os::windows::ffi::OsStrExt;
use std::ptr;
use winapi::shared::minwindef::*;
use winapi::um::fileapi::*;
use winapi::um::ioapiset::*;
use winapi::um::winbase::*;
use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT;
use winapi::um::winnt::*;
use windows_sys::Win32::Foundation::*;
use windows_sys::Win32::Storage::FileSystem::*;
use windows_sys::Win32::System::Ioctl::FSCTL_SET_REPARSE_POINT;
use windows_sys::Win32::System::SystemServices::*;
use windows_sys::Win32::System::IO::*;

const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;

#[repr(C)]
#[allow(non_snake_case)]
struct REPARSE_MOUNTPOINT_DATA_BUFFER {
ReparseTag: DWORD,
ReparseDataLength: DWORD,
Reserved: WORD,
ReparseTargetLength: WORD,
ReparseTargetMaximumLength: WORD,
Reserved1: WORD,
ReparseTarget: WCHAR,
ReparseTag: u32,
ReparseDataLength: u32,
Reserved: u16,
ReparseTargetLength: u16,
ReparseTargetMaximumLength: u16,
Reserved1: u16,
ReparseTarget: u16,
}

// We're using low-level APIs to create the junction, and these are more picky about paths.
Expand All @@ -194,12 +193,12 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
ptr::null_mut(),
OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
ptr::null_mut(),
0,
);

let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
let db = data.as_mut_ptr().cast::<REPARSE_MOUNTPOINT_DATA_BUFFER>();
let buf = &mut (*db).ReparseTarget as *mut WCHAR;
let buf = &mut (*db).ReparseTarget as *mut u16;
let mut i = 0;
// FIXME: this conversion is very hacky
let v = br"\??\";
Expand All @@ -211,13 +210,13 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
*buf.offset(i) = 0;
i += 1;
(*db).ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
(*db).ReparseTargetMaximumLength = (i * 2) as WORD;
(*db).ReparseTargetLength = ((i - 1) * 2) as WORD;
(*db).ReparseDataLength = (*db).ReparseTargetLength as DWORD + 12;
(*db).ReparseTargetMaximumLength = (i * 2) as u16;
(*db).ReparseTargetLength = ((i - 1) * 2) as u16;
(*db).ReparseDataLength = (*db).ReparseTargetLength as u32 + 12;

let mut ret = 0;
let res = DeviceIoControl(
h.cast(),
h,
FSCTL_SET_REPARSE_POINT,
data.as_mut_ptr().cast(),
(*db).ReparseDataLength + 8,
Expand Down