net: replace winapi with windows-sys (#5204)

This commit is contained in:
Kenny Kerr 2022-11-22 10:23:26 -06:00 committed by GitHub
parent e14307393a
commit 299bd6aee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 169 additions and 233 deletions

View File

@ -24,8 +24,8 @@ httpdate = "1.0"
once_cell = "1.5.2"
rand = "0.8.3"
[target.'cfg(windows)'.dev-dependencies.winapi]
version = "0.3.8"
[target.'cfg(windows)'.dev-dependencies.windows-sys]
version = "0.42.0"
[[example]]
name = "chat"

View File

@ -6,7 +6,7 @@ async fn windows_main() -> io::Result<()> {
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
use tokio::time;
use winapi::shared::winerror;
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
const PIPE_NAME: &str = r"\\.\pipe\named-pipe-multi-client";
const N: usize = 10;
@ -59,7 +59,7 @@ async fn windows_main() -> io::Result<()> {
let mut client = loop {
match ClientOptions::new().open(PIPE_NAME) {
Ok(client) => break client,
Err(e) if e.raw_os_error() == Some(winerror::ERROR_PIPE_BUSY as i32) => (),
Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
Err(e) => return Err(e),
}

View File

@ -52,14 +52,11 @@ net = [
"mio/os-ext",
"mio/net",
"socket2",
"winapi/fileapi",
"winapi/handleapi",
"winapi/namedpipeapi",
"winapi/winbase",
"winapi/winnt",
"winapi/minwindef",
"winapi/accctrl",
"winapi/aclapi",
"windows-sys/Win32_Foundation",
"windows-sys/Win32_Security",
"windows-sys/Win32_Storage_FileSystem",
"windows-sys/Win32_System_Pipes",
"windows-sys/Win32_System_SystemServices",
]
process = [
"bytes",
@ -68,12 +65,9 @@ process = [
"mio/os-ext",
"mio/net",
"signal-hook-registry",
"winapi/handleapi",
"winapi/minwindef",
"winapi/processthreadsapi",
"winapi/threadpoollegacyapiset",
"winapi/winbase",
"winapi/winnt",
"windows-sys/Win32_Foundation",
"windows-sys/Win32_System_Threading",
"windows-sys/Win32_System_WindowsProgramming",
]
# Includes basic task execution capabilities
rt = []
@ -87,9 +81,8 @@ signal = [
"mio/net",
"mio/os-ext",
"signal-hook-registry",
"winapi/consoleapi",
"winapi/wincon",
"winapi/minwindef",
"windows-sys/Win32_Foundation",
"windows-sys/Win32_System_Console",
]
sync = []
test-util = ["rt", "sync", "time"]
@ -131,12 +124,17 @@ signal-hook-registry = { version = "1.1.1", optional = true }
libc = { version = "0.2.42" }
nix = { version = "0.24", default-features = false, features = ["fs", "socket"] }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.8"
default-features = false
features = ["std"]
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.42.0"
optional = true
[target.'cfg(docsrs)'.dependencies.windows-sys]
version = "0.42.0"
features = [
"Win32_Foundation",
"Win32_Security_Authorization",
]
[target.'cfg(windows)'.dev-dependencies.ntapi]
version = "0.3.6"

View File

@ -21,4 +21,3 @@
pub enum NotDefinedHere {}
pub mod os;
pub mod winapi;

View File

@ -1,66 +0,0 @@
//! See [winapi].
//!
//! [winapi]: https://docs.rs/winapi
/// See [winapi::shared](https://docs.rs/winapi/*/winapi/shared/index.html).
pub mod shared {
/// See [winapi::shared::winerror](https://docs.rs/winapi/*/winapi/shared/winerror/index.html).
#[allow(non_camel_case_types)]
pub mod winerror {
/// See [winapi::shared::winerror::ERROR_ACCESS_DENIED][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/shared/winerror/constant.ERROR_ACCESS_DENIED.html
pub type ERROR_ACCESS_DENIED = crate::doc::NotDefinedHere;
/// See [winapi::shared::winerror::ERROR_PIPE_BUSY][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/shared/winerror/constant.ERROR_PIPE_BUSY.html
pub type ERROR_PIPE_BUSY = crate::doc::NotDefinedHere;
/// See [winapi::shared::winerror::ERROR_MORE_DATA][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/shared/winerror/constant.ERROR_MORE_DATA.html
pub type ERROR_MORE_DATA = crate::doc::NotDefinedHere;
}
}
/// See [winapi::um](https://docs.rs/winapi/*/winapi/um/index.html).
pub mod um {
/// See [winapi::um::winbase](https://docs.rs/winapi/*/winapi/um/winbase/index.html).
#[allow(non_camel_case_types)]
pub mod winbase {
/// See [winapi::um::winbase::PIPE_TYPE_MESSAGE][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/winbase/constant.PIPE_TYPE_MESSAGE.html
pub type PIPE_TYPE_MESSAGE = crate::doc::NotDefinedHere;
/// See [winapi::um::winbase::PIPE_TYPE_BYTE][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/winbase/constant.PIPE_TYPE_BYTE.html
pub type PIPE_TYPE_BYTE = crate::doc::NotDefinedHere;
/// See [winapi::um::winbase::PIPE_CLIENT_END][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/winbase/constant.PIPE_CLIENT_END.html
pub type PIPE_CLIENT_END = crate::doc::NotDefinedHere;
/// See [winapi::um::winbase::PIPE_SERVER_END][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/winbase/constant.PIPE_SERVER_END.html
pub type PIPE_SERVER_END = crate::doc::NotDefinedHere;
/// See [winapi::um::winbase::SECURITY_IDENTIFICATION][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/winbase/constant.SECURITY_IDENTIFICATION.html
pub type SECURITY_IDENTIFICATION = crate::doc::NotDefinedHere;
}
/// See [winapi::um::minwinbase](https://docs.rs/winapi/*/winapi/um/minwinbase/index.html).
#[allow(non_camel_case_types)]
pub mod minwinbase {
/// See [winapi::um::minwinbase::SECURITY_ATTRIBUTES][winapi]
///
/// [winapi]: https://docs.rs/winapi/*/winapi/um/minwinbase/constant.SECURITY_ATTRIBUTES.html
pub type SECURITY_ATTRIBUTES = crate::doc::NotDefinedHere;
}
}

View File

@ -542,7 +542,7 @@ feature! {
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::FILE_FLAG_DELETE_ON_CLOSE;
/// use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_DELETE_ON_CLOSE;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
@ -581,7 +581,7 @@ feature! {
/// # Examples
///
/// ```no_run
/// use winapi::um::winnt::FILE_ATTRIBUTE_HIDDEN;
/// use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_HIDDEN;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
@ -624,7 +624,7 @@ feature! {
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::SECURITY_IDENTIFICATION;
/// use windows_sys::Win32::Storage::FileSystem::SECURITY_IDENTIFICATION;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]

View File

@ -578,14 +578,6 @@ pub(crate) use self::doc::os;
#[allow(unused)]
pub(crate) use std::os;
#[cfg(docsrs)]
#[allow(unused)]
pub(crate) use self::doc::winapi;
#[cfg(all(not(docsrs), windows, feature = "net"))]
#[allow(unused)]
pub(crate) use winapi;
cfg_macros! {
/// Implementation detail of the `select!` macro. This macro is **not**
/// intended to be used as part of the public API and is permitted to

View File

@ -20,21 +20,18 @@ cfg_io_util! {
#[cfg(not(docsrs))]
mod doc {
pub(super) use crate::os::windows::ffi::OsStrExt;
pub(super) use crate::winapi::shared::minwindef::{DWORD, FALSE};
pub(super) use crate::winapi::um::fileapi;
pub(super) use crate::winapi::um::handleapi;
pub(super) use crate::winapi::um::namedpipeapi;
pub(super) use crate::winapi::um::winbase;
pub(super) use crate::winapi::um::winnt;
pub(super) mod windows_sys {
pub(crate) use windows_sys::{
Win32::Foundation::*, Win32::Storage::FileSystem::*, Win32::System::Pipes::*,
Win32::System::SystemServices::*,
};
}
pub(super) use mio::windows as mio_windows;
}
// NB: none of these shows up in public API, so don't document them.
#[cfg(docsrs)]
mod doc {
pub type DWORD = crate::doc::NotDefinedHere;
pub(super) mod mio_windows {
pub type NamedPipe = crate::doc::NotDefinedHere;
}
@ -101,7 +98,6 @@ use self::doc::*;
/// # Ok(()) }
/// ```
///
/// [`ERROR_PIPE_BUSY`]: crate::winapi::shared::winerror::ERROR_PIPE_BUSY
/// [Windows named pipe]: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
#[derive(Debug)]
pub struct NamedPipeServer {
@ -209,7 +205,7 @@ impl NamedPipeServer {
/// ```
/// use tokio::io::AsyncWriteExt;
/// use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
/// use winapi::shared::winerror;
/// use windows_sys::Win32::Foundation::ERROR_PIPE_NOT_CONNECTED;
///
/// const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-disconnect";
///
@ -229,7 +225,7 @@ impl NamedPipeServer {
/// // Write fails with an OS-specific error after client has been
/// // disconnected.
/// let e = client.write(b"ping").await.unwrap_err();
/// assert_eq!(e.raw_os_error(), Some(winerror::ERROR_PIPE_NOT_CONNECTED as i32));
/// assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_NOT_CONNECTED as i32));
/// # Ok(()) }
/// ```
pub fn disconnect(&self) -> io::Result<()> {
@ -905,7 +901,7 @@ impl AsRawHandle for NamedPipeServer {
/// use std::time::Duration;
/// use tokio::net::windows::named_pipe::ClientOptions;
/// use tokio::time;
/// use winapi::shared::winerror;
/// use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
///
/// const PIPE_NAME: &str = r"\\.\pipe\named-pipe-idiomatic-client";
///
@ -913,7 +909,7 @@ impl AsRawHandle for NamedPipeServer {
/// let client = loop {
/// match ClientOptions::new().open(PIPE_NAME) {
/// Ok(client) => break client,
/// Err(e) if e.raw_os_error() == Some(winerror::ERROR_PIPE_BUSY as i32) => (),
/// Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
/// Err(e) => return Err(e),
/// }
///
@ -924,7 +920,7 @@ impl AsRawHandle for NamedPipeServer {
/// # Ok(()) }
/// ```
///
/// [`ERROR_PIPE_BUSY`]: crate::winapi::shared::winerror::ERROR_PIPE_BUSY
/// [`ERROR_PIPE_BUSY`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Foundation/constant.ERROR_PIPE_BUSY.html
/// [Windows named pipe]: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
#[derive(Debug)]
pub struct NamedPipeClient {
@ -1647,12 +1643,12 @@ macro_rules! bool_flag {
/// See [`ServerOptions::create`].
#[derive(Debug, Clone)]
pub struct ServerOptions {
open_mode: DWORD,
pipe_mode: DWORD,
max_instances: DWORD,
out_buffer_size: DWORD,
in_buffer_size: DWORD,
default_timeout: DWORD,
open_mode: u32,
pipe_mode: u32,
max_instances: u32,
out_buffer_size: u32,
in_buffer_size: u32,
default_timeout: u32,
}
impl ServerOptions {
@ -1669,9 +1665,9 @@ impl ServerOptions {
/// ```
pub fn new() -> ServerOptions {
ServerOptions {
open_mode: winbase::PIPE_ACCESS_DUPLEX | winbase::FILE_FLAG_OVERLAPPED,
pipe_mode: winbase::PIPE_TYPE_BYTE | winbase::PIPE_REJECT_REMOTE_CLIENTS,
max_instances: winbase::PIPE_UNLIMITED_INSTANCES,
open_mode: windows_sys::PIPE_ACCESS_DUPLEX | windows_sys::FILE_FLAG_OVERLAPPED,
pipe_mode: windows_sys::PIPE_TYPE_BYTE | windows_sys::PIPE_REJECT_REMOTE_CLIENTS,
max_instances: windows_sys::PIPE_UNLIMITED_INSTANCES,
out_buffer_size: 65536,
in_buffer_size: 65536,
default_timeout: 0,
@ -1688,8 +1684,8 @@ impl ServerOptions {
/// [`dwPipeMode`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn pipe_mode(&mut self, pipe_mode: PipeMode) -> &mut Self {
self.pipe_mode = match pipe_mode {
PipeMode::Byte => winbase::PIPE_TYPE_BYTE,
PipeMode::Message => winbase::PIPE_TYPE_MESSAGE,
PipeMode::Byte => windows_sys::PIPE_TYPE_BYTE,
PipeMode::Message => windows_sys::PIPE_TYPE_MESSAGE,
};
self
@ -1787,7 +1783,7 @@ impl ServerOptions {
/// # Ok(()) }
/// ```
pub fn access_inbound(&mut self, allowed: bool) -> &mut Self {
bool_flag!(self.open_mode, allowed, winbase::PIPE_ACCESS_INBOUND);
bool_flag!(self.open_mode, allowed, windows_sys::PIPE_ACCESS_INBOUND);
self
}
@ -1885,7 +1881,7 @@ impl ServerOptions {
/// # Ok(()) }
/// ```
pub fn access_outbound(&mut self, allowed: bool) -> &mut Self {
bool_flag!(self.open_mode, allowed, winbase::PIPE_ACCESS_OUTBOUND);
bool_flag!(self.open_mode, allowed, windows_sys::PIPE_ACCESS_OUTBOUND);
self
}
@ -1956,7 +1952,7 @@ impl ServerOptions {
bool_flag!(
self.open_mode,
first,
winbase::FILE_FLAG_FIRST_PIPE_INSTANCE
windows_sys::FILE_FLAG_FIRST_PIPE_INSTANCE
);
self
}
@ -1971,9 +1967,10 @@ impl ServerOptions {
/// use std::{io, os::windows::prelude::AsRawHandle, ptr};
//
/// use tokio::net::windows::named_pipe::ServerOptions;
/// use winapi::{
/// shared::winerror::ERROR_SUCCESS,
/// um::{accctrl::SE_KERNEL_OBJECT, aclapi::SetSecurityInfo, winnt::DACL_SECURITY_INFORMATION},
/// use windows_sys::{
/// Win32::Foundation::ERROR_SUCCESS,
/// Win32::Security::DACL_SECURITY_INFORMATION,
/// Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
/// };
///
/// const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe";
@ -1987,7 +1984,7 @@ impl ServerOptions {
/// assert_eq!(
/// ERROR_SUCCESS,
/// SetSecurityInfo(
/// pipe.as_raw_handle(),
/// pipe.as_raw_handle() as _,
/// SE_KERNEL_OBJECT,
/// DACL_SECURITY_INFORMATION,
/// ptr::null_mut(),
@ -2005,9 +2002,10 @@ impl ServerOptions {
/// use std::{io, os::windows::prelude::AsRawHandle, ptr};
//
/// use tokio::net::windows::named_pipe::ServerOptions;
/// use winapi::{
/// shared::winerror::ERROR_ACCESS_DENIED,
/// um::{accctrl::SE_KERNEL_OBJECT, aclapi::SetSecurityInfo, winnt::DACL_SECURITY_INFORMATION},
/// use windows_sys::{
/// Win32::Foundation::ERROR_ACCESS_DENIED,
/// Win32::Security::DACL_SECURITY_INFORMATION,
/// Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
/// };
///
/// const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe_fail";
@ -2021,7 +2019,7 @@ impl ServerOptions {
/// assert_eq!(
/// ERROR_ACCESS_DENIED,
/// SetSecurityInfo(
/// pipe.as_raw_handle(),
/// pipe.as_raw_handle() as _,
/// SE_KERNEL_OBJECT,
/// DACL_SECURITY_INFORMATION,
/// ptr::null_mut(),
@ -2037,7 +2035,7 @@ impl ServerOptions {
///
/// [`WRITE_DAC`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn write_dac(&mut self, requested: bool) -> &mut Self {
bool_flag!(self.open_mode, requested, winnt::WRITE_DAC);
bool_flag!(self.open_mode, requested, windows_sys::WRITE_DAC);
self
}
@ -2047,7 +2045,7 @@ impl ServerOptions {
///
/// [`WRITE_OWNER`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn write_owner(&mut self, requested: bool) -> &mut Self {
bool_flag!(self.open_mode, requested, winnt::WRITE_OWNER);
bool_flag!(self.open_mode, requested, windows_sys::WRITE_OWNER);
self
}
@ -2057,7 +2055,11 @@ impl ServerOptions {
///
/// [`ACCESS_SYSTEM_SECURITY`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn access_system_security(&mut self, requested: bool) -> &mut Self {
bool_flag!(self.open_mode, requested, winnt::ACCESS_SYSTEM_SECURITY);
bool_flag!(
self.open_mode,
requested,
windows_sys::ACCESS_SYSTEM_SECURITY
);
self
}
@ -2068,7 +2070,11 @@ impl ServerOptions {
///
/// [`PIPE_REJECT_REMOTE_CLIENTS`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea#pipe_reject_remote_clients
pub fn reject_remote_clients(&mut self, reject: bool) -> &mut Self {
bool_flag!(self.pipe_mode, reject, winbase::PIPE_REJECT_REMOTE_CLIENTS);
bool_flag!(
self.pipe_mode,
reject,
windows_sys::PIPE_REJECT_REMOTE_CLIENTS
);
self
}
@ -2090,7 +2096,7 @@ impl ServerOptions {
/// ```
/// use std::io;
/// use tokio::net::windows::named_pipe::{ServerOptions, ClientOptions};
/// use winapi::shared::winerror;
/// use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
///
/// const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-max-instances";
///
@ -2106,11 +2112,11 @@ impl ServerOptions {
///
/// // Too many servers!
/// let e = server.create(PIPE_NAME).unwrap_err();
/// assert_eq!(e.raw_os_error(), Some(winerror::ERROR_PIPE_BUSY as i32));
/// assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
///
/// // Still too many servers even if we specify a higher value!
/// let e = server.max_instances(100).create(PIPE_NAME).unwrap_err();
/// assert_eq!(e.raw_os_error(), Some(winerror::ERROR_PIPE_BUSY as i32));
/// assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
/// # Ok(()) }
/// ```
///
@ -2129,7 +2135,7 @@ impl ServerOptions {
#[track_caller]
pub fn max_instances(&mut self, instances: usize) -> &mut Self {
assert!(instances < 255, "cannot specify more than 254 instances");
self.max_instances = instances as DWORD;
self.max_instances = instances as u32;
self
}
@ -2139,7 +2145,7 @@ impl ServerOptions {
///
/// [`nOutBufferSize`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self {
self.out_buffer_size = buffer as DWORD;
self.out_buffer_size = buffer;
self
}
@ -2149,7 +2155,7 @@ impl ServerOptions {
///
/// [`nInBufferSize`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
pub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self {
self.in_buffer_size = buffer as DWORD;
self.in_buffer_size = buffer;
self
}
@ -2206,7 +2212,7 @@ impl ServerOptions {
///
/// [`create`]: ServerOptions::create
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
/// [`SECURITY_ATTRIBUTES`]: crate::winapi::um::minwinbase::SECURITY_ATTRIBUTES
/// [`SECURITY_ATTRIBUTES`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/struct.SECURITY_ATTRIBUTES.html
pub unsafe fn create_with_security_attributes_raw(
&self,
addr: impl AsRef<OsStr>,
@ -2214,7 +2220,7 @@ impl ServerOptions {
) -> io::Result<NamedPipeServer> {
let addr = encode_addr(addr);
let h = namedpipeapi::CreateNamedPipeW(
let h = windows_sys::CreateNamedPipeW(
addr.as_ptr(),
self.open_mode,
self.pipe_mode,
@ -2225,11 +2231,11 @@ impl ServerOptions {
attrs as *mut _,
);
if h == handleapi::INVALID_HANDLE_VALUE {
if h == windows_sys::INVALID_HANDLE_VALUE {
return Err(io::Error::last_os_error());
}
NamedPipeServer::from_raw_handle(h)
NamedPipeServer::from_raw_handle(h as _)
}
}
@ -2239,8 +2245,8 @@ impl ServerOptions {
/// See [`ClientOptions::open`].
#[derive(Debug, Clone)]
pub struct ClientOptions {
desired_access: DWORD,
security_qos_flags: DWORD,
desired_access: u32,
security_qos_flags: u32,
}
impl ClientOptions {
@ -2259,8 +2265,9 @@ impl ClientOptions {
/// ```
pub fn new() -> Self {
Self {
desired_access: winnt::GENERIC_READ | winnt::GENERIC_WRITE,
security_qos_flags: winbase::SECURITY_IDENTIFICATION | winbase::SECURITY_SQOS_PRESENT,
desired_access: windows_sys::GENERIC_READ | windows_sys::GENERIC_WRITE,
security_qos_flags: windows_sys::SECURITY_IDENTIFICATION
| windows_sys::SECURITY_SQOS_PRESENT,
}
}
@ -2271,7 +2278,7 @@ impl ClientOptions {
/// [`GENERIC_READ`]: https://docs.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
pub fn read(&mut self, allowed: bool) -> &mut Self {
bool_flag!(self.desired_access, allowed, winnt::GENERIC_READ);
bool_flag!(self.desired_access, allowed, windows_sys::GENERIC_READ);
self
}
@ -2282,7 +2289,7 @@ impl ClientOptions {
/// [`GENERIC_WRITE`]: https://docs.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
pub fn write(&mut self, allowed: bool) -> &mut Self {
bool_flag!(self.desired_access, allowed, winnt::GENERIC_WRITE);
bool_flag!(self.desired_access, allowed, windows_sys::GENERIC_WRITE);
self
}
@ -2305,11 +2312,11 @@ impl ClientOptions {
/// automatically when using this method.
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`SECURITY_IDENTIFICATION`]: crate::winapi::um::winbase::SECURITY_IDENTIFICATION
/// [`SECURITY_IDENTIFICATION`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Storage/FileSystem/constant.SECURITY_IDENTIFICATION.html
/// [Impersonation Levels]: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
pub fn security_qos_flags(&mut self, flags: u32) -> &mut Self {
// See: https://github.com/rust-lang/rust/pull/58216
self.security_qos_flags = flags | winbase::SECURITY_SQOS_PRESENT;
self.security_qos_flags = flags | windows_sys::SECURITY_SQOS_PRESENT;
self
}
@ -2334,8 +2341,7 @@ impl ClientOptions {
/// but the server is not currently waiting for a connection. Please see the
/// examples for how to check for this error.
///
/// [`ERROR_PIPE_BUSY`]: crate::winapi::shared::winerror::ERROR_PIPE_BUSY
/// [`winapi`]: crate::winapi
/// [`ERROR_PIPE_BUSY`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Foundation/constant.ERROR_PIPE_BUSY.html
/// [enabled I/O]: crate::runtime::Builder::enable_io
/// [Tokio Runtime]: crate::runtime::Runtime
///
@ -2346,7 +2352,7 @@ impl ClientOptions {
/// use std::time::Duration;
/// use tokio::net::windows::named_pipe::ClientOptions;
/// use tokio::time;
/// use winapi::shared::winerror;
/// use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
///
/// const PIPE_NAME: &str = r"\\.\pipe\mynamedpipe";
///
@ -2354,7 +2360,7 @@ impl ClientOptions {
/// let client = loop {
/// match ClientOptions::new().open(PIPE_NAME) {
/// Ok(client) => break client,
/// Err(e) if e.raw_os_error() == Some(winerror::ERROR_PIPE_BUSY as i32) => (),
/// Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
/// Err(e) => return Err(e),
/// }
///
@ -2384,7 +2390,7 @@ impl ClientOptions {
///
/// [`open`]: ClientOptions::open
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
/// [`SECURITY_ATTRIBUTES`]: crate::winapi::um::minwinbase::SECURITY_ATTRIBUTES
/// [`SECURITY_ATTRIBUTES`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/struct.SECURITY_ATTRIBUTES.html
pub unsafe fn open_with_security_attributes_raw(
&self,
addr: impl AsRef<OsStr>,
@ -2393,28 +2399,28 @@ impl ClientOptions {
let addr = encode_addr(addr);
// NB: We could use a platform specialized `OpenOptions` here, but since
// we have access to winapi it ultimately doesn't hurt to use
// we have access to windows_sys it ultimately doesn't hurt to use
// `CreateFile` explicitly since it allows the use of our already
// well-structured wide `addr` to pass into CreateFileW.
let h = fileapi::CreateFileW(
let h = windows_sys::CreateFileW(
addr.as_ptr(),
self.desired_access,
0,
attrs as *mut _,
fileapi::OPEN_EXISTING,
windows_sys::OPEN_EXISTING,
self.get_flags(),
ptr::null_mut(),
0,
);
if h == handleapi::INVALID_HANDLE_VALUE {
if h == windows_sys::INVALID_HANDLE_VALUE {
return Err(io::Error::last_os_error());
}
NamedPipeClient::from_raw_handle(h)
NamedPipeClient::from_raw_handle(h as _)
}
fn get_flags(&self) -> u32 {
self.security_qos_flags | winbase::FILE_FLAG_OVERLAPPED
self.security_qos_flags | windows_sys::FILE_FLAG_OVERLAPPED
}
}
@ -2427,16 +2433,19 @@ pub enum PipeMode {
/// Data is written to the pipe as a stream of bytes. The pipe does not
/// distinguish bytes written during different write operations.
///
/// Corresponds to [`PIPE_TYPE_BYTE`][crate::winapi::um::winbase::PIPE_TYPE_BYTE].
/// Corresponds to [`PIPE_TYPE_BYTE`].
///
/// [`PIPE_TYPE_BYTE`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_TYPE_BYTE.html
Byte,
/// Data is written to the pipe as a stream of messages. The pipe treats the
/// bytes written during each write operation as a message unit. Any reading
/// on a named pipe returns [`ERROR_MORE_DATA`] when a message is not read
/// completely.
///
/// Corresponds to [`PIPE_TYPE_MESSAGE`][crate::winapi::um::winbase::PIPE_TYPE_MESSAGE].
/// Corresponds to [`PIPE_TYPE_MESSAGE`].
///
/// [`ERROR_MORE_DATA`]: crate::winapi::shared::winerror::ERROR_MORE_DATA
/// [`ERROR_MORE_DATA`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Foundation/constant.ERROR_MORE_DATA.html
/// [`PIPE_TYPE_MESSAGE`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_TYPE_MESSAGE.html
Message,
}
@ -2446,11 +2455,15 @@ pub enum PipeMode {
pub enum PipeEnd {
/// The named pipe refers to the client end of a named pipe instance.
///
/// Corresponds to [`PIPE_CLIENT_END`][crate::winapi::um::winbase::PIPE_CLIENT_END].
/// Corresponds to [`PIPE_CLIENT_END`].
///
/// [`PIPE_CLIENT_END`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_CLIENT_END.html
Client,
/// The named pipe refers to the server end of a named pipe instance.
///
/// Corresponds to [`PIPE_SERVER_END`][crate::winapi::um::winbase::PIPE_SERVER_END].
/// Corresponds to [`PIPE_SERVER_END`].
///
/// [`PIPE_SERVER_END`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_SERVER_END.html
Server,
}
@ -2488,26 +2501,26 @@ unsafe fn named_pipe_info(handle: RawHandle) -> io::Result<PipeInfo> {
let mut in_buffer_size = 0;
let mut max_instances = 0;
let result = namedpipeapi::GetNamedPipeInfo(
handle,
let result = windows_sys::GetNamedPipeInfo(
handle as _,
&mut flags,
&mut out_buffer_size,
&mut in_buffer_size,
&mut max_instances,
);
if result == FALSE {
if result == 0 {
return Err(io::Error::last_os_error());
}
let mut end = PipeEnd::Client;
let mut mode = PipeMode::Byte;
if flags & winbase::PIPE_SERVER_END != 0 {
if flags & windows_sys::PIPE_SERVER_END != 0 {
end = PipeEnd::Server;
}
if flags & winbase::PIPE_TYPE_MESSAGE != 0 {
if flags & windows_sys::PIPE_TYPE_MESSAGE != 0 {
mode = PipeMode::Message;
}

View File

@ -28,16 +28,18 @@ use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, RawHandle};
use std::pin::Pin;
use std::process::Stdio;
use std::process::{Child as StdChild, Command as StdCommand, ExitStatus};
use std::ptr;
use std::sync::Arc;
use std::task::{Context, Poll};
use winapi::shared::minwindef::{DWORD, FALSE};
use winapi::um::handleapi::{DuplicateHandle, INVALID_HANDLE_VALUE};
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::threadpoollegacyapiset::UnregisterWaitEx;
use winapi::um::winbase::{RegisterWaitForSingleObject, INFINITE};
use winapi::um::winnt::{
BOOLEAN, DUPLICATE_SAME_ACCESS, HANDLE, PVOID, WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE,
use windows_sys::{
Win32::Foundation::{
DuplicateHandle, BOOLEAN, DUPLICATE_SAME_ACCESS, HANDLE, INVALID_HANDLE_VALUE,
},
Win32::System::Threading::{
GetCurrentProcess, RegisterWaitForSingleObject, UnregisterWaitEx, WT_EXECUTEINWAITTHREAD,
WT_EXECUTEONLYONCE,
},
Win32::System::WindowsProgramming::INFINITE,
};
#[must_use = "futures do nothing unless polled"]
@ -119,11 +121,11 @@ impl Future for Child {
}
let (tx, rx) = oneshot::channel();
let ptr = Box::into_raw(Box::new(Some(tx)));
let mut wait_object = ptr::null_mut();
let mut wait_object = 0;
let rc = unsafe {
RegisterWaitForSingleObject(
&mut wait_object,
inner.child.as_raw_handle(),
inner.child.as_raw_handle() as _,
Some(callback),
ptr as *mut _,
INFINITE,
@ -162,7 +164,7 @@ impl Drop for Waiting {
}
}
unsafe extern "system" fn callback(ptr: PVOID, _timer_fired: BOOLEAN) {
unsafe extern "system" fn callback(ptr: *mut std::ffi::c_void, _timer_fired: BOOLEAN) {
let complete = &mut *(ptr as *mut Option<oneshot::Sender<()>>);
let _ = complete.take().unwrap().send(());
}
@ -257,11 +259,11 @@ fn duplicate_handle<T: AsRawHandle>(io: &T) -> io::Result<StdFile> {
let status = DuplicateHandle(
cur_proc,
io.as_raw_handle(),
io.as_raw_handle() as _,
cur_proc,
&mut dup_handle,
0 as DWORD,
FALSE,
0,
0,
DUPLICATE_SAME_ACCESS,
);
@ -269,6 +271,6 @@ fn duplicate_handle<T: AsRawHandle>(io: &T) -> io::Result<StdFile> {
return Err(io::Error::last_os_error());
}
Ok(StdFile::from_raw_handle(dup_handle))
Ok(StdFile::from_raw_handle(dup_handle as _))
}
}

View File

@ -3,7 +3,7 @@
//! This module is only defined on Windows and allows receiving "ctrl-c",
//! "ctrl-break", "ctrl-logoff", "ctrl-shutdown", and "ctrl-close"
//! notifications. These events are listened for via the `SetConsoleCtrlHandler`
//! function which receives the corresponding winapi event type.
//! function which receives the corresponding windows_sys event type.
#![cfg(any(windows, docsrs))]
#![cfg_attr(docsrs, doc(cfg(all(windows, feature = "signal"))))]

View File

@ -5,31 +5,30 @@ use std::sync::Once;
use crate::signal::registry::{globals, EventId, EventInfo, Init, Storage};
use crate::signal::RxFuture;
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use winapi::um::wincon;
use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::System::Console as console;
pub(super) fn ctrl_break() -> io::Result<RxFuture> {
new(wincon::CTRL_BREAK_EVENT)
new(console::CTRL_BREAK_EVENT)
}
pub(super) fn ctrl_close() -> io::Result<RxFuture> {
new(wincon::CTRL_CLOSE_EVENT)
new(console::CTRL_CLOSE_EVENT)
}
pub(super) fn ctrl_c() -> io::Result<RxFuture> {
new(wincon::CTRL_C_EVENT)
new(console::CTRL_C_EVENT)
}
pub(super) fn ctrl_logoff() -> io::Result<RxFuture> {
new(wincon::CTRL_LOGOFF_EVENT)
new(console::CTRL_LOGOFF_EVENT)
}
pub(super) fn ctrl_shutdown() -> io::Result<RxFuture> {
new(wincon::CTRL_SHUTDOWN_EVENT)
new(console::CTRL_SHUTDOWN_EVENT)
}
fn new(signum: DWORD) -> io::Result<RxFuture> {
fn new(signum: u32) -> io::Result<RxFuture> {
global_init()?;
let rx = globals().register_listener(signum as EventId);
Ok(RxFuture::new(rx))
@ -58,12 +57,12 @@ impl Init for OsStorage {
impl Storage for OsStorage {
fn event_info(&self, id: EventId) -> Option<&EventInfo> {
match DWORD::try_from(id) {
Ok(wincon::CTRL_BREAK_EVENT) => Some(&self.ctrl_break),
Ok(wincon::CTRL_CLOSE_EVENT) => Some(&self.ctrl_close),
Ok(wincon::CTRL_C_EVENT) => Some(&self.ctrl_c),
Ok(wincon::CTRL_LOGOFF_EVENT) => Some(&self.ctrl_logoff),
Ok(wincon::CTRL_SHUTDOWN_EVENT) => Some(&self.ctrl_shutdown),
match u32::try_from(id) {
Ok(console::CTRL_BREAK_EVENT) => Some(&self.ctrl_break),
Ok(console::CTRL_CLOSE_EVENT) => Some(&self.ctrl_close),
Ok(console::CTRL_C_EVENT) => Some(&self.ctrl_c),
Ok(console::CTRL_LOGOFF_EVENT) => Some(&self.ctrl_logoff),
Ok(console::CTRL_SHUTDOWN_EVENT) => Some(&self.ctrl_shutdown),
_ => None,
}
}
@ -95,7 +94,7 @@ fn global_init() -> io::Result<()> {
let mut init = None;
INIT.call_once(|| unsafe {
let rc = SetConsoleCtrlHandler(Some(handler), TRUE);
let rc = console::SetConsoleCtrlHandler(Some(handler), 1);
let ret = if rc == 0 {
Err(io::Error::last_os_error())
} else {
@ -108,7 +107,7 @@ fn global_init() -> io::Result<()> {
init.unwrap_or_else(|| Ok(()))
}
unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
unsafe extern "system" fn handler(ty: u32) -> BOOL {
let globals = globals();
globals.record_event(ty as EventId);
@ -117,11 +116,11 @@ unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
// have the same restrictions as in Unix signal handlers, meaning we can
// go ahead and perform the broadcast here.
if globals.broadcast() {
TRUE
1
} else {
// No one is listening for this notification any more
// let the OS fire the next (possibly the default) handler.
FALSE
0
}
}
@ -145,7 +144,7 @@ mod tests {
// like sending signals on Unix, so we'll stub out the actual OS
// integration and test that our handling works.
unsafe {
super::handler(wincon::CTRL_C_EVENT);
super::handler(console::CTRL_C_EVENT);
}
assert_ready_ok!(ctrl_c.poll());
@ -162,7 +161,7 @@ mod tests {
// like sending signals on Unix, so we'll stub out the actual OS
// integration and test that our handling works.
unsafe {
super::handler(wincon::CTRL_BREAK_EVENT);
super::handler(console::CTRL_BREAK_EVENT);
}
ctrl_break.recv().await.unwrap();
@ -180,7 +179,7 @@ mod tests {
// like sending signals on Unix, so we'll stub out the actual OS
// integration and test that our handling works.
unsafe {
super::handler(wincon::CTRL_CLOSE_EVENT);
super::handler(console::CTRL_CLOSE_EVENT);
}
ctrl_close.recv().await.unwrap();
@ -198,7 +197,7 @@ mod tests {
// like sending signals on Unix, so we'll stub out the actual OS
// integration and test that our handling works.
unsafe {
super::handler(wincon::CTRL_SHUTDOWN_EVENT);
super::handler(console::CTRL_SHUTDOWN_EVENT);
}
ctrl_shutdown.recv().await.unwrap();
@ -216,7 +215,7 @@ mod tests {
// like sending signals on Unix, so we'll stub out the actual OS
// integration and test that our handling works.
unsafe {
super::handler(wincon::CTRL_LOGOFF_EVENT);
super::handler(console::CTRL_LOGOFF_EVENT);
}
ctrl_logoff.recv().await.unwrap();

View File

@ -8,7 +8,7 @@ use std::time::Duration;
use tokio::io::AsyncWriteExt;
use tokio::net::windows::named_pipe::{ClientOptions, PipeMode, ServerOptions};
use tokio::time;
use winapi::shared::winerror;
use windows_sys::Win32::Foundation::{ERROR_NO_DATA, ERROR_PIPE_BUSY, NO_ERROR, UNICODE_STRING};
#[tokio::test]
async fn test_named_pipe_client_drop() -> io::Result<()> {
@ -25,7 +25,7 @@ async fn test_named_pipe_client_drop() -> io::Result<()> {
// instance will be broken because client is gone
match server.write_all(b"ping").await {
Err(e) if e.raw_os_error() == Some(winerror::ERROR_NO_DATA as i32) => (),
Err(e) if e.raw_os_error() == Some(ERROR_NO_DATA as i32) => (),
x => panic!("{:?}", x),
}
@ -120,7 +120,7 @@ async fn test_named_pipe_multi_client() -> io::Result<()> {
let client = loop {
match ClientOptions::new().open(PIPE_NAME) {
Ok(client) => break client,
Err(e) if e.raw_os_error() == Some(winerror::ERROR_PIPE_BUSY as i32) => (),
Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
Err(e) if e.kind() == io::ErrorKind::NotFound => (),
Err(e) => return Err(e),
}
@ -249,7 +249,7 @@ async fn test_named_pipe_multi_client_ready() -> io::Result<()> {
let client = loop {
match ClientOptions::new().open(PIPE_NAME) {
Ok(client) => break client,
Err(e) if e.raw_os_error() == Some(winerror::ERROR_PIPE_BUSY as i32) => (),
Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
Err(e) if e.kind() == io::ErrorKind::NotFound => (),
Err(e) => return Err(e),
}
@ -370,10 +370,9 @@ async fn test_named_pipe_access() -> io::Result<()> {
fn num_instances(pipe_name: impl AsRef<str>) -> io::Result<u32> {
use ntapi::ntioapi;
use winapi::shared::ntdef;
let mut name = pipe_name.as_ref().encode_utf16().collect::<Vec<_>>();
let mut name = ntdef::UNICODE_STRING {
let mut name = UNICODE_STRING {
Length: (name.len() * mem::size_of::<u16>()) as u16,
MaximumLength: (name.len() * mem::size_of::<u16>()) as u16,
Buffer: name.as_mut_ptr(),
@ -393,12 +392,12 @@ fn num_instances(pipe_name: impl AsRef<str>) -> io::Result<u32> {
1024,
ntioapi::FileDirectoryInformation,
0,
&mut name,
&mut name as *mut _ as _,
0,
)
};
if status as u32 != winerror::NO_ERROR {
if status as u32 != NO_ERROR {
return Err(io::Error::last_os_error());
}

View File

@ -3,7 +3,7 @@
#![cfg(windows)]
use tokio::process::Command;
use winapi::um::processthreadsapi::GetProcessId;
use windows_sys::Win32::System::Threading::GetProcessId;
#[tokio::test]
async fn obtain_raw_handle() {