1#![allow(non_camel_case_types, non_snake_case)]
2
3use std::marker::PhantomData;
4
5use crate::co;
6use crate::decl::*;
7use crate::guard::*;
8use crate::kernel::ffi_types::*;
9
10#[repr(C)]
13pub struct BIND_OPTS3<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> {
14 cbStruct: u32,
15 pub grfFlags: co::BIND,
16 pub grfMode: co::STGM,
17 pub dwTickCountDeadline: u32,
18 pub dwTrackFlags: co::SLR,
19 pub dwClassContext: co::CLSCTX,
20 pub locale: LCID,
21 pServerInfo: *mut COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>,
22 pub hWnd: HWND,
23
24 _pServerInfo: PhantomData<&'a mut COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>>,
25}
26
27impl_default!(BIND_OPTS3, cbStruct, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i);
28
29impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> BIND_OPTS3<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'i> {
30 pub_fn_ptr_get_set!('a, pServerInfo, set_pServerInfo, COSERVERINFO<'b, 'c, 'd, 'e, 'f, 'g, 'i>);
31}
32
33#[repr(C)]
36pub struct COAUTHIDENTITY<'a, 'b, 'c> {
37 User: *mut u16,
38 UserLength: u32,
39 Domain: *mut u16,
40 DomainLength: u32,
41 Password: *mut u16,
42 PasswordLength: u32,
43 pub Flags: co::SEC_WINNT_AUTH_IDENTITY,
44
45 _User: PhantomData<&'a mut u16>,
46 _Domain: PhantomData<&'b mut u16>,
47 _Password: PhantomData<&'c mut u16>,
48}
49
50impl_default!(COAUTHIDENTITY, 'a, 'b, 'c);
51
52impl<'a, 'b, 'c> COAUTHIDENTITY<'a, 'b, 'c> {
53 pub_fn_string_ptrlen_get_set!('a, User, set_User, UserLength);
54 pub_fn_string_ptrlen_get_set!('b, Domain, set_Domain, DomainLength);
55 pub_fn_string_ptrlen_get_set!('c, Password, set_Password, PasswordLength);
56}
57
58#[repr(C)]
61pub struct COAUTHINFO<'a, 'b, 'c, 'd, 'e> {
62 pub dwAuthnSvc: co::RPC_C_AUTHN,
63 pub dwAuthzSvc: co::RPC_C_AUTHZ,
64 pwszServerPrincName: *mut u16,
65 pub dwAuthnLevel: co::RPC_C_AUTHN_LEVEL,
66 pub dwImpersonationLevel: co::RPC_C_IMP_LEVEL,
67 pAuthIdentityData: *mut COAUTHIDENTITY<'c, 'd, 'e>,
68 pub dwCapabilities: co::RPC_C_QOS_CAPABILITIES,
69
70 _pwszServerPrincName: PhantomData<&'a mut u16>,
71 _pAuthIdentityData: PhantomData<&'b mut COAUTHIDENTITY<'c, 'd, 'e>>,
72}
73
74impl_default!(COAUTHINFO, 'a, 'b, 'c, 'd, 'e);
75
76impl<'a, 'b, 'c, 'd, 'e> COAUTHINFO<'a, 'b, 'c, 'd, 'e> {
77 pub_fn_string_ptr_get_set!('a, pwszServerPrincName, set_pwszServerPrincName);
78 pub_fn_ptr_get_set!('b, pAuthIdentityData, set_pAuthIdentityData, COAUTHIDENTITY<'c, 'd, 'e>);
79}
80
81#[repr(C)]
84pub struct COSERVERINFO<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
85 dwReserved1: u32,
86 pwszName: *mut u16,
87 pAuthInfo: *mut COAUTHINFO<'c, 'd, 'e, 'f, 'g>,
88 dwReserved2: u32,
89
90 _pwszName: PhantomData<&'a mut u16>,
91 _pAuthInfo: PhantomData<&'b COAUTHINFO<'c, 'd, 'e, 'f, 'g>>,
92}
93
94impl_default!(COSERVERINFO, 'a, 'b, 'c, 'd, 'e, 'f, 'g);
95
96impl<'a, 'b, 'c, 'd, 'e, 'f, 'g> COSERVERINFO<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
97 pub_fn_string_ptr_get_set!('a, pwszName, set_pwszName);
98 pub_fn_ptr_get_set!('b, pAuthInfo, set_pAuthInfo, COAUTHINFO<'c, 'd, 'e, 'f, 'g>);
99}
100
101#[repr(C)]
106pub struct FORMATETC<'a> {
107 pub cfFormat: co::CF,
108 ptd: *mut DVTARGETDEVICE,
109 pub dwAspect: co::DVASPECT,
110 pub lindex: i32,
111 pub tymed: co::TYMED,
112
113 _ptd: PhantomData<&'a mut DVTARGETDEVICE>,
114}
115
116impl<'a> Default for FORMATETC<'a> {
117 fn default() -> Self {
118 Self {
119 cfFormat: co::CF::default(),
120 ptd: std::ptr::null_mut(),
121 dwAspect: co::DVASPECT::default(),
122 lindex: -1,
123 tymed: co::TYMED::default(),
124 _ptd: PhantomData,
125 }
126 }
127}
128
129impl<'a> FORMATETC<'a> {
130 pub_fn_ptr_get_set!('a, ptd, set_ptd, DVTARGETDEVICE);
131}
132
133#[repr(C)]
138#[derive(Default)]
139pub struct DVTARGETDEVICE {
140 pub tdSize: u32,
141 pub tdDriverNameOffset: u16,
142 pub tdDeviceNameOffset: u16,
143 pub tdPortNameOffset: u16,
144 pub tdExtDevmodeOffset: u16,
145 pub tdData: [u8; 1],
146}
147
148#[repr(transparent)]
151pub struct SNB(*mut *mut u16);
152
153impl_default!(SNB);
154
155impl Drop for SNB {
156 fn drop(&mut self) {
157 let _ = unsafe { CoTaskMemFreeGuard::new(self.0 as _, 0) }; }
159}
160
161impl SNB {
162 #[must_use]
165 pub fn from_strs(strs: &[impl AsRef<str>]) -> HrResult<Self> {
166 if strs.is_empty() {
167 return Ok(Self::default());
168 }
169
170 let tot_bytes_ptrs = (strs.len() + 1) * std::mem::size_of::<*mut u16>(); let wstrs = WString::from_str_vec(strs);
173 let num_valid_chars = wstrs
174 .as_slice() .iter()
176 .filter(|ch| **ch != 0x0000)
177 .count();
178 let tot_bytes_wstrs = ( num_valid_chars + strs.len() ) * std::mem::size_of::<u16>();
180
181 let mut block = CoTaskMemAlloc(tot_bytes_ptrs + tot_bytes_wstrs)?; let ptr_block = block.as_mut_ptr() as *mut u8;
183 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>() }
187 .get_mut(idx_cur_wstr)
188 .unwrap() = ptr_block_wstrs; idx_cur_wstr += 1;
190
191 wstrs.as_slice().iter().enumerate().for_each(|(idx, ch)| {
192 if *ch == 0x0000 && idx_cur_wstr < strs.len() {
193 unsafe {
194 *block
195 .as_mut_slice_aligned::<*mut u16>() .get_mut(idx_cur_wstr)
197 .unwrap() = ptr_block_wstrs.add(idx + 1);
198 }
199 idx_cur_wstr += 1;
200 }
201 });
202
203 *unsafe { block.as_mut_slice_aligned::<*mut u16>() }
204 .get_mut(idx_cur_wstr)
205 .unwrap() = std::ptr::null_mut(); wstrs.copy_to_slice(
208 unsafe {
210 std::slice::from_raw_parts_mut(
211 ptr_block_wstrs,
212 tot_bytes_wstrs / std::mem::size_of::<u16>(),
213 )
214 },
215 );
216
217 let (ptr, _) = block.leak();
218 Ok(Self(ptr as _))
219 }
220
221 #[must_use]
223 pub const fn as_ptr(&self) -> *mut *mut u16 {
224 self.0
225 }
226
227 #[must_use]
229 pub fn to_strings(&self) -> Vec<String> {
230 let mut vec = Vec::<String>::new();
231 if !self.0.is_null() {
232 let mut idx_ptr = 0;
233 loop {
234 let ptr_ws = unsafe {
235 let sli_ptrs = std::slice::from_raw_parts(self.0, idx_ptr + 1);
236 *sli_ptrs.get_unchecked(idx_ptr) };
238 if ptr_ws.is_null() {
239 break;
241 }
242 let ws = unsafe { WString::from_wchars_nullt(ptr_ws) };
243 vec.push(ws.to_string());
244 idx_ptr += 1;
245 }
246 }
247 vec
248 }
249}
250
251#[repr(C)]
254pub struct STGMEDIUM {
255 pub tymed: co::TYMED,
256 pub ptr: usize,
257 pub pUnkForRelease: COMPTR,
258}
259
260impl_default!(STGMEDIUM);
261
262impl STGMEDIUM {
263 #[must_use]
270 pub const unsafe fn ptr_hglobal(&self) -> Option<HGLOBAL> {
271 match &self.tymed {
272 &co::TYMED::HGLOBAL => Some(unsafe { HGLOBAL::from_ptr(self.ptr as _) }),
273 _ => None,
274 }
275 }
276}