Skip to content

Commit

Permalink
deps: Move from winapi to windows
Browse files Browse the repository at this point in the history
`winapi` is in maintenance mode and the new blessed way to access Windows APIs are the `windows`
and `windows-sys` crates. I was forced to use `windows` because `sysinfo` uses the COM APIs
which are not present in `windows-sys`.
  • Loading branch information
poliorcetics committed Mar 20, 2023
1 parent 8ade504 commit fa64a9e
Show file tree
Hide file tree
Showing 14 changed files with 659 additions and 780 deletions.
66 changes: 30 additions & 36 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,43 +36,37 @@ serde = { version = "^1.0.152", optional = true }
once_cell = "1.0"

[target.'cfg(windows)'.dependencies]
# FIXME: remove std feature once https://github.com/retep998/winapi-rs/pull/1003 has been merged.
winapi = { version = "0.3.9", features = [
"errhandlingapi",
"fileapi",
"handleapi",
"heapapi",
"ifdef",
"ioapiset",
"minwindef",
"pdh",
"psapi",
"synchapi",
"sysinfoapi",
"winbase",
"winerror",
"winioctl",
"winnt",
"oleauto",
"wbemcli",
"rpcdce",
"combaseapi",
"objidl",
"powerbase",
"netioapi",
"lmcons",
"lmaccess",
"lmapibuf",
"memoryapi",
"ntlsa",
"securitybaseapi",
"shellapi",
"std",
"iphlpapi",
"winsock2",
"sddl",
]}
ntapi = "0.4"
windows = { version = "0.46", features = [
"Win32_Foundation",
"Win32_NetworkManagement_IpHelper",
"Win32_NetworkManagement_NetManagement",
"Win32_NetworkManagement_Ndis",
"Win32_Networking_WinSock",
"Win32_Security",
"Win32_Security_Authentication_Identity",
"Win32_Security_Authorization",
"Win32_Storage_FileSystem",
"Win32_System_Com",
"Win32_System_Diagnostics_Debug",
"Win32_System_IO",
"Win32_System_Ioctl",
"Win32_System_Kernel",
"Win32_System_Memory",
"Win32_System_Ole",
"Win32_System_Performance",
"Win32_System_Power",
"Win32_System_ProcessStatus",
"Win32_System_Registry",
"Win32_System_RemoteDesktop",
"Win32_System_Rpc",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
"Win32_System_Wmi",
"Win32_UI_Shell",
]}

[target.'cfg(not(any(target_os = "unknown", target_arch = "wasm32")))'.dependencies]
libc = "^0.2.112"
Expand Down
2 changes: 1 addition & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ pub fn get_current_pid() -> Result<Pid, &'static str> {
}
} else if #[cfg(windows)] {
fn inner() -> Result<Pid, &'static str> {
use winapi::um::processthreadsapi::GetCurrentProcessId;
use windows::Win32::System::Threading::GetCurrentProcessId;

unsafe { Ok(Pid(GetCurrentProcessId() as _)) }
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ cfg_if::cfg_if! {
pub(crate) const MIN_USERS: usize = 1;
} else if #[cfg(windows)] {
mod windows;
use windows as sys;
use self::windows as sys;
mod network_helper_win;
use network_helper_win as network_helper;
mod network;
Expand Down
43 changes: 15 additions & 28 deletions src/network_helper_win.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use std::ffi::OsString;
use std::os::windows::prelude::OsStringExt;
use std::ptr::null_mut;

use winapi::shared::winerror::{ERROR_BUFFER_OVERFLOW, ERROR_SUCCESS};
use winapi::shared::ws2def::AF_UNSPEC;
use winapi::um::iphlpapi::GetAdaptersAddresses;
use winapi::um::iptypes::{
GAA_FLAG_SKIP_ANYCAST, GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_MULTICAST, PIP_ADAPTER_ADDRESSES,
use windows::Win32::Foundation::{ERROR_BUFFER_OVERFLOW, ERROR_SUCCESS};
use windows::Win32::NetworkManagement::IpHelper::{
GetAdaptersAddresses, GAA_FLAG_SKIP_ANYCAST, GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_MULTICAST,
IP_ADAPTER_ADDRESSES_LH,
};
use windows::Win32::Networking::WinSock::AF_UNSPEC;

use crate::common::MacAddr;

/// this iterator yields an interface name and address
pub(crate) struct InterfaceAddressIterator {
/// The first item in the linked list
buf: PIP_ADAPTER_ADDRESSES,
buf: *mut IP_ADAPTER_ADDRESSES_LH,
/// The current adapter
adapter: PIP_ADAPTER_ADDRESSES,
}

// Need a function to convert u16 pointer into String
// https://stackoverflow.com/a/48587463/8706476
unsafe fn u16_ptr_to_string(ptr: *const u16) -> OsString {
let len = (0..).take_while(|&i| *ptr.offset(i) != 0).count();
let slice = std::slice::from_raw_parts(ptr, len);

OsString::from_wide(slice)
adapter: *mut IP_ADAPTER_ADDRESSES_LH,
}

impl Iterator for InterfaceAddressIterator {
Expand All @@ -41,7 +28,7 @@ impl Iterator for InterfaceAddressIterator {
let adapter = self.adapter;
// Move to the next adapter
self.adapter = (*adapter).Next;
if let Ok(interface_name) = u16_ptr_to_string((*adapter).FriendlyName).into_string() {
if let Ok(interface_name) = (*adapter).FriendlyName.to_string() {
// take the first 6 bytes and return the MAC address instead
let [mac @ .., _, _] = (*adapter).PhysicalAddress;
Some((interface_name, MacAddr(mac)))
Expand All @@ -66,12 +53,12 @@ pub(crate) fn get_interface_address() -> Result<InterfaceAddressIterator, String
// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses#remarks
// A 15k buffer is recommended
let mut size: u32 = 15 * 1024;
let mut ret = ERROR_SUCCESS;
let mut ret = ERROR_SUCCESS.0;

// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses#examples
// Try to retrieve adapter information up to 3 times
for _ in 0..3 {
let buf = libc::malloc(size as _) as PIP_ADAPTER_ADDRESSES;
let buf = libc::malloc(size as _) as *mut IP_ADAPTER_ADDRESSES_LH;
// free memory on drop
let iterator = InterfaceAddressIterator { buf, adapter: buf };
if buf.is_null() {
Expand All @@ -82,15 +69,15 @@ pub(crate) fn get_interface_address() -> Result<InterfaceAddressIterator, String
}

ret = GetAdaptersAddresses(
AF_UNSPEC as u32,
AF_UNSPEC.0.into(),
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER,
null_mut(),
buf,
None,
Some(buf),
&mut size,
);
if ret == ERROR_SUCCESS {
if ret == ERROR_SUCCESS.0 {
return Ok(iterator);
} else if ret != ERROR_BUFFER_OVERFLOW {
} else if ret != ERROR_BUFFER_OVERFLOW.0 {
break;
}
// if the given memory size is too small to hold the adapter information,
Expand Down
Loading

0 comments on commit fa64a9e

Please sign in to comment.