use crate::dbgeng::{client::ProcessServer, *};
use windows_core::{PSTR, PWSTR};
use windy::{ACPString, WString};
impl_debug_interface!(
DebugSystemObjects,
DebugSystemObjectsRef,
IDebugSystemObjects4,
IDebugSystemObjects
);
impl DebugSystemObjects {
pub fn get_event_thread(&self) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetEventThread()?.into()) }
}
pub fn get_event_process(&self) -> WinResult<EngineProcessId> {
unsafe { Ok(self.0.GetEventProcess()?.into()) }
}
pub fn get_current_thread_id(&self) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetCurrentThreadId()?.into()) }
}
pub fn set_current_thread_id(
&self,
id: impl Into<EngineThreadId>,
) -> WinResult<()> {
unsafe { self.0.SetCurrentThreadId(id.into().0) }
}
pub fn get_current_process_id(&self) -> WinResult<EngineProcessId> {
unsafe { Ok(self.0.GetCurrentProcessId()?.into()) }
}
pub fn set_current_process_id(
&self,
id: impl Into<EngineProcessId>,
) -> WinResult<()> {
unsafe { self.0.SetCurrentProcessId(id.into().0) }
}
pub fn get_number_threads(&self) -> WinResult<u32> {
unsafe { self.0.GetNumberThreads() }
}
pub fn get_total_number_threads(&self) -> WinResult<(u32, u32)> {
let mut total = 0;
let mut largest_process = 0;
unsafe {
self.0
.GetTotalNumberThreads(&mut total, &mut largest_process)?;
Ok((total, largest_process))
}
}
pub fn get_thread_ids_by_index(
&self,
start: u32,
count: u32,
) -> WinResult<Vec<(EngineThreadId, ThreadId)>> {
let mut ids = Vec::with_capacity(count as usize);
let mut sys_ids = Vec::with_capacity(count as usize);
unsafe {
self.0.GetThreadIdsByIndex(
start,
count,
Some(ids.as_mut_ptr()),
Some(sys_ids.as_mut_ptr()),
)?;
ids.set_len(count as usize);
sys_ids.set_len(count as usize);
Ok(ids
.into_iter()
.zip(sys_ids)
.map(|(id, sys_id)| {
(EngineThreadId::from(id), ThreadId::from(sys_id))
})
.collect())
}
}
pub fn get_thread_id_by_processor(
&self,
processor: u32,
) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetThreadIdByProcessor(processor)?.into()) }
}
pub fn get_current_thread_data_offset(&self) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetCurrentThreadDataOffset() }
}
pub fn get_thread_id_by_data_offset(
&self,
offset: DebuggeeOffset,
) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetThreadIdByDataOffset(offset)?.into()) }
}
pub fn get_current_thread_teb(&self) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetCurrentThreadTeb() }
}
pub fn get_thread_id_by_teb(
&self,
offset: DebuggeeOffset,
) -> WinResult<EngineThreadId> {
unsafe { Ok(self.0.GetThreadIdByTeb(offset)?.into()) }
}
pub fn get_current_thread_system_id(&self) -> WinResult<ThreadId> {
unsafe { Ok(self.0.GetCurrentThreadSystemId()?.into()) }
}
pub fn get_thread_id_by_system_id(
&self,
sys_id: impl Into<ThreadId>,
) -> WinResult<EngineThreadId> {
unsafe {
Ok(self.0.GetThreadIdBySystemId(sys_id.into().into())?.into())
}
}
pub fn get_current_thread_handle(&self) -> WinResult<ThreadHandle> {
unsafe { Ok(ThreadHandle::new(self.0.GetCurrentThreadHandle()?)) }
}
pub fn get_thread_id_by_handle(
&self,
handle: &ThreadHandle,
) -> WinResult<EngineThreadId> {
unsafe {
Ok(self.0.GetThreadIdByHandle(handle.as_raw_handle())?.into())
}
}
pub fn get_number_processes(&self) -> WinResult<u32> {
unsafe { self.0.GetNumberProcesses() }
}
pub fn get_process_ids_by_index(
&self,
start: u32,
count: u32,
) -> WinResult<Vec<(EngineProcessId, ProcessId)>> {
let mut ids = Vec::with_capacity(count as usize);
let mut sys_ids = Vec::with_capacity(count as usize);
unsafe {
self.0.GetProcessIdsByIndex(
start,
count,
Some(ids.as_mut_ptr()),
Some(sys_ids.as_mut_ptr()),
)?;
ids.set_len(count as usize);
sys_ids.set_len(count as usize);
Ok(ids
.into_iter()
.zip(sys_ids)
.map(|(id, sys_id)| {
(EngineProcessId::from(id), ProcessId::from(sys_id))
})
.collect())
}
}
pub fn get_current_process_data_offset(&self) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetCurrentProcessDataOffset() }
}
pub fn get_process_id_by_data_offset(
&self,
offset: DebuggeeOffset,
) -> WinResult<EngineProcessId> {
unsafe { Ok(self.0.GetProcessIdByDataOffset(offset)?.into()) }
}
pub fn get_current_process_peb(&self) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetCurrentProcessPeb() }
}
pub fn get_process_id_by_peb(
&self,
offset: DebuggeeOffset,
) -> WinResult<EngineProcessId> {
unsafe { Ok(self.0.GetProcessIdByPeb(offset)?.into()) }
}
pub fn get_current_process_system_id(&self) -> WinResult<ProcessId> {
unsafe { Ok(self.0.GetCurrentProcessSystemId()?.into()) }
}
pub fn get_process_id_by_system_id(
&self,
sys_id: impl Into<ProcessId>,
) -> WinResult<EngineProcessId> {
unsafe {
Ok(self.0.GetProcessIdBySystemId(sys_id.into().into())?.into())
}
}
pub fn get_current_process_handle(&self) -> WinResult<ProcessHandle> {
unsafe { Ok(ProcessHandle::new(self.0.GetCurrentProcessHandle()?)) }
}
pub fn get_process_id_by_handle(
&self,
handle: &ProcessHandle,
) -> WinResult<EngineProcessId> {
unsafe {
Ok(self.0.GetProcessIdByHandle(handle.as_raw_handle())?.into())
}
}
pub fn get_current_process_executable_name(&self) -> WinResult<ACPString> {
unsafe {
astring_with_capacity(128, |v, s| {
vcall!(
self,
GetCurrentProcessExecutableName,
PSTR(v.as_mut_ptr() as *mut _),
v.len().try_into().unwrap(),
s,
)
})
}
}
}
impl DebugSystemObjects {
pub fn get_current_process_up_time(&self) -> WinResult<u32> {
unsafe { self.0.GetCurrentProcessUpTime() }
}
pub fn get_implicit_thread_data_offset(&self) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetImplicitThreadDataOffset() }
}
pub fn set_implicit_thread_data_offset(
&self,
offset: DebuggeeOffset,
) -> WinResult<()> {
unsafe { self.0.SetImplicitThreadDataOffset(offset) }
}
pub fn get_implicit_process_data_offset(
&self,
) -> WinResult<DebuggeeOffset> {
unsafe { self.0.GetImplicitProcessDataOffset() }
}
pub fn set_implicit_process_data_offset(
&self,
offset: DebuggeeOffset,
) -> WinResult<()> {
unsafe { self.0.SetImplicitProcessDataOffset(offset) }
}
}
impl DebugSystemObjects {
pub fn get_event_system(&self) -> WinResult<EngineSystemId> {
unsafe { Ok(self.0.GetEventSystem()?.into()) }
}
pub fn get_current_system_id(&self) -> WinResult<EngineSystemId> {
unsafe { Ok(self.0.GetCurrentSystemId()?.into()) }
}
pub fn set_current_system_id(
&self,
id: impl Into<EngineSystemId>,
) -> WinResult<()> {
unsafe { self.0.SetCurrentSystemId(id.into().0) }
}
pub fn get_number_systems(&self) -> WinResult<u32> {
unsafe { self.0.GetNumberSystems() }
}
pub fn get_system_ids_by_index(
&self,
start: u32,
count: u32,
) -> WinResult<Vec<EngineSystemId>> {
let mut ids = Vec::with_capacity(count as usize);
unsafe {
vcall!(self, GetSystemIdsByIndex, start, count, ids.as_mut_ptr())
.ok()?;
ids.set_len(count as usize);
}
Ok(ids.into_iter().map(EngineSystemId::from).collect())
}
pub fn get_total_number_threads_and_processes(
&self,
) -> WinResult<(u32, u32, u32, u32, u32)> {
let mut total_threads = 0;
let mut total_processes = 0;
let mut largest_process_threads = 0;
let mut largest_system_threads = 0;
let mut largest_system_processes = 0;
unsafe {
self.0.GetTotalNumberThreadsAndProcesses(
&mut total_threads,
&mut total_processes,
&mut largest_process_threads,
&mut largest_system_threads,
&mut largest_system_processes,
)?;
Ok((
total_threads,
total_processes,
largest_process_threads,
largest_system_threads,
largest_system_processes,
))
}
}
pub fn get_current_system_server(&self) -> WinResult<ProcessServer> {
unsafe { Ok(self.0.GetCurrentSystemServer()?.into()) }
}
pub fn get_system_by_server(
&self,
server: ProcessServer,
) -> WinResult<EngineSystemId> {
unsafe { Ok(self.0.GetSystemByServer(server.into())?.into()) }
}
pub fn get_current_system_server_name(&self) -> WinResult<ACPString> {
unsafe {
astring_with_capacity(128, |v, s| {
vcall!(
self,
GetCurrentSystemServerName,
PSTR(v.as_mut_ptr() as *mut _),
v.len().try_into().unwrap(),
s,
)
})
}
}
}
impl DebugSystemObjects {
pub fn get_current_process_executable_name_wide(
&self,
) -> WinResult<WString> {
unsafe {
wstring_with_capacity(128, |v, s| {
vcall!(
self,
GetCurrentProcessExecutableNameWide,
PWSTR(v.as_mut_ptr() as *mut _),
v.len().try_into().unwrap(),
s,
)
})
}
}
pub fn get_current_system_server_name_wide(&self) -> WinResult<WString> {
unsafe {
wstring_with_capacity(128, |v, s| {
vcall!(
self,
GetCurrentSystemServerNameWide,
PWSTR(v.as_mut_ptr() as *mut _),
v.len().try_into().unwrap(),
s,
)
})
}
}
}