1 // Copyright © 2015-2017 winapi-rs developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
4 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
5 // All files in the project carrying such notice may not be copied, modified, or distributed
6 // except according to those terms.
7 
8 #![allow(bad_style)]
9 
10 use std::os::raw;
11 
12 pub type wchar_t = u16;
13 
14 pub type UINT = raw::c_uint;
15 pub type LPUNKNOWN = *mut IUnknown;
16 pub type REFIID = *const IID;
17 pub type IID = GUID;
18 pub type REFCLSID = *const IID;
19 pub type PVOID = *mut raw::c_void;
20 pub type USHORT = raw::c_ushort;
21 pub type ULONG = raw::c_ulong;
22 pub type LONG = raw::c_long;
23 pub type DWORD = u32;
24 pub type LPVOID = *mut raw::c_void;
25 pub type HRESULT = raw::c_long;
26 pub type LPFILETIME = *mut FILETIME;
27 pub type BSTR = *mut OLECHAR;
28 pub type OLECHAR = WCHAR;
29 pub type WCHAR = wchar_t;
30 pub type LPCOLESTR = *const OLECHAR;
31 pub type LCID = DWORD;
32 pub type LPCWSTR = *const WCHAR;
33 pub type PULONGLONG = *mut ULONGLONG;
34 pub type ULONGLONG = u64;
35 
36 pub const S_OK: HRESULT = 0;
37 pub const S_FALSE: HRESULT = 1;
38 pub const COINIT_MULTITHREADED: u32 = 0x0;
39 
40 pub type CLSCTX = u32;
41 
42 pub const CLSCTX_INPROC_SERVER: CLSCTX = 0x1;
43 pub const CLSCTX_INPROC_HANDLER: CLSCTX = 0x2;
44 pub const CLSCTX_LOCAL_SERVER: CLSCTX = 0x4;
45 pub const CLSCTX_REMOTE_SERVER: CLSCTX = 0x10;
46 
47 pub const CLSCTX_ALL: CLSCTX =
48     CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER;
49 
50 #[repr(C)]
51 #[derive(Copy, Clone)]
52 pub struct GUID {
53     pub Data1: raw::c_ulong,
54     pub Data2: raw::c_ushort,
55     pub Data3: raw::c_ushort,
56     pub Data4: [raw::c_uchar; 8],
57 }
58 
59 #[repr(C)]
60 #[derive(Copy, Clone)]
61 pub struct FILETIME {
62     pub dwLowDateTime: DWORD,
63     pub dwHighDateTime: DWORD,
64 }
65 
66 pub trait Interface {
uuidof() -> GUID67     fn uuidof() -> GUID;
68 }
69 
70 #[link(name = "ole32")]
71 #[link(name = "oleaut32")]
72 extern "C" {}
73 
74 extern "system" {
CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT75     pub fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT;
CoCreateInstance( rclsid: REFCLSID, pUnkOuter: LPUNKNOWN, dwClsContext: DWORD, riid: REFIID, ppv: *mut LPVOID, ) -> HRESULT76     pub fn CoCreateInstance(
77         rclsid: REFCLSID,
78         pUnkOuter: LPUNKNOWN,
79         dwClsContext: DWORD,
80         riid: REFIID,
81         ppv: *mut LPVOID,
82     ) -> HRESULT;
SysFreeString(bstrString: BSTR)83     pub fn SysFreeString(bstrString: BSTR);
SysStringLen(pbstr: BSTR) -> UINT84     pub fn SysStringLen(pbstr: BSTR) -> UINT;
85 }
86 
87 #[repr(C)]
88 #[derive(Copy, Clone)]
89 pub struct SAFEARRAYBOUND {
90     pub cElements: ULONG,
91     pub lLbound: LONG,
92 }
93 
94 #[repr(C)]
95 #[derive(Copy, Clone)]
96 pub struct SAFEARRAY {
97     pub cDims: USHORT,
98     pub fFeatures: USHORT,
99     pub cbElements: ULONG,
100     pub cLocks: ULONG,
101     pub pvData: PVOID,
102     pub rgsabound: [SAFEARRAYBOUND; 1],
103 }
104 
105 pub type LPSAFEARRAY = *mut SAFEARRAY;
106 
107 macro_rules! DEFINE_GUID {
108     (
109         $name:ident, $l:expr, $w1:expr, $w2:expr,
110         $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
111     ) => {
112         pub const $name: $crate::winapi::GUID = $crate::winapi::GUID {
113             Data1: $l,
114             Data2: $w1,
115             Data3: $w2,
116             Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
117         };
118     };
119 }
120 
121 macro_rules! RIDL {
122     (#[uuid($($uuid:expr),+)]
123     interface $interface:ident ($vtbl:ident) {$(
124         fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
125     )+}) => (
126         #[repr(C)]
127         pub struct $vtbl {
128             $(pub $method: unsafe extern "system" fn(
129                 This: *mut $interface,
130                 $($p: $t),*
131             ) -> $rtr,)+
132         }
133         #[repr(C)]
134         pub struct $interface {
135             pub lpVtbl: *const $vtbl,
136         }
137         RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
138         RIDL!{@uuid $interface $($uuid),+}
139     );
140     (#[uuid($($uuid:expr),+)]
141     interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {
142     }) => (
143         #[repr(C)]
144         pub struct $vtbl {
145             pub parent: $pvtbl,
146         }
147         #[repr(C)]
148         pub struct $interface {
149             pub lpVtbl: *const $vtbl,
150         }
151         RIDL!{@deref $interface $pinterface}
152         RIDL!{@uuid $interface $($uuid),+}
153     );
154     (#[uuid($($uuid:expr),+)]
155     interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
156         fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
157     )+}) => (
158         #[repr(C)]
159         pub struct $vtbl {
160             pub parent: $pvtbl,
161             $(pub $method: unsafe extern "system" fn(
162                 This: *mut $interface,
163                 $($p: $t,)*
164             ) -> $rtr,)+
165         }
166         #[repr(C)]
167         pub struct $interface {
168             pub lpVtbl: *const $vtbl,
169         }
170         RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
171         RIDL!{@deref $interface $pinterface}
172         RIDL!{@uuid $interface $($uuid),+}
173     );
174     (@deref $interface:ident $pinterface:ident) => (
175         impl ::std::ops::Deref for $interface {
176             type Target = $pinterface;
177             #[inline]
178             fn deref(&self) -> &$pinterface {
179                 unsafe { &*(self as *const $interface as *const $pinterface) }
180             }
181         }
182     );
183     (@impl $interface:ident {$(
184         fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
185     )+}) => (
186         impl $interface {
187             $(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr {
188                 ((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*)
189             })+
190         }
191     );
192     (@uuid $interface:ident
193         $l:expr, $w1:expr, $w2:expr,
194         $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
195     ) => (
196         impl $crate::winapi::Interface for $interface {
197             #[inline]
198             fn uuidof() -> $crate::winapi::GUID {
199                 $crate::winapi::GUID {
200                     Data1: $l,
201                     Data2: $w1,
202                     Data3: $w2,
203                     Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
204                 }
205             }
206         }
207     );
208 }
209 
210 RIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)]
211 interface IUnknown(IUnknownVtbl) {
212     fn QueryInterface(
213         riid: REFIID,
214         ppvObject: *mut *mut raw::c_void,
215     ) -> HRESULT,
216     fn AddRef() -> ULONG,
217     fn Release() -> ULONG,
218 }}
219