Skip to main content

windows_erg/utils/
handles.rs

1use windows::Win32::Foundation::{CloseHandle, HANDLE, INVALID_HANDLE_VALUE};
2
3/// RAII wrapper for Win32 `HANDLE` values.
4///
5/// This type supports both owned and borrowed handle semantics using the
6/// `close_on_drop` flag.
7#[derive(Debug)]
8pub struct OwnedHandle {
9    handle: HANDLE,
10    close_on_drop: bool,
11}
12
13impl OwnedHandle {
14    /// Create an owned handle that closes on drop.
15    pub fn new(handle: HANDLE) -> Self {
16        Self {
17            handle,
18            close_on_drop: true,
19        }
20    }
21
22    /// Create a handle with explicit ownership behavior.
23    pub fn with_ownership(handle: HANDLE, close_on_drop: bool) -> Self {
24        Self {
25            handle,
26            close_on_drop,
27        }
28    }
29
30    /// Create a borrowed handle that does not close on drop.
31    pub fn borrowed(handle: HANDLE) -> Self {
32        Self {
33            handle,
34            close_on_drop: false,
35        }
36    }
37
38    /// Return the raw Win32 handle.
39    pub fn raw(&self) -> HANDLE {
40        self.handle
41    }
42
43    /// Configure whether this handle closes on drop.
44    pub fn set_close_on_drop(&mut self, close_on_drop: bool) {
45        self.close_on_drop = close_on_drop;
46    }
47
48    /// Return whether this handle closes on drop.
49    pub fn close_on_drop(&self) -> bool {
50        self.close_on_drop
51    }
52}
53
54impl Drop for OwnedHandle {
55    fn drop(&mut self) {
56        if self.close_on_drop && !self.handle.is_invalid() && self.handle != INVALID_HANDLE_VALUE {
57            let _ = unsafe { CloseHandle(self.handle) };
58        }
59    }
60}
61
62unsafe impl Send for OwnedHandle {}
63unsafe impl Sync for OwnedHandle {}