1use super::*;
2use core::ffi::c_void;
3use core::ptr::null_mut;
4
5/// Parent interface for all WinRT interfaces.
6///
7/// A WinRT object that may be used as a polymorphic stand-in for any WinRT class, interface, or boxed value.
8/// [`IInspectable`] represents the
9/// [IInspectable](https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nn-inspectable-iinspectable)
10/// interface.
11#[repr(transparent)]
12#[derive(Clone, PartialEq, Eq, Debug)]
13pub struct IInspectable(pub IUnknown);
14
15interface_hierarchy!(IInspectable, IUnknown);
16
17impl IInspectable {
18 /// Returns the canonical type name for the underlying object.
19 #[cfg(windows)]
20 pub fn GetRuntimeClassName(&self) -> Result<HSTRING> {
21 unsafe {
22 let mut abi = null_mut();
23 (self.vtable().GetRuntimeClassName)(core::mem::transmute_copy(self), &mut abi).ok()?;
24 Ok(core::mem::transmute::<*mut c_void, HSTRING>(abi))
25 }
26 }
27
28 /// Gets the trust level of the current object.
29 pub fn GetTrustLevel(&self) -> Result<i32> {
30 unsafe {
31 let mut value: i32 = 0;
32 (self.vtable().GetTrustLevel)(core::mem::transmute_copy(self), &mut value).ok()?;
33 Ok(value)
34 }
35 }
36}
37
38#[doc(hidden)]
39#[repr(C)]
40pub struct IInspectable_Vtbl {
41 pub base: IUnknown_Vtbl,
42 pub GetIids: unsafe extern "system" fn(
43 this: *mut c_void,
44 count: *mut u32,
45 values: *mut *mut GUID,
46 ) -> HRESULT,
47 pub GetRuntimeClassName:
48 unsafe extern "system" fn(this: *mut c_void, value: *mut *mut c_void) -> HRESULT,
49 pub GetTrustLevel: unsafe extern "system" fn(this: *mut c_void, value: *mut i32) -> HRESULT,
50}
51
52unsafe impl Interface for IInspectable {
53 type Vtable = IInspectable_Vtbl;
54 const IID: GUID = GUID::from_u128(uuid:0xaf86e2e0_b12d_4c6a_9c5a_d7aa65101e90);
55}
56
57impl RuntimeType for IInspectable {
58 const SIGNATURE: imp::ConstBuffer = imp::ConstBuffer::from_slice(b"cinterface(IInspectable)");
59}
60
61impl RuntimeName for IInspectable {}
62
63impl IInspectable_Vtbl {
64 pub const fn new<Identity: IUnknownImpl, Name: RuntimeName, const OFFSET: isize>() -> Self {
65 unsafe extern "system" fn GetIids(
66 _: *mut c_void,
67 count: *mut u32,
68 values: *mut *mut GUID,
69 ) -> HRESULT {
70 unsafe {
71 if count.is_null() || values.is_null() {
72 return imp::E_POINTER;
73 }
74 // Note: even if we end up implementing this in future, it still doesn't need a this pointer
75 // since the data to be returned is type- not instance-specific so can be shared for all
76 // interfaces.
77 *count = 0;
78 *values = null_mut();
79 HRESULT(0)
80 }
81 }
82 unsafe extern "system" fn GetRuntimeClassName<T: RuntimeName>(
83 _: *mut c_void,
84 value: *mut *mut c_void,
85 ) -> HRESULT {
86 unsafe {
87 if value.is_null() {
88 return imp::E_POINTER;
89 }
90
91 #[cfg(windows)]
92 {
93 *value = core::mem::transmute::<HSTRING, *mut c_void>(T::NAME.into());
94 }
95
96 #[cfg(not(windows))]
97 {
98 *value = core::ptr::null_mut();
99 }
100
101 HRESULT(0)
102 }
103 }
104 unsafe extern "system" fn GetTrustLevel<T: IUnknownImpl, const OFFSET: isize>(
105 this: *mut c_void,
106 value: *mut i32,
107 ) -> HRESULT {
108 unsafe {
109 if value.is_null() {
110 return imp::E_POINTER;
111 }
112 let this = (this as *mut *mut c_void).offset(OFFSET) as *mut T;
113 (*this).GetTrustLevel(value)
114 }
115 }
116 Self {
117 base: IUnknown_Vtbl::new::<Identity, OFFSET>(),
118 GetIids,
119 GetRuntimeClassName: GetRuntimeClassName::<Name>,
120 GetTrustLevel: GetTrustLevel::<Identity, OFFSET>,
121 }
122 }
123}
124