process_memory/
windows.rs1use winapi::shared::minwindef;
2
3use std::os::windows::io::AsRawHandle;
4use std::process::Child;
5use std::ptr;
6
7use super::{Architecture, CopyAddress, ProcessHandleExt, PutAddress, TryIntoProcessHandle};
8
9pub type Pid = minwindef::DWORD;
11pub type ProcessHandle = (winapi::um::winnt::HANDLE, Architecture);
13
14impl ProcessHandleExt for ProcessHandle {
15 #[must_use]
16 fn check_handle(&self) -> bool {
17 self.0.is_null()
18 }
19 #[must_use]
20 fn null_type() -> ProcessHandle {
21 (ptr::null_mut(), Architecture::from_native())
22 }
23 #[must_use]
24 fn set_arch(self, arch: Architecture) -> Self {
25 (self.0, arch)
26 }
27}
28
29impl TryIntoProcessHandle for minwindef::DWORD {
31 fn try_into_process_handle(&self) -> std::io::Result<ProcessHandle> {
32 let handle = unsafe {
33 winapi::um::processthreadsapi::OpenProcess(
34 winapi::um::winnt::PROCESS_CREATE_THREAD
35 | winapi::um::winnt::PROCESS_QUERY_INFORMATION
36 | winapi::um::winnt::PROCESS_VM_READ
37 | winapi::um::winnt::PROCESS_VM_WRITE
38 | winapi::um::winnt::PROCESS_VM_OPERATION,
39 winapi::shared::minwindef::FALSE,
40 *self,
41 )
42 };
43 if handle == (0 as winapi::um::winnt::HANDLE) {
44 Err(std::io::Error::last_os_error())
45 } else {
46 Ok((handle, Architecture::from_native()))
47 }
48 }
49}
50
51impl TryIntoProcessHandle for Child {
53 fn try_into_process_handle(&self) -> std::io::Result<ProcessHandle> {
54 Ok((self.as_raw_handle().cast(), Architecture::from_native()))
55 }
56}
57
58impl CopyAddress for ProcessHandle {
60 #[allow(clippy::inline_always)]
61 #[inline(always)]
62 fn get_pointer_width(&self) -> Architecture {
63 self.1
64 }
65
66 #[allow(clippy::ptr_as_ptr)]
67 fn copy_address(&self, addr: usize, buf: &mut [u8]) -> std::io::Result<()> {
68 if buf.is_empty() {
69 return Ok(());
70 }
71
72 if unsafe {
73 winapi::um::memoryapi::ReadProcessMemory(
74 self.0,
75 addr as minwindef::LPVOID,
76 buf.as_mut_ptr() as minwindef::LPVOID,
77 buf.len() as winapi::shared::basetsd::SIZE_T,
78 ptr::null_mut(),
79 )
80 } == winapi::shared::minwindef::FALSE
81 {
82 Err(std::io::Error::last_os_error())
83 } else {
84 Ok(())
85 }
86 }
87}
88
89impl PutAddress for ProcessHandle {
91 #[allow(clippy::ptr_as_ptr)]
92 fn put_address(&self, addr: usize, buf: &[u8]) -> std::io::Result<()> {
93 if buf.is_empty() {
94 return Ok(());
95 }
96 if unsafe {
97 winapi::um::memoryapi::WriteProcessMemory(
98 self.0,
99 addr as minwindef::LPVOID,
100 buf.as_ptr() as minwindef::LPCVOID,
101 buf.len() as winapi::shared::basetsd::SIZE_T,
102 ptr::null_mut(),
103 )
104 } == winapi::shared::minwindef::FALSE
105 {
106 Err(std::io::Error::last_os_error())
107 } else {
108 Ok(())
109 }
110 }
111}