#[macro_export]
#[doc(hidden)]
macro_rules! impl_debug_interface {
($name:ident, $ref_name:ident, $ty:ty) => {
$crate::__impl_debug_interface!($name, $ref_name, $ty);
impl $name {
pub fn as_base(&self) -> $ty { self.as_raw().clone() }
pub fn from_base(interface: $ty) -> Self { Self::from(interface) }
}
};
($name:ident, $ref_name:ident, $ty:ty, $base:ty) => {
$crate::__impl_debug_interface!($name, $ref_name, $ty);
impl $name {
pub fn as_base(&self) -> $base {
::windows::core::Interface::cast(self.as_raw()).unwrap()
}
pub fn from_base(base: &$base) -> Self {
Self::from_interface(base).unwrap()
}
}
impl From<$base> for $name {
fn from(value: $base) -> Self { Self::from_base(&value) }
}
impl From<&$base> for $name {
fn from(value: &$base) -> Self { Self::from_base(value) }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __impl_debug_interface {
($name:ident, $ref_name:ident, $ty:ty) => {
#[repr(transparent)]
#[derive(Clone)]
#[doc = concat!(stringify!($ty)," owned wrapper.")]
pub struct $name($ty);
impl $name {
pub fn from_interface<T: ::windows::core::Interface>(
client: &T,
) -> ::windows::core::Result<Self> {
Ok(Self(client.cast()?))
}
pub unsafe fn from_raw(
raw: *mut ::std::ffi::c_void,
) -> ::windows::core::Result<Self> {
use ::windows::core::Interface;
unsafe {
Self::from_interface(&::windows::core::IUnknown::from_raw(
raw,
))
}
}
#[inline]
pub fn as_raw(&self) -> &$ty { &self.0 }
pub fn as_ptr(&self) -> *mut std::ffi::c_void {
::windows::core::Interface::as_raw(&self.0)
}
pub fn as_interface(&self) -> &impl ::windows::core::Interface {
self.as_raw()
}
pub fn as_mut_raw(&mut self) -> &mut $ty { &mut self.0 }
pub fn as_borrowed(&self) -> $ref_name<'_> {
$ref_name(::windows::core::Interface::to_ref(&self.0))
}
}
impl From<$ty> for $name {
fn from(value: $ty) -> Self { Self(value) }
}
impl AsRef<$name> for $name {
fn as_ref(&self) -> &$name { self }
}
#[repr(transparent)]
#[derive(Clone, Copy)]
#[doc = concat!(stringify!($ty)," borrowed wrapper.")]
pub struct $ref_name<'a>(::windows::core::InterfaceRef<'a, $ty>);
impl<'a> $ref_name<'a> {
pub fn from_wrapper(interface: &'a $name) -> Self {
interface.as_borrowed()
}
pub fn from_interface(interface: &'a $ty) -> Self {
Self(::windows::core::InterfaceRef::from_interface(interface))
}
pub unsafe fn from_raw(
raw: *mut ::std::ffi::c_void,
) -> Option<Self> {
let raw = std::ptr::NonNull::new(raw)?;
unsafe {
Some(Self(::windows::core::InterfaceRef::from_raw(raw)))
}
}
#[inline]
pub fn as_raw(&self) -> &$ty { &self.0 }
pub fn as_wrapper(&self) -> &$name {
unsafe { &*(self.as_raw() as *const $ty as *const $name) }
}
pub fn to_owned(self) -> $name { $name(self.0.to_owned()) }
pub fn into_interface_ref(
self,
) -> ::windows::core::InterfaceRef<'a, $ty> {
self.0
}
pub fn as_ptr(&self) -> *mut std::ffi::c_void {
::windows::core::Interface::as_raw(self.as_raw())
}
}
impl<'a> ::core::ops::Deref for $ref_name<'a> {
type Target = $name;
fn deref(&self) -> &Self::Target { self.as_wrapper() }
}
impl<'a> From<&'a $name> for $ref_name<'a> {
fn from(value: &'a $name) -> Self { Self::from_wrapper(value) }
}
impl<'a> From<&'a $ty> for $ref_name<'a> {
fn from(value: &'a $ty) -> Self { Self::from_interface(value) }
}
impl<'a> From<::windows::core::InterfaceRef<'a, $ty>>
for $ref_name<'a>
{
fn from(value: ::windows::core::InterfaceRef<'a, $ty>) -> Self {
Self(value)
}
}
impl<'a> From<$ref_name<'a>>
for ::windows::core::InterfaceRef<'a, $ty>
{
fn from(value: $ref_name<'a>) -> Self { value.0 }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_wd_interface {
($(#[$enum_meta:meta])* $name:ident, $ty:ty) => {
#[derive(Clone)]
$(#[$enum_meta])*
pub struct $name(pub $ty);
impl $name {
pub fn from_interface<T: ::windows::core::Interface>(interface: &T) -> $crate::WdResult<Self>{
let interface = $crate::map_werr!(<$ty>::from_interface(interface),
windows::Win32::Foundation::E_NOINTERFACE => $crate::error::WdErrorKind::InterfaceNotSupported)?;
Ok(Self(interface))
}
pub fn as_interface(&self) -> &impl ::windows::core::Interface {
self.0.as_interface()
}
}
impl From<$ty> for $name {
fn from(value: $ty) -> Self { Self(value) }
}
impl AsRef<$ty> for $name {
fn as_ref(&self) -> &$ty { &self.0 }
}
impl AsRef<$name> for $name {
fn as_ref(&self) -> &$name { self }
}
};
($(#[$enum_meta:meta])* $name:ident, $ty:ty, $ty2:ty, $intf2: ty) => {
#[derive(Clone)]
$(#[$enum_meta])*
pub struct $name(pub $ty, $intf2);
impl $name {
pub fn from_interface<T: ::windows::core::Interface>(interface: &T) -> $crate::WdResult<Self>{
let interface1 = map_werr!(<$ty>::from_interface(interface),
windows::Win32::Foundation::E_NOINTERFACE => $crate::error::WdErrorKind::InterfaceNotSupported)?;
let interface2 = map_werr!(<$ty2>::from_interface(interface),
windows::Win32::Foundation::E_NOINTERFACE => $crate::error::WdErrorKind::InterfaceNotSupported)?;
Ok(Self(interface1, interface2.into()))
}
pub fn as_interface(&self) -> &impl ::windows::core::Interface {
self.0.as_interface()
}
}
impl From<$ty> for $name {
fn from(value: $ty) -> Self {
let p2=<$ty2>::from_interface(value.as_interface()).unwrap();
Self(value, p2.into())
}
}
impl AsRef<$ty> for $name {
fn as_ref(&self) -> &$ty { &self.0 }
}
impl AsRef<$name> for $name {
fn as_ref(&self) -> &$name { self }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_dbgeng_callback_interface {
($name:ident, $ty:ty) => {
pub struct $name($ty);
impl $name {
pub fn from_interface<T: ::windows::core::Interface>(
client: &T,
) -> ::windows::core::Result<Self> {
Ok(Self(client.cast()?))
}
pub fn as_raw(&self) -> &$ty { &self.0 }
pub fn as_ptr(&self) -> *mut std::ffi::c_void {
::windows::core::Interface::as_raw(&self.0)
}
pub fn as_interface(&self) -> &impl ::windows::core::Interface {
&self.0
}
pub fn as_mut_raw(&mut self) -> &mut $ty { &mut self.0 }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_ttd_view {
($name:ident, $raw:ident) => {
#[repr(transparent)]
#[doc = concat!("Non-owning TTD `", stringify!($raw), "` wrapper.")]
pub struct $name($raw);
impl $name {
#[inline]
pub fn as_raw(&self) -> *mut $raw { self.0.0.cast() }
#[inline]
pub fn as_raw_interface(&self) -> &$raw { &self.0 }
#[inline]
pub fn as_borrowed(&self) -> &Self { self }
}
impl core::fmt::Debug for $name {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
f.debug_tuple(stringify!($name)).field(&self.0.0).finish()
}
}
impl From<$raw> for $name {
#[inline]
fn from(value: $raw) -> Self { Self(value) }
}
impl AsRef<$name> for $name {
#[inline]
fn as_ref(&self) -> &$name { self }
}
impl AsRef<$raw> for $name {
#[inline]
fn as_ref(&self) -> &$raw { &self.0 }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! vcall {
($self:ident, $($func:ident).+ $(, $arg:expr)* $(,)?) => {
(::windows::core::Interface::vtable(&$self.0).$($func).+)(
::windows::core::Interface::as_raw(&$self.0),
$($arg,)*
)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! enum_flags {
(
$(#[$enum_meta:meta])*
$vis:vis enum $name:ident : $t:ty {
$(
$(#[$var_meta:meta])*
$variant:ident = $const:tt
),* $(,)?
}
$(, invalid = $panic:expr $(,)?)?
) => {
#[repr($t)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
$(#[$enum_meta])*
$vis enum $name {
$(
#[doc = stringify!($const)]
$(#[$var_meta])*
$variant = $const,
)*
}
impl ::core::convert::TryFrom<$t> for $name {
type Error = $crate::error::WdError;
fn try_from(value: $t) -> Result<Self,Self::Error> {
Ok(match value {
$(
$const => Self::$variant,
)*
x => Err($crate::error::WdError::from_kind($crate::error::WdErrorKind::InvalidFlags(x as u32)))?,
})
}
}
impl ::core::convert::From<$name> for $t {
fn from(val: $name) -> Self {
val as $t
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! hr {
($e:expr) => {
match $e {
::windows::Win32::Foundation::S_OK => Ok(true),
::windows::Win32::Foundation::S_FALSE => Ok(false),
hr => Err(::windows::core::Error::from_hresult(hr)),
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! pca {
($s:expr) => {
::windows::core::PCSTR($s.as_ref().as_u8_ptr())
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! pa {
($s:expr) => {
::windows::core::PSTR($s.as_mut_ptr() as *mut u8)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! pcw {
($s:expr) => {
::windows::core::PCWSTR($s.as_ref().as_ptr())
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! pw {
($s:expr) => {
::windows::core::PWSTR($s.as_mut_ptr() as *mut u16)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! b2w {
($s:expr) => {
::windy::WString::new($s.as_ref()).unwrap()
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_callbacks_func {
(@forward $func_name:ident( $($arg_name:ident: $arg_type:ty $(,)?)*) -> $ret_type: ty) => {
fn $func_name(&self, $($arg_name: $arg_type,)*) -> $ret_type {
match self.policy {
$crate::callbacks::WdCallbacksErrorPolicy::DiscontinueWhenForwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
let fd_ok = fd_res?;
let bk_res =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
match bk_res {
None => Ok(fd_ok),
Some(bk_res) => bk_res,
}
}
$crate::callbacks::WdCallbacksErrorPolicy::BackwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
let bk_res =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
bk_res.map_or(fd_res, |bk_res| bk_res)
}
$crate::callbacks::WdCallbacksErrorPolicy::ForwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
let _ =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
fd_res
}
}
}
};
(@backward $func_name:ident( $($arg_name:ident: $arg_type:ty $(,)?)*) -> $ret_type: ty) => {
fn $func_name(&self, $($arg_name: $arg_type,)*) -> $ret_type {
match self.policy {
$crate::callbacks::WdCallbacksErrorPolicy::DiscontinueWhenForwardError => {
let fd_res =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
match fd_res {
None => {
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
Some(fd_res)=> {
fd_res?;
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
}
}
$crate::callbacks::WdCallbacksErrorPolicy::BackwardError => {
let _ =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
$crate::callbacks::WdCallbacksErrorPolicy::ForwardError => {
let fd_res =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
let bk_res =
self.backward.$func_name($($arg_name,)*);
fd_res.map_or(bk_res, |fd_res| fd_res)
}
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_callbacks_func_ds {
(@forward $func_name:ident( $($arg_name:ident: $arg_type:ty $(,)?)*)) => {
fn $func_name(&self, $($arg_name: $arg_type,)*) -> $crate::data::DebugStatus {
match self.policy {
$crate::callbacks::WdCallbacksErrorPolicy::DiscontinueWhenForwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
if fd_res != $crate::data::DebugStatus::NoChange {
return fd_res;
}
let bk_res =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
bk_res.unwrap_or(fd_res)
}
$crate::callbacks::WdCallbacksErrorPolicy::BackwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
let bk_res =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
bk_res.unwrap_or(fd_res)
}
$crate::callbacks::WdCallbacksErrorPolicy::ForwardError => {
let fd_res =
self.forward.$func_name($($arg_name.clone(),)*);
let _ =
self.backward.as_ref().map(|x| x.$func_name($($arg_name,)*));
fd_res
}
}
}
};
(@backward $func_name:ident( $($arg_name:ident: $arg_type:ty $(,)?)*)) => {
fn $func_name(&self, $($arg_name: $arg_type,)*) -> $crate::data::DebugStatus {
match self.policy {
$crate::callbacks::WdCallbacksErrorPolicy::DiscontinueWhenForwardError => {
let fd_res =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
match fd_res {
None => {
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
Some(fd_res) => {
if fd_res != $crate::data::DebugStatus::NoChange {
return fd_res;
}
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
}
}
$crate::callbacks::WdCallbacksErrorPolicy::BackwardError => {
let _ =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
let bk_res =
self.backward.$func_name($($arg_name,)*);
bk_res
}
$crate::callbacks::WdCallbacksErrorPolicy::ForwardError => {
let fd_res =
self.forward.as_ref().map(|x| x.$func_name($($arg_name.clone(),)*));
let bk_res =
self.backward.$func_name($($arg_name,)*);
fd_res.unwrap_or(bk_res)
}
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_callbacks_catch_unwind {
() => {
fn set_poisoned(&self, poisoned: bool) { self.poisoned.set(poisoned) }
pub fn is_poisoned(&self) -> bool { self.poisoned.get() }
pub fn clear_poison(&self) { self.set_poisoned(false) }
fn __catch_unwind<T>(
&self,
f: impl FnOnce() -> windows::core::Result<T>,
) -> windows::core::Result<T> {
if self.poisoned.replace(true) {
return Err(windows::Win32::Foundation::E_UNEXPECTED.into());
}
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
Ok(res) => {
self.set_poisoned(false);
res
}
Err(_) => Err(windows::Win32::Foundation::E_UNEXPECTED.into()),
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_id {
(
$(#[$enum_meta:meta])*
$name:ident: $type:ty) => {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
$(#[$enum_meta])*
pub struct $name(pub $type);
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,"{}", self.0)
}
}
impl From<$type> for $name {
fn from(value: $type) -> Self { Self(value) }
}
impl From<$name> for $type {
fn from(val: $name) -> Self { val.0 }
}
impl PartialEq<$type> for $name {
fn eq(&self, other: &$type) -> bool { self.0 == *other }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! dmerr {
($object:expr, $e:expr $(,)?) => {
if let Err(hr) = $e {
return Err($crate::error::DbgModelError::new(hr, $object));
}
};
(@raw $object:expr, $e:expr $(,)?) => {{
let hr = $e;
if hr.is_err() {
let object = if $object.is_null() {
None
} else {
Some($crate::dbgmodel::ModelObject::from_raw($object).unwrap())
};
return Err($crate::error::DbgModelError::new(hr, object));
}
let object = $crate::dbgmodel::ModelObject::from_raw($object).unwrap();
object
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! assert_size {
($name:ident, $size:expr) => {
const _: () = {
assert!(::core::mem::size_of::<$name>() == $size);
};
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_raw_value {
($get_func:ident, $mut_func:ident, $offset_func:ident -> & $ty:ty) => {
fn $get_func(&self) -> &$ty;
fn $mut_func(&mut self) -> &mut $ty;
fn $offset_func(&mut self) -> $crate::DebuggeeOffset;
};
(
$get_func:ident,
$mut_func:ident,
$offset_func:ident -> &
$ty:ty,
$e:ident
) => {
fn $get_func(&self) -> &$ty { &self.$e }
fn $mut_func(&mut self) -> &mut $ty { &mut self.$e }
fn $offset_func(&mut self) -> $crate::DebuggeeOffset {
::core::mem::offset_of!(Self, $e) as u64
}
};
($get_func:ident, $mut_func:ident, $offset_func:ident -> $ty:ty) => {
fn $get_func(&self) -> $ty;
fn $mut_func(&mut self) -> &mut $ty;
fn $offset_func(&mut self) -> $crate::DebuggeeOffset;
};
(
$get_func:ident,
$mut_func:ident,
$offset_func:ident ->
$ty:ty,
$e:ident
) => {
fn $get_func(&self) -> $ty { self.$e }
fn $mut_func(&mut self) -> &mut $ty { &mut self.$e }
fn $offset_func(&mut self) -> $crate::DebuggeeOffset {
::core::mem::offset_of!(Self, $e) as u64
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_raw_value2 {
($get_func:ident, $mut_func:ident, $offset_func:ident -> & $ty:ty) => {
fn $get_func(&self) -> &$ty;
fn $mut_func(&mut self) -> &mut $ty;
fn $offset_func(&mut self) -> $crate::DebuggeeOffset;
};
(
$get_func:ident,
$mut_func:ident,
$offset_func:ident -> &
$ty:ty,
$e:ident
) => {
fn $get_func(&self) -> &$ty { &self.$e }
fn $mut_func(&mut self) -> &mut $ty { &mut self.$e }
fn $offset_func(&mut self) -> $crate::DebuggeeOffset {
::core::mem::offset_of!(Self, $e) as u64
}
};
($get_func:ident, $mut_func:ident, $offset_func:ident -> $ty:ty) => {
fn $get_func(&self) -> $ty;
fn $mut_func(&mut self) -> &mut $ty;
fn $offset_func(&mut self) -> $crate::DebuggeeOffset;
};
(
$inner_type:ident,
$get_func:ident,
$mut_func:ident,
$offset_func:ident ->
$ty:ty,
$e:ident
) => {
fn $get_func(&self) -> $ty { self.inner.$e }
fn $mut_func(&mut self) -> &mut $ty { &mut self.inner.$e }
fn $offset_func(&mut self) -> $crate::DebuggeeOffset {
::core::mem::offset_of!($inner_type<Self>, $e) as u64
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_typed {
(@Copy $name:ident) => {
impl<T, const OFFSET: $crate::DebuggeeOffset> Copy
for $name<T, OFFSET>
{
}
};
(@Clone $name:ident) => {
impl<T, const OFFSET: $crate::DebuggeeOffset> Clone
for $name<T, OFFSET>
{
fn clone(&self) -> Self { *self }
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! map_werr {
(
$result:expr,
$(
$hresult:path => $variant:expr
),+ $(,)?
) => {{
$result.map_err(|e| {
let code = e.code();
match code {
$(
$hresult => {$variant}.into_error(),
)+
_ => $crate::error::WdError::from_kind_with_hr($crate::error::WdErrorKind::Other, code),
}
})
}};
}