| use std::fmt; |
| use std::io; |
| use std::mem; |
| use std::ptr; |
| |
| use winapi::shared::ntdef::{HANDLE, NULL}; |
| use winapi::um::minwinbase::*; |
| use winapi::um::synchapi::*; |
| |
| /// A wrapper around `OVERLAPPED` to provide "rustic" accessors and |
| /// initializers. |
| pub struct Overlapped(OVERLAPPED); |
| |
| impl fmt::Debug for Overlapped { |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| write!(f, "OVERLAPPED") |
| } |
| } |
| |
| unsafe impl Send for Overlapped {} |
| unsafe impl Sync for Overlapped {} |
| |
| impl Overlapped { |
| /// Creates a new zeroed out instance of an overlapped I/O tracking state. |
| /// |
| /// This is suitable for passing to methods which will then later get |
| /// notified via an I/O Completion Port. |
| pub fn zero() -> Overlapped { |
| Overlapped(unsafe { mem::zeroed() }) |
| } |
| |
| /// Creates a new `Overlapped` with an initialized non-null `hEvent`. The caller is |
| /// responsible for calling `CloseHandle` on the `hEvent` field of the returned |
| /// `Overlapped`. The event is created with `bManualReset` set to `FALSE`, meaning after a |
| /// single thread waits on the event, it will be reset. |
| pub fn initialize_with_autoreset_event() -> io::Result<Overlapped> { |
| let event = unsafe { CreateEventW(ptr::null_mut(), 0i32, 0i32, ptr::null()) }; |
| if event == NULL { |
| return Err(io::Error::last_os_error()); |
| } |
| let mut overlapped = Self::zero(); |
| overlapped.set_event(event); |
| Ok(overlapped) |
| } |
| |
| /// Creates a new `Overlapped` function pointer from the underlying |
| /// `OVERLAPPED`, wrapping in the "rusty" wrapper for working with |
| /// accessors. |
| /// |
| /// # Unsafety |
| /// |
| /// This function doesn't validate `ptr` nor the lifetime of the returned |
| /// pointer at all, it's recommended to use this method with extreme |
| /// caution. |
| pub unsafe fn from_raw<'a>(ptr: *mut OVERLAPPED) -> &'a mut Overlapped { |
| &mut *(ptr as *mut Overlapped) |
| } |
| |
| /// Gain access to the raw underlying data |
| pub fn raw(&self) -> *mut OVERLAPPED { |
| &self.0 as *const _ as *mut _ |
| } |
| |
| /// Sets the offset inside this overlapped structure. |
| /// |
| /// Note that for I/O operations in general this only has meaning for I/O |
| /// handles that are on a seeking device that supports the concept of an |
| /// offset. |
| pub fn set_offset(&mut self, offset: u64) { |
| let s = unsafe { self.0.u.s_mut() }; |
| s.Offset = offset as u32; |
| s.OffsetHigh = (offset >> 32) as u32; |
| } |
| |
| /// Reads the offset inside this overlapped structure. |
| pub fn offset(&self) -> u64 { |
| let s = unsafe { self.0.u.s() }; |
| (s.Offset as u64) | ((s.OffsetHigh as u64) << 32) |
| } |
| |
| /// Sets the `hEvent` field of this structure. |
| /// |
| /// The event specified can be null. |
| pub fn set_event(&mut self, event: HANDLE) { |
| self.0.hEvent = event; |
| } |
| |
| /// Reads the `hEvent` field of this structure, may return null. |
| pub fn event(&self) -> HANDLE { |
| self.0.hEvent |
| } |
| } |