#![allow(clippy::undocumented_unsafe_blocks)]
use crate::{AcError, Result};
use std::os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
};
use windows::Win32::Foundation::HANDLE;
#[derive(Debug)]
pub(crate) struct Handle(OwnedHandle);
impl Handle {
pub(crate) unsafe fn from_raw(h: RawHandle) -> Result<Self> {
if h.is_null() {
return Err(AcError::Win32("invalid null handle".into()));
}
if h as isize == -1 {
return Err(AcError::Win32("invalid handle value".into()));
}
let owned = unsafe { OwnedHandle::from_raw_handle(h) };
Ok(Self(owned))
}
pub(crate) fn as_borrowed(&self) -> BorrowedHandle<'_> {
self.0.as_handle()
}
#[allow(dead_code)]
pub(crate) fn into_owned(self) -> OwnedHandle {
self.0
}
pub(crate) fn as_win32(&self) -> HANDLE {
HANDLE(self.as_borrowed().as_raw_handle())
}
pub(crate) fn into_file(self) -> std::fs::File {
let raw = self.0.into_raw_handle();
unsafe { std::fs::File::from_raw_handle(raw) }
}
}
#[cfg(test)]
mod tests {
use super::*;
use windows::Win32::Foundation::WAIT_OBJECT_0;
use windows::Win32::System::Threading::{CreateEventW, SetEvent, WaitForSingleObject};
#[test]
fn handle_wraps_event_and_closes() {
unsafe {
let raw = CreateEventW(None, true, false, None)
.expect("create event")
.0 as *mut _;
let h = Handle::from_raw(raw).expect("wrap handle");
let hr = SetEvent(h.as_win32());
assert!(hr.is_ok());
let wr = WaitForSingleObject(h.as_win32(), 1000);
assert_eq!(wr, WAIT_OBJECT_0);
let _ = h;
}
}
}