win_sys/
memory.rs

1use std::{
2    ffi::{c_void, OsStr},
3    mem::size_of,
4    ptr::null,
5};
6
7#[doc(hidden)]
8pub use windows::Win32::System::Memory::{
9    self, FILE_MAP, FILE_MAP_ALL_ACCESS, FILE_MAP_READ, FILE_MAP_WRITE, MEMORY_BASIC_INFORMATION,
10    PAGE_PROTECTION_FLAGS, PAGE_READWRITE,
11};
12
13use crate::*;
14
15use core::result::Result;
16
17pub struct ViewOfFile(*mut c_void);
18impl ViewOfFile {
19    pub fn as_mut_ptr(&self) -> *mut c_void {
20        self.0
21    }
22}
23impl core::fmt::Pointer for ViewOfFile {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        core::fmt::Pointer::fmt(&self.0, f)
26    }
27}
28impl Drop for ViewOfFile {
29    fn drop(&mut self) {
30        unsafe {
31            Memory::UnmapViewOfFile(self.0);
32        }
33    }
34}
35
36#[allow(non_snake_case)]
37pub fn MapViewOfFile(
38    hfilemappingobject: HANDLE,
39    dwdesiredaccess: FILE_MAP,
40    dwfileoffsethigh: u32,
41    dwfileoffsetlow: u32,
42    dwnumberofbytestomap: usize,
43) -> Result<ViewOfFile, Error> {
44    let v = unsafe {
45        Memory::MapViewOfFile(
46            hfilemappingobject,
47            dwdesiredaccess,
48            dwfileoffsethigh,
49            dwfileoffsetlow,
50            dwnumberofbytestomap,
51        )
52    };
53
54    if v.is_null() {
55        return Err(Error::from_win32());
56    }
57
58    Ok(ViewOfFile(v))
59}
60
61pub struct FileMapping(HANDLE);
62impl FileMapping {
63    pub fn as_handle(&self) -> HANDLE {
64        self.0
65    }
66}
67impl core::fmt::UpperHex for FileMapping {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        core::fmt::UpperHex::fmt(&self.0 .0, f)
70    }
71}
72impl Drop for FileMapping {
73    fn drop(&mut self) {
74        let _ = CloseHandle(self.0);
75    }
76}
77
78#[allow(non_snake_case)]
79pub fn CreateFileMapping<S: AsRef<OsStr>>(
80    hfile: HANDLE,
81    lpfilemappingattributes: Option<&SECURITY_ATTRIBUTES>,
82    flprotect: PAGE_PROTECTION_FLAGS,
83    dwmaximumsizehigh: u32,
84    dwmaximumsizelow: u32,
85    lpname: S,
86) -> Result<FileMapping, Error> {
87    let sec_attr = match lpfilemappingattributes {
88        Some(s) => s as *const SECURITY_ATTRIBUTES,
89        None => null(),
90    };
91
92    let h = unsafe {
93        Memory::CreateFileMappingW(
94            hfile,
95            sec_attr,
96            flprotect,
97            dwmaximumsizehigh,
98            dwmaximumsizelow,
99            lpname.as_ref(),
100        )
101    };
102
103    Ok(FileMapping(h.ok()?))
104}
105
106#[allow(non_snake_case)]
107pub fn OpenFileMapping<S: AsRef<OsStr>>(
108    desired_access: FILE_MAP,
109    inherit_handle: bool,
110    name: S,
111) -> Result<FileMapping, Error> {
112    let h = unsafe {
113        Memory::OpenFileMappingW(
114            desired_access.0,
115            inherit_handle,
116            name.as_ref(),
117        )
118    };
119
120    Ok(FileMapping(h.ok()?))
121}
122
123#[allow(clippy::not_unsafe_ptr_arg_deref)]
124#[allow(non_snake_case)]
125pub fn VirtualQuery(
126    lpaddress: *const c_void,
127    lpbuffer: &mut MEMORY_BASIC_INFORMATION,
128) -> Result<(), Error> {
129    let bytes_written = unsafe {
130        Memory::VirtualQuery(
131            lpaddress,
132            lpbuffer as *mut MEMORY_BASIC_INFORMATION,
133            size_of::<MEMORY_BASIC_INFORMATION>(),
134        )
135    };
136
137    if (bytes_written as usize) < size_of::<MEMORY_BASIC_INFORMATION>() {
138        return Err(Error::from_win32());
139    }
140
141    Ok(())
142}