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}