use {
super::*,
crate::{mut2ptr, ref2ptr, DebugExpectExt, OrErrno, TryClone},
std::{
fmt::{self, Debug, Formatter},
mem::MaybeUninit,
},
widestring::U16CStr,
windows_sys::Win32::{
Security::{InitializeSecurityDescriptor, SECURITY_DESCRIPTOR, SE_SELF_RELATIVE},
System::SystemServices::SECURITY_DESCRIPTOR_REVISION,
},
};
#[repr(C)]
pub struct SecurityDescriptor(SECURITY_DESCRIPTOR);
unsafe impl Sync for SecurityDescriptor {}
unsafe impl Send for SecurityDescriptor {}
unsafe impl AsSecurityDescriptor for SecurityDescriptor {
#[inline(always)]
fn as_sd(&self) -> *const c_void { ref2ptr(self).cast() }
}
unsafe impl AsSecurityDescriptorMut for SecurityDescriptor {
#[inline(always)]
fn as_sd_mut(&mut self) -> *mut c_void { mut2ptr(self).cast() }
}
impl SecurityDescriptor {
pub fn new() -> io::Result<Self> {
let mut sd = MaybeUninit::<SECURITY_DESCRIPTOR>::uninit();
unsafe {
InitializeSecurityDescriptor(mut2ptr(&mut sd).cast(), SECURITY_DESCRIPTOR_REVISION)
.true_or_errno(||
Self::from_owned(sd.assume_init()))
}
}
pub fn deserialize(sdsf: &U16CStr) -> io::Result<Self> {
let srsd = c_wrappers::deserialize(sdsf)?;
unsafe { BorrowedSecurityDescriptor::from_ptr(srsd.as_ptr()) }.to_owned_sd()
}
#[inline(always)]
pub unsafe fn from_owned(mut sd: SECURITY_DESCRIPTOR) -> Self {
debug_assert!(
unsafe {
c_wrappers::control_and_revision(ref2ptr(&sd).cast())
.expect("failed to verify that security descriptor is not self-relative")
.0
& SE_SELF_RELATIVE
== 0
},
"self-relative security descriptor not allowed here"
);
unsafe {
validate(mut2ptr(&mut sd).cast());
}
Self(sd)
}
}
impl Default for SecurityDescriptor {
fn default() -> Self {
Self::new().expect("could not default-initialize security descriptor")
}
}
impl TryClone for SecurityDescriptor {
#[inline]
fn try_clone(&self) -> io::Result<Self> { unsafe { super::clone(self.as_sd()) } }
}
impl SecurityDescriptor {
#[inline(always)]
pub fn borrow(&self) -> BorrowedSecurityDescriptor<'_> {
unsafe { BorrowedSecurityDescriptor::from_ptr(ref2ptr(self).cast()) }
}
#[inline(always)]
pub fn borrow_mut(&mut self) -> MutBorrowedSecurityDescriptor<'_> {
unsafe { MutBorrowedSecurityDescriptor::from_ptr(mut2ptr(self).cast()) }
}
}
impl Debug for SecurityDescriptor {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("SecurityDescriptor").field(&ref2ptr(self)).finish()
}
}
impl Drop for SecurityDescriptor {
fn drop(&mut self) {
self.free_contents().debug_expect("failed to free memory owned by security descriptor");
}
}