#![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::*;
#[repr(C)]
pub struct BIND_OPTS3<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> {
cbStruct: u32,
pub grfFlags: co::BIND,
pub grfMode: co::STGM,
pub dwTickCountDeadline: u32,
pub dwTrackFlags: co::SLR,
pub dwClassContext: co::CLSCTX,
pub locale: LCID,
pServerInfo: *mut COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>,
pub hWnd: HWND,
_pServerInfo: PhantomData<&'a mut COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>>,
}
impl_default!(BIND_OPTS3, cbStruct, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i);
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> BIND_OPTS3<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> {
pub_fn_ptr_get_set!('a, pServerInfo, set_pServerInfo, COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>);
}
#[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_LEVEL,
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> {
pub cfFormat: co::CF,
ptd: *mut DVTARGETDEVICE,
pub dwAspect: co::DVASPECT,
pub lindex: i32,
pub tymed: co::TYMED,
_ptd: PhantomData<&'a mut DVTARGETDEVICE>,
}
impl<'a> Default for FORMATETC<'a> {
fn default() -> Self {
Self {
cfFormat: co::CF::default(),
ptd: std::ptr::null_mut(),
dwAspect: co::DVASPECT::default(),
lindex: -1,
tymed: co::TYMED::default(),
_ptd: PhantomData,
}
}
}
impl<'a> FORMATETC<'a> {
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],
}
#[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 from_strs(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
}
}
#[repr(C)]
pub struct STGMEDIUM {
pub tymed: co::TYMED,
pub ptr: usize,
pub pUnkForRelease: COMPTR,
}
impl_default!(STGMEDIUM);
impl STGMEDIUM {
#[must_use]
pub const unsafe fn ptr_hglobal(&self) -> Option<HGLOBAL> {
match &self.tymed {
&co::TYMED::HGLOBAL => Some(unsafe { HGLOBAL::from_ptr(self.ptr as _) }),
_ => None,
}
}
}