#![allow(non_camel_case_types, non_snake_case)]
use std::marker::PhantomData;
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::ffi_types::*;
use crate::prelude::*;
#[repr(C)]
pub struct COAUTHIDENTITY<'a, 'b, 'c> {
User: *mut u16,
UserLength: u32,
Domain: *mut u16,
DomainLength: u32,
Password: *mut u16,
PasswordLength: u32,
pub Flags: co::SEC_WINNT_AUTH_IDENTITY,
_User: PhantomData<&'a mut u16>,
_Domain: PhantomData<&'b mut u16>,
_Password: PhantomData<&'c mut u16>,
}
impl_default!(COAUTHIDENTITY, 'a, 'b, 'c);
impl<'a, 'b, 'c> COAUTHIDENTITY<'a, 'b, 'c> {
pub_fn_string_ptrlen_get_set!('a, User, set_User, UserLength);
pub_fn_string_ptrlen_get_set!('b, Domain, set_Domain, DomainLength);
pub_fn_string_ptrlen_get_set!('c, Password, set_Password, PasswordLength);
}
#[repr(C)]
pub struct COAUTHINFO<'a, 'b, 'c, 'd, 'e> {
pub dwAuthnSvc: co::RPC_C_AUTHN,
pub dwAuthzSvc: co::RPC_C_AUTHZ,
pwszServerPrincName: *mut u16,
pub dwAuthnLevel: co::RPC_C_AUTHN,
pub dwImpersonationLevel: co::RPC_C_IMP_LEVEL,
pAuthIdentityData: *mut COAUTHIDENTITY<'c, 'd, 'e>,
pub dwCapabilities: co::RPC_C_QOS_CAPABILITIES,
_pwszServerPrincName: PhantomData<&'a mut u16>,
_pAuthIdentityData: PhantomData<&'b mut COAUTHIDENTITY<'c, 'd, 'e>>,
}
impl_default!(COAUTHINFO, 'a, 'b, 'c, 'd, 'e);
impl<'a, 'b, 'c, 'd, 'e> COAUTHINFO<'a, 'b, 'c, 'd, 'e> {
pub_fn_string_ptr_get_set!('a, pwszServerPrincName, set_pwszServerPrincName);
pub_fn_ptr_get_set!('b, pAuthIdentityData, set_pAuthIdentityData, COAUTHIDENTITY<'c, 'd, 'e>);
}
#[repr(C)]
pub struct COSERVERINFO<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
dwReserved1: u32,
pwszName: *mut u16,
pAuthInfo: *mut COAUTHINFO<'c, 'd, 'e, 'f, 'g>,
dwReserved2: u32,
_pwszName: PhantomData<&'a mut u16>,
_pAuthInfo: PhantomData<&'b COAUTHINFO<'c, 'd, 'e, 'f, 'g>>,
}
impl_default!(COSERVERINFO, 'a, 'b, 'c, 'd, 'e, 'f, 'g);
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g> COSERVERINFO<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
pub_fn_string_ptr_get_set!('a, pwszName, set_pwszName);
pub_fn_ptr_get_set!('b, pAuthInfo, set_pAuthInfo, COAUTHINFO<'c, 'd, 'e, 'f, 'g>);
}
#[repr(C)]
pub struct FORMATETC<'a> {
cfFormat: u16,
ptd: *mut DVTARGETDEVICE,
pub dwAspect: u32,
pub lindex: i32,
pub tymed: co::TYMED,
_ptd: PhantomData<&'a mut DVTARGETDEVICE>,
}
impl<'a> Default for FORMATETC<'a> {
fn default() -> Self {
Self {
cfFormat: 0,
ptd: std::ptr::null_mut(),
dwAspect: 0,
lindex: -1,
tymed: co::TYMED::default(),
_ptd: PhantomData,
}
}
}
impl<'a> FORMATETC<'a> {
#[must_use]
pub fn cfFormat(&self) -> co::CF {
unsafe { co::CF::from_raw(self.cfFormat as _) }
}
pub fn set_cfFormat(&mut self, val: co::CF) {
self.cfFormat = val.raw() as _;
}
pub_fn_ptr_get_set!('a, ptd, set_ptd, DVTARGETDEVICE);
}
#[repr(C)]
#[derive(Default)]
pub struct DVTARGETDEVICE {
pub tdSize: u32,
pub tdDriverNameOffset: u16,
pub tdDeviceNameOffset: u16,
pub tdPortNameOffset: u16,
pub tdExtDevmodeOffset: u16,
pub tdData: [u8; 1],
}
impl VariableSized for DVTARGETDEVICE {}
#[repr(C)]
pub struct MULTI_QI<'a> {
pIID: *mut co::IID,
pItf: COMPTR,
pub hr: co::HRESULT,
_pIID: PhantomData<&'a mut co::IID>,
}
impl_default!(MULTI_QI, 'a);
impl_drop_comptr!(pItf, MULTI_QI, 'a);
impl<'a> MULTI_QI<'a> {
pub_fn_ptr_get_set!('a, pIID, set_pIID, co::IID);
pub_fn_comptr_get_set!(pItf, set_pItf, ole_IUnknown);
}
#[repr(transparent)]
pub struct SNB(*mut *mut u16);
impl_default!(SNB);
impl Drop for SNB {
fn drop(&mut self) {
let _ = unsafe { CoTaskMemFreeGuard::new(self.0 as _, 0) }; }
}
impl SNB {
#[must_use]
pub fn new(strs: &[impl AsRef<str>]) -> HrResult<Self> {
if strs.is_empty() {
return Ok(Self::default());
}
let tot_bytes_ptrs = (strs.len() + 1) * std::mem::size_of::<*mut u16>(); let wstrs = WString::from_str_vec(strs);
let num_valid_chars = wstrs.as_slice() .iter()
.filter(|ch| **ch != 0x0000)
.count();
let tot_bytes_wstrs = ( num_valid_chars + strs.len() ) * std::mem::size_of::<u16>();
let mut block = CoTaskMemAlloc(tot_bytes_ptrs + tot_bytes_wstrs)?; let ptr_block = block.as_mut_ptr() as *mut u8;
let ptr_block_wstrs = unsafe { ptr_block.add(tot_bytes_ptrs) } as *mut u16; let mut idx_cur_wstr = 0; *unsafe { block.as_mut_slice_aligned::<*mut u16>() }
.get_mut(idx_cur_wstr).unwrap() = ptr_block_wstrs; idx_cur_wstr += 1;
wstrs.as_slice()
.iter()
.enumerate()
.for_each(|(idx, ch)| {
if *ch == 0x0000 && idx_cur_wstr < strs.len() {
unsafe {
*block.as_mut_slice_aligned::<*mut u16>() .get_mut(idx_cur_wstr).unwrap() = ptr_block_wstrs.add(idx + 1);
}
idx_cur_wstr += 1;
}
});
*unsafe { block.as_mut_slice_aligned::<*mut u16>() }
.get_mut(idx_cur_wstr).unwrap() = std::ptr::null_mut(); wstrs.copy_to_slice( unsafe {
std::slice::from_raw_parts_mut(
ptr_block_wstrs,
tot_bytes_wstrs / std::mem::size_of::<u16>(),
)
},
);
let (ptr, _) = block.leak();
Ok(Self(ptr as _))
}
#[must_use]
pub const fn as_ptr(&self) -> *mut *mut u16 {
self.0
}
#[must_use]
pub fn to_strings(&self) -> Vec<String> {
let mut vec = Vec::<String>::new();
if !self.0.is_null() {
let mut idx_ptr = 0;
loop {
let ptr_ws = unsafe {
let sli_ptrs = std::slice::from_raw_parts(self.0, idx_ptr + 1);
*sli_ptrs.get_unchecked(idx_ptr) };
if ptr_ws.is_null() { break;
}
let ws = unsafe { WString::from_wchars_nullt(ptr_ws) };
vec.push(ws.to_string());
idx_ptr += 1;
}
}
vec
}
}