diff options
| author | David Lönnhager <david.l@mullvad.net> | 2023-10-17 11:24:08 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-10-20 18:17:06 +0200 |
| commit | b3cc38c2bea1869e495206ec1febc6a92bb300bc (patch) | |
| tree | 6c9663ef925b5699db8c2befcb5fa910b0e28deb /talpid-windows/src | |
| parent | 5f5e7b3c0e4b14cd8cbd4e53919e3555e24319ed (diff) | |
| download | mullvadvpn-b3cc38c2bea1869e495206ec1febc6a92bb300bc.tar.xz mullvadvpn-b3cc38c2bea1869e495206ec1febc6a92bb300bc.zip | |
Move Event and Overlapped to talpid-windows crate
Diffstat (limited to 'talpid-windows/src')
| -rw-r--r-- | talpid-windows/src/io.rs | 49 | ||||
| -rw-r--r-- | talpid-windows/src/lib.rs | 12 | ||||
| -rw-r--r-- | talpid-windows/src/sync.rs | 75 |
3 files changed, 136 insertions, 0 deletions
diff --git a/talpid-windows/src/io.rs b/talpid-windows/src/io.rs new file mode 100644 index 0000000000..1bcffb30d3 --- /dev/null +++ b/talpid-windows/src/io.rs @@ -0,0 +1,49 @@ +use std::{io, mem}; +use windows_sys::Win32::System::IO::OVERLAPPED; + +use crate::sync::Event; + +/// Abstraction over `OVERLAPPED`. +pub struct Overlapped { + overlapped: OVERLAPPED, + event: Option<Event>, +} + +unsafe impl Send for Overlapped {} +unsafe impl Sync for Overlapped {} + +impl Overlapped { + /// Creates an `OVERLAPPED` object with `hEvent` set. + pub fn new(event: Option<Event>) -> io::Result<Self> { + let mut overlapped = Overlapped { + overlapped: unsafe { mem::zeroed() }, + event: None, + }; + overlapped.set_event(event); + Ok(overlapped) + } + + /// Borrows the underlying `OVERLAPPED` object. + pub fn as_mut_ptr(&mut self) -> *mut OVERLAPPED { + &mut self.overlapped + } + + /// Returns a reference to the associated event. + pub fn get_event(&self) -> Option<&Event> { + self.event.as_ref() + } + + /// Sets the event object for the underlying `OVERLAPPED` object (i.e., `hEvent`) + fn set_event(&mut self, event: Option<Event>) { + match event { + Some(event) => { + self.overlapped.hEvent = event.as_raw(); + self.event = Some(event); + } + None => { + self.overlapped.hEvent = 0; + self.event = None; + } + } + } +} diff --git a/talpid-windows/src/lib.rs b/talpid-windows/src/lib.rs new file mode 100644 index 0000000000..edc471aa33 --- /dev/null +++ b/talpid-windows/src/lib.rs @@ -0,0 +1,12 @@ +//! Interface with low-level windows specific bits. + +#![deny(missing_docs)] +#![deny(rust_2018_idioms)] + +/// Windows I/O +#[cfg(windows)] +pub mod io; + +/// Synchronization (event objects, etc.) +#[cfg(windows)] +pub mod sync; diff --git a/talpid-windows/src/sync.rs b/talpid-windows/src/sync.rs new file mode 100644 index 0000000000..7b4ed59be3 --- /dev/null +++ b/talpid-windows/src/sync.rs @@ -0,0 +1,75 @@ +use std::{io, ptr}; +use windows_sys::Win32::{ + Foundation::{CloseHandle, DuplicateHandle, BOOL, DUPLICATE_SAME_ACCESS, HANDLE}, + System::Threading::{CreateEventW, GetCurrentProcess, SetEvent}, +}; + +/// Windows event object +pub struct Event(HANDLE); + +unsafe impl Send for Event {} +unsafe impl Sync for Event {} + +impl Event { + /// Create a new event object using `CreateEventW` + pub fn new(manual_reset: bool, initial_state: bool) -> io::Result<Self> { + let event = unsafe { + CreateEventW( + ptr::null_mut(), + bool_to_winbool(manual_reset), + bool_to_winbool(initial_state), + ptr::null(), + ) + }; + if event == 0 { + return Err(io::Error::last_os_error()); + } + Ok(Self(event)) + } + + /// Signal the event object + pub fn set(&self) -> io::Result<()> { + if unsafe { SetEvent(self.0) } == 0 { + return Err(io::Error::last_os_error()); + } + Ok(()) + } + + /// Return raw event object + pub fn as_raw(&self) -> HANDLE { + self.0 + } + + /// Duplicate the event object with `DuplicateHandle()` + pub fn duplicate(&self) -> io::Result<Event> { + let mut new_event = 0; + let status = unsafe { + DuplicateHandle( + GetCurrentProcess(), + self.0, + GetCurrentProcess(), + &mut new_event, + 0, + 0, + DUPLICATE_SAME_ACCESS, + ) + }; + if status == 0 { + return Err(io::Error::last_os_error()); + } + Ok(Event(new_event)) + } +} + +impl Drop for Event { + fn drop(&mut self) { + unsafe { CloseHandle(self.0) }; + } +} + +const fn bool_to_winbool(val: bool) -> BOOL { + match val { + true => 1, + false => 0, + } +} |
