├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── rustfmt.toml └── src ├── bitfield.rs ├── lib.rs ├── ntbcd.rs ├── ntdbg.rs ├── ntexapi.rs ├── ntgdi.rs ├── ntimage.rs ├── ntioapi.rs ├── ntkeapi.rs ├── ntldr.rs ├── ntlpcapi.rs ├── ntmisc.rs ├── ntmmapi.rs ├── ntnls.rs ├── ntobapi.rs ├── ntpebteb.rs ├── ntpfapi.rs ├── ntpnpapi.rs ├── ntpoapi.rs ├── ntpsapi.rs ├── ntregapi.rs ├── ntrtl.rs ├── ntsam.rs ├── ntseapi.rs ├── ntsmss.rs ├── ntsxs.rs ├── nttmapi.rs ├── nttp.rs ├── ntwow64.rs ├── ntxcapi.rs ├── ntzwapi.rs ├── phnt_ntdef.rs ├── subprocesstag.rs └── winsta.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: windows-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: cargo build --verbose 21 | - name: Run tests 22 | run: cargo test --verbose 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "windows-native" 3 | version = "1.0.44" 4 | authors = ["NiiightmareXD"] 5 | edition = "2021" 6 | description = "Windows Native Undocumented API for Rust Language 🔥" 7 | documentation = "https://docs.rs/windows-native" 8 | readme = "README.md" 9 | repository = "https://github.com/NiiightmareXD/windows-native" 10 | license = "MIT" 11 | keywords = ["native", "windows", "ffi", "win32", "com"] 12 | categories = ["os::windows-apis", "api-bindings", "external-ffi-bindings"] 13 | 14 | [dependencies] 15 | windows = { version = "0.58.0", features = [ 16 | "Win32_Foundation", 17 | "Win32_System_ApplicationInstallationAndServicing", 18 | "Win32_Devices_DeviceAndDriverInstallation", 19 | "Win32_System_Diagnostics_Debug", 20 | "Win32_System_SystemServices", 21 | "Win32_Security", 22 | "Win32_System_Kernel", 23 | "Win32_System_Memory", 24 | "Win32_System_Ioctl", 25 | "Win32_Storage_FileSystem", 26 | "Win32_UI_WindowsAndMessaging", 27 | "Win32_System_Threading", 28 | "Win32_System_WindowsProgramming", 29 | "Win32_System_Power", 30 | "Win32_System_Performance_HardwareCounterProfiling", 31 | "Win32_System_JobObjects", 32 | "Win32_System_SystemInformation", 33 | "Win32_System_Diagnostics_Etw", 34 | "Win32_System_IO", 35 | "Wdk_Foundation", 36 | "Wdk_System_SystemServices", 37 | "Wdk_Storage_FileSystem", 38 | "Win32_Security_Authentication_Identity", 39 | "Wdk_System_SystemInformation", 40 | "Wdk_System_Threading", 41 | "Wdk_System_Registry", 42 | "Wdk_System_Memory", 43 | "Win32_System_PasswordManagement", 44 | ], default-features = false } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 NiiightmareXD 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Native   ![Crates.io](https://img.shields.io/crates/l/windows-native) ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/NiiightmareXD/windows-native/rust.yml) ![Crates.io](https://img.shields.io/crates/v/windows-native) 2 | 3 | The **Windows-Native** Rust library provides a convenient and safe way to access the native Windows undocumented APIs using the Rust programming language. These APIs are mostly exported from the Process Hacker native API headers (phnt), enabling you to interact with Windows internals in a reliable and efficient manner. 4 | 5 | Please note that using undocumented APIs can be risky, as they might change without notice in different Windows versions and can potentially cause system instability. Use this library with caution and ensure you have a good understanding of the implications of using undocumented APIs. 6 | 7 | ## Features 8 | 9 | - Access undocumented Windows APIs through Rust. 10 | - Headers sourced mainly from Process Hacker's NT headers. 11 | - Provides a safer interface compared to raw FFI. 12 | - Detailed documentation and examples for each API. 13 | - Easy-to-use functions and types for common Windows tasks. 14 | 15 | ## Installation 16 | 17 | Add this library to your `Cargo.toml`: 18 | 19 | ```toml 20 | [dependencies] 21 | windows-native = "1.0.40" 22 | ``` 23 | or run this command 24 | 25 | ``` 26 | cargo add windows-native 27 | ``` 28 | 29 | this crate works with [windows-rs](https://github.com/microsoft/windows-rs) so you have to install that too. 30 | 31 | ## Usage 32 | 33 | ```rust 34 | use std::{thread, time::Duration}; 35 | 36 | use windows_native::ntpsapi::{NtResumeProcess, NtSuspendProcess}; 37 | use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; 38 | 39 | let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, false, 69420).unwrap() }; 40 | let result = unsafe { NtSuspendProcess(handle) }; 41 | println!("Result {:?}", result); 42 | thread::sleep(Duration::from_secs(3)); 43 | let result = unsafe { NtResumeProcess(handle) }; 44 | println!("Result {:?}", result); 45 | ``` 46 | 47 | ## Documentation 48 | 49 | Detailed documentation for each API and type can be found [here](https://docs.rs/windows-native/). 50 | 51 | ## Contributing 52 | 53 | Contributions are welcome! If you find a bug or want to add new features to the library, please open an issue or submit a pull request. 54 | 55 | ## License 56 | 57 | This project is licensed under the [MIT License](LICENSE). 58 | 59 | ## Disclaimer 60 | 61 | **Windows-Native** is provided as-is and does not guarantee compatibility with future Windows versions. Using undocumented APIs can have unintended consequences, including system instability and security vulnerabilities. Use at your own risk. 62 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | wrap_comments = true 2 | version = "Two" 3 | use_try_shorthand = true 4 | use_field_init_shorthand = true 5 | unstable_features = true 6 | normalize_doc_attributes = true 7 | normalize_comments = true 8 | imports_granularity = "Crate" 9 | -------------------------------------------------------------------------------- /src/bitfield.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 3 | pub struct BitfieldUnit { 4 | storage: Storage, 5 | } 6 | 7 | impl BitfieldUnit { 8 | #[inline] 9 | 10 | pub const fn new(storage: Storage) -> Self { 11 | Self { storage } 12 | } 13 | } 14 | 15 | impl BitfieldUnit 16 | where 17 | Storage: AsRef<[u8]> + AsMut<[u8]>, 18 | { 19 | #[inline] 20 | pub fn get_bit(&self, index: usize) -> bool { 21 | debug_assert!(index / 8 < self.storage.as_ref().len()); 22 | 23 | let byte_index = index / 8; 24 | 25 | let byte = self.storage.as_ref()[byte_index]; 26 | 27 | let bit_index = if cfg!(target_endian = "big") { 28 | 7 - (index % 8) 29 | } else { 30 | index % 8 31 | }; 32 | 33 | let mask = 1 << bit_index; 34 | 35 | byte & mask == mask 36 | } 37 | 38 | #[inline] 39 | pub fn set_bit(&mut self, index: usize, val: bool) { 40 | debug_assert!(index / 8 < self.storage.as_ref().len()); 41 | 42 | let byte_index = index / 8; 43 | 44 | let byte = &mut self.storage.as_mut()[byte_index]; 45 | 46 | let bit_index = if cfg!(target_endian = "big") { 47 | 7 - (index % 8) 48 | } else { 49 | index % 8 50 | }; 51 | 52 | let mask = 1 << bit_index; 53 | 54 | if val { 55 | *byte |= mask; 56 | } else { 57 | *byte &= !mask; 58 | } 59 | } 60 | 61 | #[inline] 62 | pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { 63 | debug_assert!(bit_width <= 64); 64 | 65 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 66 | 67 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 68 | 69 | let mut val = 0; 70 | 71 | for i in 0..(bit_width as usize) { 72 | if self.get_bit(i + bit_offset) { 73 | let index = if cfg!(target_endian = "big") { 74 | bit_width as usize - 1 - i 75 | } else { 76 | i 77 | }; 78 | 79 | val |= 1 << index; 80 | } 81 | } 82 | 83 | val 84 | } 85 | 86 | #[inline] 87 | pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { 88 | debug_assert!(bit_width <= 64); 89 | 90 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 91 | 92 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 93 | 94 | for i in 0..(bit_width as usize) { 95 | let mask = 1 << i; 96 | 97 | let val_bit_is_set = val & mask == mask; 98 | 99 | let index = if cfg!(target_endian = "big") { 100 | bit_width as usize - 1 - i 101 | } else { 102 | i 103 | }; 104 | 105 | self.set_bit(index + bit_offset, val_bit_is_set); 106 | } 107 | } 108 | } 109 | 110 | #[repr(C)] 111 | #[derive(Default)] 112 | pub struct ArrayField(std::marker::PhantomData, [T; 0]); 113 | 114 | impl ArrayField { 115 | #[inline] 116 | 117 | pub const fn new() -> Self { 118 | Self(std::marker::PhantomData, []) 119 | } 120 | 121 | #[inline] 122 | pub const fn as_ptr(&self) -> *const T { 123 | self as *const _ as *const T 124 | } 125 | 126 | #[inline] 127 | pub fn as_mut_ptr(&mut self) -> *mut T { 128 | self as *mut _ as *mut T 129 | } 130 | 131 | #[inline] 132 | #[allow(clippy::missing_safety_doc)] 133 | 134 | pub const unsafe fn as_slice(&self, len: usize) -> &[T] { 135 | std::slice::from_raw_parts(self.as_ptr(), len) 136 | } 137 | 138 | #[inline] 139 | #[allow(clippy::missing_safety_doc)] 140 | 141 | pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { 142 | std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) 143 | } 144 | } 145 | 146 | impl std::fmt::Debug for ArrayField { 147 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 148 | fmt.write_str("ArrayField") 149 | } 150 | } 151 | 152 | #[repr(C)] 153 | pub struct UnionField(std::marker::PhantomData); 154 | 155 | impl UnionField { 156 | #[inline] 157 | 158 | pub const fn new() -> Self { 159 | Self(std::marker::PhantomData) 160 | } 161 | 162 | #[inline] 163 | #[allow(clippy::missing_safety_doc)] 164 | 165 | pub unsafe fn as_ref(&self) -> &T { 166 | std::mem::transmute(self) 167 | } 168 | 169 | #[inline] 170 | #[allow(clippy::missing_safety_doc)] 171 | 172 | pub unsafe fn as_mut(&mut self) -> &mut T { 173 | std::mem::transmute(self) 174 | } 175 | } 176 | 177 | impl std::default::Default for UnionField { 178 | #[inline] 179 | 180 | fn default() -> Self { 181 | Self::new() 182 | } 183 | } 184 | 185 | impl std::clone::Clone for UnionField { 186 | #[inline] 187 | #[allow(clippy::non_canonical_clone_impl)] 188 | 189 | fn clone(&self) -> Self { 190 | Self::new() 191 | } 192 | } 193 | 194 | impl std::marker::Copy for UnionField {} 195 | 196 | impl std::fmt::Debug for UnionField { 197 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 198 | fmt.write_str("UnionField") 199 | } 200 | } 201 | 202 | impl std::hash::Hash for UnionField { 203 | fn hash(&self, _state: &mut H) {} 204 | } 205 | 206 | impl std::cmp::PartialEq for UnionField { 207 | fn eq(&self, _other: &Self) -> bool { 208 | true 209 | } 210 | } 211 | 212 | impl std::cmp::Eq for UnionField {} 213 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Windows Native Rust Library 2 | //! 3 | //! The **Windows-Native** Rust library provides a convenient and safe way to 4 | //! access the native Windows undocumented APIs using the Rust programming 5 | //! language. These APIs are mostly exported from the Process Hacker native API 6 | //! headers (phnt), enabling you to interact with Windows internals in a 7 | //! reliable and efficient manner. 8 | //! 9 | //! Please note that using undocumented APIs can be risky, as they might change 10 | //! without notice in different Windows versions and can potentially cause 11 | //! system instability. Use this library with caution and ensure you have a good 12 | //! understanding of the implications of using undocumented APIs. 13 | //! 14 | //! ## Features 15 | //! 16 | //! - Access undocumented Windows APIs through Rust. 17 | //! - Headers sourced mainly from Process Hacker's NT headers. 18 | //! - Provides a safer interface compared to raw FFI. 19 | //! - Detailed documentation and examples for each API. 20 | //! - Easy-to-use functions and types for common Windows tasks. 21 | //! 22 | //! ## Installation 23 | //! 24 | //! Add this library to your `Cargo.toml`: 25 | //! 26 | //! ```toml 27 | //! [dependencies] 28 | //! windows-native = "1.0.40" 29 | //! ``` 30 | //! or run this command 31 | //! 32 | //! ```text 33 | //! cargo add windows-native 34 | //! ``` 35 | //! 36 | //! and then install [windows-rs](https://github.com/microsoft/windows-rs) 37 | //! 38 | //! ## Usage 39 | //! 40 | //! ```no_run 41 | //! # fn main() { 42 | //! use std::{thread, time::Duration}; 43 | //! 44 | //! use windows_native::ntpsapi::{NtResumeProcess, NtSuspendProcess}; 45 | //! use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; 46 | //! 47 | //! let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, false, 69420).unwrap() }; 48 | //! let result = unsafe { NtSuspendProcess(handle) }; 49 | //! println!("Result {:?}", result); 50 | //! thread::sleep(Duration::from_secs(3)); 51 | //! let result = unsafe { NtResumeProcess(handle) }; 52 | //! println!("Result {:?}", result); 53 | //! # } 54 | //! ``` 55 | //! 56 | //! ## Contributing 57 | //! 58 | //! Contributions are welcome! If you find a bug or want to add new features to 59 | //! the library, please open an issue or submit a pull request. 60 | //! 61 | //! ## Disclaimer 62 | //! 63 | //! **Windows-Native** is provided as-is and does not guarantee compatibility 64 | //! with future Windows versions. Using undocumented APIs can have unintended 65 | //! consequences, including system instability and security vulnerabilities. Use 66 | //! at your own risk. 67 | #![allow(non_camel_case_types)] 68 | #![allow(non_snake_case)] 69 | #![allow(non_upper_case_globals)] 70 | #![allow(clippy::too_many_arguments)] 71 | #![warn(clippy::cargo)] 72 | 73 | pub mod bitfield; 74 | pub mod ntbcd; 75 | pub mod ntdbg; 76 | pub mod ntexapi; 77 | pub mod ntgdi; 78 | pub mod ntimage; 79 | pub mod ntioapi; 80 | pub mod ntkeapi; 81 | pub mod ntldr; 82 | pub mod ntlpcapi; 83 | pub mod ntmisc; 84 | pub mod ntmmapi; 85 | pub mod ntnls; 86 | pub mod ntobapi; 87 | pub mod ntpebteb; 88 | pub mod ntpfapi; 89 | pub mod ntpnpapi; 90 | pub mod ntpoapi; 91 | pub mod ntpsapi; 92 | pub mod ntregapi; 93 | pub mod ntrtl; 94 | pub mod ntsam; 95 | pub mod ntseapi; 96 | pub mod ntsmss; 97 | pub mod ntsxs; 98 | pub mod nttmapi; 99 | pub mod nttp; 100 | pub mod ntwow64; 101 | pub mod ntxcapi; 102 | pub mod ntzwapi; 103 | pub mod phnt_ntdef; 104 | pub mod subprocesstag; 105 | pub mod winsta; 106 | -------------------------------------------------------------------------------- /src/ntdbg.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | core::GUID, 3 | Wdk::Foundation::OBJECT_ATTRIBUTES, 4 | Win32::{ 5 | Foundation::{BOOLEAN, HANDLE, NTSTATUS}, 6 | System::{ 7 | Diagnostics::{ 8 | Debug::{DEBUG_EVENT, EXCEPTION_RECORD}, 9 | Etw::PENABLECALLBACK, 10 | }, 11 | WindowsProgramming::CLIENT_ID, 12 | }, 13 | }, 14 | }; 15 | 16 | use crate::{bitfield::UnionField, phnt_ntdef::PREGHANDLE}; 17 | 18 | pub const DEBUG_READ_EVENT: u32 = 1; 19 | pub const DEBUG_PROCESS_ASSIGN: u32 = 2; 20 | pub const DEBUG_SET_INFORMATION: u32 = 4; 21 | pub const DEBUG_QUERY_INFORMATION: u32 = 8; 22 | pub const DEBUG_ALL_ACCESS: u32 = 2031631; 23 | pub const DEBUG_KILL_ON_CLOSE: u32 = 1; 24 | 25 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 26 | extern "system" { 27 | pub fn DbgUserBreakPoint(); 28 | } 29 | 30 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 31 | extern "system" { 32 | pub fn DbgBreakPoint(); 33 | } 34 | 35 | #[repr(C)] 36 | pub struct DBGKM_EXCEPTION { 37 | pub ExceptionRecord: EXCEPTION_RECORD, 38 | pub FirstChance: u32, 39 | } 40 | 41 | impl Default for DBGKM_EXCEPTION { 42 | fn default() -> Self { 43 | unsafe { std::mem::zeroed() } 44 | } 45 | } 46 | 47 | impl std::fmt::Debug for DBGKM_EXCEPTION { 48 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 49 | write!(f, "DBGKM_EXCEPTION {{ }}") 50 | } 51 | } 52 | 53 | #[repr(C)] 54 | pub struct DBGKM_CREATE_THREAD { 55 | pub SubSystemKey: u32, 56 | pub StartAddress: *mut std::ffi::c_void, 57 | } 58 | 59 | impl Default for DBGKM_CREATE_THREAD { 60 | fn default() -> Self { 61 | unsafe { std::mem::zeroed() } 62 | } 63 | } 64 | 65 | impl std::fmt::Debug for DBGKM_CREATE_THREAD { 66 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 67 | write!(f, "DBGKM_CREATE_THREAD {{ }}") 68 | } 69 | } 70 | 71 | #[repr(C)] 72 | pub struct DBGKM_CREATE_PROCESS { 73 | pub SubSystemKey: u32, 74 | pub FileHandle: HANDLE, 75 | pub BaseOfImage: *mut std::ffi::c_void, 76 | pub DebugInfoFileOffset: u32, 77 | pub DebugInfoSize: u32, 78 | pub InitialThread: DBGKM_CREATE_THREAD, 79 | } 80 | 81 | impl Default for DBGKM_CREATE_PROCESS { 82 | fn default() -> Self { 83 | unsafe { std::mem::zeroed() } 84 | } 85 | } 86 | 87 | impl std::fmt::Debug for DBGKM_CREATE_PROCESS { 88 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 89 | write!( 90 | f, 91 | "DBGKM_CREATE_PROCESS {{ InitialThread: {:?} }}", 92 | self.InitialThread 93 | ) 94 | } 95 | } 96 | 97 | #[repr(C)] 98 | pub struct DBGKM_EXIT_THREAD { 99 | pub ExitStatus: NTSTATUS, 100 | } 101 | 102 | impl Default for DBGKM_EXIT_THREAD { 103 | fn default() -> Self { 104 | unsafe { std::mem::zeroed() } 105 | } 106 | } 107 | 108 | impl std::fmt::Debug for DBGKM_EXIT_THREAD { 109 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 110 | write!(f, "DBGKM_EXIT_THREAD {{ }}") 111 | } 112 | } 113 | 114 | #[repr(C)] 115 | pub struct DBGKM_EXIT_PROCESS { 116 | pub ExitStatus: NTSTATUS, 117 | } 118 | 119 | impl Default for DBGKM_EXIT_PROCESS { 120 | fn default() -> Self { 121 | unsafe { std::mem::zeroed() } 122 | } 123 | } 124 | 125 | impl std::fmt::Debug for DBGKM_EXIT_PROCESS { 126 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 127 | write!(f, "DBGKM_EXIT_PROCESS {{ }}") 128 | } 129 | } 130 | 131 | #[repr(C)] 132 | pub struct DBGKM_LOAD_DLL { 133 | pub FileHandle: HANDLE, 134 | pub BaseOfDll: *mut std::ffi::c_void, 135 | pub DebugInfoFileOffset: u32, 136 | pub DebugInfoSize: u32, 137 | pub NamePointer: *mut std::ffi::c_void, 138 | } 139 | 140 | impl Default for DBGKM_LOAD_DLL { 141 | fn default() -> Self { 142 | unsafe { std::mem::zeroed() } 143 | } 144 | } 145 | 146 | impl std::fmt::Debug for DBGKM_LOAD_DLL { 147 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 148 | write!(f, "DBGKM_LOAD_DLL {{ }}") 149 | } 150 | } 151 | 152 | #[repr(C)] 153 | pub struct DBGKM_UNLOAD_DLL { 154 | pub BaseAddress: *mut std::ffi::c_void, 155 | } 156 | 157 | impl Default for DBGKM_UNLOAD_DLL { 158 | fn default() -> Self { 159 | unsafe { std::mem::zeroed() } 160 | } 161 | } 162 | 163 | impl std::fmt::Debug for DBGKM_UNLOAD_DLL { 164 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 165 | write!(f, "DBGKM_UNLOAD_DLL {{ }}") 166 | } 167 | } 168 | 169 | #[repr(i32)] 170 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 171 | pub enum DBG_STATE { 172 | DbgIdle = 0, 173 | DbgReplyPending = 1, 174 | DbgCreateThreadStateChange = 2, 175 | DbgCreateProcessStateChange = 3, 176 | DbgExitThreadStateChange = 4, 177 | DbgExitProcessStateChange = 5, 178 | DbgExceptionStateChange = 6, 179 | DbgBreakpointStateChange = 7, 180 | DbgSingleStepStateChange = 8, 181 | DbgLoadDllStateChange = 9, 182 | DbgUnloadDllStateChange = 10, 183 | } 184 | 185 | #[repr(C)] 186 | pub struct DBGUI_CREATE_THREAD { 187 | pub HandleToThread: HANDLE, 188 | pub NewThread: DBGKM_CREATE_THREAD, 189 | } 190 | 191 | impl Default for DBGUI_CREATE_THREAD { 192 | fn default() -> Self { 193 | unsafe { std::mem::zeroed() } 194 | } 195 | } 196 | 197 | impl std::fmt::Debug for DBGUI_CREATE_THREAD { 198 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 199 | write!( 200 | f, 201 | "DBGUI_CREATE_THREAD {{ NewThread: {:?} }}", 202 | self.NewThread 203 | ) 204 | } 205 | } 206 | 207 | #[repr(C)] 208 | pub struct DBGUI_CREATE_PROCESS { 209 | pub HandleToProcess: HANDLE, 210 | pub HandleToThread: HANDLE, 211 | pub NewProcess: DBGKM_CREATE_PROCESS, 212 | } 213 | 214 | impl Default for DBGUI_CREATE_PROCESS { 215 | fn default() -> Self { 216 | unsafe { std::mem::zeroed() } 217 | } 218 | } 219 | 220 | impl std::fmt::Debug for DBGUI_CREATE_PROCESS { 221 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 222 | write!( 223 | f, 224 | "DBGUI_CREATE_PROCESS {{ NewProcess: {:?} }}", 225 | self.NewProcess 226 | ) 227 | } 228 | } 229 | 230 | #[repr(C)] 231 | pub struct DBGUI_WAIT_STATE_CHANGE { 232 | pub NewState: DBG_STATE, 233 | pub AppClientId: CLIENT_ID, 234 | pub StateInfo: DBGUI_WAIT_STATE_CHANGE_1, 235 | } 236 | 237 | #[repr(C)] 238 | pub struct DBGUI_WAIT_STATE_CHANGE_1 { 239 | pub Exception: UnionField, 240 | pub CreateThread: UnionField, 241 | pub CreateProcessInfo: UnionField, 242 | pub ExitThread: UnionField, 243 | pub ExitProcess: UnionField, 244 | pub LoadDll: UnionField, 245 | pub UnloadDll: UnionField, 246 | pub union_field: [u64; 20], 247 | } 248 | 249 | impl Default for DBGUI_WAIT_STATE_CHANGE_1 { 250 | fn default() -> Self { 251 | unsafe { std::mem::zeroed() } 252 | } 253 | } 254 | 255 | impl std::fmt::Debug for DBGUI_WAIT_STATE_CHANGE_1 { 256 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 257 | write!(f, "DBGUI_WAIT_STATE_CHANGE_1 {{ union }}") 258 | } 259 | } 260 | 261 | impl Default for DBGUI_WAIT_STATE_CHANGE { 262 | fn default() -> Self { 263 | unsafe { std::mem::zeroed() } 264 | } 265 | } 266 | 267 | impl std::fmt::Debug for DBGUI_WAIT_STATE_CHANGE { 268 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 269 | write!( 270 | f, 271 | "DBGUI_WAIT_STATE_CHANGE {{ NewState: {:?}, StateInfo: {:?} }}", 272 | self.NewState, self.StateInfo 273 | ) 274 | } 275 | } 276 | 277 | #[repr(i32)] 278 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 279 | pub enum DEBUGOBJECTINFOCLASS { 280 | DebugObjectUnusedInformation = 0, 281 | DebugObjectKillProcessOnExitInformation = 1, 282 | MaxDebugObjectInfoClass = 2, 283 | } 284 | 285 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 286 | extern "system" { 287 | pub fn NtCreateDebugObject( 288 | DebugObjectHandle: *mut HANDLE, 289 | DesiredAccess: u32, 290 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 291 | Flags: u32, 292 | ) -> NTSTATUS; 293 | } 294 | 295 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 296 | extern "system" { 297 | pub fn NtDebugActiveProcess(ProcessHandle: HANDLE, DebugObjectHandle: HANDLE) -> NTSTATUS; 298 | } 299 | 300 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 301 | extern "system" { 302 | pub fn NtDebugContinue( 303 | DebugObjectHandle: HANDLE, 304 | ClientId: *mut CLIENT_ID, 305 | ContinueStatus: NTSTATUS, 306 | ) -> NTSTATUS; 307 | } 308 | 309 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 310 | extern "system" { 311 | pub fn NtRemoveProcessDebug(ProcessHandle: HANDLE, DebugObjectHandle: HANDLE) -> NTSTATUS; 312 | } 313 | 314 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 315 | extern "system" { 316 | pub fn NtSetInformationDebugObject( 317 | DebugObjectHandle: HANDLE, 318 | DebugObjectInformationClass: DEBUGOBJECTINFOCLASS, 319 | DebugInformation: *mut std::ffi::c_void, 320 | DebugInformationLength: u32, 321 | ReturnLength: *mut u32, 322 | ) -> NTSTATUS; 323 | } 324 | 325 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 326 | extern "system" { 327 | pub fn NtWaitForDebugEvent( 328 | DebugObjectHandle: HANDLE, 329 | Alertable: BOOLEAN, 330 | Timeout: *mut i64, 331 | WaitStateChange: *mut DBGUI_WAIT_STATE_CHANGE, 332 | ) -> NTSTATUS; 333 | } 334 | 335 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 336 | extern "system" { 337 | pub fn DbgUiConnectToDbg() -> NTSTATUS; 338 | } 339 | 340 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 341 | extern "system" { 342 | pub fn DbgUiGetThreadDebugObject() -> HANDLE; 343 | } 344 | 345 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 346 | extern "system" { 347 | pub fn DbgUiSetThreadDebugObject(DebugObject: HANDLE); 348 | } 349 | 350 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 351 | extern "system" { 352 | pub fn DbgUiWaitStateChange( 353 | StateChange: *mut DBGUI_WAIT_STATE_CHANGE, 354 | Timeout: *mut i64, 355 | ) -> NTSTATUS; 356 | } 357 | 358 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 359 | extern "system" { 360 | pub fn DbgUiContinue(AppClientId: *mut CLIENT_ID, ContinueStatus: NTSTATUS) -> NTSTATUS; 361 | } 362 | 363 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 364 | extern "system" { 365 | pub fn DbgUiStopDebugging(Process: HANDLE) -> NTSTATUS; 366 | } 367 | 368 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 369 | extern "system" { 370 | pub fn DbgUiDebugActiveProcess(Process: HANDLE) -> NTSTATUS; 371 | } 372 | 373 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 374 | extern "system" { 375 | pub fn DbgUiRemoteBreakin(Context: *mut std::ffi::c_void); 376 | } 377 | 378 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 379 | extern "system" { 380 | pub fn DbgUiIssueRemoteBreakin(Process: HANDLE) -> NTSTATUS; 381 | } 382 | 383 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 384 | extern "system" { 385 | pub fn DbgUiConvertStateChangeStructure( 386 | StateChange: *mut DBGUI_WAIT_STATE_CHANGE, 387 | DebugEvent: *mut DEBUG_EVENT, 388 | ) -> NTSTATUS; 389 | } 390 | 391 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 392 | extern "system" { 393 | pub fn DbgUiConvertStateChangeStructureEx( 394 | StateChange: *mut DBGUI_WAIT_STATE_CHANGE, 395 | DebugEvent: *mut DEBUG_EVENT, 396 | ) -> NTSTATUS; 397 | } 398 | 399 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 400 | extern "system" { 401 | pub fn EtwEventRegister( 402 | ProviderId: *const GUID, 403 | EnableCallback: PENABLECALLBACK, 404 | CallbackContext: *mut std::ffi::c_void, 405 | RegHandle: PREGHANDLE, 406 | ) -> NTSTATUS; 407 | } 408 | -------------------------------------------------------------------------------- /src/ntgdi.rs: -------------------------------------------------------------------------------- 1 | use crate::bitfield::{BitfieldUnit, UnionField}; 2 | 3 | pub const GDI_MAX_HANDLE_COUNT: u32 = 65535; 4 | pub const GDI_HANDLE_INDEX_SHIFT: u32 = 0; 5 | pub const GDI_HANDLE_INDEX_BITS: u32 = 16; 6 | pub const GDI_HANDLE_INDEX_MASK: u32 = 65535; 7 | pub const GDI_HANDLE_TYPE_SHIFT: u32 = 16; 8 | pub const GDI_HANDLE_TYPE_BITS: u32 = 5; 9 | pub const GDI_HANDLE_TYPE_MASK: u32 = 31; 10 | pub const GDI_HANDLE_ALTTYPE_SHIFT: u32 = 21; 11 | pub const GDI_HANDLE_ALTTYPE_BITS: u32 = 2; 12 | pub const GDI_HANDLE_ALTTYPE_MASK: u32 = 3; 13 | pub const GDI_HANDLE_STOCK_SHIFT: u32 = 23; 14 | pub const GDI_HANDLE_STOCK_BITS: u32 = 1; 15 | pub const GDI_HANDLE_STOCK_MASK: u32 = 1; 16 | pub const GDI_HANDLE_UNIQUE_SHIFT: u32 = 24; 17 | pub const GDI_HANDLE_UNIQUE_BITS: u32 = 8; 18 | pub const GDI_HANDLE_UNIQUE_MASK: u32 = 255; 19 | pub const GDI_DEF_TYPE: u32 = 0; 20 | pub const GDI_DC_TYPE: u32 = 1; 21 | pub const GDI_DD_DIRECTDRAW_TYPE: u32 = 2; 22 | pub const GDI_DD_SURFACE_TYPE: u32 = 3; 23 | pub const GDI_RGN_TYPE: u32 = 4; 24 | pub const GDI_SURF_TYPE: u32 = 5; 25 | pub const GDI_CLIENTOBJ_TYPE: u32 = 6; 26 | pub const GDI_PATH_TYPE: u32 = 7; 27 | pub const GDI_PAL_TYPE: u32 = 8; 28 | pub const GDI_ICMLCS_TYPE: u32 = 9; 29 | pub const GDI_LFONT_TYPE: u32 = 10; 30 | pub const GDI_RFONT_TYPE: u32 = 11; 31 | pub const GDI_PFE_TYPE: u32 = 12; 32 | pub const GDI_PFT_TYPE: u32 = 13; 33 | pub const GDI_ICMCXF_TYPE: u32 = 14; 34 | pub const GDI_ICMDLL_TYPE: u32 = 15; 35 | pub const GDI_BRUSH_TYPE: u32 = 16; 36 | pub const GDI_PFF_TYPE: u32 = 17; 37 | pub const GDI_CACHE_TYPE: u32 = 18; 38 | pub const GDI_SPACE_TYPE: u32 = 19; 39 | pub const GDI_DBRUSH_TYPE: u32 = 20; 40 | pub const GDI_META_TYPE: u32 = 21; 41 | pub const GDI_EFSTATE_TYPE: u32 = 22; 42 | pub const GDI_BMFD_TYPE: u32 = 23; 43 | pub const GDI_VTFD_TYPE: u32 = 24; 44 | pub const GDI_TTFD_TYPE: u32 = 25; 45 | pub const GDI_RC_TYPE: u32 = 26; 46 | pub const GDI_TEMP_TYPE: u32 = 27; 47 | pub const GDI_DRVOBJ_TYPE: u32 = 28; 48 | pub const GDI_DCIOBJ_TYPE: u32 = 29; 49 | pub const GDI_SPOOL_TYPE: u32 = 30; 50 | pub const GDI_ALTTYPE_1: u32 = 2097152; 51 | pub const GDI_ALTTYPE_2: u32 = 4194304; 52 | pub const GDI_ALTTYPE_3: u32 = 6291456; 53 | pub const GDI_CLIENT_BITMAP_TYPE: u32 = 327680; 54 | pub const GDI_CLIENT_BRUSH_TYPE: u32 = 1048576; 55 | pub const GDI_CLIENT_CLIENTOBJ_TYPE: u32 = 393216; 56 | pub const GDI_CLIENT_DC_TYPE: u32 = 65536; 57 | pub const GDI_CLIENT_FONT_TYPE: u32 = 655360; 58 | pub const GDI_CLIENT_PALETTE_TYPE: u32 = 524288; 59 | pub const GDI_CLIENT_REGION_TYPE: u32 = 262144; 60 | pub const GDI_CLIENT_ALTDC_TYPE: u32 = 2162688; 61 | pub const GDI_CLIENT_DIBSECTION_TYPE: u32 = 2424832; 62 | pub const GDI_CLIENT_EXTPEN_TYPE: u32 = 5242880; 63 | pub const GDI_CLIENT_METADC16_TYPE: u32 = 6684672; 64 | pub const GDI_CLIENT_METAFILE_TYPE: u32 = 4587520; 65 | pub const GDI_CLIENT_METAFILE16_TYPE: u32 = 2490368; 66 | pub const GDI_CLIENT_PEN_TYPE: u32 = 3145728; 67 | 68 | #[repr(C)] 69 | pub struct GDI_HANDLE_ENTRY { 70 | pub Anonymous1: GDI_HANDLE_ENTRY_1, 71 | pub Owner: GDI_HANDLE_ENTRY_2, 72 | pub Unique: u16, 73 | pub Type: u8, 74 | pub Flags: u8, 75 | pub UserPointer: *mut std::ffi::c_void, 76 | } 77 | 78 | #[repr(C)] 79 | pub struct GDI_HANDLE_ENTRY_1 { 80 | pub Object: UnionField<*mut std::ffi::c_void>, 81 | pub NextFree: UnionField<*mut std::ffi::c_void>, 82 | pub union_field: u64, 83 | } 84 | 85 | impl Default for GDI_HANDLE_ENTRY_1 { 86 | fn default() -> Self { 87 | unsafe { std::mem::zeroed() } 88 | } 89 | } 90 | 91 | impl std::fmt::Debug for GDI_HANDLE_ENTRY_1 { 92 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 93 | write!(f, "GDI_HANDLE_ENTRY_1 {{ union }}") 94 | } 95 | } 96 | 97 | #[repr(C)] 98 | pub struct GDI_HANDLE_ENTRY_2 { 99 | pub Anonymous1: UnionField, 100 | pub Value: UnionField, 101 | pub union_field: u32, 102 | } 103 | 104 | #[repr(C)] 105 | pub struct GDI_HANDLE_ENTRY_2_1 { 106 | pub ProcessId: u16, 107 | _bitfield_align_1: [u16; 0], 108 | _bitfield_1: BitfieldUnit<[u8; 2]>, 109 | } 110 | 111 | impl Default for GDI_HANDLE_ENTRY_2_1 { 112 | fn default() -> Self { 113 | unsafe { std::mem::zeroed() } 114 | } 115 | } 116 | 117 | impl std::fmt::Debug for GDI_HANDLE_ENTRY_2_1 { 118 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 119 | write!( 120 | f, 121 | "GDI_HANDLE_ENTRY_2_1 {{ Lock : {:?}, Count : {:?} }}", 122 | self.Lock(), 123 | self.Count() 124 | ) 125 | } 126 | } 127 | 128 | impl GDI_HANDLE_ENTRY_2_1 { 129 | #[inline] 130 | pub fn Lock(&self) -> u16 { 131 | self._bitfield_1.get(0usize, 1u8) as u16 132 | } 133 | 134 | #[inline] 135 | pub fn set_Lock(&mut self, val: u16) { 136 | self._bitfield_1.set(0usize, 1u8, val as u64) 137 | } 138 | 139 | #[inline] 140 | pub fn Count(&self) -> u16 { 141 | self._bitfield_1.get(1usize, 15u8) as u16 142 | } 143 | 144 | #[inline] 145 | pub fn set_Count(&mut self, val: u16) { 146 | self._bitfield_1.set(1usize, 15u8, val as u64) 147 | } 148 | 149 | #[inline] 150 | pub fn new_bitfield_1(Lock: u16, Count: u16) -> BitfieldUnit<[u8; 2]> { 151 | let mut bitfield_unit: BitfieldUnit<[u8; 2]> = Default::default(); 152 | 153 | bitfield_unit.set(0usize, 1u8, Lock as u64); 154 | 155 | bitfield_unit.set(1usize, 15u8, Count as u64); 156 | 157 | bitfield_unit 158 | } 159 | } 160 | 161 | impl Default for GDI_HANDLE_ENTRY_2 { 162 | fn default() -> Self { 163 | unsafe { std::mem::zeroed() } 164 | } 165 | } 166 | 167 | impl std::fmt::Debug for GDI_HANDLE_ENTRY_2 { 168 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 169 | write!(f, "GDI_HANDLE_ENTRY_2 {{ union }}") 170 | } 171 | } 172 | 173 | impl Default for GDI_HANDLE_ENTRY { 174 | fn default() -> Self { 175 | unsafe { std::mem::zeroed() } 176 | } 177 | } 178 | 179 | impl std::fmt::Debug for GDI_HANDLE_ENTRY { 180 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 181 | write!( 182 | f, 183 | "GDI_HANDLE_ENTRY {{ Anonymous1: {:?}, Owner: {:?} }}", 184 | self.Anonymous1, self.Owner 185 | ) 186 | } 187 | } 188 | 189 | #[repr(C)] 190 | pub struct GDI_SHARED_MEMORY { 191 | pub Handles: [GDI_HANDLE_ENTRY; 65535], 192 | } 193 | 194 | impl Default for GDI_SHARED_MEMORY { 195 | fn default() -> Self { 196 | unsafe { std::mem::zeroed() } 197 | } 198 | } 199 | 200 | impl std::fmt::Debug for GDI_SHARED_MEMORY { 201 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 202 | write!(f, "GDI_SHARED_MEMORY {{ Handles: {:?} }}", self.Handles) 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/ntimage.rs: -------------------------------------------------------------------------------- 1 | use crate::bitfield::{BitfieldUnit, UnionField}; 2 | 3 | pub const IMAGE_FILE_MACHINE_CHPE_X86: u32 = 14948; 4 | pub const IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL: u32 = 0; 5 | pub const IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE: u32 = 1; 6 | pub const IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA: u32 = 2; 7 | pub const IMAGE_DVRT_ARM64X_FIXUP_SIZE_2BYTES: u32 = 1; 8 | pub const IMAGE_DVRT_ARM64X_FIXUP_SIZE_4BYTES: u32 = 2; 9 | pub const IMAGE_DVRT_ARM64X_FIXUP_SIZE_8BYTES: u32 = 3; 10 | pub const IMAGE_DYNAMIC_RELOCATION_ARM64X: u32 = 6; 11 | pub const IMAGE_DYNAMIC_RELOCATION_MM_SHARED_USER_DATA_VA: u32 = 2147352576; 12 | pub const IMAGE_DEBUG_POGO_SIGNATURE_LTCG: &[u8; 4] = b"LTCG"; 13 | pub const IMAGE_DEBUG_POGO_SIGNATURE_PGU: &[u8; 4] = b"PGU\0"; 14 | pub const IMAGE_DYNAMIC_RELOCATION_KI_USER_SHARED_DATA64: u64 = 18446734727860715520; 15 | 16 | #[repr(C)] 17 | pub struct IMAGE_DEBUG_POGO_ENTRY { 18 | pub Rva: u32, 19 | pub Size: u32, 20 | pub Name: [i8; 1], 21 | } 22 | 23 | impl Default for IMAGE_DEBUG_POGO_ENTRY { 24 | fn default() -> Self { 25 | unsafe { std::mem::zeroed() } 26 | } 27 | } 28 | 29 | impl std::fmt::Debug for IMAGE_DEBUG_POGO_ENTRY { 30 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 31 | write!(f, "IMAGE_DEBUG_POGO_ENTRY {{ Name: {:?} }}", self.Name) 32 | } 33 | } 34 | 35 | #[repr(C)] 36 | pub struct IMAGE_DEBUG_POGO_SIGNATURE { 37 | pub Signature: u32, 38 | } 39 | 40 | impl Default for IMAGE_DEBUG_POGO_SIGNATURE { 41 | fn default() -> Self { 42 | unsafe { std::mem::zeroed() } 43 | } 44 | } 45 | 46 | impl std::fmt::Debug for IMAGE_DEBUG_POGO_SIGNATURE { 47 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 48 | write!(f, "IMAGE_DEBUG_POGO_SIGNATURE {{ }}") 49 | } 50 | } 51 | 52 | #[repr(C)] 53 | #[repr(align(2))] 54 | pub struct IMAGE_RELOCATION_RECORD { 55 | _bitfield_align_1: [u16; 0], 56 | _bitfield_1: BitfieldUnit<[u8; 2]>, 57 | } 58 | 59 | impl Default for IMAGE_RELOCATION_RECORD { 60 | fn default() -> Self { 61 | unsafe { std::mem::zeroed() } 62 | } 63 | } 64 | 65 | impl std::fmt::Debug for IMAGE_RELOCATION_RECORD { 66 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 67 | write!( 68 | f, 69 | "IMAGE_RELOCATION_RECORD {{ Offset : {:?}, Type : {:?} }}", 70 | self.Offset(), 71 | self.Type() 72 | ) 73 | } 74 | } 75 | 76 | impl IMAGE_RELOCATION_RECORD { 77 | #[inline] 78 | pub fn Offset(&self) -> u16 { 79 | self._bitfield_1.get(0usize, 12u8) as u16 80 | } 81 | 82 | #[inline] 83 | pub fn set_Offset(&mut self, val: u16) { 84 | self._bitfield_1.set(0usize, 12u8, val as u64) 85 | } 86 | 87 | #[inline] 88 | pub fn Type(&self) -> u16 { 89 | self._bitfield_1.get(12usize, 4u8) as u16 90 | } 91 | 92 | #[inline] 93 | pub fn set_Type(&mut self, val: u16) { 94 | self._bitfield_1.set(12usize, 4u8, val as u64) 95 | } 96 | 97 | #[inline] 98 | pub fn new_bitfield_1(Offset: u16, Type: u16) -> BitfieldUnit<[u8; 2]> { 99 | let mut bitfield_unit: BitfieldUnit<[u8; 2]> = Default::default(); 100 | 101 | bitfield_unit.set(0usize, 12u8, Offset as u64); 102 | 103 | bitfield_unit.set(12usize, 4u8, Type as u64); 104 | 105 | bitfield_unit 106 | } 107 | } 108 | 109 | #[repr(C)] 110 | pub struct IMAGE_CHPE_METADATA_X86 { 111 | pub Version: u32, 112 | pub CHPECodeAddressRangeOffset: u32, 113 | pub CHPECodeAddressRangeCount: u32, 114 | pub WowA64ExceptionHandlerFunctionPointer: u32, 115 | pub WowA64DispatchCallFunctionPointer: u32, 116 | pub WowA64DispatchIndirectCallFunctionPointer: u32, 117 | pub WowA64DispatchIndirectCallCfgFunctionPointer: u32, 118 | pub WowA64DispatchRetFunctionPointer: u32, 119 | pub WowA64DispatchRetLeafFunctionPointer: u32, 120 | pub WowA64DispatchJumpFunctionPointer: u32, 121 | pub CompilerIATPointer: u32, 122 | pub WowA64RdtscFunctionPointer: u32, 123 | } 124 | 125 | impl Default for IMAGE_CHPE_METADATA_X86 { 126 | fn default() -> Self { 127 | unsafe { std::mem::zeroed() } 128 | } 129 | } 130 | 131 | impl std::fmt::Debug for IMAGE_CHPE_METADATA_X86 { 132 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 133 | write!(f, "IMAGE_CHPE_METADATA_X86 {{ }}") 134 | } 135 | } 136 | 137 | #[repr(C)] 138 | pub struct IMAGE_CHPE_RANGE_ENTRY { 139 | pub Anonymous1: IMAGE_CHPE_RANGE_ENTRY_1, 140 | pub Length: u32, 141 | } 142 | 143 | #[repr(C)] 144 | pub struct IMAGE_CHPE_RANGE_ENTRY_1 { 145 | pub StartOffset: UnionField, 146 | pub Anonymous1: UnionField, 147 | pub union_field: u32, 148 | } 149 | 150 | #[repr(C)] 151 | #[repr(align(4))] 152 | pub struct IMAGE_CHPE_RANGE_ENTRY_1_1 { 153 | _bitfield_align_1: [u32; 0], 154 | _bitfield_1: BitfieldUnit<[u8; 4]>, 155 | } 156 | 157 | impl Default for IMAGE_CHPE_RANGE_ENTRY_1_1 { 158 | fn default() -> Self { 159 | unsafe { std::mem::zeroed() } 160 | } 161 | } 162 | 163 | impl std::fmt::Debug for IMAGE_CHPE_RANGE_ENTRY_1_1 { 164 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 165 | write!( 166 | f, 167 | "IMAGE_CHPE_RANGE_ENTRY_1_1 {{ NativeCode : {:?}, AddressBits : {:?} }}", 168 | self.NativeCode(), 169 | self.AddressBits() 170 | ) 171 | } 172 | } 173 | 174 | impl IMAGE_CHPE_RANGE_ENTRY_1_1 { 175 | #[inline] 176 | pub fn NativeCode(&self) -> u32 { 177 | self._bitfield_1.get(0usize, 1u8) as u32 178 | } 179 | 180 | #[inline] 181 | pub fn set_NativeCode(&mut self, val: u32) { 182 | self._bitfield_1.set(0usize, 1u8, val as u64) 183 | } 184 | 185 | #[inline] 186 | pub fn AddressBits(&self) -> u32 { 187 | self._bitfield_1.get(1usize, 31u8) as u32 188 | } 189 | 190 | #[inline] 191 | pub fn set_AddressBits(&mut self, val: u32) { 192 | self._bitfield_1.set(1usize, 31u8, val as u64) 193 | } 194 | 195 | #[inline] 196 | pub fn new_bitfield_1(NativeCode: u32, AddressBits: u32) -> BitfieldUnit<[u8; 4]> { 197 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 198 | 199 | bitfield_unit.set(0usize, 1u8, NativeCode as u64); 200 | 201 | bitfield_unit.set(1usize, 31u8, AddressBits as u64); 202 | 203 | bitfield_unit 204 | } 205 | } 206 | 207 | impl Default for IMAGE_CHPE_RANGE_ENTRY_1 { 208 | fn default() -> Self { 209 | unsafe { std::mem::zeroed() } 210 | } 211 | } 212 | 213 | impl std::fmt::Debug for IMAGE_CHPE_RANGE_ENTRY_1 { 214 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 215 | write!(f, "IMAGE_CHPE_RANGE_ENTRY_1 {{ union }}") 216 | } 217 | } 218 | 219 | impl Default for IMAGE_CHPE_RANGE_ENTRY { 220 | fn default() -> Self { 221 | unsafe { std::mem::zeroed() } 222 | } 223 | } 224 | 225 | impl std::fmt::Debug for IMAGE_CHPE_RANGE_ENTRY { 226 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 227 | write!( 228 | f, 229 | "IMAGE_CHPE_RANGE_ENTRY {{ Anonymous1: {:?} }}", 230 | self.Anonymous1 231 | ) 232 | } 233 | } 234 | 235 | #[repr(C)] 236 | pub struct IMAGE_ARM64EC_METADATA { 237 | pub Version: u32, 238 | pub CodeMap: u32, 239 | pub CodeMapCount: u32, 240 | pub CodeRangesToEntryPoints: u32, 241 | pub RedirectionMetadata: u32, 242 | pub tbd__os_arm64x_dispatch_call_no_redirect: u32, 243 | pub tbd__os_arm64x_dispatch_ret: u32, 244 | pub tbd__os_arm64x_dispatch_call: u32, 245 | pub tbd__os_arm64x_dispatch_icall: u32, 246 | pub tbd__os_arm64x_dispatch_icall_cfg: u32, 247 | pub AlternateEntryPoint: u32, 248 | pub AuxiliaryIAT: u32, 249 | pub CodeRangesToEntryPointsCount: u32, 250 | pub RedirectionMetadataCount: u32, 251 | pub GetX64InformationFunctionPointer: u32, 252 | pub SetX64InformationFunctionPointer: u32, 253 | pub ExtraRFETable: u32, 254 | pub ExtraRFETableSize: u32, 255 | pub __os_arm64x_dispatch_fptr: u32, 256 | pub AuxiliaryIATCopy: u32, 257 | } 258 | 259 | impl Default for IMAGE_ARM64EC_METADATA { 260 | fn default() -> Self { 261 | unsafe { std::mem::zeroed() } 262 | } 263 | } 264 | 265 | impl std::fmt::Debug for IMAGE_ARM64EC_METADATA { 266 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 267 | write!(f, "IMAGE_ARM64EC_METADATA {{ }}") 268 | } 269 | } 270 | 271 | #[repr(C)] 272 | pub struct IMAGE_ARM64EC_REDIRECTION_ENTRY { 273 | pub Source: u32, 274 | pub Destination: u32, 275 | } 276 | 277 | impl Default for IMAGE_ARM64EC_REDIRECTION_ENTRY { 278 | fn default() -> Self { 279 | unsafe { std::mem::zeroed() } 280 | } 281 | } 282 | 283 | impl std::fmt::Debug for IMAGE_ARM64EC_REDIRECTION_ENTRY { 284 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 285 | write!(f, "IMAGE_ARM64EC_REDIRECTION_ENTRY {{ }}") 286 | } 287 | } 288 | 289 | #[repr(C)] 290 | pub struct IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT { 291 | pub StartRva: u32, 292 | pub EndRva: u32, 293 | pub EntryPoint: u32, 294 | } 295 | 296 | impl Default for IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT { 297 | fn default() -> Self { 298 | unsafe { std::mem::zeroed() } 299 | } 300 | } 301 | 302 | impl std::fmt::Debug for IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT { 303 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 304 | write!(f, "IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT {{ }}") 305 | } 306 | } 307 | 308 | #[repr(C)] 309 | #[repr(align(2))] 310 | pub struct IMAGE_DVRT_ARM64X_FIXUP_RECORD { 311 | _bitfield_align_1: [u16; 0], 312 | _bitfield_1: BitfieldUnit<[u8; 2]>, 313 | } 314 | 315 | impl Default for IMAGE_DVRT_ARM64X_FIXUP_RECORD { 316 | fn default() -> Self { 317 | unsafe { std::mem::zeroed() } 318 | } 319 | } 320 | 321 | impl std::fmt::Debug for IMAGE_DVRT_ARM64X_FIXUP_RECORD { 322 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 323 | write!( 324 | f, 325 | "IMAGE_DVRT_ARM64X_FIXUP_RECORD {{ Offset : {:?}, Type : {:?}, Size : {:?} }}", 326 | self.Offset(), 327 | self.Type(), 328 | self.Size() 329 | ) 330 | } 331 | } 332 | 333 | impl IMAGE_DVRT_ARM64X_FIXUP_RECORD { 334 | #[inline] 335 | pub fn Offset(&self) -> u16 { 336 | self._bitfield_1.get(0usize, 12u8) as u16 337 | } 338 | 339 | #[inline] 340 | pub fn set_Offset(&mut self, val: u16) { 341 | self._bitfield_1.set(0usize, 12u8, val as u64) 342 | } 343 | 344 | #[inline] 345 | pub fn Type(&self) -> u16 { 346 | self._bitfield_1.get(12usize, 2u8) as u16 347 | } 348 | 349 | #[inline] 350 | pub fn set_Type(&mut self, val: u16) { 351 | self._bitfield_1.set(12usize, 2u8, val as u64) 352 | } 353 | 354 | #[inline] 355 | pub fn Size(&self) -> u16 { 356 | self._bitfield_1.get(14usize, 2u8) as u16 357 | } 358 | 359 | #[inline] 360 | pub fn set_Size(&mut self, val: u16) { 361 | self._bitfield_1.set(14usize, 2u8, val as u64) 362 | } 363 | 364 | #[inline] 365 | pub fn new_bitfield_1(Offset: u16, Type: u16, Size: u16) -> BitfieldUnit<[u8; 2]> { 366 | let mut bitfield_unit: BitfieldUnit<[u8; 2]> = Default::default(); 367 | 368 | bitfield_unit.set(0usize, 12u8, Offset as u64); 369 | 370 | bitfield_unit.set(12usize, 2u8, Type as u64); 371 | 372 | bitfield_unit.set(14usize, 2u8, Size as u64); 373 | 374 | bitfield_unit 375 | } 376 | } 377 | 378 | #[repr(C)] 379 | #[repr(align(2))] 380 | pub struct IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { 381 | _bitfield_align_1: [u16; 0], 382 | _bitfield_1: BitfieldUnit<[u8; 2]>, 383 | } 384 | 385 | impl Default for IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { 386 | fn default() -> Self { 387 | unsafe { std::mem::zeroed() } 388 | } 389 | } 390 | 391 | impl std::fmt::Debug for IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { 392 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 393 | write!( 394 | f, 395 | "IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD {{ Offset : {:?}, Type : {:?}, Sign : {:?}, Scale : {:?} }}", 396 | self.Offset(), 397 | self.Type(), 398 | self.Sign(), 399 | self.Scale() 400 | ) 401 | } 402 | } 403 | 404 | impl IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { 405 | #[inline] 406 | pub fn Offset(&self) -> u16 { 407 | self._bitfield_1.get(0usize, 12u8) as u16 408 | } 409 | 410 | #[inline] 411 | pub fn set_Offset(&mut self, val: u16) { 412 | self._bitfield_1.set(0usize, 12u8, val as u64) 413 | } 414 | 415 | #[inline] 416 | pub fn Type(&self) -> u16 { 417 | self._bitfield_1.get(12usize, 2u8) as u16 418 | } 419 | 420 | #[inline] 421 | pub fn set_Type(&mut self, val: u16) { 422 | self._bitfield_1.set(12usize, 2u8, val as u64) 423 | } 424 | 425 | #[inline] 426 | pub fn Sign(&self) -> u16 { 427 | self._bitfield_1.get(14usize, 1u8) as u16 428 | } 429 | 430 | #[inline] 431 | pub fn set_Sign(&mut self, val: u16) { 432 | self._bitfield_1.set(14usize, 1u8, val as u64) 433 | } 434 | 435 | #[inline] 436 | pub fn Scale(&self) -> u16 { 437 | self._bitfield_1.get(15usize, 1u8) as u16 438 | } 439 | 440 | #[inline] 441 | pub fn set_Scale(&mut self, val: u16) { 442 | self._bitfield_1.set(15usize, 1u8, val as u64) 443 | } 444 | 445 | #[inline] 446 | pub fn new_bitfield_1(Offset: u16, Type: u16, Sign: u16, Scale: u16) -> BitfieldUnit<[u8; 2]> { 447 | let mut bitfield_unit: BitfieldUnit<[u8; 2]> = Default::default(); 448 | 449 | bitfield_unit.set(0usize, 12u8, Offset as u64); 450 | 451 | bitfield_unit.set(12usize, 2u8, Type as u64); 452 | 453 | bitfield_unit.set(14usize, 1u8, Sign as u64); 454 | 455 | bitfield_unit.set(15usize, 1u8, Scale as u64); 456 | 457 | bitfield_unit 458 | } 459 | } 460 | -------------------------------------------------------------------------------- /src/ntkeapi.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::{BOOLEAN, NTSTATUS}; 2 | 3 | #[repr(i32)] 4 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 5 | pub enum KTHREAD_STATE { 6 | Initialized = 0, 7 | Ready = 1, 8 | Running = 2, 9 | Standby = 3, 10 | Terminated = 4, 11 | Waiting = 5, 12 | Transition = 6, 13 | DeferredReady = 7, 14 | GateWaitObsolete = 8, 15 | WaitingForProcessInSwap = 9, 16 | MaximumThreadState = 10, 17 | } 18 | 19 | impl KHETERO_CPU_POLICY {} 20 | 21 | #[repr(i32)] 22 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 23 | pub enum KHETERO_CPU_POLICY { 24 | KHeteroCpuPolicyAll = 0, 25 | KHeteroCpuPolicyLarge = 1, 26 | KHeteroCpuPolicyLargeOrIdle = 2, 27 | KHeteroCpuPolicySmall = 3, 28 | KHeteroCpuPolicySmallOrIdle = 4, 29 | KHeteroCpuPolicyDynamic = 5, 30 | KHeteroCpuPolicyBiasedSmall = 6, 31 | KHeteroCpuPolicyBiasedLarge = 7, 32 | KHeteroCpuPolicyDefault = 8, 33 | KHeteroCpuPolicyMax = 9, 34 | } 35 | 36 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 37 | extern "system" { 38 | pub fn NtCallbackReturn( 39 | OutputBuffer: *mut std::ffi::c_void, 40 | OutputLength: u32, 41 | Status: NTSTATUS, 42 | ) -> NTSTATUS; 43 | } 44 | 45 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 46 | extern "system" { 47 | pub fn NtFlushProcessWriteBuffers() -> NTSTATUS; 48 | } 49 | 50 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 51 | extern "system" { 52 | pub fn NtQueryDebugFilterState(ComponentId: u32, Level: u32) -> NTSTATUS; 53 | } 54 | 55 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 56 | extern "system" { 57 | pub fn NtSetDebugFilterState(ComponentId: u32, Level: u32, State: BOOLEAN) -> NTSTATUS; 58 | } 59 | 60 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 61 | extern "system" { 62 | pub fn NtYieldExecution() -> NTSTATUS; 63 | } 64 | -------------------------------------------------------------------------------- /src/ntmisc.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::{HANDLE, NTSTATUS}; 2 | 3 | pub const FLT_PORT_ALL_ACCESS: u32 = 2031617; 4 | 5 | #[repr(i32)] 6 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 7 | pub enum VDMSERVICECLASS { 8 | VdmStartExecution = 0, 9 | VdmQueueInterrupt = 1, 10 | VdmDelayInterrupt = 2, 11 | VdmInitialize = 3, 12 | VdmFeatures = 4, 13 | VdmSetInt21Handler = 5, 14 | VdmQueryDir = 6, 15 | VdmPrinterDirectIoOpen = 7, 16 | VdmPrinterDirectIoClose = 8, 17 | VdmPrinterInitialize = 9, 18 | VdmSetLdtEntries = 10, 19 | VdmSetProcessLdtInfo = 11, 20 | VdmAdlibEmulation = 12, 21 | VdmPMCliControl = 13, 22 | VdmQueryVdmProcess = 14, 23 | VdmPreInitialize = 15, 24 | } 25 | 26 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 27 | extern "system" { 28 | pub fn NtVdmControl(Service: VDMSERVICECLASS, ServiceData: *mut std::ffi::c_void) -> NTSTATUS; 29 | } 30 | 31 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 32 | extern "system" { 33 | pub fn NtTraceEvent( 34 | TraceHandle: HANDLE, 35 | Flags: u32, 36 | FieldSize: u32, 37 | Fields: *mut std::ffi::c_void, 38 | ) -> NTSTATUS; 39 | } 40 | 41 | #[repr(i32)] 42 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 43 | pub enum TRACE_CONTROL_INFORMATION_CLASS { 44 | TraceControlStartLogger = 1, 45 | TraceControlStopLogger = 2, 46 | TraceControlQueryLogger = 3, 47 | TraceControlUpdateLogger = 4, 48 | TraceControlFlushLogger = 5, 49 | TraceControlIncrementLoggerFile = 6, 50 | TraceControlUnknown = 7, 51 | TraceControlRealtimeConnect = 11, 52 | TraceControlActivityIdCreate = 12, 53 | TraceControlWdiDispatchControl = 13, 54 | TraceControlRealtimeDisconnectConsumerByHandle = 14, 55 | TraceControlRegisterGuidsCode = 15, 56 | TraceControlReceiveNotification = 16, 57 | TraceControlSendDataBlock = 17, 58 | TraceControlSendReplyDataBlock = 18, 59 | TraceControlReceiveReplyDataBlock = 19, 60 | TraceControlWdiUpdateSem = 20, 61 | TraceControlEnumTraceGuidList = 21, 62 | TraceControlGetTraceGuidInfo = 22, 63 | TraceControlEnumerateTraceGuids = 23, 64 | TraceControlRegisterSecurityProv = 24, 65 | TraceControlQueryReferenceTime = 25, 66 | TraceControlTrackProviderBinary = 26, 67 | TraceControlAddNotificationEvent = 27, 68 | TraceControlUpdateDisallowList = 28, 69 | TraceControlSetEnableAllKeywordsCode = 29, 70 | TraceControlSetProviderTraitsCode = 30, 71 | TraceControlUseDescriptorTypeCode = 31, 72 | TraceControlEnumTraceGroupList = 32, 73 | TraceControlGetTraceGroupInfo = 33, 74 | TraceControlGetDisallowList = 34, 75 | TraceControlSetCompressionSettings = 35, 76 | TraceControlGetCompressionSettings = 36, 77 | TraceControlUpdatePeriodicCaptureState = 37, 78 | TraceControlGetPrivateSessionTraceHandle = 38, 79 | TraceControlRegisterPrivateSession = 39, 80 | TraceControlQuerySessionDemuxObject = 40, 81 | TraceControlSetProviderBinaryTracking = 41, 82 | TraceControlMaxLoggers = 42, 83 | TraceControlMaxPmcCounter = 43, 84 | TraceControlQueryUsedProcessorCount = 44, 85 | TraceControlGetPmcOwnership = 45, 86 | } 87 | 88 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 89 | extern "system" { 90 | pub fn NtTraceControl( 91 | TraceInformationClass: TRACE_CONTROL_INFORMATION_CLASS, 92 | InputBuffer: *mut std::ffi::c_void, 93 | InputBufferLength: u32, 94 | TraceInformation: *mut std::ffi::c_void, 95 | TraceInformationLength: u32, 96 | ReturnLength: *mut u32, 97 | ) -> NTSTATUS; 98 | } 99 | -------------------------------------------------------------------------------- /src/ntnls.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::BOOLEAN; 2 | 3 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 4 | extern "system" { 5 | 6 | pub static mut NlsAnsiCodePage: u16; 7 | } 8 | 9 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 10 | extern "system" { 11 | 12 | pub static mut NlsMbCodePageTag: BOOLEAN; 13 | } 14 | 15 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 16 | extern "system" { 17 | 18 | pub static mut NlsMbOemCodePageTag: BOOLEAN; 19 | } 20 | -------------------------------------------------------------------------------- /src/ntobapi.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | Wdk::Foundation::{OBJECT_ATTRIBUTES, OBJECT_INFORMATION_CLASS}, 3 | Win32::{ 4 | Foundation::{BOOLEAN, HANDLE, NTSTATUS, UNICODE_STRING}, 5 | Security::GENERIC_MAPPING, 6 | System::Kernel::WAIT_TYPE, 7 | }, 8 | }; 9 | 10 | use crate::bitfield::{BitfieldUnit, UnionField}; 11 | 12 | pub const OBJ_PROTECT_CLOSE: u32 = 1; 13 | pub const OBJ_AUDIT_OBJECT_CLOSE: u32 = 4; 14 | pub const OBJECT_TYPE_ALL_ACCESS: u32 = 983041; 15 | pub const DIRECTORY_ALL_ACCESS: u32 = 983055; 16 | pub const SYMBOLIC_LINK_ALL_ACCESS: u32 = 983041; 17 | pub const SYMBOLIC_LINK_ALL_ACCESS_EX: u32 = 1048575; 18 | pub const OBJECT_BOUNDARY_DESCRIPTOR_VERSION: u32 = 1; 19 | pub const ObjectNameInformation: u32 = 1; 20 | pub const ObjectTypesInformation: u32 = 3; 21 | pub const ObjectHandleFlagInformation: u32 = 4; 22 | pub const ObjectSessionInformation: u32 = 5; 23 | pub const ObjectSessionObjectInformation: u32 = 6; 24 | 25 | #[repr(C)] 26 | pub struct OBJECT_BASIC_INFORMATION { 27 | pub Attributes: u32, 28 | pub GrantedAccess: u32, 29 | pub HandleCount: u32, 30 | pub PointerCount: u32, 31 | pub PagedPoolCharge: u32, 32 | pub NonPagedPoolCharge: u32, 33 | pub Reserved: [u32; 3], 34 | pub NameInfoSize: u32, 35 | pub TypeInfoSize: u32, 36 | pub SecurityDescriptorSize: u32, 37 | pub CreationTime: i64, 38 | } 39 | 40 | impl Default for OBJECT_BASIC_INFORMATION { 41 | fn default() -> Self { 42 | unsafe { std::mem::zeroed() } 43 | } 44 | } 45 | 46 | impl std::fmt::Debug for OBJECT_BASIC_INFORMATION { 47 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 48 | write!( 49 | f, 50 | "OBJECT_BASIC_INFORMATION {{ Reserved: {:?} }}", 51 | self.Reserved 52 | ) 53 | } 54 | } 55 | 56 | #[repr(C)] 57 | pub struct OBJECT_TYPE_INFORMATION { 58 | pub TypeName: UNICODE_STRING, 59 | pub TotalNumberOfObjects: u32, 60 | pub TotalNumberOfHandles: u32, 61 | pub TotalPagedPoolUsage: u32, 62 | pub TotalNonPagedPoolUsage: u32, 63 | pub TotalNamePoolUsage: u32, 64 | pub TotalHandleTableUsage: u32, 65 | pub HighWaterNumberOfObjects: u32, 66 | pub HighWaterNumberOfHandles: u32, 67 | pub HighWaterPagedPoolUsage: u32, 68 | pub HighWaterNonPagedPoolUsage: u32, 69 | pub HighWaterNamePoolUsage: u32, 70 | pub HighWaterHandleTableUsage: u32, 71 | pub InvalidAttributes: u32, 72 | pub GenericMapping: GENERIC_MAPPING, 73 | pub ValidAccessMask: u32, 74 | pub SecurityRequired: BOOLEAN, 75 | pub MaintainHandleCount: BOOLEAN, 76 | pub TypeIndex: u8, 77 | pub ReservedByte: i8, 78 | pub PoolType: u32, 79 | pub DefaultPagedPoolCharge: u32, 80 | pub DefaultNonPagedPoolCharge: u32, 81 | } 82 | 83 | impl Default for OBJECT_TYPE_INFORMATION { 84 | fn default() -> Self { 85 | unsafe { std::mem::zeroed() } 86 | } 87 | } 88 | 89 | impl std::fmt::Debug for OBJECT_TYPE_INFORMATION { 90 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 91 | write!(f, "OBJECT_TYPE_INFORMATION {{ }}") 92 | } 93 | } 94 | 95 | #[repr(C)] 96 | pub struct OBJECT_TYPES_INFORMATION { 97 | pub NumberOfTypes: u32, 98 | } 99 | 100 | impl Default for OBJECT_TYPES_INFORMATION { 101 | fn default() -> Self { 102 | unsafe { std::mem::zeroed() } 103 | } 104 | } 105 | 106 | impl std::fmt::Debug for OBJECT_TYPES_INFORMATION { 107 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 108 | write!(f, "OBJECT_TYPES_INFORMATION {{ }}") 109 | } 110 | } 111 | 112 | #[repr(C)] 113 | pub struct OBJECT_HANDLE_FLAG_INFORMATION { 114 | pub Inherit: BOOLEAN, 115 | pub ProtectFromClose: BOOLEAN, 116 | } 117 | 118 | impl Default for OBJECT_HANDLE_FLAG_INFORMATION { 119 | fn default() -> Self { 120 | unsafe { std::mem::zeroed() } 121 | } 122 | } 123 | 124 | impl std::fmt::Debug for OBJECT_HANDLE_FLAG_INFORMATION { 125 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 126 | write!(f, "OBJECT_HANDLE_FLAG_INFORMATION {{ }}") 127 | } 128 | } 129 | 130 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 131 | extern "system" { 132 | pub fn NtSetInformationObject( 133 | Handle: HANDLE, 134 | ObjectInformationClass: OBJECT_INFORMATION_CLASS, 135 | ObjectInformation: *mut std::ffi::c_void, 136 | ObjectInformationLength: u32, 137 | ) -> NTSTATUS; 138 | } 139 | 140 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 141 | extern "system" { 142 | pub fn NtDuplicateObject( 143 | SourceProcessHandle: HANDLE, 144 | SourceHandle: HANDLE, 145 | TargetProcessHandle: HANDLE, 146 | TargetHandle: *mut HANDLE, 147 | DesiredAccess: u32, 148 | HandleAttributes: u32, 149 | Options: u32, 150 | ) -> NTSTATUS; 151 | } 152 | 153 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 154 | extern "system" { 155 | pub fn NtMakeTemporaryObject(Handle: HANDLE) -> NTSTATUS; 156 | } 157 | 158 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 159 | extern "system" { 160 | pub fn NtMakePermanentObject(Handle: HANDLE) -> NTSTATUS; 161 | } 162 | 163 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 164 | extern "system" { 165 | pub fn NtSignalAndWaitForSingleObject( 166 | SignalHandle: HANDLE, 167 | WaitHandle: HANDLE, 168 | Alertable: BOOLEAN, 169 | Timeout: *mut i64, 170 | ) -> NTSTATUS; 171 | } 172 | 173 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 174 | extern "system" { 175 | pub fn NtWaitForMultipleObjects( 176 | Count: u32, 177 | Handles: *mut HANDLE, 178 | WaitType: WAIT_TYPE, 179 | Alertable: BOOLEAN, 180 | Timeout: *mut i64, 181 | ) -> NTSTATUS; 182 | } 183 | 184 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 185 | extern "system" { 186 | pub fn NtWaitForMultipleObjects32( 187 | Count: u32, 188 | Handles: *mut i32, 189 | WaitType: WAIT_TYPE, 190 | Alertable: BOOLEAN, 191 | Timeout: *mut i64, 192 | ) -> NTSTATUS; 193 | } 194 | 195 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 196 | extern "system" { 197 | pub fn NtCompareObjects(FirstObjectHandle: HANDLE, SecondObjectHandle: HANDLE) -> NTSTATUS; 198 | } 199 | 200 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 201 | extern "system" { 202 | pub fn NtCreateDirectoryObject( 203 | DirectoryHandle: *mut HANDLE, 204 | DesiredAccess: u32, 205 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 206 | ) -> NTSTATUS; 207 | } 208 | 209 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 210 | extern "system" { 211 | pub fn NtCreateDirectoryObjectEx( 212 | DirectoryHandle: *mut HANDLE, 213 | DesiredAccess: u32, 214 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 215 | ShadowDirectoryHandle: HANDLE, 216 | Flags: u32, 217 | ) -> NTSTATUS; 218 | } 219 | 220 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 221 | extern "system" { 222 | pub fn NtOpenDirectoryObject( 223 | DirectoryHandle: *mut HANDLE, 224 | DesiredAccess: u32, 225 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 226 | ) -> NTSTATUS; 227 | } 228 | 229 | #[repr(C)] 230 | pub struct OBJECT_DIRECTORY_INFORMATION { 231 | pub Name: UNICODE_STRING, 232 | pub TypeName: UNICODE_STRING, 233 | } 234 | 235 | impl Default for OBJECT_DIRECTORY_INFORMATION { 236 | fn default() -> Self { 237 | unsafe { std::mem::zeroed() } 238 | } 239 | } 240 | 241 | impl std::fmt::Debug for OBJECT_DIRECTORY_INFORMATION { 242 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 243 | write!(f, "OBJECT_DIRECTORY_INFORMATION {{ }}") 244 | } 245 | } 246 | 247 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 248 | extern "system" { 249 | pub fn NtQueryDirectoryObject( 250 | DirectoryHandle: HANDLE, 251 | Buffer: *mut std::ffi::c_void, 252 | Length: u32, 253 | ReturnSingleEntry: BOOLEAN, 254 | RestartScan: BOOLEAN, 255 | Context: *mut u32, 256 | ReturnLength: *mut u32, 257 | ) -> NTSTATUS; 258 | } 259 | 260 | #[repr(i32)] 261 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 262 | pub enum BOUNDARY_ENTRY_TYPE { 263 | OBNS_Invalid = 0, 264 | OBNS_Name = 1, 265 | OBNS_SID = 2, 266 | OBNS_IL = 3, 267 | } 268 | 269 | #[repr(C)] 270 | pub struct OBJECT_BOUNDARY_ENTRY { 271 | pub EntryType: BOUNDARY_ENTRY_TYPE, 272 | pub EntrySize: u32, 273 | } 274 | 275 | impl Default for OBJECT_BOUNDARY_ENTRY { 276 | fn default() -> Self { 277 | unsafe { std::mem::zeroed() } 278 | } 279 | } 280 | 281 | impl std::fmt::Debug for OBJECT_BOUNDARY_ENTRY { 282 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 283 | write!( 284 | f, 285 | "OBJECT_BOUNDARY_ENTRY {{ EntryType: {:?} }}", 286 | self.EntryType 287 | ) 288 | } 289 | } 290 | 291 | #[repr(C)] 292 | pub struct OBJECT_BOUNDARY_DESCRIPTOR { 293 | pub Version: u32, 294 | pub Items: u32, 295 | pub TotalSize: u32, 296 | pub Anonymous1: OBJECT_BOUNDARY_DESCRIPTOR_1, 297 | } 298 | 299 | #[repr(C)] 300 | pub struct OBJECT_BOUNDARY_DESCRIPTOR_1 { 301 | pub Flags: UnionField, 302 | pub Anonymous1: UnionField, 303 | pub union_field: u32, 304 | } 305 | 306 | #[repr(C)] 307 | #[repr(align(4))] 308 | pub struct OBJECT_BOUNDARY_DESCRIPTOR_1_1 { 309 | _bitfield_align_1: [u32; 0], 310 | _bitfield_1: BitfieldUnit<[u8; 4]>, 311 | } 312 | 313 | impl Default for OBJECT_BOUNDARY_DESCRIPTOR_1_1 { 314 | fn default() -> Self { 315 | unsafe { std::mem::zeroed() } 316 | } 317 | } 318 | 319 | impl std::fmt::Debug for OBJECT_BOUNDARY_DESCRIPTOR_1_1 { 320 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 321 | write!( 322 | f, 323 | "OBJECT_BOUNDARY_DESCRIPTOR_1_1 {{ AddAppContainerSid : {:?}, Reserved : {:?} }}", 324 | self.AddAppContainerSid(), 325 | self.Reserved() 326 | ) 327 | } 328 | } 329 | 330 | impl OBJECT_BOUNDARY_DESCRIPTOR_1_1 { 331 | #[inline] 332 | pub fn AddAppContainerSid(&self) -> u32 { 333 | self._bitfield_1.get(0usize, 1u8) as u32 334 | } 335 | 336 | #[inline] 337 | pub fn set_AddAppContainerSid(&mut self, val: u32) { 338 | self._bitfield_1.set(0usize, 1u8, val as u64) 339 | } 340 | 341 | #[inline] 342 | pub fn Reserved(&self) -> u32 { 343 | self._bitfield_1.get(1usize, 31u8) as u32 344 | } 345 | 346 | #[inline] 347 | pub fn set_Reserved(&mut self, val: u32) { 348 | self._bitfield_1.set(1usize, 31u8, val as u64) 349 | } 350 | 351 | #[inline] 352 | pub fn new_bitfield_1(AddAppContainerSid: u32, Reserved: u32) -> BitfieldUnit<[u8; 4]> { 353 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 354 | 355 | bitfield_unit.set(0usize, 1u8, AddAppContainerSid as u64); 356 | 357 | bitfield_unit.set(1usize, 31u8, Reserved as u64); 358 | 359 | bitfield_unit 360 | } 361 | } 362 | 363 | impl Default for OBJECT_BOUNDARY_DESCRIPTOR_1 { 364 | fn default() -> Self { 365 | unsafe { std::mem::zeroed() } 366 | } 367 | } 368 | 369 | impl std::fmt::Debug for OBJECT_BOUNDARY_DESCRIPTOR_1 { 370 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 371 | write!(f, "OBJECT_BOUNDARY_DESCRIPTOR_1 {{ union }}") 372 | } 373 | } 374 | 375 | impl Default for OBJECT_BOUNDARY_DESCRIPTOR { 376 | fn default() -> Self { 377 | unsafe { std::mem::zeroed() } 378 | } 379 | } 380 | 381 | impl std::fmt::Debug for OBJECT_BOUNDARY_DESCRIPTOR { 382 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 383 | write!( 384 | f, 385 | "OBJECT_BOUNDARY_DESCRIPTOR {{ Anonymous1: {:?} }}", 386 | self.Anonymous1 387 | ) 388 | } 389 | } 390 | 391 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 392 | extern "system" { 393 | pub fn NtCreatePrivateNamespace( 394 | NamespaceHandle: *mut HANDLE, 395 | DesiredAccess: u32, 396 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 397 | BoundaryDescriptor: *mut OBJECT_BOUNDARY_DESCRIPTOR, 398 | ) -> NTSTATUS; 399 | } 400 | 401 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 402 | extern "system" { 403 | pub fn NtOpenPrivateNamespace( 404 | NamespaceHandle: *mut HANDLE, 405 | DesiredAccess: u32, 406 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 407 | BoundaryDescriptor: *mut OBJECT_BOUNDARY_DESCRIPTOR, 408 | ) -> NTSTATUS; 409 | } 410 | 411 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 412 | extern "system" { 413 | pub fn NtDeletePrivateNamespace(NamespaceHandle: HANDLE) -> NTSTATUS; 414 | } 415 | 416 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 417 | extern "system" { 418 | pub fn NtCreateSymbolicLinkObject( 419 | LinkHandle: *mut HANDLE, 420 | DesiredAccess: u32, 421 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 422 | LinkTarget: *mut UNICODE_STRING, 423 | ) -> NTSTATUS; 424 | } 425 | 426 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 427 | extern "system" { 428 | pub fn NtOpenSymbolicLinkObject( 429 | LinkHandle: *mut HANDLE, 430 | DesiredAccess: u32, 431 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 432 | ) -> NTSTATUS; 433 | } 434 | 435 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 436 | extern "system" { 437 | pub fn NtQuerySymbolicLinkObject( 438 | LinkHandle: HANDLE, 439 | LinkTarget: *mut UNICODE_STRING, 440 | ReturnedLength: *mut u32, 441 | ) -> NTSTATUS; 442 | } 443 | 444 | #[repr(i32)] 445 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 446 | pub enum SYMBOLIC_LINK_INFO_CLASS { 447 | SymbolicLinkGlobalInformation = 1, 448 | SymbolicLinkAccessMask = 2, 449 | MaxnSymbolicLinkInfoClass = 3, 450 | } 451 | 452 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 453 | extern "system" { 454 | pub fn NtSetInformationSymbolicLink( 455 | LinkHandle: HANDLE, 456 | SymbolicLinkInformationClass: SYMBOLIC_LINK_INFO_CLASS, 457 | SymbolicLinkInformation: *mut std::ffi::c_void, 458 | SymbolicLinkInformationLength: u32, 459 | ) -> NTSTATUS; 460 | } 461 | -------------------------------------------------------------------------------- /src/ntpfapi.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::HANDLE; 2 | 3 | use crate::{ 4 | bitfield::{BitfieldUnit, UnionField}, 5 | ntexapi::SYSTEM_MEMORY_LIST_INFORMATION, 6 | ntmmapi::MMPFN_IDENTITY, 7 | }; 8 | 9 | pub const PF_BOOT_CONTROL_VERSION: u32 = 1; 10 | pub const PREFETCHER_INFORMATION_VERSION: u32 = 23; 11 | pub const PF_PFN_PRIO_REQUEST_VERSION: u32 = 1; 12 | pub const PF_PFN_PRIO_REQUEST_QUERY_MEMORY_LIST: u32 = 1; 13 | pub const PF_PFN_PRIO_REQUEST_VALID_FLAGS: u32 = 1; 14 | pub const PF_PRIVSOURCE_QUERY_REQUEST_VERSION: u32 = 8; 15 | pub const PF_PRIVSOURCE_QUERY_REQUEST_FLAGS_QUERYWSPAGES: u32 = 1; 16 | pub const PF_PRIVSOURCE_QUERY_REQUEST_FLAGS_QUERYCOMPRESSEDPAGES: u32 = 2; 17 | pub const PF_PRIVSOURCE_QUERY_REQUEST_FLAGS_QUERYSKIPPAGES: u32 = 4; 18 | pub const PF_SCENARIO_PHASE_INFO_VERSION: u32 = 4; 19 | pub const PF_ROBUSTNESS_CONTROL_VERSION: u32 = 1; 20 | pub const PF_MEMORY_LIST_INFO_VERSION: u32 = 1; 21 | pub const PF_PHYSICAL_MEMORY_RANGE_INFO_V1_VERSION: u32 = 1; 22 | pub const PF_PHYSICAL_MEMORY_RANGE_INFO_V2_VERSION: u32 = 2; 23 | pub const PF_REPURPOSED_BY_PREFETCH_INFO_VERSION: u32 = 1; 24 | pub const PF_VIRTUAL_QUERY_VERSION: u32 = 1; 25 | pub const PF_MIN_WS_AGE_RATE_CONTROL_VERSION: u32 = 1; 26 | pub const PF_DEPRIORITIZE_OLD_PAGES_VERSION: u32 = 3; 27 | pub const PF_GPU_UTILIZATION_INFO_VERSION: u32 = 1; 28 | pub const SUPERFETCH_INFORMATION_VERSION: u32 = 45; 29 | pub const PREFETCHER_INFORMATION_MAGIC: &[u8; 4] = b"kuhC"; 30 | pub const SUPERFETCH_INFORMATION_MAGIC: &[u8; 4] = b"kuhC"; 31 | 32 | #[repr(i32)] 33 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 34 | pub enum PF_BOOT_PHASE_ID { 35 | PfKernelInitPhase = 0, 36 | PfBootDriverInitPhase = 90, 37 | PfSystemDriverInitPhase = 120, 38 | PfSessionManagerInitPhase = 150, 39 | PfSMRegistryInitPhase = 180, 40 | PfVideoInitPhase = 210, 41 | PfPostVideoInitPhase = 240, 42 | PfBootAcceptedRegistryInitPhase = 270, 43 | PfUserShellReadyPhase = 300, 44 | PfMaxBootPhaseId = 900, 45 | } 46 | 47 | #[repr(i32)] 48 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 49 | pub enum PF_ENABLE_STATUS { 50 | PfSvNotSpecified = 0, 51 | PfSvEnabled = 1, 52 | PfSvDisabled = 2, 53 | PfSvMaxEnableStatus = 3, 54 | } 55 | 56 | #[repr(C)] 57 | pub struct PF_TRACE_LIMITS { 58 | pub MaxNumPages: u32, 59 | pub MaxNumSections: u32, 60 | pub TimerPeriod: i64, 61 | } 62 | 63 | impl Default for PF_TRACE_LIMITS { 64 | fn default() -> Self { 65 | unsafe { std::mem::zeroed() } 66 | } 67 | } 68 | 69 | impl std::fmt::Debug for PF_TRACE_LIMITS { 70 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 71 | write!(f, "PF_TRACE_LIMITS {{ }}") 72 | } 73 | } 74 | 75 | #[repr(C)] 76 | pub struct PF_SYSTEM_PREFETCH_PARAMETERS { 77 | pub EnableStatus: [PF_ENABLE_STATUS; 2], 78 | pub TraceLimits: [PF_TRACE_LIMITS; 2], 79 | pub MaxNumActiveTraces: u32, 80 | pub MaxNumSavedTraces: u32, 81 | pub RootDirPath: [u16; 32], 82 | pub HostingApplicationList: [u16; 128], 83 | } 84 | 85 | impl Default for PF_SYSTEM_PREFETCH_PARAMETERS { 86 | fn default() -> Self { 87 | unsafe { std::mem::zeroed() } 88 | } 89 | } 90 | 91 | impl std::fmt::Debug for PF_SYSTEM_PREFETCH_PARAMETERS { 92 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 93 | write!( 94 | f, 95 | "PF_SYSTEM_PREFETCH_PARAMETERS {{ EnableStatus: {:?}, TraceLimits: {:?}, RootDirPath: {:?}, HostingApplicationList: {:?} }}", 96 | self.EnableStatus, self.TraceLimits, self.RootDirPath, self.HostingApplicationList 97 | ) 98 | } 99 | } 100 | 101 | #[repr(C)] 102 | pub struct PF_BOOT_CONTROL { 103 | pub Version: u32, 104 | pub DisableBootPrefetching: u32, 105 | } 106 | 107 | impl Default for PF_BOOT_CONTROL { 108 | fn default() -> Self { 109 | unsafe { std::mem::zeroed() } 110 | } 111 | } 112 | 113 | impl std::fmt::Debug for PF_BOOT_CONTROL { 114 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 115 | write!(f, "PF_BOOT_CONTROL {{ }}") 116 | } 117 | } 118 | 119 | #[repr(i32)] 120 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 121 | pub enum PREFETCHER_INFORMATION_CLASS { 122 | PrefetcherRetrieveTrace = 1, 123 | PrefetcherSystemParameters = 2, 124 | PrefetcherBootPhase = 3, 125 | PrefetcherSpare1 = 4, 126 | PrefetcherBootControl = 5, 127 | PrefetcherScenarioPolicyControl = 6, 128 | PrefetcherSpare2 = 7, 129 | PrefetcherAppLaunchScenarioControl = 8, 130 | PrefetcherInformationMax = 9, 131 | } 132 | 133 | #[repr(C)] 134 | pub struct PREFETCHER_INFORMATION { 135 | pub Version: u32, 136 | pub Magic: u32, 137 | pub PrefetcherInformationClass: PREFETCHER_INFORMATION_CLASS, 138 | pub PrefetcherInformation: *mut std::ffi::c_void, 139 | pub PrefetcherInformationLength: u32, 140 | } 141 | 142 | impl Default for PREFETCHER_INFORMATION { 143 | fn default() -> Self { 144 | unsafe { std::mem::zeroed() } 145 | } 146 | } 147 | 148 | impl std::fmt::Debug for PREFETCHER_INFORMATION { 149 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 150 | write!( 151 | f, 152 | "PREFETCHER_INFORMATION {{ PrefetcherInformationClass: {:?} }}", 153 | self.PrefetcherInformationClass 154 | ) 155 | } 156 | } 157 | 158 | #[repr(C)] 159 | pub struct PF_SYSTEM_SUPERFETCH_PARAMETERS { 160 | pub EnabledComponents: u32, 161 | pub BootID: u32, 162 | pub SavedSectInfoTracesMax: u32, 163 | pub SavedPageAccessTracesMax: u32, 164 | pub ScenarioPrefetchTimeoutStandby: u32, 165 | pub ScenarioPrefetchTimeoutHibernate: u32, 166 | pub ScenarioPrefetchTimeoutHiberBoot: u32, 167 | } 168 | 169 | impl Default for PF_SYSTEM_SUPERFETCH_PARAMETERS { 170 | fn default() -> Self { 171 | unsafe { std::mem::zeroed() } 172 | } 173 | } 174 | 175 | impl std::fmt::Debug for PF_SYSTEM_SUPERFETCH_PARAMETERS { 176 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 177 | write!(f, "PF_SYSTEM_SUPERFETCH_PARAMETERS {{ }}") 178 | } 179 | } 180 | 181 | impl PF_EVENT_TYPE {} 182 | 183 | #[repr(i32)] 184 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 185 | pub enum PF_EVENT_TYPE { 186 | PfEventTypeImageLoad = 0, 187 | PfEventTypeAppLaunch = 1, 188 | PfEventTypeStartTrace = 2, 189 | PfEventTypeEndTrace = 3, 190 | PfEventTypeTimestamp = 4, 191 | PfEventTypeOperation = 5, 192 | PfEventTypeRepurpose = 6, 193 | PfEventTypeForegroundProcess = 7, 194 | PfEventTypeTimeRange = 8, 195 | PfEventTypeUserInput = 9, 196 | PfEventTypeFileAccess = 10, 197 | PfEventTypeUnmap = 11, 198 | PfEventTypeMemInfo = 12, 199 | PfEventTypeFileDelete = 13, 200 | PfEventTypeAppExit = 14, 201 | PfEventTypeSystemTime = 15, 202 | PfEventTypePower = 16, 203 | PfEventTypeSessionChange = 17, 204 | PfEventTypeHardFaultTimeStamp = 18, 205 | PfEventTypeVirtualFree = 19, 206 | PfEventTypePerfInfo = 20, 207 | PfEventTypeProcessSnapshot = 21, 208 | PfEventTypeUserSnapshot = 22, 209 | PfEventTypeStreamSequenceNumber = 23, 210 | PfEventTypeFileTruncate = 24, 211 | PfEventTypeFileRename = 25, 212 | PfEventTypeFileCreate = 26, 213 | PfEventTypeAgCxContext = 27, 214 | PfEventTypePowerAction = 28, 215 | PfEventTypeHardFaultTS = 29, 216 | PfEventTypeRobustInfo = 30, 217 | PfEventTypeFileDefrag = 31, 218 | PfEventTypeMax = 32, 219 | } 220 | 221 | #[repr(C)] 222 | pub struct PF_LOG_EVENT_DATA { 223 | _bitfield_align_1: [u32; 0], 224 | _bitfield_1: BitfieldUnit<[u8; 4]>, 225 | pub EventData: *mut std::ffi::c_void, 226 | } 227 | 228 | impl Default for PF_LOG_EVENT_DATA { 229 | fn default() -> Self { 230 | unsafe { std::mem::zeroed() } 231 | } 232 | } 233 | 234 | impl std::fmt::Debug for PF_LOG_EVENT_DATA { 235 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 236 | write!( 237 | f, 238 | "PF_LOG_EVENT_DATA {{ EventType : {:?}, Flags : {:?}, DataSize : {:?} }}", 239 | self.EventType(), 240 | self.Flags(), 241 | self.DataSize() 242 | ) 243 | } 244 | } 245 | 246 | impl PF_LOG_EVENT_DATA { 247 | #[inline] 248 | pub fn EventType(&self) -> u32 { 249 | self._bitfield_1.get(0usize, 5u8) as u32 250 | } 251 | 252 | #[inline] 253 | pub fn set_EventType(&mut self, val: u32) { 254 | self._bitfield_1.set(0usize, 5u8, val as u64) 255 | } 256 | 257 | #[inline] 258 | pub fn Flags(&self) -> u32 { 259 | self._bitfield_1.get(5usize, 2u8) as u32 260 | } 261 | 262 | #[inline] 263 | pub fn set_Flags(&mut self, val: u32) { 264 | self._bitfield_1.set(5usize, 2u8, val as u64) 265 | } 266 | 267 | #[inline] 268 | pub fn DataSize(&self) -> u32 { 269 | self._bitfield_1.get(7usize, 25u8) as u32 270 | } 271 | 272 | #[inline] 273 | pub fn set_DataSize(&mut self, val: u32) { 274 | self._bitfield_1.set(7usize, 25u8, val as u64) 275 | } 276 | 277 | #[inline] 278 | pub fn new_bitfield_1(EventType: u32, Flags: u32, DataSize: u32) -> BitfieldUnit<[u8; 4]> { 279 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 280 | 281 | bitfield_unit.set(0usize, 5u8, EventType as u64); 282 | 283 | bitfield_unit.set(5usize, 2u8, Flags as u64); 284 | 285 | bitfield_unit.set(7usize, 25u8, DataSize as u64); 286 | 287 | bitfield_unit 288 | } 289 | } 290 | 291 | #[repr(C)] 292 | pub struct PF_PFN_PRIO_REQUEST { 293 | pub Version: u32, 294 | pub RequestFlags: u32, 295 | pub PfnCount: usize, 296 | pub MemInfo: SYSTEM_MEMORY_LIST_INFORMATION, 297 | pub PageData: [MMPFN_IDENTITY; 256], 298 | } 299 | 300 | impl Default for PF_PFN_PRIO_REQUEST { 301 | fn default() -> Self { 302 | unsafe { std::mem::zeroed() } 303 | } 304 | } 305 | 306 | impl std::fmt::Debug for PF_PFN_PRIO_REQUEST { 307 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 308 | write!(f, "PF_PFN_PRIO_REQUEST {{ PageData: {:?} }}", self.PageData) 309 | } 310 | } 311 | 312 | #[repr(i32)] 313 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 314 | pub enum PFS_PRIVATE_PAGE_SOURCE_TYPE { 315 | PfsPrivateSourceKernel = 0, 316 | PfsPrivateSourceSession = 1, 317 | PfsPrivateSourceProcess = 2, 318 | PfsPrivateSourceMax = 3, 319 | } 320 | 321 | #[repr(C)] 322 | pub struct PFS_PRIVATE_PAGE_SOURCE { 323 | pub Type: PFS_PRIVATE_PAGE_SOURCE_TYPE, 324 | pub Anonymous1: PFS_PRIVATE_PAGE_SOURCE_1, 325 | pub ImagePathHash: u32, 326 | pub UniqueProcessHash: usize, 327 | } 328 | 329 | #[repr(C)] 330 | pub struct PFS_PRIVATE_PAGE_SOURCE_1 { 331 | pub SessionId: UnionField, 332 | pub ProcessId: UnionField, 333 | pub union_field: u32, 334 | } 335 | 336 | impl Default for PFS_PRIVATE_PAGE_SOURCE_1 { 337 | fn default() -> Self { 338 | unsafe { std::mem::zeroed() } 339 | } 340 | } 341 | 342 | impl std::fmt::Debug for PFS_PRIVATE_PAGE_SOURCE_1 { 343 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 344 | write!(f, "PFS_PRIVATE_PAGE_SOURCE_1 {{ union }}") 345 | } 346 | } 347 | 348 | impl Default for PFS_PRIVATE_PAGE_SOURCE { 349 | fn default() -> Self { 350 | unsafe { std::mem::zeroed() } 351 | } 352 | } 353 | 354 | impl std::fmt::Debug for PFS_PRIVATE_PAGE_SOURCE { 355 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 356 | write!( 357 | f, 358 | "PFS_PRIVATE_PAGE_SOURCE {{ Type: {:?}, Anonymous1: {:?} }}", 359 | self.Type, self.Anonymous1 360 | ) 361 | } 362 | } 363 | 364 | #[repr(C)] 365 | pub struct PF_PRIVSOURCE_INFO { 366 | pub DbInfo: PFS_PRIVATE_PAGE_SOURCE, 367 | pub EProcess: *mut std::ffi::c_void, 368 | pub WsPrivatePages: usize, 369 | pub TotalPrivatePages: usize, 370 | pub SessionID: u32, 371 | pub ImageName: [i8; 16], 372 | pub Anonymous1: PF_PRIVSOURCE_INFO_1, 373 | pub WsTotalPages: usize, 374 | pub DeepFreezeTimeMs: u32, 375 | _bitfield_align_1: [u32; 0], 376 | _bitfield_1: BitfieldUnit<[u8; 4]>, 377 | } 378 | 379 | #[repr(C)] 380 | pub struct PF_PRIVSOURCE_INFO_1 { 381 | pub WsSwapPages: UnionField, 382 | pub SessionPagedPoolPages: UnionField, 383 | pub StoreSizePages: UnionField, 384 | pub union_field: u64, 385 | } 386 | 387 | impl Default for PF_PRIVSOURCE_INFO_1 { 388 | fn default() -> Self { 389 | unsafe { std::mem::zeroed() } 390 | } 391 | } 392 | 393 | impl std::fmt::Debug for PF_PRIVSOURCE_INFO_1 { 394 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 395 | write!(f, "PF_PRIVSOURCE_INFO_1 {{ union }}") 396 | } 397 | } 398 | 399 | impl Default for PF_PRIVSOURCE_INFO { 400 | fn default() -> Self { 401 | unsafe { std::mem::zeroed() } 402 | } 403 | } 404 | 405 | impl std::fmt::Debug for PF_PRIVSOURCE_INFO { 406 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 407 | write!( 408 | f, 409 | "PF_PRIVSOURCE_INFO {{ DbInfo: {:?}, ImageName: {:?}, Anonymous1: {:?}, ModernApp : {:?}, DeepFrozen : {:?}, Foreground : {:?}, PerProcessStore : {:?}, Spare : {:?} }}", 410 | self.DbInfo, 411 | self.ImageName, 412 | self.Anonymous1, 413 | self.ModernApp(), 414 | self.DeepFrozen(), 415 | self.Foreground(), 416 | self.PerProcessStore(), 417 | self.Spare() 418 | ) 419 | } 420 | } 421 | 422 | impl PF_PRIVSOURCE_INFO { 423 | #[inline] 424 | pub fn ModernApp(&self) -> u32 { 425 | self._bitfield_1.get(0usize, 1u8) as u32 426 | } 427 | 428 | #[inline] 429 | pub fn set_ModernApp(&mut self, val: u32) { 430 | self._bitfield_1.set(0usize, 1u8, val as u64) 431 | } 432 | 433 | #[inline] 434 | pub fn DeepFrozen(&self) -> u32 { 435 | self._bitfield_1.get(1usize, 1u8) as u32 436 | } 437 | 438 | #[inline] 439 | pub fn set_DeepFrozen(&mut self, val: u32) { 440 | self._bitfield_1.set(1usize, 1u8, val as u64) 441 | } 442 | 443 | #[inline] 444 | pub fn Foreground(&self) -> u32 { 445 | self._bitfield_1.get(2usize, 1u8) as u32 446 | } 447 | 448 | #[inline] 449 | pub fn set_Foreground(&mut self, val: u32) { 450 | self._bitfield_1.set(2usize, 1u8, val as u64) 451 | } 452 | 453 | #[inline] 454 | pub fn PerProcessStore(&self) -> u32 { 455 | self._bitfield_1.get(3usize, 1u8) as u32 456 | } 457 | 458 | #[inline] 459 | pub fn set_PerProcessStore(&mut self, val: u32) { 460 | self._bitfield_1.set(3usize, 1u8, val as u64) 461 | } 462 | 463 | #[inline] 464 | pub fn Spare(&self) -> u32 { 465 | self._bitfield_1.get(4usize, 28u8) as u32 466 | } 467 | 468 | #[inline] 469 | pub fn set_Spare(&mut self, val: u32) { 470 | self._bitfield_1.set(4usize, 28u8, val as u64) 471 | } 472 | 473 | #[inline] 474 | pub fn new_bitfield_1( 475 | ModernApp: u32, 476 | DeepFrozen: u32, 477 | Foreground: u32, 478 | PerProcessStore: u32, 479 | Spare: u32, 480 | ) -> BitfieldUnit<[u8; 4]> { 481 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 482 | 483 | bitfield_unit.set(0usize, 1u8, ModernApp as u64); 484 | 485 | bitfield_unit.set(1usize, 1u8, DeepFrozen as u64); 486 | 487 | bitfield_unit.set(2usize, 1u8, Foreground as u64); 488 | 489 | bitfield_unit.set(3usize, 1u8, PerProcessStore as u64); 490 | 491 | bitfield_unit.set(4usize, 28u8, Spare as u64); 492 | 493 | bitfield_unit 494 | } 495 | } 496 | 497 | #[repr(C)] 498 | pub struct PF_PRIVSOURCE_QUERY_REQUEST { 499 | pub Version: u32, 500 | pub Flags: u32, 501 | pub InfoCount: u32, 502 | pub InfoArray: [PF_PRIVSOURCE_INFO; 1], 503 | } 504 | 505 | impl Default for PF_PRIVSOURCE_QUERY_REQUEST { 506 | fn default() -> Self { 507 | unsafe { std::mem::zeroed() } 508 | } 509 | } 510 | 511 | impl std::fmt::Debug for PF_PRIVSOURCE_QUERY_REQUEST { 512 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 513 | write!( 514 | f, 515 | "PF_PRIVSOURCE_QUERY_REQUEST {{ InfoArray: {:?} }}", 516 | self.InfoArray 517 | ) 518 | } 519 | } 520 | 521 | #[repr(i32)] 522 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 523 | pub enum PF_PHASED_SCENARIO_TYPE { 524 | PfScenarioTypeNone = 0, 525 | PfScenarioTypeStandby = 1, 526 | PfScenarioTypeHibernate = 2, 527 | PfScenarioTypeFUS = 3, 528 | PfScenarioTypeMax = 4, 529 | } 530 | 531 | #[repr(C)] 532 | pub struct PF_SCENARIO_PHASE_INFO { 533 | pub Version: u32, 534 | pub ScenType: PF_PHASED_SCENARIO_TYPE, 535 | pub PhaseId: u32, 536 | pub SequenceNumber: u32, 537 | pub Flags: u32, 538 | pub FUSUserId: u32, 539 | } 540 | 541 | impl Default for PF_SCENARIO_PHASE_INFO { 542 | fn default() -> Self { 543 | unsafe { std::mem::zeroed() } 544 | } 545 | } 546 | 547 | impl std::fmt::Debug for PF_SCENARIO_PHASE_INFO { 548 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 549 | write!( 550 | f, 551 | "PF_SCENARIO_PHASE_INFO {{ ScenType: {:?} }}", 552 | self.ScenType 553 | ) 554 | } 555 | } 556 | 557 | #[repr(C)] 558 | pub struct PF_MEMORY_LIST_NODE { 559 | _bitfield_align_1: [u64; 0], 560 | _bitfield_1: BitfieldUnit<[u8; 8]>, 561 | pub StandbyLowPageCount: u64, 562 | pub StandbyMediumPageCount: u64, 563 | pub StandbyHighPageCount: u64, 564 | pub FreePageCount: u64, 565 | pub ModifiedPageCount: u64, 566 | } 567 | 568 | impl Default for PF_MEMORY_LIST_NODE { 569 | fn default() -> Self { 570 | unsafe { std::mem::zeroed() } 571 | } 572 | } 573 | 574 | impl std::fmt::Debug for PF_MEMORY_LIST_NODE { 575 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 576 | write!( 577 | f, 578 | "PF_MEMORY_LIST_NODE {{ Node : {:?}, Spare : {:?} }}", 579 | self.Node(), 580 | self.Spare() 581 | ) 582 | } 583 | } 584 | 585 | impl PF_MEMORY_LIST_NODE { 586 | #[inline] 587 | pub fn Node(&self) -> u64 { 588 | self._bitfield_1.get(0usize, 8u8) 589 | } 590 | 591 | #[inline] 592 | pub fn set_Node(&mut self, val: u64) { 593 | self._bitfield_1.set(0usize, 8u8, val) 594 | } 595 | 596 | #[inline] 597 | pub fn Spare(&self) -> u64 { 598 | self._bitfield_1.get(8usize, 56u8) 599 | } 600 | 601 | #[inline] 602 | pub fn set_Spare(&mut self, val: u64) { 603 | self._bitfield_1.set(8usize, 56u8, val) 604 | } 605 | 606 | #[inline] 607 | pub fn new_bitfield_1(Node: u64, Spare: u64) -> BitfieldUnit<[u8; 8]> { 608 | let mut bitfield_unit: BitfieldUnit<[u8; 8]> = Default::default(); 609 | 610 | bitfield_unit.set(0usize, 8u8, Node); 611 | 612 | bitfield_unit.set(8usize, 56u8, Spare); 613 | 614 | bitfield_unit 615 | } 616 | } 617 | 618 | #[repr(C)] 619 | pub struct PF_ROBUST_PROCESS_ENTRY { 620 | pub ImagePathHash: u32, 621 | pub Pid: u32, 622 | pub Alignment: u32, 623 | } 624 | 625 | impl Default for PF_ROBUST_PROCESS_ENTRY { 626 | fn default() -> Self { 627 | unsafe { std::mem::zeroed() } 628 | } 629 | } 630 | 631 | impl std::fmt::Debug for PF_ROBUST_PROCESS_ENTRY { 632 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 633 | write!(f, "PF_ROBUST_PROCESS_ENTRY {{ }}") 634 | } 635 | } 636 | 637 | #[repr(C)] 638 | pub struct PF_ROBUST_FILE_ENTRY { 639 | pub FilePathHash: u32, 640 | } 641 | 642 | impl Default for PF_ROBUST_FILE_ENTRY { 643 | fn default() -> Self { 644 | unsafe { std::mem::zeroed() } 645 | } 646 | } 647 | 648 | impl std::fmt::Debug for PF_ROBUST_FILE_ENTRY { 649 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 650 | write!(f, "PF_ROBUST_FILE_ENTRY {{ }}") 651 | } 652 | } 653 | 654 | #[repr(i32)] 655 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 656 | pub enum PF_ROBUSTNESS_CONTROL_COMMAND { 657 | PfRpControlUpdate = 0, 658 | PfRpControlReset = 1, 659 | PfRpControlRobustAllStart = 2, 660 | PfRpControlRobustAllStop = 3, 661 | PfRpControlCommandMax = 4, 662 | } 663 | 664 | #[repr(C)] 665 | pub struct PF_ROBUSTNESS_CONTROL { 666 | pub Version: u32, 667 | pub Command: PF_ROBUSTNESS_CONTROL_COMMAND, 668 | pub DeprioProcessCount: u32, 669 | pub ExemptProcessCount: u32, 670 | pub DeprioFileCount: u32, 671 | pub ExemptFileCount: u32, 672 | pub ProcessEntries: [PF_ROBUST_PROCESS_ENTRY; 1], 673 | pub FileEntries: [PF_ROBUST_FILE_ENTRY; 1], 674 | } 675 | 676 | impl Default for PF_ROBUSTNESS_CONTROL { 677 | fn default() -> Self { 678 | unsafe { std::mem::zeroed() } 679 | } 680 | } 681 | 682 | impl std::fmt::Debug for PF_ROBUSTNESS_CONTROL { 683 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 684 | write!( 685 | f, 686 | "PF_ROBUSTNESS_CONTROL {{ Command: {:?}, ProcessEntries: {:?}, FileEntries: {:?} }}", 687 | self.Command, self.ProcessEntries, self.FileEntries 688 | ) 689 | } 690 | } 691 | 692 | #[repr(C)] 693 | pub struct PF_TIME_CONTROL { 694 | pub TimeAdjustment: i32, 695 | } 696 | 697 | impl Default for PF_TIME_CONTROL { 698 | fn default() -> Self { 699 | unsafe { std::mem::zeroed() } 700 | } 701 | } 702 | 703 | impl std::fmt::Debug for PF_TIME_CONTROL { 704 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 705 | write!(f, "PF_TIME_CONTROL {{ }}") 706 | } 707 | } 708 | 709 | #[repr(C)] 710 | pub struct PF_MEMORY_LIST_INFO { 711 | pub Version: u32, 712 | pub Size: u32, 713 | pub NodeCount: u32, 714 | pub Nodes: [PF_MEMORY_LIST_NODE; 1], 715 | } 716 | 717 | impl Default for PF_MEMORY_LIST_INFO { 718 | fn default() -> Self { 719 | unsafe { std::mem::zeroed() } 720 | } 721 | } 722 | 723 | impl std::fmt::Debug for PF_MEMORY_LIST_INFO { 724 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 725 | write!(f, "PF_MEMORY_LIST_INFO {{ Nodes: {:?} }}", self.Nodes) 726 | } 727 | } 728 | 729 | #[repr(C)] 730 | pub struct PF_PHYSICAL_MEMORY_RANGE { 731 | pub BasePfn: usize, 732 | pub PageCount: usize, 733 | } 734 | 735 | impl Default for PF_PHYSICAL_MEMORY_RANGE { 736 | fn default() -> Self { 737 | unsafe { std::mem::zeroed() } 738 | } 739 | } 740 | 741 | impl std::fmt::Debug for PF_PHYSICAL_MEMORY_RANGE { 742 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 743 | write!(f, "PF_PHYSICAL_MEMORY_RANGE {{ }}") 744 | } 745 | } 746 | 747 | #[repr(C)] 748 | pub struct PF_PHYSICAL_MEMORY_RANGE_INFO_V1 { 749 | pub Version: u32, 750 | pub RangeCount: u32, 751 | pub Ranges: [PF_PHYSICAL_MEMORY_RANGE; 1], 752 | } 753 | 754 | impl Default for PF_PHYSICAL_MEMORY_RANGE_INFO_V1 { 755 | fn default() -> Self { 756 | unsafe { std::mem::zeroed() } 757 | } 758 | } 759 | 760 | impl std::fmt::Debug for PF_PHYSICAL_MEMORY_RANGE_INFO_V1 { 761 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 762 | write!( 763 | f, 764 | "PF_PHYSICAL_MEMORY_RANGE_INFO_V1 {{ Ranges: {:?} }}", 765 | self.Ranges 766 | ) 767 | } 768 | } 769 | 770 | #[repr(C)] 771 | pub struct PF_PHYSICAL_MEMORY_RANGE_INFO_V2 { 772 | pub Version: u32, 773 | pub Flags: u32, 774 | pub RangeCount: u32, 775 | pub Ranges: [PF_PHYSICAL_MEMORY_RANGE; 1], 776 | } 777 | 778 | impl Default for PF_PHYSICAL_MEMORY_RANGE_INFO_V2 { 779 | fn default() -> Self { 780 | unsafe { std::mem::zeroed() } 781 | } 782 | } 783 | 784 | impl std::fmt::Debug for PF_PHYSICAL_MEMORY_RANGE_INFO_V2 { 785 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 786 | write!( 787 | f, 788 | "PF_PHYSICAL_MEMORY_RANGE_INFO_V2 {{ Ranges: {:?} }}", 789 | self.Ranges 790 | ) 791 | } 792 | } 793 | 794 | #[repr(C)] 795 | pub struct PF_REPURPOSED_BY_PREFETCH_INFO { 796 | pub Version: u32, 797 | pub RepurposedByPrefetch: usize, 798 | } 799 | 800 | impl Default for PF_REPURPOSED_BY_PREFETCH_INFO { 801 | fn default() -> Self { 802 | unsafe { std::mem::zeroed() } 803 | } 804 | } 805 | 806 | impl std::fmt::Debug for PF_REPURPOSED_BY_PREFETCH_INFO { 807 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 808 | write!(f, "PF_REPURPOSED_BY_PREFETCH_INFO {{ }}") 809 | } 810 | } 811 | 812 | #[repr(C)] 813 | pub struct PF_VIRTUAL_QUERY { 814 | pub Version: u32, 815 | pub Anonymous1: PF_VIRTUAL_QUERY_1, 816 | pub QueryBuffer: *mut std::ffi::c_void, 817 | pub QueryBufferSize: usize, 818 | pub ProcessHandle: HANDLE, 819 | } 820 | 821 | #[repr(C)] 822 | pub struct PF_VIRTUAL_QUERY_1 { 823 | pub Flags: UnionField, 824 | pub Anonymous1: UnionField, 825 | pub union_field: u32, 826 | } 827 | 828 | #[repr(C)] 829 | #[repr(align(4))] 830 | pub struct PF_VIRTUAL_QUERY_1_1 { 831 | _bitfield_align_1: [u32; 0], 832 | _bitfield_1: BitfieldUnit<[u8; 4]>, 833 | } 834 | 835 | impl Default for PF_VIRTUAL_QUERY_1_1 { 836 | fn default() -> Self { 837 | unsafe { std::mem::zeroed() } 838 | } 839 | } 840 | 841 | impl std::fmt::Debug for PF_VIRTUAL_QUERY_1_1 { 842 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 843 | write!( 844 | f, 845 | "PF_VIRTUAL_QUERY_1_1 {{ FaultInPageTables : {:?}, ReportPageTables : {:?}, Spare : {:?} }}", 846 | self.FaultInPageTables(), 847 | self.ReportPageTables(), 848 | self.Spare() 849 | ) 850 | } 851 | } 852 | 853 | impl PF_VIRTUAL_QUERY_1_1 { 854 | #[inline] 855 | pub fn FaultInPageTables(&self) -> u32 { 856 | self._bitfield_1.get(0usize, 1u8) as u32 857 | } 858 | 859 | #[inline] 860 | pub fn set_FaultInPageTables(&mut self, val: u32) { 861 | self._bitfield_1.set(0usize, 1u8, val as u64) 862 | } 863 | 864 | #[inline] 865 | pub fn ReportPageTables(&self) -> u32 { 866 | self._bitfield_1.get(1usize, 1u8) as u32 867 | } 868 | 869 | #[inline] 870 | pub fn set_ReportPageTables(&mut self, val: u32) { 871 | self._bitfield_1.set(1usize, 1u8, val as u64) 872 | } 873 | 874 | #[inline] 875 | pub fn Spare(&self) -> u32 { 876 | self._bitfield_1.get(2usize, 30u8) as u32 877 | } 878 | 879 | #[inline] 880 | pub fn set_Spare(&mut self, val: u32) { 881 | self._bitfield_1.set(2usize, 30u8, val as u64) 882 | } 883 | 884 | #[inline] 885 | pub fn new_bitfield_1( 886 | FaultInPageTables: u32, 887 | ReportPageTables: u32, 888 | Spare: u32, 889 | ) -> BitfieldUnit<[u8; 4]> { 890 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 891 | 892 | bitfield_unit.set(0usize, 1u8, FaultInPageTables as u64); 893 | 894 | bitfield_unit.set(1usize, 1u8, ReportPageTables as u64); 895 | 896 | bitfield_unit.set(2usize, 30u8, Spare as u64); 897 | 898 | bitfield_unit 899 | } 900 | } 901 | 902 | impl Default for PF_VIRTUAL_QUERY_1 { 903 | fn default() -> Self { 904 | unsafe { std::mem::zeroed() } 905 | } 906 | } 907 | 908 | impl std::fmt::Debug for PF_VIRTUAL_QUERY_1 { 909 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 910 | write!(f, "PF_VIRTUAL_QUERY_1 {{ union }}") 911 | } 912 | } 913 | 914 | impl Default for PF_VIRTUAL_QUERY { 915 | fn default() -> Self { 916 | unsafe { std::mem::zeroed() } 917 | } 918 | } 919 | 920 | impl std::fmt::Debug for PF_VIRTUAL_QUERY { 921 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 922 | write!( 923 | f, 924 | "PF_VIRTUAL_QUERY {{ Anonymous1: {:?} }}", 925 | self.Anonymous1 926 | ) 927 | } 928 | } 929 | 930 | #[repr(C)] 931 | pub struct PF_MIN_WS_AGE_RATE_CONTROL { 932 | pub Version: u32, 933 | pub SecondsToOldestAge: u32, 934 | } 935 | 936 | impl Default for PF_MIN_WS_AGE_RATE_CONTROL { 937 | fn default() -> Self { 938 | unsafe { std::mem::zeroed() } 939 | } 940 | } 941 | 942 | impl std::fmt::Debug for PF_MIN_WS_AGE_RATE_CONTROL { 943 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 944 | write!(f, "PF_MIN_WS_AGE_RATE_CONTROL {{ }}") 945 | } 946 | } 947 | 948 | #[repr(C)] 949 | pub struct PF_DEPRIORITIZE_OLD_PAGES { 950 | pub Version: u32, 951 | pub ProcessHandle: HANDLE, 952 | pub Anonymous1: PF_DEPRIORITIZE_OLD_PAGES_1, 953 | } 954 | 955 | #[repr(C)] 956 | pub struct PF_DEPRIORITIZE_OLD_PAGES_1 { 957 | pub Flags: UnionField, 958 | pub Anonymous1: UnionField, 959 | pub union_field: u32, 960 | } 961 | 962 | #[repr(C)] 963 | #[repr(align(4))] 964 | pub struct PF_DEPRIORITIZE_OLD_PAGES_1_1 { 965 | _bitfield_align_1: [u32; 0], 966 | _bitfield_1: BitfieldUnit<[u8; 4]>, 967 | } 968 | 969 | impl Default for PF_DEPRIORITIZE_OLD_PAGES_1_1 { 970 | fn default() -> Self { 971 | unsafe { std::mem::zeroed() } 972 | } 973 | } 974 | 975 | impl std::fmt::Debug for PF_DEPRIORITIZE_OLD_PAGES_1_1 { 976 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 977 | write!( 978 | f, 979 | "PF_DEPRIORITIZE_OLD_PAGES_1_1 {{ TargetPriority : {:?}, TrimPages : {:?}, Spare : {:?} }}", 980 | self.TargetPriority(), 981 | self.TrimPages(), 982 | self.Spare() 983 | ) 984 | } 985 | } 986 | 987 | impl PF_DEPRIORITIZE_OLD_PAGES_1_1 { 988 | #[inline] 989 | pub fn TargetPriority(&self) -> u32 { 990 | self._bitfield_1.get(0usize, 4u8) as u32 991 | } 992 | 993 | #[inline] 994 | pub fn set_TargetPriority(&mut self, val: u32) { 995 | self._bitfield_1.set(0usize, 4u8, val as u64) 996 | } 997 | 998 | #[inline] 999 | pub fn TrimPages(&self) -> u32 { 1000 | self._bitfield_1.get(4usize, 2u8) as u32 1001 | } 1002 | 1003 | #[inline] 1004 | pub fn set_TrimPages(&mut self, val: u32) { 1005 | self._bitfield_1.set(4usize, 2u8, val as u64) 1006 | } 1007 | 1008 | #[inline] 1009 | pub fn Spare(&self) -> u32 { 1010 | self._bitfield_1.get(6usize, 26u8) as u32 1011 | } 1012 | 1013 | #[inline] 1014 | pub fn set_Spare(&mut self, val: u32) { 1015 | self._bitfield_1.set(6usize, 26u8, val as u64) 1016 | } 1017 | 1018 | #[inline] 1019 | pub fn new_bitfield_1( 1020 | TargetPriority: u32, 1021 | TrimPages: u32, 1022 | Spare: u32, 1023 | ) -> BitfieldUnit<[u8; 4]> { 1024 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 1025 | 1026 | bitfield_unit.set(0usize, 4u8, TargetPriority as u64); 1027 | 1028 | bitfield_unit.set(4usize, 2u8, TrimPages as u64); 1029 | 1030 | bitfield_unit.set(6usize, 26u8, Spare as u64); 1031 | 1032 | bitfield_unit 1033 | } 1034 | } 1035 | 1036 | impl Default for PF_DEPRIORITIZE_OLD_PAGES_1 { 1037 | fn default() -> Self { 1038 | unsafe { std::mem::zeroed() } 1039 | } 1040 | } 1041 | 1042 | impl std::fmt::Debug for PF_DEPRIORITIZE_OLD_PAGES_1 { 1043 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1044 | write!(f, "PF_DEPRIORITIZE_OLD_PAGES_1 {{ union }}") 1045 | } 1046 | } 1047 | 1048 | impl Default for PF_DEPRIORITIZE_OLD_PAGES { 1049 | fn default() -> Self { 1050 | unsafe { std::mem::zeroed() } 1051 | } 1052 | } 1053 | 1054 | impl std::fmt::Debug for PF_DEPRIORITIZE_OLD_PAGES { 1055 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1056 | write!( 1057 | f, 1058 | "PF_DEPRIORITIZE_OLD_PAGES {{ Anonymous1: {:?} }}", 1059 | self.Anonymous1 1060 | ) 1061 | } 1062 | } 1063 | 1064 | #[repr(C)] 1065 | pub struct PF_GPU_UTILIZATION_INFO { 1066 | pub Version: u32, 1067 | pub SessionId: u32, 1068 | pub GpuTime: u64, 1069 | } 1070 | 1071 | impl Default for PF_GPU_UTILIZATION_INFO { 1072 | fn default() -> Self { 1073 | unsafe { std::mem::zeroed() } 1074 | } 1075 | } 1076 | 1077 | impl std::fmt::Debug for PF_GPU_UTILIZATION_INFO { 1078 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1079 | write!(f, "PF_GPU_UTILIZATION_INFO {{ }}") 1080 | } 1081 | } 1082 | 1083 | #[repr(i32)] 1084 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 1085 | pub enum SUPERFETCH_INFORMATION_CLASS { 1086 | SuperfetchRetrieveTrace = 1, 1087 | SuperfetchSystemParameters = 2, 1088 | SuperfetchLogEvent = 3, 1089 | SuperfetchGenerateTrace = 4, 1090 | SuperfetchPrefetch = 5, 1091 | SuperfetchPfnQuery = 6, 1092 | SuperfetchPfnSetPriority = 7, 1093 | SuperfetchPrivSourceQuery = 8, 1094 | SuperfetchSequenceNumberQuery = 9, 1095 | SuperfetchScenarioPhase = 10, 1096 | SuperfetchWorkerPriority = 11, 1097 | SuperfetchScenarioQuery = 12, 1098 | SuperfetchScenarioPrefetch = 13, 1099 | SuperfetchRobustnessControl = 14, 1100 | SuperfetchTimeControl = 15, 1101 | SuperfetchMemoryListQuery = 16, 1102 | SuperfetchMemoryRangesQuery = 17, 1103 | SuperfetchTracingControl = 18, 1104 | SuperfetchTrimWhileAgingControl = 19, 1105 | SuperfetchRepurposedByPrefetch = 20, 1106 | SuperfetchChannelPowerRequest = 21, 1107 | SuperfetchMovePages = 22, 1108 | SuperfetchVirtualQuery = 23, 1109 | SuperfetchCombineStatsQuery = 24, 1110 | SuperfetchSetMinWsAgeRate = 25, 1111 | SuperfetchDeprioritizeOldPagesInWs = 26, 1112 | SuperfetchFileExtentsQuery = 27, 1113 | SuperfetchGpuUtilizationQuery = 28, 1114 | SuperfetchPfnSet = 29, 1115 | SuperfetchInformationMax = 30, 1116 | } 1117 | 1118 | #[repr(C)] 1119 | pub struct SUPERFETCH_INFORMATION { 1120 | pub Version: u32, 1121 | pub Magic: u32, 1122 | pub SuperfetchInformationClass: SUPERFETCH_INFORMATION_CLASS, 1123 | pub SuperfetchInformation: *mut std::ffi::c_void, 1124 | pub SuperfetchInformationLength: u32, 1125 | } 1126 | 1127 | impl Default for SUPERFETCH_INFORMATION { 1128 | fn default() -> Self { 1129 | unsafe { std::mem::zeroed() } 1130 | } 1131 | } 1132 | 1133 | impl std::fmt::Debug for SUPERFETCH_INFORMATION { 1134 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1135 | write!( 1136 | f, 1137 | "SUPERFETCH_INFORMATION {{ SuperfetchInformationClass: {:?} }}", 1138 | self.SuperfetchInformationClass 1139 | ) 1140 | } 1141 | } 1142 | -------------------------------------------------------------------------------- /src/ntpnpapi.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | core::GUID, 3 | Win32::{ 4 | Devices::DeviceAndDriverInstallation::PNP_VETO_TYPE, 5 | Foundation::{NTSTATUS, UNICODE_STRING}, 6 | }, 7 | }; 8 | 9 | use crate::bitfield::UnionField; 10 | 11 | #[repr(i32)] 12 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 13 | pub enum PLUGPLAY_EVENT_CATEGORY { 14 | HardwareProfileChangeEvent = 0, 15 | TargetDeviceChangeEvent = 1, 16 | DeviceClassChangeEvent = 2, 17 | CustomDeviceEvent = 3, 18 | DeviceInstallEvent = 4, 19 | DeviceArrivalEvent = 5, 20 | PowerEvent = 6, 21 | VetoEvent = 7, 22 | BlockedDriverEvent = 8, 23 | InvalidIDEvent = 9, 24 | MaxPlugEventCategory = 10, 25 | } 26 | 27 | #[repr(C)] 28 | pub struct PLUGPLAY_EVENT_BLOCK { 29 | pub EventGuid: GUID, 30 | pub EventCategory: PLUGPLAY_EVENT_CATEGORY, 31 | pub Result: *mut u32, 32 | pub Flags: u32, 33 | pub TotalSize: u32, 34 | pub DeviceObject: *mut std::ffi::c_void, 35 | pub u: PLUGPLAY_EVENT_BLOCK_1, 36 | } 37 | 38 | #[repr(C)] 39 | pub struct PLUGPLAY_EVENT_BLOCK_1 { 40 | pub DeviceClass: UnionField, 41 | pub TargetDevice: UnionField, 42 | pub InstallDevice: UnionField, 43 | pub CustomNotification: UnionField, 44 | pub ProfileNotification: UnionField, 45 | pub PowerNotification: UnionField, 46 | pub VetoNotification: UnionField, 47 | pub BlockedDriverNotification: UnionField, 48 | pub InvalidIDNotification: UnionField, 49 | pub union_field: [u64; 3], 50 | } 51 | 52 | #[repr(C)] 53 | pub struct PLUGPLAY_EVENT_BLOCK_1_1 { 54 | pub ClassGuid: GUID, 55 | pub SymbolicLinkName: [u16; 1], 56 | } 57 | 58 | impl Default for PLUGPLAY_EVENT_BLOCK_1_1 { 59 | fn default() -> Self { 60 | unsafe { std::mem::zeroed() } 61 | } 62 | } 63 | 64 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_1 { 65 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 66 | write!( 67 | f, 68 | "PLUGPLAY_EVENT_BLOCK_1_1 {{ SymbolicLinkName: {:?} }}", 69 | self.SymbolicLinkName 70 | ) 71 | } 72 | } 73 | 74 | #[repr(C)] 75 | pub struct PLUGPLAY_EVENT_BLOCK_1_2 { 76 | pub DeviceIds: [u16; 1], 77 | } 78 | 79 | impl Default for PLUGPLAY_EVENT_BLOCK_1_2 { 80 | fn default() -> Self { 81 | unsafe { std::mem::zeroed() } 82 | } 83 | } 84 | 85 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_2 { 86 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 87 | write!( 88 | f, 89 | "PLUGPLAY_EVENT_BLOCK_1_2 {{ DeviceIds: {:?} }}", 90 | self.DeviceIds 91 | ) 92 | } 93 | } 94 | 95 | #[repr(C)] 96 | pub struct PLUGPLAY_EVENT_BLOCK_1_3 { 97 | pub DeviceId: [u16; 1], 98 | } 99 | 100 | impl Default for PLUGPLAY_EVENT_BLOCK_1_3 { 101 | fn default() -> Self { 102 | unsafe { std::mem::zeroed() } 103 | } 104 | } 105 | 106 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_3 { 107 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 108 | write!( 109 | f, 110 | "PLUGPLAY_EVENT_BLOCK_1_3 {{ DeviceId: {:?} }}", 111 | self.DeviceId 112 | ) 113 | } 114 | } 115 | 116 | #[repr(C)] 117 | pub struct PLUGPLAY_EVENT_BLOCK_1_4 { 118 | pub NotificationStructure: *mut std::ffi::c_void, 119 | pub DeviceIds: [u16; 1], 120 | } 121 | 122 | impl Default for PLUGPLAY_EVENT_BLOCK_1_4 { 123 | fn default() -> Self { 124 | unsafe { std::mem::zeroed() } 125 | } 126 | } 127 | 128 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_4 { 129 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 130 | write!( 131 | f, 132 | "PLUGPLAY_EVENT_BLOCK_1_4 {{ DeviceIds: {:?} }}", 133 | self.DeviceIds 134 | ) 135 | } 136 | } 137 | 138 | #[repr(C)] 139 | pub struct PLUGPLAY_EVENT_BLOCK_1_5 { 140 | pub Notification: *mut std::ffi::c_void, 141 | } 142 | 143 | impl Default for PLUGPLAY_EVENT_BLOCK_1_5 { 144 | fn default() -> Self { 145 | unsafe { std::mem::zeroed() } 146 | } 147 | } 148 | 149 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_5 { 150 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 151 | write!(f, "PLUGPLAY_EVENT_BLOCK_1_5 {{ }}") 152 | } 153 | } 154 | 155 | #[repr(C)] 156 | pub struct PLUGPLAY_EVENT_BLOCK_1_6 { 157 | pub NotificationCode: u32, 158 | pub NotificationData: u32, 159 | } 160 | 161 | impl Default for PLUGPLAY_EVENT_BLOCK_1_6 { 162 | fn default() -> Self { 163 | unsafe { std::mem::zeroed() } 164 | } 165 | } 166 | 167 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_6 { 168 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 169 | write!(f, "PLUGPLAY_EVENT_BLOCK_1_6 {{ }}") 170 | } 171 | } 172 | 173 | #[repr(C)] 174 | pub struct PLUGPLAY_EVENT_BLOCK_1_7 { 175 | pub VetoType: PNP_VETO_TYPE, 176 | pub DeviceIdVetoNameBuffer: [u16; 1], 177 | } 178 | 179 | impl Default for PLUGPLAY_EVENT_BLOCK_1_7 { 180 | fn default() -> Self { 181 | unsafe { std::mem::zeroed() } 182 | } 183 | } 184 | 185 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_7 { 186 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 187 | write!( 188 | f, 189 | "PLUGPLAY_EVENT_BLOCK_1_7 {{ DeviceIdVetoNameBuffer: {:?} }}", 190 | self.DeviceIdVetoNameBuffer 191 | ) 192 | } 193 | } 194 | 195 | #[repr(C)] 196 | pub struct PLUGPLAY_EVENT_BLOCK_1_8 { 197 | pub BlockedDriverGuid: GUID, 198 | } 199 | 200 | impl Default for PLUGPLAY_EVENT_BLOCK_1_8 { 201 | fn default() -> Self { 202 | unsafe { std::mem::zeroed() } 203 | } 204 | } 205 | 206 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_8 { 207 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 208 | write!(f, "PLUGPLAY_EVENT_BLOCK_1_8 {{ }}") 209 | } 210 | } 211 | 212 | #[repr(C)] 213 | pub struct PLUGPLAY_EVENT_BLOCK_1_9 { 214 | pub ParentId: [u16; 1], 215 | } 216 | 217 | impl Default for PLUGPLAY_EVENT_BLOCK_1_9 { 218 | fn default() -> Self { 219 | unsafe { std::mem::zeroed() } 220 | } 221 | } 222 | 223 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1_9 { 224 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 225 | write!( 226 | f, 227 | "PLUGPLAY_EVENT_BLOCK_1_9 {{ ParentId: {:?} }}", 228 | self.ParentId 229 | ) 230 | } 231 | } 232 | 233 | impl Default for PLUGPLAY_EVENT_BLOCK_1 { 234 | fn default() -> Self { 235 | unsafe { std::mem::zeroed() } 236 | } 237 | } 238 | 239 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK_1 { 240 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 241 | write!(f, "PLUGPLAY_EVENT_BLOCK_1 {{ union }}") 242 | } 243 | } 244 | 245 | impl Default for PLUGPLAY_EVENT_BLOCK { 246 | fn default() -> Self { 247 | unsafe { std::mem::zeroed() } 248 | } 249 | } 250 | 251 | impl std::fmt::Debug for PLUGPLAY_EVENT_BLOCK { 252 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 253 | write!( 254 | f, 255 | "PLUGPLAY_EVENT_BLOCK {{ EventCategory: {:?}, u: {:?} }}", 256 | self.EventCategory, self.u 257 | ) 258 | } 259 | } 260 | 261 | #[repr(i32)] 262 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 263 | pub enum PLUGPLAY_CONTROL_CLASS { 264 | PlugPlayControlEnumerateDevice = 0, 265 | PlugPlayControlRegisterNewDevice = 1, 266 | PlugPlayControlDeregisterDevice = 2, 267 | PlugPlayControlInitializeDevice = 3, 268 | PlugPlayControlStartDevice = 4, 269 | PlugPlayControlUnlockDevice = 5, 270 | PlugPlayControlQueryAndRemoveDevice = 6, 271 | PlugPlayControlUserResponse = 7, 272 | PlugPlayControlGenerateLegacyDevice = 8, 273 | PlugPlayControlGetInterfaceDeviceList = 9, 274 | PlugPlayControlProperty = 10, 275 | PlugPlayControlDeviceClassAssociation = 11, 276 | PlugPlayControlGetRelatedDevice = 12, 277 | PlugPlayControlGetInterfaceDeviceAlias = 13, 278 | PlugPlayControlDeviceStatus = 14, 279 | PlugPlayControlGetDeviceDepth = 15, 280 | PlugPlayControlQueryDeviceRelations = 16, 281 | PlugPlayControlTargetDeviceRelation = 17, 282 | PlugPlayControlQueryConflictList = 18, 283 | PlugPlayControlRetrieveDock = 19, 284 | PlugPlayControlResetDevice = 20, 285 | PlugPlayControlHaltDevice = 21, 286 | PlugPlayControlGetBlockedDriverList = 22, 287 | PlugPlayControlGetDeviceInterfaceEnabled = 23, 288 | MaxPlugPlayControl = 24, 289 | } 290 | 291 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 292 | extern "system" { 293 | pub fn NtPlugPlayControl( 294 | PnPControlClass: PLUGPLAY_CONTROL_CLASS, 295 | PnPControlData: *mut std::ffi::c_void, 296 | PnPControlDataLength: u32, 297 | ) -> NTSTATUS; 298 | } 299 | 300 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 301 | extern "system" { 302 | pub fn NtSerializeBoot() -> NTSTATUS; 303 | } 304 | 305 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 306 | extern "system" { 307 | pub fn NtEnableLastKnownGood() -> NTSTATUS; 308 | } 309 | 310 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 311 | extern "system" { 312 | pub fn NtDisableLastKnownGood() -> NTSTATUS; 313 | } 314 | 315 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 316 | extern "system" { 317 | pub fn NtReplacePartitionUnit( 318 | TargetInstancePath: *mut UNICODE_STRING, 319 | SpareInstancePath: *mut UNICODE_STRING, 320 | Flags: u32, 321 | ) -> NTSTATUS; 322 | } 323 | -------------------------------------------------------------------------------- /src/ntregapi.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | Wdk::{ 3 | Foundation::OBJECT_ATTRIBUTES, 4 | System::Registry::{KEY_INFORMATION_CLASS, KEY_VALUE_INFORMATION_CLASS}, 5 | }, 6 | Win32::{ 7 | Foundation::{BOOLEAN, HANDLE, NTSTATUS, UNICODE_STRING}, 8 | System::IO::{IO_STATUS_BLOCK, PIO_APC_ROUTINE}, 9 | }, 10 | }; 11 | 12 | use crate::bitfield::{BitfieldUnit, UnionField}; 13 | 14 | pub const REG_INIT_BOOT_SM: u32 = 0; 15 | pub const REG_INIT_BOOT_SETUP: u32 = 1; 16 | pub const REG_INIT_BOOT_ACCEPTED_BASE: u32 = 2; 17 | pub const REG_INIT_BOOT_ACCEPTED_MAX: u32 = 1001; 18 | pub const REG_MAX_KEY_VALUE_NAME_LENGTH: u32 = 32767; 19 | pub const REG_MAX_KEY_NAME_LENGTH: u32 = 512; 20 | pub const REG_FLAG_VOLATILE: u32 = 1; 21 | pub const REG_FLAG_LINK: u32 = 2; 22 | pub const REG_KEY_DONT_VIRTUALIZE: u32 = 2; 23 | pub const REG_KEY_DONT_SILENT_FAIL: u32 = 4; 24 | pub const REG_KEY_RECURSE_FLAG: u32 = 8; 25 | pub const CM_EXTENDED_PARAMETER_TYPE_BITS: u32 = 8; 26 | pub const VR_DEVICE_NAME: &[u8; 19] = b"\\Device\\VRegDriver\0"; 27 | pub const VR_FLAG_INHERIT_TRUST_CLASS: u32 = 1; 28 | pub const VR_FLAG_WRITE_THROUGH_HIVE: u32 = 2; 29 | pub const VR_FLAG_LOCAL_MACHINE_TRUST_CLASS: u32 = 4; 30 | pub const VR_KEY_COMROOT: u32 = 0; 31 | pub const VR_KEY_MACHINE_SOFTWARE: u32 = 1; 32 | pub const VR_KEY_CONTROL_SET: u32 = 2; 33 | pub const IOCTL_VR_INITIALIZE_JOB_FOR_VREG: u32 = 2228228; 34 | pub const IOCTL_VR_LOAD_DIFFERENCING_HIVE: u32 = 2228232; 35 | pub const IOCTL_VR_CREATE_NAMESPACE_NODE: u32 = 2228236; 36 | pub const IOCTL_VR_MODIFY_FLAGS: u32 = 2228240; 37 | pub const IOCTL_VR_CREATE_MULTIPLE_NAMESPACE_NODES: u32 = 2228244; 38 | pub const IOCTL_VR_UNLOAD_DYNAMICALLY_LOADED_HIVES: u32 = 2228248; 39 | pub const IOCTL_VR_GET_VIRTUAL_ROOT_KEY: u32 = 2228252; 40 | pub const IOCTL_VR_LOAD_DIFFERENCING_HIVE_FOR_HOST: u32 = 2228256; 41 | pub const IOCTL_VR_UNLOAD_DIFFERENCING_HIVE_FOR_HOST: u32 = 2228260; 42 | 43 | #[repr(C)] 44 | pub struct KEY_FLAGS_INFORMATION { 45 | pub Wow64Flags: u32, 46 | pub KeyFlags: u32, 47 | pub ControlFlags: u32, 48 | } 49 | 50 | impl Default for KEY_FLAGS_INFORMATION { 51 | fn default() -> Self { 52 | unsafe { std::mem::zeroed() } 53 | } 54 | } 55 | 56 | impl std::fmt::Debug for KEY_FLAGS_INFORMATION { 57 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 58 | write!(f, "KEY_FLAGS_INFORMATION {{ }}") 59 | } 60 | } 61 | 62 | #[repr(C)] 63 | pub struct KEY_HANDLE_TAGS_INFORMATION { 64 | pub HandleTags: u32, 65 | } 66 | 67 | impl Default for KEY_HANDLE_TAGS_INFORMATION { 68 | fn default() -> Self { 69 | unsafe { std::mem::zeroed() } 70 | } 71 | } 72 | 73 | impl std::fmt::Debug for KEY_HANDLE_TAGS_INFORMATION { 74 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 75 | write!(f, "KEY_HANDLE_TAGS_INFORMATION {{ }}") 76 | } 77 | } 78 | 79 | #[repr(C)] 80 | #[repr(align(4))] 81 | pub struct KEY_SET_LAYER_INFORMATION { 82 | _bitfield_align_1: [u32; 0], 83 | _bitfield_1: BitfieldUnit<[u8; 4]>, 84 | } 85 | 86 | impl Default for KEY_SET_LAYER_INFORMATION { 87 | fn default() -> Self { 88 | unsafe { std::mem::zeroed() } 89 | } 90 | } 91 | 92 | impl std::fmt::Debug for KEY_SET_LAYER_INFORMATION { 93 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 94 | write!( 95 | f, 96 | "KEY_SET_LAYER_INFORMATION {{ IsTombstone : {:?}, IsSupersedeLocal : {:?}, IsSupersedeTree : {:?}, ClassIsInherited : {:?}, Reserved : {:?} }}", 97 | self.IsTombstone(), 98 | self.IsSupersedeLocal(), 99 | self.IsSupersedeTree(), 100 | self.ClassIsInherited(), 101 | self.Reserved() 102 | ) 103 | } 104 | } 105 | 106 | impl KEY_SET_LAYER_INFORMATION { 107 | #[inline] 108 | pub fn IsTombstone(&self) -> u32 { 109 | self._bitfield_1.get(0usize, 1u8) as u32 110 | } 111 | 112 | #[inline] 113 | pub fn set_IsTombstone(&mut self, val: u32) { 114 | self._bitfield_1.set(0usize, 1u8, val as u64) 115 | } 116 | 117 | #[inline] 118 | pub fn IsSupersedeLocal(&self) -> u32 { 119 | self._bitfield_1.get(1usize, 1u8) as u32 120 | } 121 | 122 | #[inline] 123 | pub fn set_IsSupersedeLocal(&mut self, val: u32) { 124 | self._bitfield_1.set(1usize, 1u8, val as u64) 125 | } 126 | 127 | #[inline] 128 | pub fn IsSupersedeTree(&self) -> u32 { 129 | self._bitfield_1.get(2usize, 1u8) as u32 130 | } 131 | 132 | #[inline] 133 | pub fn set_IsSupersedeTree(&mut self, val: u32) { 134 | self._bitfield_1.set(2usize, 1u8, val as u64) 135 | } 136 | 137 | #[inline] 138 | pub fn ClassIsInherited(&self) -> u32 { 139 | self._bitfield_1.get(3usize, 1u8) as u32 140 | } 141 | 142 | #[inline] 143 | pub fn set_ClassIsInherited(&mut self, val: u32) { 144 | self._bitfield_1.set(3usize, 1u8, val as u64) 145 | } 146 | 147 | #[inline] 148 | pub fn Reserved(&self) -> u32 { 149 | self._bitfield_1.get(4usize, 28u8) as u32 150 | } 151 | 152 | #[inline] 153 | pub fn set_Reserved(&mut self, val: u32) { 154 | self._bitfield_1.set(4usize, 28u8, val as u64) 155 | } 156 | 157 | #[inline] 158 | pub fn new_bitfield_1( 159 | IsTombstone: u32, 160 | IsSupersedeLocal: u32, 161 | IsSupersedeTree: u32, 162 | ClassIsInherited: u32, 163 | Reserved: u32, 164 | ) -> BitfieldUnit<[u8; 4]> { 165 | let mut bitfield_unit: BitfieldUnit<[u8; 4]> = Default::default(); 166 | 167 | bitfield_unit.set(0usize, 1u8, IsTombstone as u64); 168 | 169 | bitfield_unit.set(1usize, 1u8, IsSupersedeLocal as u64); 170 | 171 | bitfield_unit.set(2usize, 1u8, IsSupersedeTree as u64); 172 | 173 | bitfield_unit.set(3usize, 1u8, ClassIsInherited as u64); 174 | 175 | bitfield_unit.set(4usize, 28u8, Reserved as u64); 176 | 177 | bitfield_unit 178 | } 179 | } 180 | 181 | #[repr(i32)] 182 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 183 | pub enum CM_EXTENDED_PARAMETER_TYPE { 184 | CmExtendedParameterInvalidType = 0, 185 | CmExtendedParameterTrustClassKey = 1, 186 | CmExtendedParameterEvent = 2, 187 | CmExtendedParameterFileAccessToken = 3, 188 | CmExtendedParameterMax = 4, 189 | } 190 | 191 | #[repr(C)] 192 | pub struct CM_EXTENDED_PARAMETER { 193 | pub Anonymous1: CM_EXTENDED_PARAMETER_1, 194 | pub Anonymous2: CM_EXTENDED_PARAMETER_2, 195 | } 196 | 197 | #[repr(C)] 198 | #[repr(align(8))] 199 | pub struct CM_EXTENDED_PARAMETER_1 { 200 | _bitfield_align_1: [u64; 0], 201 | _bitfield_1: BitfieldUnit<[u8; 8]>, 202 | } 203 | 204 | impl Default for CM_EXTENDED_PARAMETER_1 { 205 | fn default() -> Self { 206 | unsafe { std::mem::zeroed() } 207 | } 208 | } 209 | 210 | impl std::fmt::Debug for CM_EXTENDED_PARAMETER_1 { 211 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 212 | write!( 213 | f, 214 | "CM_EXTENDED_PARAMETER_1 {{ Type : {:?}, Reserved : {:?} }}", 215 | self.Type(), 216 | self.Reserved() 217 | ) 218 | } 219 | } 220 | 221 | impl CM_EXTENDED_PARAMETER_1 { 222 | #[inline] 223 | pub fn Type(&self) -> u64 { 224 | self._bitfield_1.get(0usize, 8u8) 225 | } 226 | 227 | #[inline] 228 | pub fn set_Type(&mut self, val: u64) { 229 | self._bitfield_1.set(0usize, 8u8, val) 230 | } 231 | 232 | #[inline] 233 | pub fn Reserved(&self) -> u64 { 234 | self._bitfield_1.get(8usize, 56u8) 235 | } 236 | 237 | #[inline] 238 | pub fn set_Reserved(&mut self, val: u64) { 239 | self._bitfield_1.set(8usize, 56u8, val) 240 | } 241 | 242 | #[inline] 243 | pub fn new_bitfield_1(Type: u64, Reserved: u64) -> BitfieldUnit<[u8; 8]> { 244 | let mut bitfield_unit: BitfieldUnit<[u8; 8]> = Default::default(); 245 | 246 | bitfield_unit.set(0usize, 8u8, Type); 247 | 248 | bitfield_unit.set(8usize, 56u8, Reserved); 249 | 250 | bitfield_unit 251 | } 252 | } 253 | 254 | #[repr(C)] 255 | pub struct CM_EXTENDED_PARAMETER_2 { 256 | pub ULong64: UnionField, 257 | pub Pointer: UnionField<*mut std::ffi::c_void>, 258 | pub Size: UnionField, 259 | pub Handle: UnionField, 260 | pub ULong: UnionField, 261 | pub AccessMask: UnionField, 262 | pub union_field: u64, 263 | } 264 | 265 | impl Default for CM_EXTENDED_PARAMETER_2 { 266 | fn default() -> Self { 267 | unsafe { std::mem::zeroed() } 268 | } 269 | } 270 | 271 | impl std::fmt::Debug for CM_EXTENDED_PARAMETER_2 { 272 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 273 | write!(f, "CM_EXTENDED_PARAMETER_2 {{ union }}") 274 | } 275 | } 276 | 277 | impl Default for CM_EXTENDED_PARAMETER { 278 | fn default() -> Self { 279 | unsafe { std::mem::zeroed() } 280 | } 281 | } 282 | 283 | impl std::fmt::Debug for CM_EXTENDED_PARAMETER { 284 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 285 | write!( 286 | f, 287 | "CM_EXTENDED_PARAMETER {{ Anonymous1: {:?}, Anonymous2: {:?} }}", 288 | self.Anonymous1, self.Anonymous2 289 | ) 290 | } 291 | } 292 | 293 | #[repr(i32)] 294 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 295 | pub enum REG_ACTION { 296 | KeyAdded = 0, 297 | KeyRemoved = 1, 298 | KeyModified = 2, 299 | } 300 | 301 | #[repr(C)] 302 | pub struct REG_NOTIFY_INFORMATION { 303 | pub NextEntryOffset: u32, 304 | pub Action: REG_ACTION, 305 | pub KeyLength: u32, 306 | pub Key: [u16; 1], 307 | } 308 | 309 | impl Default for REG_NOTIFY_INFORMATION { 310 | fn default() -> Self { 311 | unsafe { std::mem::zeroed() } 312 | } 313 | } 314 | 315 | impl std::fmt::Debug for REG_NOTIFY_INFORMATION { 316 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 317 | write!( 318 | f, 319 | "REG_NOTIFY_INFORMATION {{ Action: {:?}, Key: {:?} }}", 320 | self.Action, self.Key 321 | ) 322 | } 323 | } 324 | 325 | #[repr(C)] 326 | pub struct KEY_PID_ARRAY { 327 | pub ProcessId: HANDLE, 328 | pub KeyName: UNICODE_STRING, 329 | } 330 | 331 | impl Default for KEY_PID_ARRAY { 332 | fn default() -> Self { 333 | unsafe { std::mem::zeroed() } 334 | } 335 | } 336 | 337 | impl std::fmt::Debug for KEY_PID_ARRAY { 338 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 339 | write!(f, "KEY_PID_ARRAY {{ }}") 340 | } 341 | } 342 | 343 | #[repr(C)] 344 | pub struct KEY_OPEN_SUBKEYS_INFORMATION { 345 | pub Count: u32, 346 | pub KeyArray: [KEY_PID_ARRAY; 1], 347 | } 348 | 349 | impl Default for KEY_OPEN_SUBKEYS_INFORMATION { 350 | fn default() -> Self { 351 | unsafe { std::mem::zeroed() } 352 | } 353 | } 354 | 355 | impl std::fmt::Debug for KEY_OPEN_SUBKEYS_INFORMATION { 356 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 357 | write!( 358 | f, 359 | "KEY_OPEN_SUBKEYS_INFORMATION {{ KeyArray: {:?} }}", 360 | self.KeyArray 361 | ) 362 | } 363 | } 364 | 365 | #[repr(C)] 366 | pub struct VR_INITIALIZE_JOB_FOR_VREG { 367 | pub Job: HANDLE, 368 | } 369 | 370 | impl Default for VR_INITIALIZE_JOB_FOR_VREG { 371 | fn default() -> Self { 372 | unsafe { std::mem::zeroed() } 373 | } 374 | } 375 | 376 | impl std::fmt::Debug for VR_INITIALIZE_JOB_FOR_VREG { 377 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 378 | write!(f, "VR_INITIALIZE_JOB_FOR_VREG {{ }}") 379 | } 380 | } 381 | 382 | #[repr(C)] 383 | pub struct VR_LOAD_DIFFERENCING_HIVE { 384 | pub Job: HANDLE, 385 | pub NextLayerIsHost: u32, 386 | pub Flags: u32, 387 | pub LoadFlags: u32, 388 | pub KeyPathLength: u16, 389 | pub HivePathLength: u16, 390 | pub NextLayerKeyPathLength: u16, 391 | pub FileAccessToken: HANDLE, 392 | pub Strings: [u16; 1], 393 | } 394 | 395 | impl Default for VR_LOAD_DIFFERENCING_HIVE { 396 | fn default() -> Self { 397 | unsafe { std::mem::zeroed() } 398 | } 399 | } 400 | 401 | impl std::fmt::Debug for VR_LOAD_DIFFERENCING_HIVE { 402 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 403 | write!( 404 | f, 405 | "VR_LOAD_DIFFERENCING_HIVE {{ Strings: {:?} }}", 406 | self.Strings 407 | ) 408 | } 409 | } 410 | 411 | #[repr(C)] 412 | pub struct VR_CREATE_NAMESPACE_NODE { 413 | pub Job: HANDLE, 414 | pub ContainerPathLength: u16, 415 | pub HostPathLength: u16, 416 | pub Flags: u32, 417 | pub AccessMask: u32, 418 | pub Strings: [u16; 1], 419 | } 420 | 421 | impl Default for VR_CREATE_NAMESPACE_NODE { 422 | fn default() -> Self { 423 | unsafe { std::mem::zeroed() } 424 | } 425 | } 426 | 427 | impl std::fmt::Debug for VR_CREATE_NAMESPACE_NODE { 428 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 429 | write!( 430 | f, 431 | "VR_CREATE_NAMESPACE_NODE {{ Strings: {:?} }}", 432 | self.Strings 433 | ) 434 | } 435 | } 436 | 437 | #[repr(C)] 438 | pub struct VR_MODIFY_FLAGS { 439 | pub Job: HANDLE, 440 | pub AddFlags: u32, 441 | pub RemoveFlags: u32, 442 | } 443 | 444 | impl Default for VR_MODIFY_FLAGS { 445 | fn default() -> Self { 446 | unsafe { std::mem::zeroed() } 447 | } 448 | } 449 | 450 | impl std::fmt::Debug for VR_MODIFY_FLAGS { 451 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 452 | write!(f, "VR_MODIFY_FLAGS {{ }}") 453 | } 454 | } 455 | 456 | #[repr(C)] 457 | pub struct NAMESPACE_NODE_DATA { 458 | pub AccessMask: u32, 459 | pub ContainerPathLength: u16, 460 | pub HostPathLength: u16, 461 | pub Flags: u32, 462 | pub Strings: [u16; 1], 463 | } 464 | 465 | impl Default for NAMESPACE_NODE_DATA { 466 | fn default() -> Self { 467 | unsafe { std::mem::zeroed() } 468 | } 469 | } 470 | 471 | impl std::fmt::Debug for NAMESPACE_NODE_DATA { 472 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 473 | write!(f, "NAMESPACE_NODE_DATA {{ Strings: {:?} }}", self.Strings) 474 | } 475 | } 476 | 477 | #[repr(C)] 478 | pub struct VR_CREATE_MULTIPLE_NAMESPACE_NODES { 479 | pub Job: HANDLE, 480 | pub NumNewKeys: u32, 481 | pub Keys: [NAMESPACE_NODE_DATA; 1], 482 | } 483 | 484 | impl Default for VR_CREATE_MULTIPLE_NAMESPACE_NODES { 485 | fn default() -> Self { 486 | unsafe { std::mem::zeroed() } 487 | } 488 | } 489 | 490 | impl std::fmt::Debug for VR_CREATE_MULTIPLE_NAMESPACE_NODES { 491 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 492 | write!( 493 | f, 494 | "VR_CREATE_MULTIPLE_NAMESPACE_NODES {{ Keys: {:?} }}", 495 | self.Keys 496 | ) 497 | } 498 | } 499 | 500 | #[repr(C)] 501 | pub struct VR_UNLOAD_DYNAMICALLY_LOADED_HIVES { 502 | pub Job: HANDLE, 503 | } 504 | 505 | impl Default for VR_UNLOAD_DYNAMICALLY_LOADED_HIVES { 506 | fn default() -> Self { 507 | unsafe { std::mem::zeroed() } 508 | } 509 | } 510 | 511 | impl std::fmt::Debug for VR_UNLOAD_DYNAMICALLY_LOADED_HIVES { 512 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 513 | write!(f, "VR_UNLOAD_DYNAMICALLY_LOADED_HIVES {{ }}") 514 | } 515 | } 516 | 517 | #[repr(C)] 518 | pub struct VR_GET_VIRTUAL_ROOT { 519 | pub Job: HANDLE, 520 | pub Index: u32, 521 | } 522 | 523 | impl Default for VR_GET_VIRTUAL_ROOT { 524 | fn default() -> Self { 525 | unsafe { std::mem::zeroed() } 526 | } 527 | } 528 | 529 | impl std::fmt::Debug for VR_GET_VIRTUAL_ROOT { 530 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 531 | write!(f, "VR_GET_VIRTUAL_ROOT {{ }}") 532 | } 533 | } 534 | 535 | #[repr(C)] 536 | pub struct VR_GET_VIRTUAL_ROOT_RESULT { 537 | pub Key: HANDLE, 538 | } 539 | 540 | impl Default for VR_GET_VIRTUAL_ROOT_RESULT { 541 | fn default() -> Self { 542 | unsafe { std::mem::zeroed() } 543 | } 544 | } 545 | 546 | impl std::fmt::Debug for VR_GET_VIRTUAL_ROOT_RESULT { 547 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 548 | write!(f, "VR_GET_VIRTUAL_ROOT_RESULT {{ }}") 549 | } 550 | } 551 | 552 | #[repr(C)] 553 | pub struct VR_LOAD_DIFFERENCING_HIVE_FOR_HOST { 554 | pub LoadFlags: u32, 555 | pub Flags: u32, 556 | pub KeyPathLength: u16, 557 | pub HivePathLength: u16, 558 | pub NextLayerKeyPathLength: u16, 559 | pub FileAccessToken: HANDLE, 560 | pub Strings: [u16; 1], 561 | } 562 | 563 | impl Default for VR_LOAD_DIFFERENCING_HIVE_FOR_HOST { 564 | fn default() -> Self { 565 | unsafe { std::mem::zeroed() } 566 | } 567 | } 568 | 569 | impl std::fmt::Debug for VR_LOAD_DIFFERENCING_HIVE_FOR_HOST { 570 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 571 | write!( 572 | f, 573 | "VR_LOAD_DIFFERENCING_HIVE_FOR_HOST {{ Strings: {:?} }}", 574 | self.Strings 575 | ) 576 | } 577 | } 578 | 579 | #[repr(C)] 580 | pub struct VR_UNLOAD_DIFFERENCING_HIVE_FOR_HOST { 581 | pub Reserved: u32, 582 | pub TargetKeyPathLength: u16, 583 | pub TargetKeyPath: [u16; 1], 584 | } 585 | 586 | impl Default for VR_UNLOAD_DIFFERENCING_HIVE_FOR_HOST { 587 | fn default() -> Self { 588 | unsafe { std::mem::zeroed() } 589 | } 590 | } 591 | 592 | impl std::fmt::Debug for VR_UNLOAD_DIFFERENCING_HIVE_FOR_HOST { 593 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 594 | write!( 595 | f, 596 | "VR_UNLOAD_DIFFERENCING_HIVE_FOR_HOST {{ TargetKeyPath: {:?} }}", 597 | self.TargetKeyPath 598 | ) 599 | } 600 | } 601 | 602 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 603 | extern "system" { 604 | pub fn NtCreateKey( 605 | KeyHandle: *mut HANDLE, 606 | DesiredAccess: u32, 607 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 608 | TitleIndex: u32, 609 | Class: *mut UNICODE_STRING, 610 | CreateOptions: u32, 611 | Disposition: *mut u32, 612 | ) -> NTSTATUS; 613 | } 614 | 615 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 616 | extern "system" { 617 | pub fn NtCreateKeyTransacted( 618 | KeyHandle: *mut HANDLE, 619 | DesiredAccess: u32, 620 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 621 | TitleIndex: u32, 622 | Class: *mut UNICODE_STRING, 623 | CreateOptions: u32, 624 | TransactionHandle: HANDLE, 625 | Disposition: *mut u32, 626 | ) -> NTSTATUS; 627 | } 628 | 629 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 630 | extern "system" { 631 | pub fn NtOpenKey( 632 | KeyHandle: *mut HANDLE, 633 | DesiredAccess: u32, 634 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 635 | ) -> NTSTATUS; 636 | } 637 | 638 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 639 | extern "system" { 640 | pub fn NtOpenKeyTransacted( 641 | KeyHandle: *mut HANDLE, 642 | DesiredAccess: u32, 643 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 644 | TransactionHandle: HANDLE, 645 | ) -> NTSTATUS; 646 | } 647 | 648 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 649 | extern "system" { 650 | pub fn NtOpenKeyEx( 651 | KeyHandle: *mut HANDLE, 652 | DesiredAccess: u32, 653 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 654 | OpenOptions: u32, 655 | ) -> NTSTATUS; 656 | } 657 | 658 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 659 | extern "system" { 660 | pub fn NtOpenKeyTransactedEx( 661 | KeyHandle: *mut HANDLE, 662 | DesiredAccess: u32, 663 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 664 | OpenOptions: u32, 665 | TransactionHandle: HANDLE, 666 | ) -> NTSTATUS; 667 | } 668 | 669 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 670 | extern "system" { 671 | pub fn NtDeleteKey(KeyHandle: HANDLE) -> NTSTATUS; 672 | } 673 | 674 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 675 | extern "system" { 676 | pub fn NtDeleteValueKey(KeyHandle: HANDLE, ValueName: *mut UNICODE_STRING) -> NTSTATUS; 677 | } 678 | 679 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 680 | extern "system" { 681 | pub fn NtQueryKey( 682 | KeyHandle: HANDLE, 683 | KeyInformationClass: KEY_INFORMATION_CLASS, 684 | KeyInformation: *mut std::ffi::c_void, 685 | Length: u32, 686 | ResultLength: *mut u32, 687 | ) -> NTSTATUS; 688 | } 689 | 690 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 691 | extern "system" { 692 | pub fn NtQueryValueKey( 693 | KeyHandle: HANDLE, 694 | ValueName: *mut UNICODE_STRING, 695 | KeyValueInformationClass: KEY_VALUE_INFORMATION_CLASS, 696 | KeyValueInformation: *mut std::ffi::c_void, 697 | Length: u32, 698 | ResultLength: *mut u32, 699 | ) -> NTSTATUS; 700 | } 701 | 702 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 703 | extern "system" { 704 | pub fn NtSetValueKey( 705 | KeyHandle: HANDLE, 706 | ValueName: *mut UNICODE_STRING, 707 | TitleIndex: u32, 708 | Type: u32, 709 | Data: *mut std::ffi::c_void, 710 | DataSize: u32, 711 | ) -> NTSTATUS; 712 | } 713 | 714 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 715 | extern "system" { 716 | pub fn NtEnumerateKey( 717 | KeyHandle: HANDLE, 718 | Index: u32, 719 | KeyInformationClass: KEY_INFORMATION_CLASS, 720 | KeyInformation: *mut std::ffi::c_void, 721 | Length: u32, 722 | ResultLength: *mut u32, 723 | ) -> NTSTATUS; 724 | } 725 | 726 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 727 | extern "system" { 728 | pub fn NtEnumerateValueKey( 729 | KeyHandle: HANDLE, 730 | Index: u32, 731 | KeyValueInformationClass: KEY_VALUE_INFORMATION_CLASS, 732 | KeyValueInformation: *mut std::ffi::c_void, 733 | Length: u32, 734 | ResultLength: *mut u32, 735 | ) -> NTSTATUS; 736 | } 737 | 738 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 739 | extern "system" { 740 | pub fn NtFlushKey(KeyHandle: HANDLE) -> NTSTATUS; 741 | } 742 | 743 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 744 | extern "system" { 745 | pub fn NtCompactKeys(Count: u32, KeyArray: *mut HANDLE) -> NTSTATUS; 746 | } 747 | 748 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 749 | extern "system" { 750 | pub fn NtCompressKey(KeyHandle: HANDLE) -> NTSTATUS; 751 | } 752 | 753 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 754 | extern "system" { 755 | pub fn NtLoadKey( 756 | TargetKey: *mut OBJECT_ATTRIBUTES, 757 | SourceFile: *mut OBJECT_ATTRIBUTES, 758 | ) -> NTSTATUS; 759 | } 760 | 761 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 762 | extern "system" { 763 | pub fn NtLoadKey2( 764 | TargetKey: *mut OBJECT_ATTRIBUTES, 765 | SourceFile: *mut OBJECT_ATTRIBUTES, 766 | Flags: u32, 767 | ) -> NTSTATUS; 768 | } 769 | 770 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 771 | extern "system" { 772 | pub fn NtLoadKeyEx( 773 | TargetKey: *mut OBJECT_ATTRIBUTES, 774 | SourceFile: *mut OBJECT_ATTRIBUTES, 775 | Flags: u32, 776 | TrustClassKey: HANDLE, 777 | Event: HANDLE, 778 | DesiredAccess: u32, 779 | RootHandle: *mut HANDLE, 780 | Reserved: *mut std::ffi::c_void, 781 | ) -> NTSTATUS; 782 | } 783 | 784 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 785 | extern "system" { 786 | pub fn NtLoadKey3( 787 | TargetKey: *mut OBJECT_ATTRIBUTES, 788 | SourceFile: *mut OBJECT_ATTRIBUTES, 789 | Flags: u32, 790 | ExtendedParameters: *mut CM_EXTENDED_PARAMETER, 791 | ExtendedParameterCount: u32, 792 | DesiredAccess: u32, 793 | RootHandle: *mut HANDLE, 794 | Reserved: *mut std::ffi::c_void, 795 | ) -> NTSTATUS; 796 | } 797 | 798 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 799 | extern "system" { 800 | pub fn NtReplaceKey( 801 | NewFile: *mut OBJECT_ATTRIBUTES, 802 | TargetHandle: HANDLE, 803 | OldFile: *mut OBJECT_ATTRIBUTES, 804 | ) -> NTSTATUS; 805 | } 806 | 807 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 808 | extern "system" { 809 | pub fn NtSaveKey(KeyHandle: HANDLE, FileHandle: HANDLE) -> NTSTATUS; 810 | } 811 | 812 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 813 | extern "system" { 814 | pub fn NtSaveKeyEx(KeyHandle: HANDLE, FileHandle: HANDLE, Format: u32) -> NTSTATUS; 815 | } 816 | 817 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 818 | extern "system" { 819 | pub fn NtSaveMergedKeys( 820 | HighPrecedenceKeyHandle: HANDLE, 821 | LowPrecedenceKeyHandle: HANDLE, 822 | FileHandle: HANDLE, 823 | ) -> NTSTATUS; 824 | } 825 | 826 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 827 | extern "system" { 828 | pub fn NtRestoreKey(KeyHandle: HANDLE, FileHandle: HANDLE, Flags: u32) -> NTSTATUS; 829 | } 830 | 831 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 832 | extern "system" { 833 | pub fn NtUnloadKey(TargetKey: *mut OBJECT_ATTRIBUTES) -> NTSTATUS; 834 | } 835 | 836 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 837 | extern "system" { 838 | pub fn NtUnloadKey2(TargetKey: *mut OBJECT_ATTRIBUTES, Flags: u32) -> NTSTATUS; 839 | } 840 | 841 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 842 | extern "system" { 843 | pub fn NtUnloadKeyEx(TargetKey: *mut OBJECT_ATTRIBUTES, Event: HANDLE) -> NTSTATUS; 844 | } 845 | 846 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 847 | extern "system" { 848 | pub fn NtNotifyChangeKey( 849 | KeyHandle: HANDLE, 850 | Event: HANDLE, 851 | ApcRoutine: PIO_APC_ROUTINE, 852 | ApcContext: *mut std::ffi::c_void, 853 | IoStatusBlock: *mut IO_STATUS_BLOCK, 854 | CompletionFilter: u32, 855 | WatchTree: BOOLEAN, 856 | Buffer: *mut std::ffi::c_void, 857 | BufferSize: u32, 858 | Asynchronous: BOOLEAN, 859 | ) -> NTSTATUS; 860 | } 861 | 862 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 863 | extern "system" { 864 | pub fn NtQueryOpenSubKeys(TargetKey: *mut OBJECT_ATTRIBUTES, HandleCount: *mut u32) 865 | -> NTSTATUS; 866 | } 867 | 868 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 869 | extern "system" { 870 | pub fn NtQueryOpenSubKeysEx( 871 | TargetKey: *mut OBJECT_ATTRIBUTES, 872 | BufferLength: u32, 873 | Buffer: *mut std::ffi::c_void, 874 | RequiredSize: *mut u32, 875 | ) -> NTSTATUS; 876 | } 877 | 878 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 879 | extern "system" { 880 | pub fn NtInitializeRegistry(BootCondition: u16) -> NTSTATUS; 881 | } 882 | 883 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 884 | extern "system" { 885 | pub fn NtLockRegistryKey(KeyHandle: HANDLE) -> NTSTATUS; 886 | } 887 | 888 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 889 | extern "system" { 890 | pub fn NtLockProductActivationKeys(pPrivateVer: *mut u32, pSafeMode: *mut u32) -> NTSTATUS; 891 | } 892 | 893 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 894 | extern "system" { 895 | pub fn NtFreezeRegistry(TimeOutInSeconds: u32) -> NTSTATUS; 896 | } 897 | 898 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 899 | extern "system" { 900 | pub fn NtThawRegistry() -> NTSTATUS; 901 | } 902 | 903 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 904 | extern "system" { 905 | pub fn NtCreateRegistryTransaction( 906 | RegistryTransactionHandle: *mut HANDLE, 907 | DesiredAccess: u32, 908 | ObjAttributes: *mut OBJECT_ATTRIBUTES, 909 | CreateOptions: u32, 910 | ) -> NTSTATUS; 911 | } 912 | 913 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 914 | extern "system" { 915 | pub fn NtCommitRegistryTransaction(RegistryTransactionHandle: HANDLE, Flags: u32) -> NTSTATUS; 916 | } 917 | -------------------------------------------------------------------------------- /src/ntseapi.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | Wdk::Foundation::OBJECT_ATTRIBUTES, 3 | Win32::{ 4 | Foundation::{BOOLEAN, HANDLE, LUID, NTSTATUS, UNICODE_STRING}, 5 | Security::{ 6 | GENERIC_MAPPING, OBJECT_TYPE_LIST, PRIVILEGE_SET, PSID, SECURITY_DESCRIPTOR, 7 | SID_AND_ATTRIBUTES, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_MANDATORY_POLICY, 8 | TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_TYPE, 9 | TOKEN_USER, 10 | }, 11 | }, 12 | }; 13 | 14 | use crate::bitfield::UnionField; 15 | 16 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_INVALID: u32 = 0; 17 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_INT64: u32 = 1; 18 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_UINT64: u32 = 2; 19 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_STRING: u32 = 3; 20 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_FQBN: u32 = 4; 21 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_SID: u32 = 5; 22 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_BOOLEAN: u32 = 6; 23 | pub const TOKEN_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING: u32 = 16; 24 | pub const TOKEN_SECURITY_ATTRIBUTE_NON_INHERITABLE: u32 = 1; 25 | pub const TOKEN_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE: u32 = 2; 26 | pub const TOKEN_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY: u32 = 4; 27 | pub const TOKEN_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT: u32 = 8; 28 | pub const TOKEN_SECURITY_ATTRIBUTE_DISABLED: u32 = 16; 29 | pub const TOKEN_SECURITY_ATTRIBUTE_MANDATORY: u32 = 32; 30 | pub const TOKEN_SECURITY_ATTRIBUTE_COMPARE_IGNORE: u32 = 64; 31 | pub const TOKEN_SECURITY_ATTRIBUTE_VALID_FLAGS: u32 = 63; 32 | pub const TOKEN_SECURITY_ATTRIBUTE_CUSTOM_FLAGS: u32 = 4294901760; 33 | pub const TOKEN_SECURITY_ATTRIBUTES_INFORMATION_VERSION_V1: u32 = 1; 34 | pub const TOKEN_SECURITY_ATTRIBUTES_INFORMATION_VERSION: u32 = 1; 35 | 36 | #[repr(C)] 37 | pub struct TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE { 38 | pub Version: u64, 39 | pub Name: UNICODE_STRING, 40 | } 41 | 42 | impl Default for TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE { 43 | fn default() -> Self { 44 | unsafe { std::mem::zeroed() } 45 | } 46 | } 47 | 48 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE { 49 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 50 | write!(f, "TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE {{ }}") 51 | } 52 | } 53 | 54 | #[repr(C)] 55 | pub struct TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE { 56 | pub pValue: *mut std::ffi::c_void, 57 | pub ValueLength: u32, 58 | } 59 | 60 | impl Default for TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE { 61 | fn default() -> Self { 62 | unsafe { std::mem::zeroed() } 63 | } 64 | } 65 | 66 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE { 67 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 68 | write!(f, "TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE {{ }}") 69 | } 70 | } 71 | 72 | #[repr(C)] 73 | pub struct TOKEN_SECURITY_ATTRIBUTE_V1 { 74 | pub Name: UNICODE_STRING, 75 | pub ValueType: u16, 76 | pub Reserved: u16, 77 | pub Flags: u32, 78 | pub ValueCount: u32, 79 | pub Values: TOKEN_SECURITY_ATTRIBUTE_V1_1, 80 | } 81 | 82 | #[repr(C)] 83 | pub struct TOKEN_SECURITY_ATTRIBUTE_V1_1 { 84 | pub pInt64: UnionField<*mut i64>, 85 | pub pUint64: UnionField<*mut u64>, 86 | pub pString: UnionField<*mut UNICODE_STRING>, 87 | pub pFqbn: UnionField<*mut TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE>, 88 | pub pOctetString: UnionField<*mut TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE>, 89 | pub union_field: u64, 90 | } 91 | 92 | impl Default for TOKEN_SECURITY_ATTRIBUTE_V1_1 { 93 | fn default() -> Self { 94 | unsafe { std::mem::zeroed() } 95 | } 96 | } 97 | 98 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTE_V1_1 { 99 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 100 | write!(f, "TOKEN_SECURITY_ATTRIBUTE_V1_1 {{ union }}") 101 | } 102 | } 103 | 104 | impl Default for TOKEN_SECURITY_ATTRIBUTE_V1 { 105 | fn default() -> Self { 106 | unsafe { std::mem::zeroed() } 107 | } 108 | } 109 | 110 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTE_V1 { 111 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 112 | write!( 113 | f, 114 | "TOKEN_SECURITY_ATTRIBUTE_V1 {{ Values: {:?} }}", 115 | self.Values 116 | ) 117 | } 118 | } 119 | 120 | #[repr(C)] 121 | pub struct TOKEN_SECURITY_ATTRIBUTES_INFORMATION { 122 | pub Version: u16, 123 | pub Reserved: u16, 124 | pub AttributeCount: u32, 125 | pub Attribute: TOKEN_SECURITY_ATTRIBUTES_INFORMATION_1, 126 | } 127 | 128 | #[repr(C)] 129 | #[derive(Copy, Clone)] 130 | 131 | pub union TOKEN_SECURITY_ATTRIBUTES_INFORMATION_1 { 132 | pub pAttributeV1: *mut TOKEN_SECURITY_ATTRIBUTE_V1, 133 | } 134 | 135 | impl Default for TOKEN_SECURITY_ATTRIBUTES_INFORMATION_1 { 136 | fn default() -> Self { 137 | unsafe { std::mem::zeroed() } 138 | } 139 | } 140 | 141 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTES_INFORMATION_1 { 142 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 143 | write!(f, "TOKEN_SECURITY_ATTRIBUTES_INFORMATION_1 {{ union }}") 144 | } 145 | } 146 | 147 | impl Default for TOKEN_SECURITY_ATTRIBUTES_INFORMATION { 148 | fn default() -> Self { 149 | unsafe { std::mem::zeroed() } 150 | } 151 | } 152 | 153 | impl std::fmt::Debug for TOKEN_SECURITY_ATTRIBUTES_INFORMATION { 154 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 155 | write!( 156 | f, 157 | "TOKEN_SECURITY_ATTRIBUTES_INFORMATION {{ Attribute: {:?} }}", 158 | self.Attribute 159 | ) 160 | } 161 | } 162 | 163 | #[repr(i32)] 164 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 165 | pub enum TOKEN_SECURITY_ATTRIBUTE_OPERATION { 166 | TOKEN_SECURITY_ATTRIBUTE_OPERATION_NONE = 0, 167 | TOKEN_SECURITY_ATTRIBUTE_OPERATION_REPLACE_ALL = 1, 168 | TOKEN_SECURITY_ATTRIBUTE_OPERATION_ADD = 2, 169 | TOKEN_SECURITY_ATTRIBUTE_OPERATION_DELETE = 3, 170 | TOKEN_SECURITY_ATTRIBUTE_OPERATION_REPLACE = 4, 171 | } 172 | 173 | #[repr(C)] 174 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] 175 | pub struct TOKEN_SECURITY_ATTRIBUTES_AND_OPERATION_INFORMATION { 176 | pub Attributes: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 177 | pub Operations: *mut TOKEN_SECURITY_ATTRIBUTE_OPERATION, 178 | } 179 | 180 | impl Default for TOKEN_SECURITY_ATTRIBUTES_AND_OPERATION_INFORMATION { 181 | fn default() -> Self { 182 | unsafe { std::mem::zeroed() } 183 | } 184 | } 185 | 186 | #[repr(C)] 187 | pub struct TOKEN_PROCESS_TRUST_LEVEL { 188 | pub TrustLevelSid: PSID, 189 | } 190 | 191 | impl Default for TOKEN_PROCESS_TRUST_LEVEL { 192 | fn default() -> Self { 193 | unsafe { std::mem::zeroed() } 194 | } 195 | } 196 | 197 | impl std::fmt::Debug for TOKEN_PROCESS_TRUST_LEVEL { 198 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 199 | write!(f, "TOKEN_PROCESS_TRUST_LEVEL {{ }}") 200 | } 201 | } 202 | 203 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 204 | extern "system" { 205 | pub fn NtCreateToken( 206 | TokenHandle: *mut HANDLE, 207 | DesiredAccess: u32, 208 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 209 | Type: TOKEN_TYPE, 210 | AuthenticationId: *mut LUID, 211 | ExpirationTime: *mut i64, 212 | User: *mut TOKEN_USER, 213 | Groups: *mut TOKEN_GROUPS, 214 | Privileges: *mut TOKEN_PRIVILEGES, 215 | Owner: *mut TOKEN_OWNER, 216 | PrimaryGroup: *mut TOKEN_PRIMARY_GROUP, 217 | DefaultDacl: *mut TOKEN_DEFAULT_DACL, 218 | Source: *mut TOKEN_SOURCE, 219 | ) -> NTSTATUS; 220 | } 221 | 222 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 223 | extern "system" { 224 | pub fn NtCreateLowBoxToken( 225 | TokenHandle: *mut HANDLE, 226 | ExistingTokenHandle: HANDLE, 227 | DesiredAccess: u32, 228 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 229 | PackageSid: PSID, 230 | CapabilityCount: u32, 231 | Capabilities: *mut SID_AND_ATTRIBUTES, 232 | HandleCount: u32, 233 | Handles: *mut HANDLE, 234 | ) -> NTSTATUS; 235 | } 236 | 237 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 238 | extern "system" { 239 | pub fn NtCreateTokenEx( 240 | TokenHandle: *mut HANDLE, 241 | DesiredAccess: u32, 242 | ObjectAttributes: *mut OBJECT_ATTRIBUTES, 243 | Type: TOKEN_TYPE, 244 | AuthenticationId: *mut LUID, 245 | ExpirationTime: *mut i64, 246 | User: *mut TOKEN_USER, 247 | Groups: *mut TOKEN_GROUPS, 248 | Privileges: *mut TOKEN_PRIVILEGES, 249 | UserAttributes: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 250 | DeviceAttributes: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 251 | DeviceGroups: *mut TOKEN_GROUPS, 252 | MandatoryPolicy: *mut TOKEN_MANDATORY_POLICY, 253 | Owner: *mut TOKEN_OWNER, 254 | PrimaryGroup: *mut TOKEN_PRIMARY_GROUP, 255 | DefaultDacl: *mut TOKEN_DEFAULT_DACL, 256 | Source: *mut TOKEN_SOURCE, 257 | ) -> NTSTATUS; 258 | } 259 | 260 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 261 | extern "system" { 262 | pub fn NtAdjustTokenClaimsAndDeviceGroups( 263 | TokenHandle: HANDLE, 264 | UserResetToDefault: BOOLEAN, 265 | DeviceResetToDefault: BOOLEAN, 266 | DeviceGroupsResetToDefault: BOOLEAN, 267 | NewUserState: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 268 | NewDeviceState: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 269 | NewDeviceGroupsState: *mut TOKEN_GROUPS, 270 | UserBufferLength: u32, 271 | PreviousUserState: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 272 | DeviceBufferLength: u32, 273 | PreviousDeviceState: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 274 | DeviceGroupsBufferLength: u32, 275 | PreviousDeviceGroups: *mut TOKEN_GROUPS, 276 | UserReturnLength: *mut u32, 277 | DeviceReturnLength: *mut u32, 278 | DeviceGroupsReturnBufferLength: *mut u32, 279 | ) -> NTSTATUS; 280 | } 281 | 282 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 283 | extern "system" { 284 | pub fn NtFilterTokenEx( 285 | ExistingTokenHandle: HANDLE, 286 | Flags: u32, 287 | SidsToDisable: *mut TOKEN_GROUPS, 288 | PrivilegesToDelete: *mut TOKEN_PRIVILEGES, 289 | RestrictedSids: *mut TOKEN_GROUPS, 290 | DisableUserClaimsCount: u32, 291 | UserClaimsToDisable: *mut UNICODE_STRING, 292 | DisableDeviceClaimsCount: u32, 293 | DeviceClaimsToDisable: *mut UNICODE_STRING, 294 | DeviceGroupsToDisable: *mut TOKEN_GROUPS, 295 | RestrictedUserAttributes: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 296 | RestrictedDeviceAttributes: *mut TOKEN_SECURITY_ATTRIBUTES_INFORMATION, 297 | RestrictedDeviceGroups: *mut TOKEN_GROUPS, 298 | NewTokenHandle: *mut HANDLE, 299 | ) -> NTSTATUS; 300 | } 301 | 302 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 303 | extern "system" { 304 | pub fn NtCompareTokens( 305 | FirstTokenHandle: HANDLE, 306 | SecondTokenHandle: HANDLE, 307 | Equal: *mut BOOLEAN, 308 | ) -> NTSTATUS; 309 | } 310 | 311 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 312 | extern "system" { 313 | pub fn NtQuerySecurityAttributesToken( 314 | TokenHandle: HANDLE, 315 | Attributes: *mut UNICODE_STRING, 316 | NumberOfAttributes: u32, 317 | Buffer: *mut std::ffi::c_void, 318 | Length: u32, 319 | ReturnLength: *mut u32, 320 | ) -> NTSTATUS; 321 | } 322 | 323 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 324 | extern "system" { 325 | pub fn NtAccessCheck( 326 | SecurityDescriptor: *mut SECURITY_DESCRIPTOR, 327 | ClientToken: HANDLE, 328 | DesiredAccess: u32, 329 | GenericMapping: *mut GENERIC_MAPPING, 330 | PrivilegeSet: *mut PRIVILEGE_SET, 331 | PrivilegeSetLength: *mut u32, 332 | GrantedAccess: *mut u32, 333 | AccessStatus: *mut NTSTATUS, 334 | ) -> NTSTATUS; 335 | } 336 | 337 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 338 | extern "system" { 339 | pub fn NtAccessCheckByType( 340 | SecurityDescriptor: *mut SECURITY_DESCRIPTOR, 341 | PrincipalSelfSid: PSID, 342 | ClientToken: HANDLE, 343 | DesiredAccess: u32, 344 | ObjectTypeList: *mut OBJECT_TYPE_LIST, 345 | ObjectTypeListLength: u32, 346 | GenericMapping: *mut GENERIC_MAPPING, 347 | PrivilegeSet: *mut PRIVILEGE_SET, 348 | PrivilegeSetLength: *mut u32, 349 | GrantedAccess: *mut u32, 350 | AccessStatus: *mut NTSTATUS, 351 | ) -> NTSTATUS; 352 | } 353 | 354 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 355 | extern "system" { 356 | pub fn NtAccessCheckByTypeResultList( 357 | SecurityDescriptor: *mut SECURITY_DESCRIPTOR, 358 | PrincipalSelfSid: PSID, 359 | ClientToken: HANDLE, 360 | DesiredAccess: u32, 361 | ObjectTypeList: *mut OBJECT_TYPE_LIST, 362 | ObjectTypeListLength: u32, 363 | GenericMapping: *mut GENERIC_MAPPING, 364 | PrivilegeSet: *mut PRIVILEGE_SET, 365 | PrivilegeSetLength: *mut u32, 366 | GrantedAccess: *mut u32, 367 | AccessStatus: *mut NTSTATUS, 368 | ) -> NTSTATUS; 369 | } 370 | 371 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 372 | extern "system" { 373 | pub fn NtSetCachedSigningLevel( 374 | Flags: u32, 375 | InputSigningLevel: u8, 376 | SourceFiles: *mut HANDLE, 377 | SourceFileCount: u32, 378 | TargetFile: HANDLE, 379 | ) -> NTSTATUS; 380 | } 381 | 382 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 383 | extern "system" { 384 | pub fn NtGetCachedSigningLevel( 385 | File: HANDLE, 386 | Flags: *mut u32, 387 | SigningLevel: *mut u8, 388 | Thumbprint: *mut u8, 389 | ThumbprintSize: *mut u32, 390 | ThumbprintAlgorithm: *mut u32, 391 | ) -> NTSTATUS; 392 | } 393 | 394 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 395 | extern "system" { 396 | pub fn NtCompareSigningLevels(FirstSigningLevel: u8, SecondSigningLevel: u8) -> NTSTATUS; 397 | } 398 | -------------------------------------------------------------------------------- /src/ntsmss.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::{HANDLE, NTSTATUS, UNICODE_STRING}; 2 | 3 | use crate::ntlpcapi::PORT_MESSAGE; 4 | 5 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 6 | extern "system" { 7 | pub fn RtlConnectToSm( 8 | ApiPortName: *mut UNICODE_STRING, 9 | ApiPortHandle: HANDLE, 10 | ProcessImageType: u32, 11 | SmssConnection: *mut HANDLE, 12 | ) -> NTSTATUS; 13 | } 14 | 15 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 16 | extern "system" { 17 | pub fn RtlSendMsgToSm(ApiPortHandle: HANDLE, MessageData: *mut PORT_MESSAGE) -> NTSTATUS; 18 | } 19 | -------------------------------------------------------------------------------- /src/ntsxs.rs: -------------------------------------------------------------------------------- 1 | use windows::{ 2 | core::GUID, 3 | Win32::{ 4 | Foundation::{BOOLEAN, HANDLE, UNICODE_STRING}, 5 | System::{ 6 | ApplicationInstallationAndServicing::{ 7 | ACTCTX_COMPATIBILITY_ELEMENT_TYPE, ACTCTX_REQUESTED_RUN_LEVEL, 8 | }, 9 | Kernel::LIST_ENTRY, 10 | }, 11 | }, 12 | }; 13 | 14 | pub const ACTIVATION_CONTEXT_DATA_FORMAT_WHISTLER: u32 = 1; 15 | pub const ACTIVATION_CONTEXT_FLAG_NO_INHERIT: u32 = 1; 16 | pub const ACTIVATION_CONTEXT_DATA_TOC_HEADER_DENSE: u32 = 1; 17 | pub const ACTIVATION_CONTEXT_DATA_TOC_HEADER_INORDER: u32 = 2; 18 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_INVALID: u32 = 1; 19 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_ROOT: u32 = 2; 20 | pub const ACTIVATION_CONTEXT_SECTION_FORMAT_UNKNOWN: u32 = 0; 21 | pub const ACTIVATION_CONTEXT_SECTION_FORMAT_STRING_TABLE: u32 = 1; 22 | pub const ACTIVATION_CONTEXT_SECTION_FORMAT_GUID_TABLE: u32 = 2; 23 | pub const ACTIVATION_CONTEXT_STRING_SECTION_FORMAT_WHISTLER: u32 = 1; 24 | pub const ACTIVATION_CONTEXT_STRING_SECTION_CASE_INSENSITIVE: u32 = 1; 25 | pub const ACTIVATION_CONTEXT_STRING_SECTION_ENTRIES_IN_PSEUDOKEY_ORDER: u32 = 2; 26 | pub const ACTIVATION_CONTEXT_GUID_SECTION_FORMAT_WHISTLER: u32 = 1; 27 | pub const ACTIVATION_CONTEXT_GUID_SECTION_ENTRIES_IN_ORDER: u32 = 1; 28 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_FORMAT_WHISTLER: u32 = 1; 29 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_ASSEMBLY: u32 = 1; 30 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_POLICY_APPLIED: u32 = 2; 31 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ASSEMBLY_POLICY_APPLIED: u32 = 4; 32 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_POLICY_APPLIED: u32 = 8; 33 | pub const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_PRIVATE_ASSEMBLY: u32 = 16; 34 | pub const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 35 | pub const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME: u32 = 1; 36 | pub const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT: u32 = 2; 37 | pub const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND: u32 = 4; 38 | pub const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL: u32 = 39 | 8; 40 | pub const ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 41 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 42 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_INVALID: u32 = 0; 43 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_APARTMENT: u32 = 1; 44 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_FREE: u32 = 2; 45 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_SINGLE: u32 = 3; 46 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_BOTH: u32 = 4; 47 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_NEUTRAL: u32 = 5; 48 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET: u32 = 8; 49 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_DEFAULT: u32 = 256; 50 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_ICON: u32 = 512; 51 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_CONTENT: u32 = 1024; 52 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_THUMBNAIL: u32 = 2048; 53 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_DOCPRINT: u32 = 4096; 54 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER: u32 = 1; 55 | pub const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS: u32 = 2; 56 | pub const ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 57 | pub const ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_NUM_METHODS_VALID: u32 = 1; 58 | pub const ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_BASE_INTERFACE_VALID: u32 = 2; 59 | pub const ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 60 | pub const ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION_FORMAT_WHISTLER: u32 = 1; 61 | pub const ACTIVATION_CONTEXT_DATA_CLR_SURROGATE_FORMAT_WHISTLER: u32 = 1; 62 | pub const ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS_FORMAT_LONGHORN: u32 = 1; 63 | pub const SXS_WINDOWS_SETTINGS_NAMESPACE: &[u8; 54] = 64 | b"http://schemas.microsoft.com/SMI/2005/WindowsSettings\0"; 65 | pub const SXS_WINDOWS_SETTINGS_2011_NAMESPACE: &[u8; 54] = 66 | b"http://schemas.microsoft.com/SMI/2011/WindowsSettings\0"; 67 | pub const SXS_WINDOWS_SETTINGS_2013_NAMESPACE: &[u8; 54] = 68 | b"http://schemas.microsoft.com/SMI/2013/WindowsSettings\0"; 69 | pub const SXS_WINDOWS_SETTINGS_2014_NAMESPACE: &[u8; 54] = 70 | b"http://schemas.microsoft.com/SMI/2014/WindowsSettings\0"; 71 | pub const SXS_WINDOWS_SETTINGS_2016_NAMESPACE: &[u8; 54] = 72 | b"http://schemas.microsoft.com/SMI/2016/WindowsSettings\0"; 73 | pub const SXS_WINDOWS_SETTINGS_2017_NAMESPACE: &[u8; 54] = 74 | b"http://schemas.microsoft.com/SMI/2017/WindowsSettings\0"; 75 | pub const SXS_WINDOWS_SETTINGS_2019_NAMESPACE: &[u8; 54] = 76 | b"http://schemas.microsoft.com/SMI/2019/WindowsSettings\0"; 77 | pub const SXS_WINDOWS_SETTINGS_2020_NAMESPACE: &[u8; 54] = 78 | b"http://schemas.microsoft.com/SMI/2020/WindowsSettings\0"; 79 | pub const ASSEMBLY_STORAGE_MAP_ASSEMBLY_ARRAY_IS_HEAP_ALLOCATED: u32 = 1; 80 | pub const ACTIVATION_CONTEXT_NOTIFICATION_DESTROY: u32 = 1; 81 | pub const ACTIVATION_CONTEXT_NOTIFICATION_ZOMBIFY: u32 = 2; 82 | pub const ACTIVATION_CONTEXT_NOTIFICATION_USED: u32 = 3; 83 | pub const RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION: u32 = 1; 84 | pub const RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NO_DEACTIVATE: u32 = 2; 85 | pub const RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ON_FREE_LIST: u32 = 4; 86 | pub const RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_HEAP_ALLOCATED: u32 = 8; 87 | pub const RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NOT_REALLY_ACTIVATED: u32 = 16; 88 | pub const ACTIVATION_CONTEXT_STACK_FLAG_QUERIES_DISABLED: u32 = 1; 89 | pub const ACTIVATION_CONTEXT_DATA_MAGIC: &[u8; 4] = b"xtcA"; 90 | pub const ACTIVATION_CONTEXT_STRING_SECTION_MAGIC: &[u8; 4] = b"dHsS"; 91 | pub const ACTIVATION_CONTEXT_GUID_SECTION_MAGIC: &[u8; 4] = b"dHsG"; 92 | 93 | #[repr(C)] 94 | pub struct ACTIVATION_CONTEXT_DATA { 95 | pub Magic: u32, 96 | pub HeaderSize: u32, 97 | pub FormatVersion: u32, 98 | pub TotalSize: u32, 99 | pub DefaultTocOffset: u32, 100 | pub ExtendedTocOffset: u32, 101 | pub AssemblyRosterOffset: u32, 102 | pub Flags: u32, 103 | } 104 | 105 | impl Default for ACTIVATION_CONTEXT_DATA { 106 | fn default() -> Self { 107 | unsafe { std::mem::zeroed() } 108 | } 109 | } 110 | 111 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA { 112 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 113 | write!(f, "ACTIVATION_CONTEXT_DATA {{ }}") 114 | } 115 | } 116 | 117 | #[repr(C)] 118 | pub struct ACTIVATION_CONTEXT_DATA_TOC_HEADER { 119 | pub HeaderSize: u32, 120 | pub EntryCount: u32, 121 | pub FirstEntryOffset: u32, 122 | pub Flags: u32, 123 | } 124 | 125 | impl Default for ACTIVATION_CONTEXT_DATA_TOC_HEADER { 126 | fn default() -> Self { 127 | unsafe { std::mem::zeroed() } 128 | } 129 | } 130 | 131 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_TOC_HEADER { 132 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 133 | write!(f, "ACTIVATION_CONTEXT_DATA_TOC_HEADER {{ }}") 134 | } 135 | } 136 | 137 | #[repr(C)] 138 | pub struct ACTIVATION_CONTEXT_DATA_TOC_ENTRY { 139 | pub Id: u32, 140 | pub Offset: u32, 141 | pub Length: u32, 142 | pub Format: u32, 143 | } 144 | 145 | impl Default for ACTIVATION_CONTEXT_DATA_TOC_ENTRY { 146 | fn default() -> Self { 147 | unsafe { std::mem::zeroed() } 148 | } 149 | } 150 | 151 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_TOC_ENTRY { 152 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 153 | write!(f, "ACTIVATION_CONTEXT_DATA_TOC_ENTRY {{ }}") 154 | } 155 | } 156 | 157 | #[repr(C)] 158 | pub struct ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER { 159 | pub HeaderSize: u32, 160 | pub EntryCount: u32, 161 | pub FirstEntryOffset: u32, 162 | pub Flags: u32, 163 | } 164 | 165 | impl Default for ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER { 166 | fn default() -> Self { 167 | unsafe { std::mem::zeroed() } 168 | } 169 | } 170 | 171 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER { 172 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 173 | write!(f, "ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER {{ }}") 174 | } 175 | } 176 | 177 | #[repr(C)] 178 | pub struct ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY { 179 | pub ExtensionGuid: GUID, 180 | pub TocOffset: u32, 181 | pub Length: u32, 182 | } 183 | 184 | impl Default for ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY { 185 | fn default() -> Self { 186 | unsafe { std::mem::zeroed() } 187 | } 188 | } 189 | 190 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY { 191 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 192 | write!(f, "ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY {{ }}") 193 | } 194 | } 195 | 196 | #[repr(C)] 197 | pub struct ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER { 198 | pub HeaderSize: u32, 199 | pub HashAlgorithm: u32, 200 | pub EntryCount: u32, 201 | pub FirstEntryOffset: u32, 202 | pub AssemblyInformationSectionOffset: u32, 203 | } 204 | 205 | impl Default for ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER { 206 | fn default() -> Self { 207 | unsafe { std::mem::zeroed() } 208 | } 209 | } 210 | 211 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER { 212 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 213 | write!(f, "ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER {{ }}") 214 | } 215 | } 216 | 217 | #[repr(C)] 218 | pub struct ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY { 219 | pub Flags: u32, 220 | pub PseudoKey: u32, 221 | pub AssemblyNameOffset: u32, 222 | pub AssemblyNameLength: u32, 223 | pub AssemblyInformationOffset: u32, 224 | pub AssemblyInformationLength: u32, 225 | } 226 | 227 | impl Default for ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY { 228 | fn default() -> Self { 229 | unsafe { std::mem::zeroed() } 230 | } 231 | } 232 | 233 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY { 234 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 235 | write!(f, "ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY {{ }}") 236 | } 237 | } 238 | 239 | #[repr(C)] 240 | pub struct ACTIVATION_CONTEXT_STRING_SECTION_HEADER { 241 | pub Magic: u32, 242 | pub HeaderSize: u32, 243 | pub FormatVersion: u32, 244 | pub DataFormatVersion: u32, 245 | pub Flags: u32, 246 | pub ElementCount: u32, 247 | pub ElementListOffset: u32, 248 | pub HashAlgorithm: u32, 249 | pub SearchStructureOffset: u32, 250 | pub UserDataOffset: u32, 251 | pub UserDataSize: u32, 252 | } 253 | 254 | impl Default for ACTIVATION_CONTEXT_STRING_SECTION_HEADER { 255 | fn default() -> Self { 256 | unsafe { std::mem::zeroed() } 257 | } 258 | } 259 | 260 | impl std::fmt::Debug for ACTIVATION_CONTEXT_STRING_SECTION_HEADER { 261 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 262 | write!(f, "ACTIVATION_CONTEXT_STRING_SECTION_HEADER {{ }}") 263 | } 264 | } 265 | 266 | #[repr(C)] 267 | pub struct ACTIVATION_CONTEXT_STRING_SECTION_ENTRY { 268 | pub PseudoKey: u32, 269 | pub KeyOffset: u32, 270 | pub KeyLength: u32, 271 | pub Offset: u32, 272 | pub Length: u32, 273 | pub AssemblyRosterIndex: u32, 274 | } 275 | 276 | impl Default for ACTIVATION_CONTEXT_STRING_SECTION_ENTRY { 277 | fn default() -> Self { 278 | unsafe { std::mem::zeroed() } 279 | } 280 | } 281 | 282 | impl std::fmt::Debug for ACTIVATION_CONTEXT_STRING_SECTION_ENTRY { 283 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 284 | write!(f, "ACTIVATION_CONTEXT_STRING_SECTION_ENTRY {{ }}") 285 | } 286 | } 287 | 288 | #[repr(C)] 289 | pub struct ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE { 290 | pub BucketTableEntryCount: u32, 291 | pub BucketTableOffset: u32, 292 | } 293 | 294 | impl Default for ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE { 295 | fn default() -> Self { 296 | unsafe { std::mem::zeroed() } 297 | } 298 | } 299 | 300 | impl std::fmt::Debug for ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE { 301 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 302 | write!(f, "ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE {{ }}") 303 | } 304 | } 305 | 306 | #[repr(C)] 307 | pub struct ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET { 308 | pub ChainCount: u32, 309 | pub ChainOffset: u32, 310 | } 311 | 312 | impl Default for ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET { 313 | fn default() -> Self { 314 | unsafe { std::mem::zeroed() } 315 | } 316 | } 317 | 318 | impl std::fmt::Debug for ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET { 319 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 320 | write!(f, "ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET {{ }}") 321 | } 322 | } 323 | 324 | #[repr(C)] 325 | pub struct ACTIVATION_CONTEXT_GUID_SECTION_HEADER { 326 | pub Magic: u32, 327 | pub HeaderSize: u32, 328 | pub FormatVersion: u32, 329 | pub DataFormatVersion: u32, 330 | pub Flags: u32, 331 | pub ElementCount: u32, 332 | pub ElementListOffset: u32, 333 | pub SearchStructureOffset: u32, 334 | pub UserDataOffset: u32, 335 | pub UserDataSize: u32, 336 | } 337 | 338 | impl Default for ACTIVATION_CONTEXT_GUID_SECTION_HEADER { 339 | fn default() -> Self { 340 | unsafe { std::mem::zeroed() } 341 | } 342 | } 343 | 344 | impl std::fmt::Debug for ACTIVATION_CONTEXT_GUID_SECTION_HEADER { 345 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 346 | write!(f, "ACTIVATION_CONTEXT_GUID_SECTION_HEADER {{ }}") 347 | } 348 | } 349 | 350 | #[repr(C)] 351 | pub struct ACTIVATION_CONTEXT_GUID_SECTION_ENTRY { 352 | pub Guid: GUID, 353 | pub Offset: u32, 354 | pub Length: u32, 355 | pub AssemblyRosterIndex: u32, 356 | } 357 | 358 | impl Default for ACTIVATION_CONTEXT_GUID_SECTION_ENTRY { 359 | fn default() -> Self { 360 | unsafe { std::mem::zeroed() } 361 | } 362 | } 363 | 364 | impl std::fmt::Debug for ACTIVATION_CONTEXT_GUID_SECTION_ENTRY { 365 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 366 | write!(f, "ACTIVATION_CONTEXT_GUID_SECTION_ENTRY {{ }}") 367 | } 368 | } 369 | 370 | #[repr(C)] 371 | pub struct ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE { 372 | pub BucketTableEntryCount: u32, 373 | pub BucketTableOffset: u32, 374 | } 375 | 376 | impl Default for ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE { 377 | fn default() -> Self { 378 | unsafe { std::mem::zeroed() } 379 | } 380 | } 381 | 382 | impl std::fmt::Debug for ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE { 383 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 384 | write!(f, "ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE {{ }}") 385 | } 386 | } 387 | 388 | #[repr(C)] 389 | pub struct ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET { 390 | pub ChainCount: u32, 391 | pub ChainOffset: u32, 392 | } 393 | 394 | impl Default for ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET { 395 | fn default() -> Self { 396 | unsafe { std::mem::zeroed() } 397 | } 398 | } 399 | 400 | impl std::fmt::Debug for ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET { 401 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 402 | write!(f, "ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET {{ }}") 403 | } 404 | } 405 | 406 | #[repr(C, packed(4))] 407 | pub struct ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION { 408 | pub Size: u32, 409 | pub Flags: u32, 410 | pub EncodedAssemblyIdentityLength: u32, 411 | pub EncodedAssemblyIdentityOffset: u32, 412 | pub ManifestPathType: u32, 413 | pub ManifestPathLength: u32, 414 | pub ManifestPathOffset: u32, 415 | pub ManifestLastWriteTime: i64, 416 | pub PolicyPathType: u32, 417 | pub PolicyPathLength: u32, 418 | pub PolicyPathOffset: u32, 419 | pub PolicyLastWriteTime: i64, 420 | pub MetadataSatelliteRosterIndex: u32, 421 | pub Unused2: u32, 422 | pub ManifestVersionMajor: u32, 423 | pub ManifestVersionMinor: u32, 424 | pub PolicyVersionMajor: u32, 425 | pub PolicyVersionMinor: u32, 426 | pub AssemblyDirectoryNameLength: u32, 427 | pub AssemblyDirectoryNameOffset: u32, 428 | pub NumOfFilesInAssembly: u32, 429 | pub LanguageLength: u32, 430 | pub LanguageOffset: u32, 431 | pub RunLevel: ACTCTX_REQUESTED_RUN_LEVEL, 432 | pub UiAccess: u32, 433 | } 434 | 435 | impl Default for ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION { 436 | fn default() -> Self { 437 | unsafe { std::mem::zeroed() } 438 | } 439 | } 440 | 441 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION { 442 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 443 | write!(f, "ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION {{ }}") 444 | } 445 | } 446 | 447 | #[repr(C)] 448 | pub struct ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION { 449 | pub Size: u32, 450 | pub Flags: u32, 451 | pub PolicyCoherencyGuid: GUID, 452 | pub PolicyOverrideGuid: GUID, 453 | pub ApplicationDirectoryPathType: u32, 454 | pub ApplicationDirectoryLength: u32, 455 | pub ApplicationDirectoryOffset: u32, 456 | pub ResourceName: u32, 457 | } 458 | 459 | impl Default for ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION { 460 | fn default() -> Self { 461 | unsafe { std::mem::zeroed() } 462 | } 463 | } 464 | 465 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION { 466 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 467 | write!( 468 | f, 469 | "ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION {{ }}" 470 | ) 471 | } 472 | } 473 | 474 | #[repr(C)] 475 | pub struct ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION { 476 | pub Size: u32, 477 | pub Flags: u32, 478 | pub TotalPathLength: u32, 479 | pub PathSegmentCount: u32, 480 | pub PathSegmentOffset: u32, 481 | } 482 | 483 | impl Default for ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION { 484 | fn default() -> Self { 485 | unsafe { std::mem::zeroed() } 486 | } 487 | } 488 | 489 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION { 490 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 491 | write!(f, "ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION {{ }}") 492 | } 493 | } 494 | 495 | #[repr(C)] 496 | pub struct ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT { 497 | pub Length: u32, 498 | pub Offset: u32, 499 | } 500 | 501 | impl Default for ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT { 502 | fn default() -> Self { 503 | unsafe { std::mem::zeroed() } 504 | } 505 | } 506 | 507 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT { 508 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 509 | write!( 510 | f, 511 | "ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT {{ }}" 512 | ) 513 | } 514 | } 515 | 516 | #[repr(C)] 517 | pub struct ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION { 518 | pub Size: u32, 519 | pub Flags: u32, 520 | pub VersionSpecificClassNameLength: u32, 521 | pub VersionSpecificClassNameOffset: u32, 522 | pub DllNameLength: u32, 523 | pub DllNameOffset: u32, 524 | } 525 | 526 | impl Default for ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION { 527 | fn default() -> Self { 528 | unsafe { std::mem::zeroed() } 529 | } 530 | } 531 | 532 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION { 533 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 534 | write!(f, "ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION {{ }}") 535 | } 536 | } 537 | 538 | #[repr(C)] 539 | pub struct ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION { 540 | pub Size: u32, 541 | pub Flags: u32, 542 | pub ThreadingModel: u32, 543 | pub ReferenceClsid: GUID, 544 | pub ConfiguredClsid: GUID, 545 | pub ImplementedClsid: GUID, 546 | pub TypeLibraryId: GUID, 547 | pub ModuleLength: u32, 548 | pub ModuleOffset: u32, 549 | pub ProgIdLength: u32, 550 | pub ProgIdOffset: u32, 551 | pub ShimDataLength: u32, 552 | pub ShimDataOffset: u32, 553 | pub MiscStatusDefault: u32, 554 | pub MiscStatusContent: u32, 555 | pub MiscStatusThumbnail: u32, 556 | pub MiscStatusIcon: u32, 557 | pub MiscStatusDocPrint: u32, 558 | } 559 | 560 | impl Default for ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION { 561 | fn default() -> Self { 562 | unsafe { std::mem::zeroed() } 563 | } 564 | } 565 | 566 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION { 567 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 568 | write!(f, "ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION {{ }}") 569 | } 570 | } 571 | 572 | #[repr(C)] 573 | pub struct ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM { 574 | pub Size: u32, 575 | pub Flags: u32, 576 | pub Type: u32, 577 | pub ModuleLength: u32, 578 | pub ModuleOffset: u32, 579 | pub TypeLength: u32, 580 | pub TypeOffset: u32, 581 | pub ShimVersionLength: u32, 582 | pub ShimVersionOffset: u32, 583 | pub DataLength: u32, 584 | pub DataOffset: u32, 585 | } 586 | 587 | impl Default for ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM { 588 | fn default() -> Self { 589 | unsafe { std::mem::zeroed() } 590 | } 591 | } 592 | 593 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM { 594 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 595 | write!( 596 | f, 597 | "ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM {{ }}" 598 | ) 599 | } 600 | } 601 | 602 | #[repr(C)] 603 | pub struct ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION { 604 | pub Size: u32, 605 | pub Flags: u32, 606 | pub ProxyStubClsid32: GUID, 607 | pub NumMethods: u32, 608 | pub TypeLibraryId: GUID, 609 | pub BaseInterface: GUID, 610 | pub NameLength: u32, 611 | pub NameOffset: u32, 612 | } 613 | 614 | impl Default for ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION { 615 | fn default() -> Self { 616 | unsafe { std::mem::zeroed() } 617 | } 618 | } 619 | 620 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION { 621 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 622 | write!( 623 | f, 624 | "ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION {{ }}" 625 | ) 626 | } 627 | } 628 | 629 | #[repr(C)] 630 | pub struct ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION { 631 | pub Major: u16, 632 | pub Minor: u16, 633 | } 634 | 635 | impl Default for ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION { 636 | fn default() -> Self { 637 | unsafe { std::mem::zeroed() } 638 | } 639 | } 640 | 641 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION { 642 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 643 | write!(f, "ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION {{ }}") 644 | } 645 | } 646 | 647 | #[repr(C)] 648 | pub struct ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION { 649 | pub Size: u32, 650 | pub Flags: u32, 651 | pub NameLength: u32, 652 | pub NameOffset: u32, 653 | pub ResourceId: u16, 654 | pub LibraryFlags: u16, 655 | pub HelpDirLength: u32, 656 | pub HelpDirOffset: u32, 657 | pub Version: ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION, 658 | } 659 | 660 | impl Default for ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION { 661 | fn default() -> Self { 662 | unsafe { std::mem::zeroed() } 663 | } 664 | } 665 | 666 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION { 667 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 668 | write!( 669 | f, 670 | "ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION {{ Version: {:?} }}", 671 | self.Version 672 | ) 673 | } 674 | } 675 | 676 | #[repr(C)] 677 | pub struct ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION { 678 | pub Size: u32, 679 | pub Flags: u32, 680 | pub ConfiguredClsidOffset: u32, 681 | } 682 | 683 | impl Default for ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION { 684 | fn default() -> Self { 685 | unsafe { std::mem::zeroed() } 686 | } 687 | } 688 | 689 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION { 690 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 691 | write!(f, "ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION {{ }}") 692 | } 693 | } 694 | 695 | #[repr(C)] 696 | pub struct ACTIVATION_CONTEXT_DATA_CLR_SURROGATE { 697 | pub Size: u32, 698 | pub Flags: u32, 699 | pub SurrogateIdent: GUID, 700 | pub VersionOffset: u32, 701 | pub VersionLength: u32, 702 | pub TypeNameOffset: u32, 703 | pub TypeNameLength: u32, 704 | } 705 | 706 | impl Default for ACTIVATION_CONTEXT_DATA_CLR_SURROGATE { 707 | fn default() -> Self { 708 | unsafe { std::mem::zeroed() } 709 | } 710 | } 711 | 712 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_CLR_SURROGATE { 713 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 714 | write!(f, "ACTIVATION_CONTEXT_DATA_CLR_SURROGATE {{ }}") 715 | } 716 | } 717 | 718 | #[repr(C)] 719 | pub struct ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS { 720 | pub Size: u32, 721 | pub Flags: u32, 722 | pub SettingNamespaceLength: u32, 723 | pub SettingNamespaceOffset: u32, 724 | pub SettingNameLength: u32, 725 | pub SettingNameOffset: u32, 726 | pub SettingValueLength: u32, 727 | pub SettingValueOffset: u32, 728 | } 729 | 730 | impl Default for ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS { 731 | fn default() -> Self { 732 | unsafe { std::mem::zeroed() } 733 | } 734 | } 735 | 736 | impl std::fmt::Debug for ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS { 737 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 738 | write!(f, "ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS {{ }}") 739 | } 740 | } 741 | 742 | #[repr(C)] 743 | pub struct COMPATIBILITY_CONTEXT_ELEMENT_LEGACY { 744 | pub Id: GUID, 745 | pub Type: ACTCTX_COMPATIBILITY_ELEMENT_TYPE, 746 | } 747 | 748 | impl Default for COMPATIBILITY_CONTEXT_ELEMENT_LEGACY { 749 | fn default() -> Self { 750 | unsafe { std::mem::zeroed() } 751 | } 752 | } 753 | 754 | impl std::fmt::Debug for COMPATIBILITY_CONTEXT_ELEMENT_LEGACY { 755 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 756 | write!(f, "COMPATIBILITY_CONTEXT_ELEMENT_LEGACY {{ }}") 757 | } 758 | } 759 | 760 | #[repr(C)] 761 | pub struct ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION_LEGACY { 762 | pub ElementCount: u32, 763 | pub Elements: [COMPATIBILITY_CONTEXT_ELEMENT_LEGACY; 1], 764 | } 765 | 766 | impl Default for ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION_LEGACY { 767 | fn default() -> Self { 768 | unsafe { std::mem::zeroed() } 769 | } 770 | } 771 | 772 | impl std::fmt::Debug for ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION_LEGACY { 773 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 774 | write!( 775 | f, 776 | "ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION_LEGACY {{ Elements: {:?} }}", 777 | self.Elements 778 | ) 779 | } 780 | } 781 | 782 | #[repr(C)] 783 | pub struct ASSEMBLY_STORAGE_MAP_ENTRY { 784 | pub Flags: u32, 785 | pub DosPath: UNICODE_STRING, 786 | pub Handle: HANDLE, 787 | } 788 | 789 | impl Default for ASSEMBLY_STORAGE_MAP_ENTRY { 790 | fn default() -> Self { 791 | unsafe { std::mem::zeroed() } 792 | } 793 | } 794 | 795 | impl std::fmt::Debug for ASSEMBLY_STORAGE_MAP_ENTRY { 796 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 797 | write!(f, "ASSEMBLY_STORAGE_MAP_ENTRY {{ }}") 798 | } 799 | } 800 | 801 | #[repr(C)] 802 | pub struct ASSEMBLY_STORAGE_MAP { 803 | pub Flags: u32, 804 | pub AssemblyCount: u32, 805 | pub AssemblyArray: *mut *mut ASSEMBLY_STORAGE_MAP_ENTRY, 806 | } 807 | 808 | impl Default for ASSEMBLY_STORAGE_MAP { 809 | fn default() -> Self { 810 | unsafe { std::mem::zeroed() } 811 | } 812 | } 813 | 814 | impl std::fmt::Debug for ASSEMBLY_STORAGE_MAP { 815 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 816 | write!( 817 | f, 818 | "ASSEMBLY_STORAGE_MAP {{ AssemblyArray: {:?} }}", 819 | self.AssemblyArray 820 | ) 821 | } 822 | } 823 | 824 | pub type PACTIVATION_CONTEXT_NOTIFY_ROUTINE = std::option::Option< 825 | unsafe extern "system" fn( 826 | NotificationType: u32, 827 | ActivationContext: *mut ACTIVATION_CONTEXT, 828 | ActivationContextData: *mut ACTIVATION_CONTEXT_DATA, 829 | NotificationContext: *mut std::ffi::c_void, 830 | NotificationData: *mut std::ffi::c_void, 831 | DisableThisNotification: *mut BOOLEAN, 832 | ), 833 | >; 834 | 835 | #[repr(C)] 836 | pub struct ACTIVATION_CONTEXT { 837 | pub RefCount: i32, 838 | pub Flags: u32, 839 | pub ActivationContextData: *mut ACTIVATION_CONTEXT_DATA, 840 | pub NotificationRoutine: PACTIVATION_CONTEXT_NOTIFY_ROUTINE, 841 | pub NotificationContext: *mut std::ffi::c_void, 842 | pub SentNotifications: [u32; 8], 843 | pub DisabledNotifications: [u32; 8], 844 | pub StorageMap: ASSEMBLY_STORAGE_MAP, 845 | pub InlineStorageMapEntries: [*mut ASSEMBLY_STORAGE_MAP_ENTRY; 32], 846 | } 847 | 848 | impl Default for ACTIVATION_CONTEXT { 849 | fn default() -> Self { 850 | unsafe { std::mem::zeroed() } 851 | } 852 | } 853 | 854 | impl std::fmt::Debug for ACTIVATION_CONTEXT { 855 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 856 | write!( 857 | f, 858 | "ACTIVATION_CONTEXT {{ ActivationContextData: {:?}, NotificationRoutine: {:?}, SentNotifications: {:?}, DisabledNotifications: {:?}, StorageMap: {:?}, InlineStorageMapEntries: {:?} }}", 859 | self.ActivationContextData, 860 | self.NotificationRoutine, 861 | self.SentNotifications, 862 | self.DisabledNotifications, 863 | self.StorageMap, 864 | self.InlineStorageMapEntries 865 | ) 866 | } 867 | } 868 | 869 | #[repr(C)] 870 | pub struct RTL_ACTIVATION_CONTEXT_STACK_FRAME { 871 | pub Previous: *mut RTL_ACTIVATION_CONTEXT_STACK_FRAME, 872 | pub ActivationContext: *mut ACTIVATION_CONTEXT, 873 | pub Flags: u32, 874 | } 875 | 876 | impl Default for RTL_ACTIVATION_CONTEXT_STACK_FRAME { 877 | fn default() -> Self { 878 | unsafe { std::mem::zeroed() } 879 | } 880 | } 881 | 882 | impl std::fmt::Debug for RTL_ACTIVATION_CONTEXT_STACK_FRAME { 883 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 884 | write!( 885 | f, 886 | "RTL_ACTIVATION_CONTEXT_STACK_FRAME {{ Previous: {:?} }}", 887 | self.Previous 888 | ) 889 | } 890 | } 891 | 892 | #[repr(C)] 893 | pub struct ACTIVATION_CONTEXT_STACK { 894 | pub ActiveFrame: *mut RTL_ACTIVATION_CONTEXT_STACK_FRAME, 895 | pub FrameListCache: LIST_ENTRY, 896 | pub Flags: u32, 897 | pub NextCookieSequenceNumber: u32, 898 | pub StackId: u32, 899 | } 900 | 901 | impl Default for ACTIVATION_CONTEXT_STACK { 902 | fn default() -> Self { 903 | unsafe { std::mem::zeroed() } 904 | } 905 | } 906 | 907 | impl std::fmt::Debug for ACTIVATION_CONTEXT_STACK { 908 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 909 | write!( 910 | f, 911 | "ACTIVATION_CONTEXT_STACK {{ ActiveFrame: {:?} }}", 912 | self.ActiveFrame 913 | ) 914 | } 915 | } 916 | -------------------------------------------------------------------------------- /src/nttmapi.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::NTSTATUS; 2 | 3 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 4 | extern "system" { 5 | pub fn NtFreezeTransactions(FreezeTimeout: *mut i64, ThawTimeout: *mut i64) -> NTSTATUS; 6 | } 7 | 8 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 9 | extern "system" { 10 | pub fn NtThawTransactions() -> NTSTATUS; 11 | } 12 | -------------------------------------------------------------------------------- /src/nttp.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::{ 2 | Foundation::{HANDLE, NTSTATUS}, 3 | System::{ 4 | Threading::{ 5 | CRITICAL_SECTION, PTP_CALLBACK_INSTANCE, PTP_CLEANUP_GROUP, PTP_IO, PTP_POOL, 6 | PTP_SIMPLE_CALLBACK, PTP_TIMER, PTP_TIMER_CALLBACK, PTP_WAIT, PTP_WAIT_CALLBACK, 7 | PTP_WORK, PTP_WORK_CALLBACK, TP_CALLBACK_ENVIRON_V3, TP_POOL_STACK_INFORMATION, 8 | }, 9 | IO::IO_STATUS_BLOCK, 10 | }, 11 | }; 12 | 13 | pub type PTP_ALPC_CALLBACK = std::option::Option< 14 | unsafe extern "system" fn( 15 | Instance: PTP_CALLBACK_INSTANCE, 16 | Context: *mut std::ffi::c_void, 17 | Alpc: *mut std::ffi::c_void, 18 | ), 19 | >; 20 | 21 | pub type PTP_ALPC_CALLBACK_EX = std::option::Option< 22 | unsafe extern "system" fn( 23 | Instance: PTP_CALLBACK_INSTANCE, 24 | Context: *mut std::ffi::c_void, 25 | Alpc: *mut std::ffi::c_void, 26 | ApcContext: *mut std::ffi::c_void, 27 | ), 28 | >; 29 | 30 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 31 | extern "system" { 32 | pub fn TpAllocPool(PoolReturn: *mut PTP_POOL, Reserved: *mut std::ffi::c_void) -> NTSTATUS; 33 | } 34 | 35 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 36 | extern "system" { 37 | pub fn TpReleasePool(Pool: PTP_POOL); 38 | } 39 | 40 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 41 | extern "system" { 42 | pub fn TpSetPoolMaxThreads(Pool: PTP_POOL, MaxThreads: u32); 43 | } 44 | 45 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 46 | extern "system" { 47 | pub fn TpSetPoolMinThreads(Pool: PTP_POOL, MinThreads: u32) -> NTSTATUS; 48 | } 49 | 50 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 51 | extern "system" { 52 | pub fn TpQueryPoolStackInformation( 53 | Pool: PTP_POOL, 54 | PoolStackInformation: *mut TP_POOL_STACK_INFORMATION, 55 | ) -> NTSTATUS; 56 | } 57 | 58 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 59 | extern "system" { 60 | pub fn TpSetPoolStackInformation( 61 | Pool: PTP_POOL, 62 | PoolStackInformation: *mut TP_POOL_STACK_INFORMATION, 63 | ) -> NTSTATUS; 64 | } 65 | 66 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 67 | extern "system" { 68 | pub fn TpSetPoolThreadBasePriority(Pool: PTP_POOL, BasePriority: u32) -> NTSTATUS; 69 | } 70 | 71 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 72 | extern "system" { 73 | pub fn TpAllocCleanupGroup(CleanupGroupReturn: *mut PTP_CLEANUP_GROUP) -> NTSTATUS; 74 | } 75 | 76 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 77 | extern "system" { 78 | pub fn TpReleaseCleanupGroup(CleanupGroup: PTP_CLEANUP_GROUP); 79 | } 80 | 81 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 82 | extern "system" { 83 | pub fn TpReleaseCleanupGroupMembers( 84 | CleanupGroup: PTP_CLEANUP_GROUP, 85 | CancelPendingCallbacks: u32, 86 | CleanupParameter: *mut std::ffi::c_void, 87 | ); 88 | } 89 | 90 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 91 | extern "system" { 92 | pub fn TpCallbackSetEventOnCompletion(Instance: PTP_CALLBACK_INSTANCE, Event: HANDLE); 93 | } 94 | 95 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 96 | extern "system" { 97 | pub fn TpCallbackReleaseSemaphoreOnCompletion( 98 | Instance: PTP_CALLBACK_INSTANCE, 99 | Semaphore: HANDLE, 100 | ReleaseCount: u32, 101 | ); 102 | } 103 | 104 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 105 | extern "system" { 106 | pub fn TpCallbackReleaseMutexOnCompletion(Instance: PTP_CALLBACK_INSTANCE, Mutex: HANDLE); 107 | } 108 | 109 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 110 | extern "system" { 111 | pub fn TpCallbackLeaveCriticalSectionOnCompletion( 112 | Instance: PTP_CALLBACK_INSTANCE, 113 | CriticalSection: *mut CRITICAL_SECTION, 114 | ); 115 | } 116 | 117 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 118 | extern "system" { 119 | pub fn TpCallbackUnloadDllOnCompletion( 120 | Instance: PTP_CALLBACK_INSTANCE, 121 | DllHandle: *mut std::ffi::c_void, 122 | ); 123 | } 124 | 125 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 126 | extern "system" { 127 | pub fn TpCallbackMayRunLong(Instance: PTP_CALLBACK_INSTANCE) -> NTSTATUS; 128 | } 129 | 130 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 131 | extern "system" { 132 | pub fn TpDisassociateCallback(Instance: PTP_CALLBACK_INSTANCE); 133 | } 134 | 135 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 136 | extern "system" { 137 | pub fn TpSimpleTryPost( 138 | Callback: PTP_SIMPLE_CALLBACK, 139 | Context: *mut std::ffi::c_void, 140 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 141 | ) -> NTSTATUS; 142 | } 143 | 144 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 145 | extern "system" { 146 | pub fn TpAllocWork( 147 | WorkReturn: *mut PTP_WORK, 148 | Callback: PTP_WORK_CALLBACK, 149 | Context: *mut std::ffi::c_void, 150 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 151 | ) -> NTSTATUS; 152 | } 153 | 154 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 155 | extern "system" { 156 | pub fn TpReleaseWork(Work: PTP_WORK); 157 | } 158 | 159 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 160 | extern "system" { 161 | pub fn TpPostWork(Work: PTP_WORK); 162 | } 163 | 164 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 165 | extern "system" { 166 | pub fn TpWaitForWork(Work: PTP_WORK, CancelPendingCallbacks: u32); 167 | } 168 | 169 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 170 | extern "system" { 171 | pub fn TpAllocTimer( 172 | Timer: *mut PTP_TIMER, 173 | Callback: PTP_TIMER_CALLBACK, 174 | Context: *mut std::ffi::c_void, 175 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 176 | ) -> NTSTATUS; 177 | } 178 | 179 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 180 | extern "system" { 181 | pub fn TpReleaseTimer(Timer: PTP_TIMER); 182 | } 183 | 184 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 185 | extern "system" { 186 | pub fn TpSetTimer(Timer: PTP_TIMER, DueTime: *mut i64, Period: u32, WindowLength: u32); 187 | } 188 | 189 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 190 | extern "system" { 191 | pub fn TpSetTimerEx( 192 | Timer: PTP_TIMER, 193 | DueTime: *mut i64, 194 | Period: u32, 195 | WindowLength: u32, 196 | ) -> NTSTATUS; 197 | } 198 | 199 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 200 | extern "system" { 201 | pub fn TpIsTimerSet(Timer: PTP_TIMER) -> u32; 202 | } 203 | 204 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 205 | extern "system" { 206 | pub fn TpWaitForTimer(Timer: PTP_TIMER, CancelPendingCallbacks: u32); 207 | } 208 | 209 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 210 | extern "system" { 211 | pub fn TpAllocWait( 212 | WaitReturn: *mut PTP_WAIT, 213 | Callback: PTP_WAIT_CALLBACK, 214 | Context: *mut std::ffi::c_void, 215 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 216 | ) -> NTSTATUS; 217 | } 218 | 219 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 220 | extern "system" { 221 | pub fn TpReleaseWait(Wait: PTP_WAIT); 222 | } 223 | 224 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 225 | extern "system" { 226 | pub fn TpSetWait(Wait: PTP_WAIT, Handle: HANDLE, Timeout: *mut i64); 227 | } 228 | 229 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 230 | extern "system" { 231 | pub fn TpSetWaitEx( 232 | Wait: PTP_WAIT, 233 | Handle: HANDLE, 234 | Timeout: *mut i64, 235 | Reserved: *mut std::ffi::c_void, 236 | ) -> NTSTATUS; 237 | } 238 | 239 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 240 | extern "system" { 241 | pub fn TpWaitForWait(Wait: PTP_WAIT, CancelPendingCallbacks: u32); 242 | } 243 | 244 | pub type PTP_IO_CALLBACK = std::option::Option< 245 | unsafe extern "system" fn( 246 | Instance: PTP_CALLBACK_INSTANCE, 247 | Context: *mut std::ffi::c_void, 248 | ApcContext: *mut std::ffi::c_void, 249 | IoSB: *mut IO_STATUS_BLOCK, 250 | Io: PTP_IO, 251 | ), 252 | >; 253 | 254 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 255 | extern "system" { 256 | pub fn TpAllocIoCompletion( 257 | IoReturn: *mut PTP_IO, 258 | File: HANDLE, 259 | Callback: PTP_IO_CALLBACK, 260 | Context: *mut std::ffi::c_void, 261 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 262 | ) -> NTSTATUS; 263 | } 264 | 265 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 266 | extern "system" { 267 | pub fn TpReleaseIoCompletion(Io: PTP_IO); 268 | } 269 | 270 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 271 | extern "system" { 272 | pub fn TpStartAsyncIoOperation(Io: PTP_IO); 273 | } 274 | 275 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 276 | extern "system" { 277 | pub fn TpCancelAsyncIoOperation(Io: PTP_IO); 278 | } 279 | 280 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 281 | extern "system" { 282 | pub fn TpWaitForIoCompletion(Io: PTP_IO, CancelPendingCallbacks: u32); 283 | } 284 | 285 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 286 | extern "system" { 287 | pub fn TpAllocAlpcCompletion( 288 | AlpcReturn: *mut *mut std::ffi::c_void, 289 | AlpcPort: HANDLE, 290 | Callback: PTP_ALPC_CALLBACK, 291 | Context: *mut std::ffi::c_void, 292 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 293 | ) -> NTSTATUS; 294 | } 295 | 296 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 297 | extern "system" { 298 | pub fn TpAllocAlpcCompletionEx( 299 | AlpcReturn: *mut *mut std::ffi::c_void, 300 | AlpcPort: HANDLE, 301 | Callback: PTP_ALPC_CALLBACK_EX, 302 | Context: *mut std::ffi::c_void, 303 | CallbackEnviron: *mut TP_CALLBACK_ENVIRON_V3, 304 | ) -> NTSTATUS; 305 | } 306 | 307 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 308 | extern "system" { 309 | pub fn TpReleaseAlpcCompletion(Alpc: *mut std::ffi::c_void); 310 | } 311 | 312 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 313 | extern "system" { 314 | pub fn TpWaitForAlpcCompletion(Alpc: *mut std::ffi::c_void); 315 | } 316 | 317 | #[repr(i32)] 318 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 319 | pub enum TP_TRACE_TYPE { 320 | TpTraceThreadPriority = 1, 321 | TpTraceThreadAffinity = 2, 322 | MaxTpTraceType = 3, 323 | } 324 | 325 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 326 | extern "system" { 327 | pub fn TpCaptureCaller(Type: TP_TRACE_TYPE); 328 | } 329 | 330 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 331 | extern "system" { 332 | pub fn TpCheckTerminateWorker(Thread: HANDLE); 333 | } 334 | -------------------------------------------------------------------------------- /src/ntxcapi.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::{ 2 | Foundation::{BOOLEAN, NTSTATUS}, 3 | System::Diagnostics::Debug::{CONTEXT, EXCEPTION_RECORD}, 4 | }; 5 | 6 | pub const KCONTINUE_FLAG_TEST_ALERT: u32 = 1; 7 | pub const KCONTINUE_FLAG_DELIVER_APC: u32 = 2; 8 | 9 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 10 | extern "system" { 11 | pub fn RtlDispatchException( 12 | ExceptionRecord: *mut EXCEPTION_RECORD, 13 | ContextRecord: *mut CONTEXT, 14 | ) -> BOOLEAN; 15 | } 16 | 17 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 18 | extern "system" { 19 | pub fn RtlRaiseStatus(Status: NTSTATUS) -> !; 20 | } 21 | 22 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 23 | extern "system" { 24 | pub fn NtContinue(ContextRecord: *mut CONTEXT, TestAlert: BOOLEAN) -> NTSTATUS; 25 | } 26 | 27 | #[repr(i32)] 28 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 29 | pub enum KCONTINUE_TYPE { 30 | KCONTINUE_UNWIND = 0, 31 | KCONTINUE_RESUME = 1, 32 | KCONTINUE_LONGJUMP = 2, 33 | KCONTINUE_SET = 3, 34 | KCONTINUE_LAST = 4, 35 | } 36 | 37 | #[repr(C)] 38 | pub struct KCONTINUE_ARGUMENT { 39 | pub ContinueType: KCONTINUE_TYPE, 40 | pub ContinueFlags: u32, 41 | pub Reserved: [u64; 2], 42 | } 43 | 44 | impl Default for KCONTINUE_ARGUMENT { 45 | fn default() -> Self { 46 | unsafe { std::mem::zeroed() } 47 | } 48 | } 49 | 50 | impl std::fmt::Debug for KCONTINUE_ARGUMENT { 51 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 52 | write!( 53 | f, 54 | "KCONTINUE_ARGUMENT {{ ContinueType: {:?}, Reserved: {:?} }}", 55 | self.ContinueType, self.Reserved 56 | ) 57 | } 58 | } 59 | 60 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 61 | extern "system" { 62 | pub fn NtContinueEx( 63 | ContextRecord: *mut CONTEXT, 64 | ContinueArgument: *mut std::ffi::c_void, 65 | ) -> NTSTATUS; 66 | } 67 | 68 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 69 | extern "system" { 70 | pub fn NtRaiseException( 71 | ExceptionRecord: *mut EXCEPTION_RECORD, 72 | ContextRecord: *mut CONTEXT, 73 | FirstChance: BOOLEAN, 74 | ) -> NTSTATUS; 75 | } 76 | -------------------------------------------------------------------------------- /src/phnt_ntdef.rs: -------------------------------------------------------------------------------- 1 | use windows::Win32::Foundation::BOOLEAN; 2 | 3 | pub const NT_FACILITY_MASK: u32 = 4095; 4 | pub const NT_FACILITY_SHIFT: u32 = 16; 5 | pub const OBJ_PROTECT_CLOSE: u32 = 1; 6 | pub const INT_ERROR: i32 = -1; 7 | pub const DESKTOP_ALL_ACCESS: u32 = 983551; 8 | pub const DESKTOP_GENERIC_READ: u32 = 131137; 9 | pub const DESKTOP_GENERIC_WRITE: u32 = 131262; 10 | pub const DESKTOP_GENERIC_EXECUTE: u32 = 131328; 11 | pub const WINSTA_GENERIC_READ: u32 = 131843; 12 | pub const WINSTA_GENERIC_WRITE: u32 = 131100; 13 | pub const WINSTA_GENERIC_EXECUTE: u32 = 131168; 14 | pub const WMIGUID_GENERIC_READ: u32 = 131085; 15 | pub const WMIGUID_GENERIC_WRITE: u32 = 131170; 16 | pub const WMIGUID_GENERIC_EXECUTE: u32 = 134800; 17 | 18 | #[repr(C)] 19 | #[repr(align(16))] 20 | pub struct QUAD_PTR { 21 | pub DoNotUseThisField1: usize, 22 | pub DoNotUseThisField2: usize, 23 | } 24 | 25 | impl Default for QUAD_PTR { 26 | fn default() -> Self { 27 | unsafe { std::mem::zeroed() } 28 | } 29 | } 30 | 31 | impl std::fmt::Debug for QUAD_PTR { 32 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 33 | write!(f, "QUAD_PTR {{ }}") 34 | } 35 | } 36 | 37 | #[repr(transparent)] 38 | #[derive(Copy, Hash, PartialEq, Eq)] 39 | pub struct PREGHANDLE(pub u64); 40 | 41 | impl PREGHANDLE { 42 | pub const fn is_invalid(&self) -> bool { 43 | self.0 == 0 44 | } 45 | } 46 | 47 | impl std::default::Default for PREGHANDLE { 48 | fn default() -> Self { 49 | unsafe { std::mem::zeroed() } 50 | } 51 | } 52 | 53 | impl std::clone::Clone for PREGHANDLE { 54 | fn clone(&self) -> Self { 55 | *self 56 | } 57 | } 58 | 59 | impl std::fmt::Debug for PREGHANDLE { 60 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 61 | f.debug_tuple("HANDLE").field(&self.0).finish() 62 | } 63 | } 64 | 65 | impl windows::core::TypeKind for PREGHANDLE { 66 | type TypeKind = windows::core::CopyType; 67 | } 68 | 69 | #[repr(transparent)] 70 | #[derive(Copy, Hash, PartialEq, Eq)] 71 | pub struct TRACEHANDLE(pub u64); 72 | 73 | impl TRACEHANDLE { 74 | pub const fn is_invalid(&self) -> bool { 75 | self.0 == 0 76 | } 77 | } 78 | 79 | impl std::default::Default for TRACEHANDLE { 80 | fn default() -> Self { 81 | unsafe { std::mem::zeroed() } 82 | } 83 | } 84 | 85 | impl std::clone::Clone for TRACEHANDLE { 86 | fn clone(&self) -> Self { 87 | *self 88 | } 89 | } 90 | 91 | impl std::fmt::Debug for TRACEHANDLE { 92 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 93 | f.debug_tuple("HANDLE").field(&self.0).finish() 94 | } 95 | } 96 | 97 | impl windows::core::TypeKind for TRACEHANDLE { 98 | type TypeKind = windows::core::CopyType; 99 | } 100 | 101 | pub type PENCLAVE_ROUTINE = 102 | Option u32>; 103 | 104 | pub type WAITORTIMERCALLBACKFUNC = 105 | Option; 106 | -------------------------------------------------------------------------------- /src/subprocesstag.rs: -------------------------------------------------------------------------------- 1 | use windows::core::{PCWSTR, PWSTR}; 2 | 3 | #[repr(i32)] 4 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 5 | pub enum TAG_INFO_LEVEL { 6 | eTagInfoLevelNameFromTag = 1, 7 | eTagInfoLevelNamesReferencingModule = 2, 8 | eTagInfoLevelNameTagMapping = 3, 9 | eTagInfoLevelMax = 4, 10 | } 11 | 12 | #[repr(i32)] 13 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] 14 | pub enum TAG_TYPE { 15 | eTagTypeService = 1, 16 | eTagTypeMax = 2, 17 | } 18 | 19 | #[repr(C)] 20 | pub struct TAG_INFO_NAME_FROM_TAG_IN_PARAMS { 21 | pub dwPid: u32, 22 | pub dwTag: u32, 23 | } 24 | 25 | impl Default for TAG_INFO_NAME_FROM_TAG_IN_PARAMS { 26 | fn default() -> Self { 27 | unsafe { std::mem::zeroed() } 28 | } 29 | } 30 | 31 | impl std::fmt::Debug for TAG_INFO_NAME_FROM_TAG_IN_PARAMS { 32 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 33 | write!(f, "TAG_INFO_NAME_FROM_TAG_IN_PARAMS {{ }}") 34 | } 35 | } 36 | 37 | #[repr(C)] 38 | pub struct TAG_INFO_NAME_FROM_TAG_OUT_PARAMS { 39 | pub eTagType: u32, 40 | pub pszName: PWSTR, 41 | } 42 | 43 | impl Default for TAG_INFO_NAME_FROM_TAG_OUT_PARAMS { 44 | fn default() -> Self { 45 | unsafe { std::mem::zeroed() } 46 | } 47 | } 48 | 49 | impl std::fmt::Debug for TAG_INFO_NAME_FROM_TAG_OUT_PARAMS { 50 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 51 | write!(f, "TAG_INFO_NAME_FROM_TAG_OUT_PARAMS {{ }}") 52 | } 53 | } 54 | 55 | #[repr(C)] 56 | pub struct TAG_INFO_NAME_FROM_TAG { 57 | pub InParams: TAG_INFO_NAME_FROM_TAG_IN_PARAMS, 58 | pub OutParams: TAG_INFO_NAME_FROM_TAG_OUT_PARAMS, 59 | } 60 | 61 | impl Default for TAG_INFO_NAME_FROM_TAG { 62 | fn default() -> Self { 63 | unsafe { std::mem::zeroed() } 64 | } 65 | } 66 | 67 | impl std::fmt::Debug for TAG_INFO_NAME_FROM_TAG { 68 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 69 | write!( 70 | f, 71 | "TAG_INFO_NAME_FROM_TAG {{ InParams: {:?}, OutParams: {:?} }}", 72 | self.InParams, self.OutParams 73 | ) 74 | } 75 | } 76 | 77 | #[repr(C)] 78 | pub struct TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS { 79 | pub dwPid: u32, 80 | pub pszModule: PWSTR, 81 | } 82 | 83 | impl Default for TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS { 84 | fn default() -> Self { 85 | unsafe { std::mem::zeroed() } 86 | } 87 | } 88 | 89 | impl std::fmt::Debug for TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS { 90 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 91 | write!(f, "TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS {{ }}") 92 | } 93 | } 94 | 95 | #[repr(C)] 96 | pub struct TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS { 97 | pub eTagType: u32, 98 | pub pmszNames: PWSTR, 99 | } 100 | 101 | impl Default for TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS { 102 | fn default() -> Self { 103 | unsafe { std::mem::zeroed() } 104 | } 105 | } 106 | 107 | impl std::fmt::Debug for TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS { 108 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 109 | write!(f, "TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS {{ }}") 110 | } 111 | } 112 | 113 | #[repr(C)] 114 | pub struct TAG_INFO_NAMES_REFERENCING_MODULE { 115 | pub InParams: TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS, 116 | pub OutParams: TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS, 117 | } 118 | 119 | impl Default for TAG_INFO_NAMES_REFERENCING_MODULE { 120 | fn default() -> Self { 121 | unsafe { std::mem::zeroed() } 122 | } 123 | } 124 | 125 | impl std::fmt::Debug for TAG_INFO_NAMES_REFERENCING_MODULE { 126 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 127 | write!( 128 | f, 129 | "TAG_INFO_NAMES_REFERENCING_MODULE {{ InParams: {:?}, OutParams: {:?} }}", 130 | self.InParams, self.OutParams 131 | ) 132 | } 133 | } 134 | 135 | #[repr(C)] 136 | pub struct TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS { 137 | pub dwPid: u32, 138 | } 139 | 140 | impl Default for TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS { 141 | fn default() -> Self { 142 | unsafe { std::mem::zeroed() } 143 | } 144 | } 145 | 146 | impl std::fmt::Debug for TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS { 147 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 148 | write!(f, "TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS {{ }}") 149 | } 150 | } 151 | 152 | #[repr(C)] 153 | pub struct TAG_INFO_NAME_TAG_MAPPING_ELEMENT { 154 | pub eTagType: u32, 155 | pub dwTag: u32, 156 | pub pszName: PWSTR, 157 | pub pszGroupName: PWSTR, 158 | } 159 | 160 | impl Default for TAG_INFO_NAME_TAG_MAPPING_ELEMENT { 161 | fn default() -> Self { 162 | unsafe { std::mem::zeroed() } 163 | } 164 | } 165 | 166 | impl std::fmt::Debug for TAG_INFO_NAME_TAG_MAPPING_ELEMENT { 167 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 168 | write!(f, "TAG_INFO_NAME_TAG_MAPPING_ELEMENT {{ }}") 169 | } 170 | } 171 | 172 | #[repr(C)] 173 | pub struct TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS { 174 | pub cElements: u32, 175 | pub pNameTagMappingElements: *mut TAG_INFO_NAME_TAG_MAPPING_ELEMENT, 176 | } 177 | 178 | impl Default for TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS { 179 | fn default() -> Self { 180 | unsafe { std::mem::zeroed() } 181 | } 182 | } 183 | 184 | impl std::fmt::Debug for TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS { 185 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 186 | write!( 187 | f, 188 | "TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS {{ pNameTagMappingElements: {:?} }}", 189 | self.pNameTagMappingElements 190 | ) 191 | } 192 | } 193 | 194 | #[repr(C)] 195 | pub struct TAG_INFO_NAME_TAG_MAPPING { 196 | pub InParams: TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS, 197 | pub pOutParams: *mut TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS, 198 | } 199 | 200 | impl Default for TAG_INFO_NAME_TAG_MAPPING { 201 | fn default() -> Self { 202 | unsafe { std::mem::zeroed() } 203 | } 204 | } 205 | 206 | impl std::fmt::Debug for TAG_INFO_NAME_TAG_MAPPING { 207 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 208 | write!( 209 | f, 210 | "TAG_INFO_NAME_TAG_MAPPING {{ InParams: {:?}, pOutParams: {:?} }}", 211 | self.InParams, self.pOutParams 212 | ) 213 | } 214 | } 215 | 216 | #[link(name = "ntdll.dll", kind = "raw-dylib", modifiers = "+verbatim")] 217 | extern "system" { 218 | pub fn I_QueryTagInformation( 219 | MachineName: PCWSTR, 220 | InfoLevel: TAG_INFO_LEVEL, 221 | TagInfo: *mut std::ffi::c_void, 222 | ) -> u32; 223 | } 224 | 225 | pub type PQUERY_TAG_INFORMATION = std::option::Option< 226 | unsafe extern "system" fn( 227 | MachineName: PCWSTR, 228 | InfoLevel: TAG_INFO_LEVEL, 229 | TagInfo: *mut std::ffi::c_void, 230 | ) -> u32, 231 | >; 232 | --------------------------------------------------------------------------------