use std::ffi::c_void;
use std::os::windows::io::{FromRawHandle, OwnedHandle};
use windows_sys::Win32::Storage::FileSystem::{
FILE_FLAGS_AND_ATTRIBUTES, FILE_SHARE_MODE, ReOpenFile as Win32ReOpenFile,
};
use win_shared_os_owned_handle::SharedHandle;
use crate::handle::SharedRaw;
use crate::outcome::{Outcome, perform_handle};
#[derive(Clone, Debug)]
#[must_use = "an unperformed request reopens nothing"]
pub struct ReOpenFile {
original: SharedHandle,
desired_access: u32,
share_mode: FILE_SHARE_MODE,
flags_and_attributes: FILE_FLAGS_AND_ATTRIBUTES,
}
impl ReOpenFile {
pub fn new(original: impl Into<SharedHandle>) -> Self {
Self {
original: original.into(),
desired_access: 0,
share_mode: 0,
flags_and_attributes: 0,
}
}
pub fn with_desired_access(mut self, desired_access: u32) -> Self {
self.desired_access = desired_access;
self
}
pub fn with_share_mode(mut self, share_mode: FILE_SHARE_MODE) -> Self {
self.share_mode = share_mode;
self
}
pub fn with_flags_and_attributes(
mut self,
flags_and_attributes: FILE_FLAGS_AND_ATTRIBUTES,
) -> Self {
self.flags_and_attributes = flags_and_attributes;
self
}
pub fn original(&self) -> &SharedHandle {
&self.original
}
#[must_use]
pub fn desired_access(&self) -> u32 {
self.desired_access
}
#[must_use]
pub fn share_mode(&self) -> FILE_SHARE_MODE {
self.share_mode
}
#[must_use]
pub fn flags_and_attributes(&self) -> FILE_FLAGS_AND_ATTRIBUTES {
self.flags_and_attributes
}
pub fn perform(&self) -> Outcome<OwnedHandle> {
let raw = perform_handle(|| {
unsafe {
Win32ReOpenFile(
self.original.raw(),
self.desired_access,
self.share_mode,
self.flags_and_attributes,
)
}
})?;
Ok(unsafe { OwnedHandle::from_raw_handle(raw.cast::<c_void>()) })
}
}
impl crate::request::Request for ReOpenFile {
type Error = crate::Win32Error;
type Output = OwnedHandle;
fn perform(&self) -> Outcome<OwnedHandle> {
Self::perform(self)
}
}
#[cfg(test)]
mod tests;