use crate::dbgeng::{client::DebugClient, *};
use windows::core::GUID;
use windy::{ACPStr, ACPString, WStr, WString};
impl_debug_interface!(
DebugBreakpoint,
DebugBreakpointRef,
IDebugBreakpoint3,
IDebugBreakpoint
);
impl DebugBreakpoint {
pub fn get_id(&self) -> WinResult<BreakpointId> {
unsafe { Ok(self.0.GetId()?.into()) }
}
pub fn get_type(&self) -> WinResult<(DebugBreakpointTypes, ProcessorType)> {
let mut break_type = 0;
let mut proc_type = 0;
unsafe {
self.0.GetType(&mut break_type, &mut proc_type)?;
Ok((
DebugBreakpointTypes::try_from(break_type)
.expect("Invalid break type"),
ProcessorType::from(proc_type),
))
}
}
pub fn get_adder(&self) -> WinResult<DebugClient> {
unsafe { DebugClient::from_interface(&self.0.GetAdder()?) }
}
pub fn get_flags(&self) -> WinResult<DebugBreakpointFlags> {
unsafe {
Ok(DebugBreakpointFlags::from_bits_retain(self.0.GetFlags()?))
}
}
pub fn add_flags(
&self,
breakpoint_flags: DebugBreakpointFlags,
) -> WinResult<()> {
unsafe { self.0.AddFlags(breakpoint_flags.bits()) }
}
pub fn remove_flags(&self, flags: DebugBreakpointFlags) -> WinResult<()> {
unsafe { self.0.RemoveFlags(flags.bits()) }
}
pub fn set_flags(&self, flags: DebugBreakpointFlags) -> WinResult<()> {
unsafe { self.0.SetFlags(flags.bits()) }
}
pub fn get_offset(&self) -> WinResult<u64> { unsafe { self.0.GetOffset() } }
pub fn set_offset(&self, offset: DebuggeeOffset) -> WinResult<()> {
unsafe { self.0.SetOffset(offset) }
}
pub fn get_data_parameters(
&self,
) -> WinResult<(u32, DebugBreakAccessTypes)> {
let mut size = 0;
let mut access_type = 0;
unsafe {
self.0.GetDataParameters(&mut size, &mut access_type)?;
Ok((size, DebugBreakAccessTypes::from_bits_retain(access_type)))
}
}
pub fn set_data_parameters(
&self,
size: u32,
access_type: DebugBreakAccessTypes,
) -> WinResult<()> {
unsafe { self.0.SetDataParameters(size, access_type.bits()) }
}
pub fn get_pass_count(&self) -> WinResult<u32> {
unsafe { self.0.GetPassCount() }
}
pub fn set_pass_count(&self, count: u32) -> WinResult<()> {
unsafe { self.0.SetPassCount(count) }
}
pub fn get_current_pass_count(&self) -> WinResult<u32> {
unsafe { self.0.GetCurrentPassCount() }
}
pub fn get_match_thread_id(&self) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetMatchThreadId()?.into()) }
}
pub fn set_match_thread_id(&self, thread: EngineThreadId) -> WinResult<()> {
unsafe { self.0.SetMatchThreadId(thread.into()) }
}
pub fn get_command(&self) -> WinResult<ACPString> {
unsafe {
astring_with_capacity(64, |v, s| {
vcall!(self, GetCommand, pa!(v), v.len().try_into().unwrap(), s)
})
}
}
pub fn set_command(&self, command: impl AsRef<ACPStr>) -> WinResult<()> {
unsafe { self.0.SetCommand(pca!(command)) }
}
pub fn get_offset_expression(&self) -> WinResult<ACPString> {
unsafe {
astring_with_capacity(64, |v, s| {
vcall!(
self,
GetOffsetExpression,
pa!(v),
v.len().try_into().unwrap(),
s
)
})
}
}
pub fn set_offset_expression(
&self,
expression: impl AsRef<ACPStr>,
) -> WinResult<()> {
unsafe { self.0.SetOffsetExpression(pca!(expression)) }
}
pub fn get_parameters(&self) -> WinResult<DebugBreakpointParameters> {
unsafe {
let mut param: DEBUG_BREAKPOINT_PARAMETERS = core::mem::zeroed();
self.0.GetParameters(&mut param)?;
Ok(DebugBreakpointParameters(param))
}
}
}
impl DebugBreakpoint {
pub fn get_command_wide(&self) -> WinResult<WString> {
unsafe {
wstring_with_capacity(64, |v, s| {
vcall!(
self,
GetCommandWide,
pw!(v),
v.len().try_into().unwrap(),
s
)
})
}
}
pub fn set_command_wide(&self, command: impl AsRef<WStr>) -> WinResult<()> {
unsafe { self.0.SetCommandWide(pcw!(command)) }
}
pub fn get_offset_expression_wide(&self) -> WinResult<WString> {
unsafe {
wstring_with_capacity(64, |v, s| {
vcall!(
self,
GetOffsetExpressionWide,
pw!(v),
v.len().try_into().unwrap(),
s
)
})
}
}
pub fn set_offset_expression_wide(
&self,
expression: impl AsRef<WStr>,
) -> WinResult<()> {
unsafe { self.0.SetOffsetExpressionWide(pcw!(expression)) }
}
}
impl DebugBreakpoint {
pub fn get_guid(&self) -> WinResult<GUID> { unsafe { self.0.GetGuid() } }
}