use crate::*;
use crate::security::Descriptor;
use winapi::shared::minwindef::FALSE;
use winapi::um::securitybaseapi::*;
use winapi::um::winnt::*;
use core::marker::PhantomData;
use core::ptr::null_mut;
#[repr(transparent)] pub struct DescriptorBuilder<'b>(Descriptor<'b>);
impl DescriptorBuilder<'static> {
pub fn new() -> Self { Self::new_revision(SECURITY_DESCRIPTOR_REVISION).unwrap() }
fn new_revision(revision: u32) -> Result<Self, Error> {
let mut b = Self(Descriptor { desc: Default::default(), phantom: PhantomData });
Error::get_last_if(FALSE == unsafe { InitializeSecurityDescriptor(b.as_pdesc(), revision) })?;
Ok(b)
}
}
impl<'builder> DescriptorBuilder<'builder> {
pub fn dacl<'acl>(mut self, dacl_present: bool, dacl: impl Into<Option<acl::Ptr<'acl>>>, dacl_defaulted: bool) -> Result<DescriptorBuilder<'acl>, Error> where 'builder : 'acl {
let dacl = dacl.into();
let dacl = dacl.map_or(null_mut(), |o| o.as_pacl());
Error::get_last_if(FALSE == unsafe { SetSecurityDescriptorDacl(self.as_pdesc(), dacl_present as _, dacl, dacl_defaulted as _) })?;
Ok(self)
}
pub fn group<'sid>(mut self, group: impl Into<Option<&'sid sid::Value>>, group_defaulted: bool) -> Result<DescriptorBuilder<'sid>, Error> where 'builder : 'sid {
let group = group.into();
let group = group.map_or(null_mut(), |o| o.as_psid());
Error::get_last_if(FALSE == unsafe { SetSecurityDescriptorGroup(self.as_pdesc(), group, group_defaulted as _) })?;
Ok(self)
}
pub fn owner<'sid>(mut self, owner: impl Into<Option<&'sid sid::Value>>, owner_defaulted: bool) -> Result<DescriptorBuilder<'sid>, Error> where 'builder : 'sid {
let owner = owner.into();
let owner = owner.map_or(null_mut(), |o| o.as_psid());
Error::get_last_if(FALSE == unsafe { SetSecurityDescriptorOwner(self.as_pdesc(), owner, owner_defaulted as _) })?;
Ok(self)
}
pub fn sacl<'acl>(mut self, sacl_present: bool, sacl: impl Into<Option<acl::Ptr<'acl>>>, sacl_defaulted: bool) -> Result<DescriptorBuilder<'acl>, Error> where 'builder : 'acl {
let sacl = sacl.into();
let sacl = sacl.map_or(null_mut(), |o| o.as_pacl());
Error::get_last_if(FALSE == unsafe { SetSecurityDescriptorSacl(self.as_pdesc(), sacl_present as _, sacl, sacl_defaulted as _) })?;
Ok(self)
}
pub fn finish(self) -> Descriptor<'builder> { self.0 }
fn as_pdesc(&mut self) -> PSECURITY_DESCRIPTOR {
let desc : *mut SECURITY_DESCRIPTOR = &mut self.0.desc;
desc.cast()
}
}