#![allow(non_camel_case_types, non_snake_case)]
use std::marker::PhantomData;
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::privs::*;
use crate::prelude::*;
#[repr(C)]
#[derive(Default)]
pub struct ACL {
pub AclRevision: u8,
pub Sbz1: u8,
pub AclSize: u16,
pub AceCount: u16,
pub Sbz2: u16,
}
#[repr(C)]
#[derive(Default)]
pub struct BY_HANDLE_FILE_INFORMATION {
pub dwFileAttributes: co::FILE_ATTRIBUTE,
pub ftCreationTime: FILETIME,
pub ftLastAccessTime: FILETIME,
pub ftLastWriteTime: FILETIME,
pub dwVolumeSerialNumber: u32,
pub nFileSizeHigh: u32,
pub nFileSizeLow: u32,
pub nNumberOfLinks: u32,
pub nFileIndexHigh: u32,
pub nFileIndexLow: u32,
}
#[repr(C)]
pub struct CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE<'a> {
pub Version: u64,
Name: *mut u16,
_Name: PhantomData<&'a mut u16>,
}
impl_default!(CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE, 'a);
impl<'a> CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE<'a> {
pub_fn_string_ptr_get_set!('a, Name, set_Name);
}
#[repr(C)]
pub struct CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE<'a> {
pValue: *mut u8,
ValueLength: u32,
_pValue: PhantomData<&'a mut ()>,
}
impl_default!(CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE, 'a);
impl<'a> CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE<'a> {
pub_fn_array_buf_get_set!('a, pValue, set_pValue, ValueLength, u8);
}
#[repr(C)]
pub struct CLAIM_SECURITY_ATTRIBUTE_V1<'a, 'b> {
Name: *mut u16,
ValueType: co::CLAIM_SECURITY_ATTRIBUTE_TYPE,
Reserved: u16,
Flags: u32,
ValueCount: u32,
Values: CLAIM_SECURITY_ATTRIBUTE_V1_union0<'b>,
_Name: PhantomData<&'a mut u16>,
}
#[repr(C)]
union CLAIM_SECURITY_ATTRIBUTE_V1_union0<'a> {
pInt64: *mut i64, pUint64: *mut u64,
ppString: *mut *mut u16,
pFqbn: *mut CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE<'a>,
pOctetString: *mut CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE<'a>,
}
impl_default!(CLAIM_SECURITY_ATTRIBUTE_V1, 'a, 'b);
impl<'a, 'b> CLAIM_SECURITY_ATTRIBUTE_V1<'a, 'b> {
pub_fn_string_ptr_get_set!('a, Name, set_Name);
#[must_use]
pub const fn FlagsLo(&self) -> co::CLAIM_SECURITY_ATTRIBUTE {
unsafe { co::CLAIM_SECURITY_ATTRIBUTE::from_raw(LOWORD(self.Flags)) }
}
pub fn set_FlagsLo(&mut self, claim: co::CLAIM_SECURITY_ATTRIBUTE) {
self.Flags = MAKEDWORD(claim.raw(), self.FlagsHi());
}
#[must_use]
pub const fn FlagsHi(&self) -> u16 {
HIWORD(self.Flags)
}
pub fn set_FlagsHi(&mut self, flags: u16) {
self.Flags = MAKEDWORD(self.FlagsLo().raw(), flags);
}
#[must_use]
pub fn Values(&self) -> ClaimSecurityAttr {
unsafe {
match self.ValueType {
co::CLAIM_SECURITY_ATTRIBUTE_TYPE::INT64 => ClaimSecurityAttr::Int64(
std::slice::from_raw_parts(self.Values.pInt64, self.ValueCount as _),
),
co::CLAIM_SECURITY_ATTRIBUTE_TYPE::UINT64 => ClaimSecurityAttr::Uint64(
std::slice::from_raw_parts(self.Values.pUint64, self.ValueCount as _),
),
co::CLAIM_SECURITY_ATTRIBUTE_TYPE::STRING => ClaimSecurityAttr::String(
std::slice::from_raw_parts(self.Values.ppString, self.ValueCount as _)
.iter()
.map(|str_ptr| WString::from_wchars_nullt(*str_ptr).to_string())
.collect(),
),
co::CLAIM_SECURITY_ATTRIBUTE_TYPE::FQBN => ClaimSecurityAttr::Fbqn(
std::slice::from_raw_parts(self.Values.pFqbn, self.ValueCount as _),
),
co::CLAIM_SECURITY_ATTRIBUTE_TYPE::OCTET_STRING => ClaimSecurityAttr::OctetString(
std::slice::from_raw_parts(self.Values.pOctetString, self.ValueCount as _),
),
_ => panic!("Invalid ValueType.")
}
}
}
}
#[repr(C)]
pub struct CLAIM_SECURITY_ATTRIBUTES_INFORMATION<'a, 'b> {
pub Version: u16,
Reserved: u16,
AttributeCount: u32,
pAttributeV1: *mut CLAIM_SECURITY_ATTRIBUTE_V1<'a, 'b>,
}
impl_default!(CLAIM_SECURITY_ATTRIBUTES_INFORMATION, 'a, 'b);
impl<'a, 'b> CLAIM_SECURITY_ATTRIBUTES_INFORMATION<'a, 'b> {
#[must_use]
pub fn pAttributeV1(&self) -> &[CLAIM_SECURITY_ATTRIBUTE_V1<'a, 'b>] {
unsafe {
std::slice::from_raw_parts(self.pAttributeV1, self.AttributeCount as _)
}
}
}
#[repr(C)]
#[derive(Default)]
pub struct CONSOLE_READCONSOLE_CONTROL {
pub nLength: u32,
pub nInitialChars: u32,
pub dwCtrlWakeupMask: u32,
pub dwControlKeyState: u32,
}
#[repr(C)]
#[derive(Default)]
pub struct DEV_BROADCAST_DEVICEINTERFACE {
pub hdr: DEV_BROADCAST_HDR,
pub dbcc_classguid: GUID,
dbcc_name: [u16; 1],
}
impl DEV_BROADCAST_DEVICEINTERFACE {
#[must_use]
pub fn dbcc_name(&self) -> String {
unsafe { WString::from_wchars_nullt(self.dbcc_name.as_ptr()) }
.to_string()
}
}
#[repr(C)]
pub struct DEV_BROADCAST_HANDLE {
pub hdr: DEV_BROADCAST_HDR,
pub dbch_handle: usize,
pub dbch_hdevnotify: usize, pub dbch_eventguid: GUID,
pub dbch_nameoffset: i16,
pub dbch_data: [u8; 1],
}
#[repr(C)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct DEV_BROADCAST_HDR {
pub dbch_size: u32,
pub dbch_devicetype: co::DBT_DEVTYP,
dbch_reserved: u32,
}
#[repr(C)]
#[derive(Default)]
pub struct DEV_BROADCAST_OEM {
pub hdr: DEV_BROADCAST_HDR,
pub dbco_identifier: u32,
pub dbco_suppfunc: u32,
}
#[repr(C)]
#[derive(Default)]
pub struct DEV_BROADCAST_PORT {
pub hdr: DEV_BROADCAST_HDR,
dbcp_name: [u16; 1],
}
impl DEV_BROADCAST_PORT {
#[must_use]
pub fn dbcp_name(&self) -> String {
unsafe { WString::from_wchars_nullt(self.dbcp_name.as_ptr()) }
.to_string()
}
}
#[derive(Default)]
pub struct DEV_BROADCAST_VOLUME {
pub hdr: DEV_BROADCAST_HDR,
pub dbcv_unitmask: u32,
pub dbcv_flags: co::DBTF,
}
#[repr(C)]
#[derive(Default, Clone, PartialEq, Eq)]
pub struct DISK_SPACE_INFORMATION {
pub ActualTotalAllocationUnits: u64,
pub ActualAvailableAllocationUnits: u64,
pub ActualPoolUnavailableAllocationUnits: u64,
pub CallerTotalAllocationUnits: u64,
pub CallerAvailableAllocationUnits: u64,
pub CallerPoolUnavailableAllocationUnits: u64,
pub UsedAllocationUnits: u64,
pub TotalReservedAllocationUnits: u64,
pub VolumeStorageReserveAllocationUnits: u64,
pub AvailableCommittedAllocationUnits: u64,
pub PoolAvailableAllocationUnits: u64,
pub SectorsPerAllocationUnit: u32,
pub BytesPerSector: u32,
}
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FILETIME {
pub dwLowDateTime: u32,
pub dwHighDateTime: u32,
}
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GUID {
data1: u32,
data2: u16,
data3: u16,
data4: u64,
}
impl std::fmt::Display for GUID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:08x}-{:04x}-{:04x}-{:04x}-{:012x}",
self.data1, self.data2, self.data3,
self.data4.swap_bytes() >> 48,
self.data4.swap_bytes() & 0x0000_ffff_ffff_ffff,
)
}
}
impl std::fmt::Debug for GUID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl GUID {
#[must_use]
pub const fn new(guid_str: &str) -> Self {
if guid_str.len() != 36 {
panic!("Bad number of GUID chars.");
}
let chs = guid_str.as_bytes();
let p1 = Self::parse_block([chs[0], chs[1], chs[2], chs[3], chs[4],
chs[5], chs[6], chs[7]]);
let p2 = Self::parse_block([chs[9], chs[10], chs[11], chs[12]]);
let p3 = Self::parse_block([chs[14], chs[15], chs[16], chs[17]]);
let p4 = Self::parse_block([chs[19], chs[20], chs[21], chs[22]]);
let p5 = Self::parse_block([chs[24], chs[25], chs[26], chs[27], chs[28],
chs[29], chs[30], chs[31], chs[32], chs[33], chs[34], chs[35]]);
Self {
data1: p1 as _,
data2: p2 as _,
data3: p3 as _,
data4: ((p4 << 48) | p5).swap_bytes(),
}
}
#[must_use]
const fn parse_block<const N: usize>(chars: [u8; N]) -> u64 {
let mut res: u64 = 0;
let mut idx: usize = 0;
while idx < N {
let ch = chars[idx];
if !Self::valid_char(ch) {
panic!("Bad GUID char.");
}
res += Self::char_to_num(ch) * 16_u64.pow((N - idx - 1) as _);
idx += 1;
}
res
}
#[must_use]
const fn valid_char(ch: u8) -> bool {
(ch >= 48 && ch <= 57) || (ch >= 65 && ch <= 70) || (ch >= 97 && ch <= 102) }
#[must_use]
const fn char_to_num(ch: u8) -> u64 {
if ch >= 48 && ch <= 57 {
ch as u64 - 48
} else if ch >= 65 && ch <= 70 {
ch as u64 - 65 + 10
} else if ch >= 97 && ch <= 102 {
ch as u64 - 97 + 10
} else {
panic!("Bad GUID char in conversion.");
}
}
}
#[repr(C)]
pub struct HEAPLIST32 {
dwSize: usize,
pub th32ProcessID: u32,
pub th32HeapID: usize,
pub dwFlags: co::HF32,
}
impl_default_with_size!(HEAPLIST32, dwSize);
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LANGID(u16);
impl_intunderlying!(LANGID, u16);
impl std::fmt::Display for LANGID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
impl LANGID {
pub const SYSTEM_DEFAULT: Self = Self::new(co::LANG::NEUTRAL, co::SUBLANG::SYS_DEFAULT);
pub const USER_DEFAULT: Self = Self::new(co::LANG::NEUTRAL, co::SUBLANG::DEFAULT);
#[must_use]
pub const fn new(lang: co::LANG, sublang: co::SUBLANG) -> Self {
Self((sublang.raw() << 10) | lang.raw())
}
#[must_use]
pub const fn primary_lang_id(self) -> co::LANG {
unsafe { co::LANG::from_raw(self.0 & 0x3ff) }
}
#[must_use]
pub const fn sub_lang_id(self) -> co::SUBLANG {
unsafe { co::SUBLANG::from_raw(self.0 >> 10) }
}
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LCID(u32);
impl_intunderlying!(LCID, u32);
impl LCID {
pub const SYSTEM_DEFAULT: Self = Self::new(LANGID::SYSTEM_DEFAULT, co::SORT::DEFAULT);
pub const USER_DEFAULT: Self = Self::new(LANGID::USER_DEFAULT, co::SORT::DEFAULT);
#[must_use]
pub const fn new(lang_id: LANGID, sort_id: co::SORT) -> Self {
Self(((sort_id.raw() as u32) << 16) | lang_id.raw() as u32)
}
#[must_use]
pub const fn lang_id(self) -> LANGID {
unsafe { LANGID::from_raw(self.raw() as _) }
}
#[must_use]
pub const fn sort_id(self) -> co::SORT {
unsafe { co::SORT::from_raw(((self.raw() >> 16) & 0xf) as _) }
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LUID {
LowPart: u32,
HighPart: i32,
}
impl std::fmt::Display for LUID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "LUID lo: {:#04x}, hi: {:#04x}", self.low_part(), self.high_part())
}
}
impl LUID {
pub const SYSTEM: Self = Self::new(0x3e7, 0x0);
pub const ANONYMOUS_LOGON: Self = Self::new(0x3e6, 0x0);
pub const LOCALSERVICE: Self = Self::new(0x3e5, 0x0);
pub const NETWORKSERVICE: Self = Self::new(0x3e4, 0x0);
pub const IUSER: Self = Self::new(0x3e3, 0x0);
pub const PROTECTED_TO_SYSTEM: Self = Self::new(0x3e2, 0x0);
#[must_use]
pub const fn new(low_part: u32, high_part: i32) -> Self {
Self { LowPart: low_part, HighPart: high_part }
}
#[must_use]
pub const fn low_part(&self) -> u32 {
self.LowPart
}
#[must_use]
pub const fn high_part(&self) -> i32 {
self.HighPart
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LUID_AND_ATTRIBUTES {
pub Luid: LUID,
pub Attributes: co::SE_PRIV_ATTR,
}
impl LUID_AND_ATTRIBUTES {
#[must_use]
pub const fn new(luid: LUID, attrs: co::SE_PRIV_ATTR) -> Self {
Self { Luid: luid, Attributes: attrs }
}
}
#[repr(C)]
pub struct MODULEENTRY32 {
dwSize: u32,
th32ModuleID: u32,
pub th32ProcessID: u32,
pub GlblcntUsage: u32,
pub ProccntUsage: u32,
pub modBaseAddr: *mut std::ffi::c_void,
pub modBaseSize: u32,
pub hModule: HINSTANCE,
szModule: [u16; MAX_MODULE_NAME32 + 1],
szExePath: [u16; MAX_PATH],
}
impl_default_with_size!(MODULEENTRY32, dwSize);
impl MODULEENTRY32 {
pub_fn_string_arr_get_set!(szModule, set_szModule);
pub_fn_string_arr_get_set!(szExePath, set_szExePath);
}
#[repr(C)]
pub struct MEMORYSTATUSEX {
dwLength: u32,
pub dwMemoryLoad: u32,
pub ullTotalPhys: u64,
pub ullAvailPhys: u64,
pub ullTotalPageFile: u64,
pub ullAvailPageFile: u64,
pub ullTotalVirtual: u64,
pub ullAvailVirtual: u64,
pub ullAvailExtendedVirtual: u64,
}
impl_default_with_size!(MEMORYSTATUSEX, dwLength);
#[repr(C)]
pub struct OSVERSIONINFOEX {
dwOSVersionInfoSize: u32,
pub dwMajorVersion: u32,
pub dwMinorVersion: u32,
pub dwBuildNumber: u32,
pub dwPlatformId: co::VER_PLATFORM,
szCSDVersion: [u16; 128],
pub wServicePackMajor: u16,
pub wServicePackMinor: u16,
pub wSuiteMask: co::VER_SUITE,
pub wProductType: co::VER_NT,
wReserved: u8,
}
impl_default_with_size!(OSVERSIONINFOEX, dwOSVersionInfoSize);
impl OSVERSIONINFOEX {
pub_fn_string_arr_get_set!(szCSDVersion, set_szCSDVersion);
}
#[repr(C)]
pub struct OVERLAPPED {
pub Internal: usize,
pub InternalHigh: usize,
pub Pointer: usize,
pub hEvent: HEVENT,
}
impl_default!(OVERLAPPED);
#[repr(C)]
pub struct POWERBROADCAST_SETTING {
pub PowerSetting: co::POWER_SETTING,
pub DataLength: u32,
Data: [u8; 1],
}
impl VariableSized for POWERBROADCAST_SETTING {}
impl POWERBROADCAST_SETTING {
#[must_use]
pub unsafe fn data(&self) -> PowerSetting {
match self.PowerSetting {
co::POWER_SETTING::ACDC_POWER_SOURCE => PowerSetting::AcDcPowerSource(
co::SYSTEM_POWER_CONDITION::from_raw(
std::slice::from_raw_parts(self.Data.as_ptr() as *const _, 1)[0],
),
),
co::POWER_SETTING::BATTERY_PERCENTAGE_REMAINING => PowerSetting::BatteryPercentageRemaining(
std::slice::from_raw_parts(self.Data.as_ptr() as *const u32, 1)[0] as _
),
co::POWER_SETTING::CONSOLE_DISPLAY_STATE => PowerSetting::ConsoleDisplayState(
co::MONITOR_DISPLAY_STATE::from_raw(
std::slice::from_raw_parts(self.Data.as_ptr() as *const _, 1)[0],
),
),
co::POWER_SETTING::GLOBAL_USER_PRESENCE => PowerSetting::GlobalUserPresence(
co::USER_ACTIVITY_PRESENCE::from_raw(
std::slice::from_raw_parts(self.Data.as_ptr() as *const _, 1)[0],
),
),
co::POWER_SETTING::IDLE_BACKGROUND_TASK => PowerSetting::IdleBackgroundTask,
co::POWER_SETTING::MONITOR_POWER_ON => PowerSetting::MonitorPowerOn(
match std::slice::from_raw_parts(self.Data.as_ptr() as *const u32, 1)[0] {
0 => false,
_ => true,
},
),
co::POWER_SETTING::POWER_SAVING_STATUS => PowerSetting::PowerSavingStatus(
match std::slice::from_raw_parts(self.Data.as_ptr() as *const u32, 1)[0] {
0 => false,
_ => true,
},
),
co::POWER_SETTING::POWERSCHEME_PERSONALITY => PowerSetting::PowerSchemePersonality(
std::slice::from_raw_parts(self.Data.as_ptr() as *const co::POWER_SAVINGS, 1)[0],
),
co::POWER_SETTING::SESSION_DISPLAY_STATUS => PowerSetting::SessionDisplayStatus(
co::MONITOR_DISPLAY_STATE::from_raw(
std::slice::from_raw_parts(self.Data.as_ptr() as *const _, 1)[0],
),
),
co::POWER_SETTING::SESSION_USER_PRESENCE => PowerSetting::SessionUserPresence(
co::USER_ACTIVITY_PRESENCE::from_raw(
std::slice::from_raw_parts(self.Data.as_ptr() as *const _, 1)[0],
),
),
co::POWER_SETTING::LIDSWITCH_STATE_CHANGE => PowerSetting::LidSwitchStateChange(
match std::slice::from_raw_parts(self.Data.as_ptr() as *const u8, 1)[0] {
0 => PowerSettingLid::Closed,
_ => PowerSettingLid::Opened,
},
),
co::POWER_SETTING::SYSTEM_AWAYMODE => PowerSetting::SystemAwayMode(
match std::slice::from_raw_parts(self.Data.as_ptr() as *const u8, 1)[0] {
0 => PowerSettingAwayMode::Exiting,
_ => PowerSettingAwayMode::Entering,
},
),
_ => panic!("Invalid co::POWER_SETTING."),
}
}
}
#[repr(C)]
pub struct PROCESS_HEAP_ENTRY {
pub lpData: *mut std::ffi::c_void,
pub cbData: u32,
pub cbOverhead: u8,
pub iRegionIndex: u8,
pub wFlags: co::PROCESS_HEAP,
union0: PROCESS_HEAP_ENTRY_union0,
}
#[repr(C)]
union PROCESS_HEAP_ENTRY_union0 {
Block: PROCESS_HEAP_ENTRY_Block,
Region: PROCESS_HEAP_ENTRY_Region,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PROCESS_HEAP_ENTRY_Block {
pub hMem: *mut std::ffi::c_void,
dwReserved: [u32; 3],
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PROCESS_HEAP_ENTRY_Region {
pub dwCommittedSize: u32,
pub dwUnCommittedSize: u32,
pub lpFirstBlock: *mut std::ffi::c_void,
pub lpLastBlock: *mut std::ffi::c_void,
}
impl_default!(PROCESS_HEAP_ENTRY);
impl PROCESS_HEAP_ENTRY {
#[must_use]
pub fn Block(&self) -> Option<&PROCESS_HEAP_ENTRY_Block> {
if self.wFlags.has(co::PROCESS_HEAP::ENTRY_MOVEABLE) {
Some(unsafe { &self.union0.Block })
} else {
None
}
}
#[must_use]
pub fn Region(&self) -> Option<&PROCESS_HEAP_ENTRY_Region> {
if self.wFlags.has(co::PROCESS_HEAP::REGION) {
Some(unsafe { &self.union0.Region })
} else {
None
}
}
}
#[repr(C)]
pub struct PROCESS_INFORMATION {
pub hProcess: HPROCESS,
pub hThread: HTHREAD,
pub dwProcessId: u32,
pub dwThreadId: u32,
}
impl_default!(PROCESS_INFORMATION);
#[repr(C)]
pub struct PROCESSENTRY32 {
dwSize: u32,
cntUsage: u32,
pub th32ProcessID: u32,
th32DefaultHeapID: usize,
th32ModuleID: u32,
pub cntThreads: u32,
pub th32ParentProcessID: u32,
pub pcPriClassBase: i32,
dwFlags: u32,
szExeFile: [u16; MAX_PATH],
}
impl_default_with_size!(PROCESSENTRY32, dwSize);
impl PROCESSENTRY32 {
pub_fn_string_arr_get_set!(szExeFile, set_szExeFile);
}
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq, Eq)]
pub struct PROCESSOR_NUMBER {
pub Group: u16,
pub Number: u8,
Reserved: u8,
}
#[repr(C)]
pub struct SECURITY_ATTRIBUTES<'a> {
nLength: u32,
lpSecurityDescriptor: *mut SECURITY_DESCRIPTOR,
bInheritHandle: i32,
_lpSecurityDescriptor: PhantomData<&'a mut SECURITY_DESCRIPTOR>,
}
impl_default_with_size!(SECURITY_ATTRIBUTES, nLength, 'a);
impl<'a> SECURITY_ATTRIBUTES<'a> {
pub_fn_ptr_get_set!('a, lpSecurityDescriptor, set_lpSecurityDescriptor, SECURITY_DESCRIPTOR);
pub_fn_bool_get_set!(bInheritHandle, set_bInheritHandle);
}
#[repr(C)]
pub struct SECURITY_DESCRIPTOR {
pub Revision: u8,
pub Sbz1: u8,
pub Control: co::SE,
pub Owner: *mut std::ffi::c_void,
pub Group: *mut std::ffi::c_void,
pub Sacl: *mut ACL,
pub Dacl: *mut ACL,
}
impl Default for SECURITY_DESCRIPTOR {
fn default() -> Self {
InitializeSecurityDescriptor().unwrap()
}
}
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq, Eq)]
pub struct SERVICE_TIMECHANGE_INFO {
liNewTime: i64,
liOldTime: i64,
}
impl SERVICE_TIMECHANGE_INFO {
#[must_use]
pub const fn liNewTime(&self) -> FILETIME {
FILETIME {
dwLowDateTime: LODWORD(self.liNewTime as _),
dwHighDateTime: HIDWORD(self.liNewTime as _),
}
}
#[must_use]
pub const fn liOldTime(&self) -> FILETIME {
FILETIME {
dwLowDateTime: LODWORD(self.liOldTime as _),
dwHighDateTime: HIDWORD(self.liOldTime as _),
}
}
pub fn set_liNewTime(&mut self, ft: FILETIME) {
self.liNewTime = MAKEQWORD(ft.dwLowDateTime, ft.dwHighDateTime) as _;
}
pub fn set_liOldTime(&mut self, ft: FILETIME) {
self.liOldTime = MAKEQWORD(ft.dwLowDateTime, ft.dwHighDateTime) as _;
}
}
#[repr(C)]
#[derive(Default, Clone, Copy)]
pub struct SERVICE_STATUS {
pub dwServiceType: co::SERVICE_TYPE,
pub dwCurrentState: co::SERVICE_STATE,
pub dwControlsAccepted: co::SERVICE_ACCEPT,
pub dwWin32ExitCode: u32,
pub dwServiceSpecificExitCode: u32,
pub dwCheckPoint: u32,
pub dwWaitPoint: u32,
}
#[repr(C)]
pub struct SID {
pub Revision: u8,
pub(in crate::kernel) SubAuthorityCount: u8,
pub IdentifierAuthority: SID_IDENTIFIER_AUTHORITY,
SubAuthority: [co::RID; 1],
}
impl VariableSized for SID {}
impl std::fmt::Display for SID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match ConvertSidToStringSid(self) {
Ok(name) => write!(f, "{}", name),
Err(err) => write!(f, "{}", err),
}
}
}
impl PartialEq<SID> for SID {
fn eq(&self, other: &SID) -> bool {
EqualSid(self, other).unwrap() }
}
impl Eq for SID {}
impl SID {
#[must_use]
pub fn SubAuthorityCount(&self) -> u8 {
self.SubAuthority().len() as _
}
#[must_use]
pub fn SubAuthority(&self) -> &[co::RID] {
unsafe {
std::slice::from_raw_parts(
self.SubAuthority.as_ptr(), self.SubAuthorityCount as _)
}
}
}
#[repr(C)]
#[derive(Clone)]
pub struct SID_AND_ATTRIBUTES<'a> {
Sid: *mut SID,
pub Attributes: u32,
_Sid: PhantomData<&'a mut SID>,
}
impl_default!(SID_AND_ATTRIBUTES, 'a);
impl<'a> SID_AND_ATTRIBUTES<'a> {
pub_fn_ptr_get_set!('a, Sid, set_Sid, SID);
}
#[repr(C)]
pub struct SID_AND_ATTRIBUTES_HASH<'a> {
SidCount: u32,
SidAttr: *mut SID_AND_ATTRIBUTES<'a>,
pub Hash: [usize; SID_HASH_SIZE],
}
impl_default!(SID_AND_ATTRIBUTES_HASH, 'a);
impl<'a> SID_AND_ATTRIBUTES_HASH<'a> {
pub_fn_array_buf_get_set!('a, SidAttr, set_SidAttr, SidCount, SID_AND_ATTRIBUTES);
}
#[repr(C)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct SID_IDENTIFIER_AUTHORITY {
pub Value: [u8; 6],
}
impl std::fmt::Display for SID_IDENTIFIER_AUTHORITY {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.Value, f) }
}
macro_rules! predef_sid_ident_au {
($name:ident, $val:expr) => {
pub const $name: Self = Self { Value: $val };
};
}
impl SID_IDENTIFIER_AUTHORITY {
predef_sid_ident_au!(NULL, [0, 0, 0, 0, 0, 0]);
predef_sid_ident_au!(WORLD, [0, 0, 0, 0, 0, 1]);
predef_sid_ident_au!(LOCAL, [0, 0, 0, 0, 0, 2]);
predef_sid_ident_au!(CREATOR, [0, 0, 0, 0, 0, 3]);
predef_sid_ident_au!(NON_UNIQUE, [0, 0, 0, 0, 0, 4]);
predef_sid_ident_au!(RESOURCE_MANAGER, [0, 0, 0, 0, 0, 9]);
predef_sid_ident_au!(NT, [0, 0, 0, 0, 0, 5]);
predef_sid_ident_au!(APP_PACKAGE, [0, 0, 0, 0, 0, 15]);
predef_sid_ident_au!(MANDATORY_LABEL, [0, 0, 0, 0, 0, 16]);
predef_sid_ident_au!(SCOPED_POLICY_ID, [0, 0, 0, 0, 0, 17]);
predef_sid_ident_au!(AUTHENTICATION, [0, 0, 0, 0, 0, 18]);
predef_sid_ident_au!(PROCESS_TRUST, [0, 0, 0, 0, 0, 19]);
}
#[repr(C)]
pub struct STARTUPINFO<'a, 'b> {
cb: u32,
lpReserved: *mut u16,
lpDesktop: *mut u16,
lpTitle: *mut u16,
pub dwX: u32,
pub dwY: u32,
pub dwXSize: u32,
pub dwYSize: u32,
pub dwXCountChars: u32,
pub dwYCountChars: u32,
pub dwFillAttribute: u32,
pub dwFlags: co::STARTF,
wShowWindow: u16, cbReserved2: u16,
lpReserved2: *mut u8,
pub hStdInput: HPIPE,
pub hStdOutput: HPIPE,
pub hStdError: HPIPE,
_lpDesktop: PhantomData<&'a mut u16>,
_lpTitle: PhantomData<&'b mut u16>,
}
impl_default_with_size!(STARTUPINFO, cb, 'a, 'b);
impl<'a, 'b> STARTUPINFO<'a, 'b> {
pub_fn_string_ptr_get_set!('a, lpDesktop, set_lpDesktop);
pub_fn_string_ptr_get_set!('a, lpTitle, set_lpTitle);
#[must_use]
pub const fn wShowWindow(&self) -> co::SW {
unsafe { co::SW::from_raw(self.wShowWindow as _) }
}
pub fn set_wShowWindow(&mut self, val: co::SW) {
self.wShowWindow = val.raw() as _;
}
}
#[repr(C)]
pub struct SYSTEM_INFO {
pub wProcessorArchitecture: co::PROCESSOR_ARCHITECTURE,
wReserved: u16,
pub dwPageSize: u32,
pub lpMinimumApplicationAddress: *mut std::ffi::c_void,
pub lpMaximumApplicationAddress: *mut std::ffi::c_void,
pub dwActiveProcessorMask: usize,
pub dwNumberOfProcessors: u32,
pub dwProcessorType: co::PROCESSOR,
pub dwAllocationGranularity: u32,
pub wProcessorLevel: u16,
pub wProcessorRevision: u16,
}
impl_default!(SYSTEM_INFO);
#[repr(C)]
#[derive(Default, Clone, PartialEq, Eq)]
pub struct SYSTEMTIME {
pub wYear: u16,
pub wMonth: u16,
pub wDayOfWeek: u16,
pub wDay: u16,
pub wHour: u16,
pub wMinute: u16,
pub wSecond: u16,
pub wMilliseconds: u16,
}
#[repr(C)]
pub struct THREADENTRY32 {
dwSize: u32,
cntUsage: u32,
pub th32ThreadID: u32,
pub th32OwnerProcessID: u32,
pub tpBasePri: i32,
tpDeltaPri: i32,
dwFlags: u32,
}
impl_default_with_size!(THREADENTRY32, dwSize);
#[repr(C)]
#[derive(Default)]
pub struct TIME_ZONE_INFORMATION {
pub bias: i32,
standardName: [u16; 32],
pub standardDate: SYSTEMTIME,
pub standardBias: i32,
daylightName: [u16; 32],
pub daylightDate: SYSTEMTIME,
pub daylightBias: i32,
}
impl TIME_ZONE_INFORMATION {
pub_fn_string_arr_get_set!(standardName, set_standardName);
pub_fn_string_arr_get_set!(daylightName, set_daylightName);
}
#[repr(C)]
pub struct TOKEN_ACCESS_INFORMATION<'a, 'b, 'c, 'd, 'e, 'f> {
SidHash: *mut SID_AND_ATTRIBUTES_HASH<'a>,
RestrictedSidHash: *mut SID_AND_ATTRIBUTES_HASH<'b>,
Privileges: *mut TOKEN_PRIVILEGES,
pub AuthenticationId: LUID,
pub TokenType: LUID,
pub ImpersonationLevel: co::SECURITY_IMPERSONATION,
pub MandatoryPolicy: TOKEN_MANDATORY_POLICY,
Flags: u32,
pub AppContainerNumber: u32,
PackageSid: *mut SID,
CapabilitiesHash: *mut SID_AND_ATTRIBUTES_HASH<'e>,
TrustLevelSid: *mut SID,
SecurityAttributes: *mut std::ffi::c_void,
_Privileges: PhantomData<&'c mut TOKEN_PRIVILEGES>,
_PackageSid: PhantomData<&'d mut SID>,
_TrustLevelSid: PhantomData<&'f mut SID>,
}
impl<'a, 'b, 'c, 'd, 'e, 'f> TOKEN_ACCESS_INFORMATION<'a, 'b, 'c, 'd, 'e, 'f> {
pub_fn_ptr_get_set!('a, SidHash, set_SidHash, SID_AND_ATTRIBUTES_HASH<'a>);
pub_fn_ptr_get_set!('b, RestrictedSidHash, set_RestrictedSidHash, SID_AND_ATTRIBUTES_HASH<'b>);
pub_fn_ptr_get_set!('c, Privileges, set_Privileges, TOKEN_PRIVILEGES);
pub_fn_ptr_get_set!('d, PackageSid, set_PackageSid, SID);
pub_fn_ptr_get_set!('e, CapabilitiesHash, set_CapabilitiesHash, SID_AND_ATTRIBUTES_HASH<'e>);
pub_fn_ptr_get_set!('f, TrustLevelSid, set_TrustLevelSid, SID);
}
impl_default!(TOKEN_ACCESS_INFORMATION, 'a, 'b, 'c, 'd, 'e, 'f);
#[repr(C)]
pub struct TOKEN_APPCONTAINER_INFORMATION<'a> {
TokenAppContainer: *mut SID,
_TokenAppContainer: PhantomData<&'a mut SID>,
}
impl_default!(TOKEN_APPCONTAINER_INFORMATION, 'a);
impl<'a> TOKEN_APPCONTAINER_INFORMATION<'a> {
pub_fn_ptr_get_set!('a, TokenAppContainer, set_TokenAppContainer, SID);
}
#[repr(C)]
pub struct TOKEN_DEFAULT_DACL<'a> {
DefaultDacl: *mut ACL,
_DefaultDacl: PhantomData<&'a mut ACL>,
}
impl_default!(TOKEN_DEFAULT_DACL, 'a);
impl<'a> TOKEN_DEFAULT_DACL<'a> {
pub_fn_ptr_get_set!('a, DefaultDacl, set_DefaultDacl, ACL);
}
#[repr(C)]
#[derive(Default)]
pub struct TOKEN_ELEVATION {
TokenIsElevated: u32,
}
impl TOKEN_ELEVATION {
pub_fn_bool_get_set!(TokenIsElevated, set_TokenIsElevated);
}
#[repr(C)]
pub struct TOKEN_GROUPS<'a> {
pub(in crate::kernel) GroupCount: u32,
Groups: [SID_AND_ATTRIBUTES<'a>; 1],
}
impl<'a> VariableSized for TOKEN_GROUPS<'a> {}
impl<'a> TOKEN_GROUPS<'a> {
#[must_use]
pub fn new(
groups: &'a [SID_AND_ATTRIBUTES<'a>],
) -> SysResult<TokenGroupsGuard<'a>>
{
TokenGroupsGuard::new(groups)
}
#[must_use]
pub const fn Groups(&self) -> &[SID_AND_ATTRIBUTES<'a>] {
unsafe {
std::slice::from_raw_parts(
self.Groups.as_ptr(),
self.GroupCount as _,
)
}
}
#[must_use]
pub fn Groups_mut(&mut self) -> &mut [SID_AND_ATTRIBUTES<'a>] {
unsafe {
std::slice::from_raw_parts_mut(
self.Groups.as_mut_ptr(),
self.GroupCount as _,
)
}
}
}
#[repr(C)]
pub struct TOKEN_GROUPS_AND_PRIVILEGES<'a, 'b, 'c> {
pub SidCount: u32,
pub SidLength: u32,
Sids: *mut SID_AND_ATTRIBUTES<'a>,
pub RestrictedSidCount: u32,
pub RestrictedSidLength: u32,
RestrictedSids: *mut SID_AND_ATTRIBUTES<'b>,
pub PrivilegeCount: u32,
pub PrivilegeLength: u32,
Privileges: *mut LUID_AND_ATTRIBUTES,
pub AuthenticationId: LUID,
_Privileges: PhantomData<&'c LUID_AND_ATTRIBUTES>,
}
impl_default!(TOKEN_GROUPS_AND_PRIVILEGES, 'a, 'b, 'c);
impl<'a, 'b, 'c> TOKEN_GROUPS_AND_PRIVILEGES<'a, 'b, 'c> {
pub_fn_ptr_get_set!('a, Sids, set_Sids, SID_AND_ATTRIBUTES<'a>);
pub_fn_ptr_get_set!('b, RestrictedSids, set_RestrictedSids, SID_AND_ATTRIBUTES<'b>);
pub_fn_ptr_get_set!('c, Privileges, set_Privileges, LUID_AND_ATTRIBUTES);
}
#[repr(C)]
pub struct TOKEN_LINKED_TOKEN {
pub LinkedToken: HACCESSTOKEN,
}
impl_default!(TOKEN_LINKED_TOKEN);
#[repr(C)]
pub struct TOKEN_MANDATORY_LABEL<'a> {
pub Label: SID_AND_ATTRIBUTES<'a>,
}
impl_default!(TOKEN_MANDATORY_LABEL, 'a);
#[repr(C)]
pub struct TOKEN_MANDATORY_POLICY {
pub Policy: co::TOKEN_MANDATORY_POLICY,
}
impl_default!(TOKEN_MANDATORY_POLICY);
#[repr(C)]
pub struct TOKEN_ORIGIN {
pub OriginatingLogonSession: LUID,
}
impl_default!(TOKEN_ORIGIN);
#[repr(C)]
pub struct TOKEN_OWNER<'a> {
Owner: *mut SID,
_Owner: PhantomData<&'a mut SID>,
}
impl_default!(TOKEN_OWNER, 'a);
impl<'a> TOKEN_OWNER<'a> {
pub_fn_ptr_get_set!('a, Owner, set_Owner, SID);
}
#[repr(C)]
pub struct TOKEN_PRIMARY_GROUP<'a> {
PrimaryGroup: *mut SID,
_Owner: PhantomData<&'a mut SID>,
}
impl_default!(TOKEN_PRIMARY_GROUP, 'a);
impl<'a> TOKEN_PRIMARY_GROUP<'a> {
pub_fn_ptr_get_set!('a, PrimaryGroup, set_PrimaryGroup, SID);
}
#[repr(C)]
pub struct TOKEN_PRIVILEGES {
pub(in crate::kernel) PrivilegeCount: u32,
Privileges: [LUID_AND_ATTRIBUTES; 1],
}
impl VariableSized for TOKEN_PRIVILEGES {}
impl TOKEN_PRIVILEGES {
#[must_use]
pub fn new(
privileges: &[LUID_AND_ATTRIBUTES],
) -> SysResult<TokenPrivilegesGuard>
{
TokenPrivilegesGuard::new(privileges)
}
#[must_use]
pub const fn Privileges(&self) -> &[LUID_AND_ATTRIBUTES] {
unsafe {
std::slice::from_raw_parts(
self.Privileges.as_ptr(),
self.PrivilegeCount as _,
)
}
}
#[must_use]
pub fn Privileges_mut(&mut self) -> &mut [LUID_AND_ATTRIBUTES] {
unsafe {
std::slice::from_raw_parts_mut(
self.Privileges.as_mut_ptr(),
self.PrivilegeCount as _,
)
}
}
}
#[repr(C)]
#[derive(PartialEq, Eq)]
pub struct TOKEN_SOURCE {
pub SourceName: [i8; TOKEN_SOURCE_LENGTH],
pub SourceIdentifier: LUID,
}
impl_default!(TOKEN_SOURCE);
#[repr(C)]
pub struct TOKEN_STATISTICS {
pub TokenId: LUID,
pub AuthenticationId: LUID,
pub ExpirationTime: i64,
pub TokenType: co::TOKEN_TYPE,
pub ImpersonationLevel: co::SECURITY_IMPERSONATION,
pub DynamicCharged: u32,
pub DynamicAvailable: u32,
pub GroupCount: u32,
pub PrivilegeCount: u32,
pub ModifiedId: LUID,
}
impl_default!(TOKEN_STATISTICS);
#[repr(C)]
#[derive(Default)]
pub struct TOKEN_USER<'a> {
pub User: SID_AND_ATTRIBUTES<'a>,
}
#[repr(C)]
#[derive(Clone)]
pub struct VALENT {
pub ve_valuename: *mut u16,
pub ve_valuelen: u32,
pub ve_valueptr: usize,
pub ve_type: co::REG,
}
impl_default!(VALENT);
impl VALENT {
#[must_use]
pub unsafe fn buf_projection<'a>(&'a self, src: &'a [u8]) -> &'a [u8] {
let proj_idx = self.ve_valueptr - src.as_ptr() as usize;
let proj_past_idx = proj_idx + self.ve_valuelen as usize;
&src[proj_idx..proj_past_idx]
}
}
#[repr(C)]
pub struct WIN32_FIND_DATA {
pub dwFileAttributes: co::FILE_ATTRIBUTE,
pub ftCreationTime: FILETIME,
pub ftLastAccessTime: FILETIME,
pub tLastWriteTime: FILETIME,
nFileSizeHigh: u32,
nFileSizeLow: u32,
dwReserved0: u32,
dwReserved1: u32,
cFileName: [u16; MAX_PATH],
cAlternateFileName: [u16; 14],
}
impl_default!(WIN32_FIND_DATA);
impl WIN32_FIND_DATA {
pub_fn_string_arr_get_set!(cFileName, set_cFileName);
pub_fn_string_arr_get_set!(cAlternateFileName, set_cAlternateFileName);
#[must_use]
pub const fn nFileSize(&self) -> u64 {
MAKEQWORD(self.nFileSizeLow, self.nFileSizeHigh)
}
}
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq)]
pub struct WTSSESSION_NOTIFICATION {
pub cbSize: u32,
pub dwSessionId: u32,
}