1 | use super::*; |
2 | use core::ffi::c_void; |
3 | use 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)] |
13 | pub struct IInspectable(pub IUnknown); |
14 | |
15 | interface_hierarchy!(IInspectable, IUnknown); |
16 | |
17 | impl 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)] |
40 | pub 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 | |
52 | unsafe impl Interface for IInspectable { |
53 | type Vtable = IInspectable_Vtbl; |
54 | const IID: GUID = GUID::from_u128(uuid:0xaf86e2e0_b12d_4c6a_9c5a_d7aa65101e90); |
55 | } |
56 | |
57 | impl RuntimeType for IInspectable { |
58 | const SIGNATURE: imp::ConstBuffer = imp::ConstBuffer::from_slice(b"cinterface(IInspectable)" ); |
59 | } |
60 | |
61 | impl RuntimeName for IInspectable {} |
62 | |
63 | impl 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 | |