use crate::*;
use std::mem::MaybeUninit;
use windows::core::{HRESULT, Interface};
use windy::{ACPStr, ACPString, WStr, WString};
pub mod advanced;
pub mod breakpoint;
pub mod callbacks;
pub mod client;
pub mod control;
pub mod data_spaces;
pub mod output_stream;
pub mod plm_client;
pub mod registers;
pub mod symbol_group;
pub mod symbols;
pub mod system_objects;
pub use advanced::*;
pub use breakpoint::*;
pub use callbacks::*;
pub use client::*;
pub use control::*;
pub use data_spaces::*;
pub use output_stream::*;
pub use plm_client::*;
pub use registers::*;
pub use symbol_group::*;
pub use symbols::*;
pub use system_objects::*;
pub(crate) type WinResult<T> = Result<T, windows::core::Error>;
pub fn debug_create() -> WinResult<DebugClient> {
unsafe { Ok(DebugCreate::<IDebugClient>()?.into()) }
}
pub fn debug_create_ex(dbgeng_options: u32) -> WinResult<DebugClient> {
unsafe { Ok(DebugCreateEx::<IDebugClient>(dbgeng_options)?.into()) }
}
pub fn debug_connect(
remote_options: impl AsRef<ACPStr>,
) -> WinResult<DebugClient> {
let mut interface = std::ptr::null_mut();
unsafe {
DebugConnect(pca!(remote_options), &IDebugClient::IID, &mut interface)?;
}
unsafe { DebugClient::from_raw(interface) }
}
pub fn debug_connect_wide(
remote_options: impl AsRef<WStr>,
) -> WinResult<DebugClient> {
let mut interface = std::ptr::null_mut();
unsafe {
DebugConnectWide(
pcw!(remote_options),
&IDebugClient::IID,
&mut interface,
)?;
}
unsafe { DebugClient::from_raw(interface) }
}
pub(crate) unsafe fn vec_with_capacity<T>(
cap: usize,
mut f: impl FnMut(&mut [MaybeUninit<T>], &mut u32) -> HRESULT,
) -> WinResult<Vec<T>> {
let mut v = Vec::with_capacity(cap);
let mut size1 = 0;
let mut size2 = 0;
unsafe {
if hr!(f(v.spare_capacity_mut(), &mut size1))? {
assert!(
size1 as usize <= v.capacity(),
"DbgEng returned a size larger than the supplied buffer"
);
v.set_len(size1 as usize);
Ok(v)
} else {
let mut v = Vec::with_capacity(size1 as usize);
assert!(
hr!(f(v.spare_capacity_mut(), &mut size2))?,
"DbgEng still reported an insufficient buffer after \
exact-size allocation"
);
assert_eq!(size1, size2);
assert!(
size2 as usize <= v.capacity(),
"DbgEng returned a size larger than the supplied buffer"
);
v.set_len(size2 as usize);
Ok(v)
}
}
}
pub(crate) unsafe fn vec_with_capacity2<T>(
cap: usize,
mut f1: impl FnMut(&mut [MaybeUninit<T>], &mut u32) -> HRESULT,
mut f2: impl FnMut(&mut [MaybeUninit<T>], &mut u32) -> HRESULT,
) -> WinResult<Vec<T>> {
let mut v = Vec::with_capacity(cap);
let mut size1 = 0;
let mut size2 = 0;
unsafe {
if hr!(f1(v.spare_capacity_mut(), &mut size1))? {
assert!(
size1 as usize <= v.capacity(),
"DbgEng returned a size larger than the supplied buffer"
);
v.set_len(size1 as usize);
Ok(v)
} else {
let mut v = Vec::with_capacity(size1 as usize);
assert!(
hr!(f2(v.spare_capacity_mut(), &mut size2))?,
"DbgEng still reported an insufficient buffer after \
exact-size allocation"
);
assert_eq!(size1, size2);
assert!(
size2 as usize <= v.capacity(),
"DbgEng returned a size larger than the supplied buffer"
);
v.set_len(size2 as usize);
Ok(v)
}
}
}
pub(crate) unsafe fn astring_with_capacity(
cap: usize,
f: impl FnMut(&mut [MaybeUninit<u8>], &mut u32) -> HRESULT,
) -> WinResult<ACPString> {
unsafe {
Ok(ACPString::from_vec_with_nul_unchecked(vec_with_capacity(
cap, f,
)?))
}
}
pub(crate) unsafe fn astring_with_capacity2(
cap: usize,
f1: impl FnMut(&mut [MaybeUninit<u8>], &mut u32) -> HRESULT,
f2: impl FnMut(&mut [MaybeUninit<u8>], &mut u32) -> HRESULT,
) -> WinResult<ACPString> {
unsafe {
Ok(ACPString::from_vec_with_nul_unchecked(vec_with_capacity2(
cap, f1, f2,
)?))
}
}
pub(crate) unsafe fn wstring_with_capacity(
cap: usize,
f: impl FnMut(&mut [MaybeUninit<u16>], &mut u32) -> HRESULT,
) -> WinResult<WString> {
unsafe {
Ok(WString::from_vec_with_nul_unchecked(vec_with_capacity(
cap, f,
)?))
}
}
pub(crate) unsafe fn wstring_with_capacity2(
cap: usize,
f1: impl FnMut(&mut [MaybeUninit<u16>], &mut u32) -> HRESULT,
f2: impl FnMut(&mut [MaybeUninit<u16>], &mut u32) -> HRESULT,
) -> WinResult<WString> {
unsafe {
Ok(WString::from_vec_with_nul_unchecked(vec_with_capacity2(
cap, f1, f2,
)?))
}
}