1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use super::*;
use bindings::Windows::Foundation::{IReference, IStringable, PropertyValue};
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct Object(IUnknown);
impl Object {
pub fn type_name(&self) -> Result<HString> {
unsafe {
let mut abi = std::ptr::null_mut();
(self.vtable().4)(self.abi(), &mut abi).ok()?;
Ok(std::mem::transmute(abi))
}
}
}
#[repr(C)]
pub struct Object_vtable(
pub unsafe extern "system" fn(this: RawPtr, iid: &Guid, interface: *mut RawPtr) -> HRESULT,
pub unsafe extern "system" fn(this: RawPtr) -> u32,
pub unsafe extern "system" fn(this: RawPtr) -> u32,
pub unsafe extern "system" fn(this: RawPtr, count: *mut u32, values: *mut *mut Guid) -> HRESULT,
pub unsafe extern "system" fn(this: RawPtr, value: *mut RawPtr) -> HRESULT,
pub unsafe extern "system" fn(this: RawPtr, value: *mut i32) -> HRESULT,
);
unsafe impl Interface for Object {
type Vtable = Object_vtable;
const IID: Guid = Guid::from_values(
0xAF86_E2E0,
0xB12D,
0x4C6A,
[0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90],
);
}
unsafe impl RuntimeType for Object {
type DefaultType = Option<Self>;
const SIGNATURE: crate::ConstBuffer =
crate::ConstBuffer::from_slice(b"cinterface(IInspectable)");
}
impl std::fmt::Debug for Object {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = self
.cast::<IStringable>()
.and_then(|s| s.ToString())
.or_else(|_| self.type_name())
.unwrap_or_default();
write!(f, "{:?} {}", self.0, name)
}
}
macro_rules! primitive_boxed_type {
($(($t:ty, $m:ident)),+) => {
$(impl std::convert::TryFrom<$t> for Object {
type Error = Error;
fn try_from(value: $t) -> Result<Self> {
PropertyValue::$m(value)
}
}
impl std::convert::TryFrom<Object> for $t {
type Error = Error;
fn try_from(value: Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<$t>>(&value)?.Value()
}
}
impl std::convert::TryFrom<&Object> for $t {
type Error = Error;
fn try_from(value: &Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<$t>>(value)?.Value()
}
})*
};
}
primitive_boxed_type! {
(bool, CreateBoolean),
(u8, CreateUInt8),
(i16, CreateInt16),
(u16, CreateUInt16),
(i32, CreateInt32),
(u32, CreateUInt32),
(i64, CreateInt64),
(u64, CreateUInt64),
(f32, CreateSingle),
(f64, CreateDouble)
}
impl std::convert::TryFrom<&str> for Object {
type Error = Error;
fn try_from(value: &str) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<HString> for Object {
type Error = Error;
fn try_from(value: HString) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<&HString> for Object {
type Error = Error;
fn try_from(value: &HString) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<Object> for HString {
type Error = Error;
fn try_from(value: Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<HString>>(&value)?.Value()
}
}
impl std::convert::TryFrom<&Object> for HString {
type Error = Error;
fn try_from(value: &Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<HString>>(value)?.Value()
}
}