mirror of https://github.com/lukechilds/cc-rs.git
Alex Crichton
8 years ago
committed by
GitHub
5 changed files with 694 additions and 7 deletions
@ -0,0 +1,125 @@ |
|||
// Copyright © 2017 winapi-rs developers
|
|||
// Licensed under the Apache License, Version 2.0
|
|||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
|
|||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
|||
// except according to those terms.
|
|||
|
|||
#![allow(unused)] |
|||
|
|||
use std::ffi::{OsStr, OsString}; |
|||
use std::mem::forget; |
|||
use std::ops::Deref; |
|||
use std::os::windows::ffi::{OsStrExt, OsStringExt}; |
|||
use std::ptr::null_mut; |
|||
use std::slice::from_raw_parts; |
|||
use winapi::Interface; |
|||
use winapi::BSTR; |
|||
use winapi::CoInitializeEx; |
|||
use winapi::COINIT_MULTITHREADED; |
|||
use winapi::{SysFreeString, SysStringLen}; |
|||
use winapi::IUnknown; |
|||
use winapi::{S_OK, S_FALSE, HRESULT}; |
|||
|
|||
pub fn initialize() -> Result<(), HRESULT> { |
|||
let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) }; |
|||
if err != S_OK && err != S_FALSE { |
|||
// S_FALSE just means COM is already initialized
|
|||
return Err(err); |
|||
} |
|||
Ok(()) |
|||
} |
|||
|
|||
pub struct ComPtr<T>(*mut T) where T: Interface; |
|||
impl<T> ComPtr<T> where T: Interface { |
|||
/// Creates a `ComPtr` to wrap a raw pointer.
|
|||
/// It takes ownership over the pointer which means it does __not__ call `AddRef`.
|
|||
/// `T` __must__ be a COM interface that inherits from `IUnknown`.
|
|||
pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> { |
|||
assert!(!ptr.is_null()); |
|||
ComPtr(ptr) |
|||
} |
|||
/// Casts up the inheritance chain
|
|||
pub fn up<U>(self) -> ComPtr<U> where T: Deref<Target=U>, U: Interface { |
|||
ComPtr(self.into_raw() as *mut U) |
|||
} |
|||
/// Extracts the raw pointer.
|
|||
/// You are now responsible for releasing it yourself.
|
|||
pub fn into_raw(self) -> *mut T { |
|||
let p = self.0; |
|||
forget(self); |
|||
p |
|||
} |
|||
/// For internal use only.
|
|||
fn as_unknown(&self) -> &IUnknown { |
|||
unsafe { &*(self.0 as *mut IUnknown) } |
|||
} |
|||
/// Performs QueryInterface fun.
|
|||
pub fn cast<U>(&self) -> Result<ComPtr<U>, i32> where U: Interface { |
|||
let mut obj = null_mut(); |
|||
let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(unsafe { ComPtr::from_raw(obj as *mut U) }) |
|||
} |
|||
} |
|||
impl<T> Deref for ComPtr<T> where T: Interface { |
|||
type Target = T; |
|||
fn deref(&self) -> &T { |
|||
unsafe { &*self.0 } |
|||
} |
|||
} |
|||
impl<T> Clone for ComPtr<T> where T: Interface { |
|||
fn clone(&self) -> Self { |
|||
unsafe { |
|||
self.as_unknown().AddRef(); |
|||
ComPtr::from_raw(self.0) |
|||
} |
|||
} |
|||
} |
|||
impl<T> Drop for ComPtr<T> where T: Interface { |
|||
fn drop(&mut self) { |
|||
unsafe { self.as_unknown().Release(); } |
|||
} |
|||
} |
|||
pub struct BStr(BSTR); |
|||
impl BStr { |
|||
pub unsafe fn from_raw(s: BSTR) -> BStr { |
|||
BStr(s) |
|||
} |
|||
pub fn to_osstring(&self) -> OsString { |
|||
let len = unsafe { SysStringLen(self.0) }; |
|||
let slice = unsafe { from_raw_parts(self.0, len as usize) }; |
|||
OsStringExt::from_wide(slice) |
|||
} |
|||
} |
|||
impl Drop for BStr { |
|||
fn drop(&mut self) { |
|||
unsafe { SysFreeString(self.0) }; |
|||
} |
|||
} |
|||
|
|||
pub trait ToWide { |
|||
fn to_wide(&self) -> Vec<u16>; |
|||
fn to_wide_null(&self) -> Vec<u16>; |
|||
} |
|||
impl<T> ToWide for T where T: AsRef<OsStr> { |
|||
fn to_wide(&self) -> Vec<u16> { |
|||
self.as_ref().encode_wide().collect() |
|||
} |
|||
fn to_wide_null(&self) -> Vec<u16> { |
|||
self.as_ref().encode_wide().chain(Some(0)).collect() |
|||
} |
|||
} |
|||
pub trait FromWide where Self: Sized { |
|||
fn from_wide(wide: &[u16]) -> Self; |
|||
fn from_wide_null(wide: &[u16]) -> Self { |
|||
let len = wide.iter().take_while(|&&c| c != 0).count(); |
|||
Self::from_wide(&wide[..len]) |
|||
} |
|||
} |
|||
impl FromWide for OsString { |
|||
fn from_wide(wide: &[u16]) -> OsString { |
|||
OsStringExt::from_wide(wide) |
|||
} |
|||
} |
|||
|
@ -0,0 +1,257 @@ |
|||
// Copyright © 2017 winapi-rs developers
|
|||
// Licensed under the Apache License, Version 2.0
|
|||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
|
|||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
|||
// except according to those terms.
|
|||
|
|||
#![allow(bad_style)] |
|||
#![allow(unused)] |
|||
|
|||
use std::ffi::OsString; |
|||
use std::ptr::null_mut; |
|||
use winapi::Interface; |
|||
use winapi::{LPFILETIME, ULONG}; |
|||
use winapi::S_FALSE; |
|||
use winapi::BSTR; |
|||
use winapi::LPCOLESTR; |
|||
use winapi::{CLSCTX_ALL, CoCreateInstance}; |
|||
use winapi::LPSAFEARRAY; |
|||
use winapi::{IUnknown, IUnknownVtbl}; |
|||
use winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG}; |
|||
|
|||
use com::{BStr, ComPtr}; |
|||
|
|||
// Bindings to the Setup.Configuration stuff
|
|||
pub type InstanceState = u32; |
|||
|
|||
pub const eNone: InstanceState = 0; |
|||
pub const eLocal: InstanceState = 1; |
|||
pub const eRegistered: InstanceState = 2; |
|||
pub const eNoRebootRequired: InstanceState = 4; |
|||
pub const eComplete: InstanceState = -1i32 as u32; |
|||
|
|||
RIDL!{#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)] |
|||
interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) { |
|||
fn GetInstanceId( |
|||
pbstrInstanceId: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetInstallDate( |
|||
pInstallDate: LPFILETIME, |
|||
) -> HRESULT, |
|||
fn GetInstallationName( |
|||
pbstrInstallationName: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetInstallationPath( |
|||
pbstrInstallationPath: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetInstallationVersion( |
|||
pbstrInstallationVersion: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetDisplayName( |
|||
lcid: LCID, |
|||
pbstrDisplayName: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetDescription( |
|||
lcid: LCID, |
|||
pbstrDescription: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn ResolvePath( |
|||
pwszRelativePath: LPCOLESTR, |
|||
pbstrAbsolutePath: *mut BSTR, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)] |
|||
interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) { |
|||
fn GetState( |
|||
pState: *mut InstanceState, |
|||
) -> HRESULT, |
|||
fn GetPackages( |
|||
ppsaPackages: *mut LPSAFEARRAY, |
|||
) -> HRESULT, |
|||
fn GetProduct( |
|||
ppPackage: *mut *mut ISetupPackageReference, |
|||
) -> HRESULT, |
|||
fn GetProductPath( |
|||
pbstrProductPath: *mut BSTR, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)] |
|||
interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) { |
|||
fn Next( |
|||
celt: ULONG, |
|||
rgelt: *mut *mut ISetupInstance, |
|||
pceltFetched: *mut ULONG, |
|||
) -> HRESULT, |
|||
fn Skip( |
|||
celt: ULONG, |
|||
) -> HRESULT, |
|||
fn Reset() -> HRESULT, |
|||
fn Clone( |
|||
ppenum: *mut *mut IEnumSetupInstances, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)] |
|||
interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) { |
|||
fn EnumInstances( |
|||
ppEnumInstances: *mut *mut IEnumSetupInstances, |
|||
) -> HRESULT, |
|||
fn GetInstanceForCurrentProcess( |
|||
ppInstance: *mut *mut ISetupInstance, |
|||
) -> HRESULT, |
|||
fn GetInstanceForPath( |
|||
wzPath: LPCWSTR, |
|||
ppInstance: *mut *mut ISetupInstance, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)] |
|||
interface ISetupConfiguration2(ISetupConfiguration2Vtbl): |
|||
ISetupConfiguration(ISetupConfigurationVtbl) { |
|||
fn EnumAllInstances( |
|||
ppEnumInstances: *mut *mut IEnumSetupInstances, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)] |
|||
interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) { |
|||
fn GetId( |
|||
pbstrId: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetVersion( |
|||
pbstrVersion: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetChip( |
|||
pbstrChip: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetLanguage( |
|||
pbstrLanguage: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetBranch( |
|||
pbstrBranch: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetType( |
|||
pbstrType: *mut BSTR, |
|||
) -> HRESULT, |
|||
fn GetUniqueId( |
|||
pbstrUniqueId: *mut BSTR, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
RIDL!{#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)] |
|||
interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) { |
|||
fn ParseVersion( |
|||
pwszVersion: LPCOLESTR, |
|||
pullVersion: PULONGLONG, |
|||
) -> HRESULT, |
|||
fn ParseVersionRange( |
|||
pwszVersionRange: LPCOLESTR, |
|||
pullMinVersion: PULONGLONG, |
|||
pullMaxVersion: PULONGLONG, |
|||
) -> HRESULT, |
|||
}} |
|||
|
|||
DEFINE_GUID!{CLSID_SetupConfiguration, |
|||
0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d} |
|||
|
|||
// Safe wrapper around the COM interfaces
|
|||
pub struct SetupConfiguration(ComPtr<ISetupConfiguration>); |
|||
|
|||
impl SetupConfiguration { |
|||
pub fn new() -> Result<SetupConfiguration, i32> { |
|||
let mut obj = null_mut(); |
|||
let err = unsafe { CoCreateInstance( |
|||
&CLSID_SetupConfiguration, null_mut(), CLSCTX_ALL, |
|||
&ISetupConfiguration::uuidof(), &mut obj, |
|||
) }; |
|||
if err < 0 { return Err(err); } |
|||
let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) }; |
|||
Ok(SetupConfiguration(obj)) |
|||
} |
|||
pub fn get_instance_for_current_process(&self) -> Result<SetupInstance, i32> { |
|||
let mut obj = null_mut(); |
|||
let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(unsafe { SetupInstance::from_raw(obj) }) |
|||
} |
|||
pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> { |
|||
let mut obj = null_mut(); |
|||
let err = unsafe { self.0.EnumInstances(&mut obj) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(unsafe { EnumSetupInstances::from_raw(obj) }) |
|||
} |
|||
pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> { |
|||
let mut obj = null_mut(); |
|||
let this = try!(self.0.cast::<ISetupConfiguration2>()); |
|||
let err = unsafe { this.EnumAllInstances(&mut obj) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(unsafe { EnumSetupInstances::from_raw(obj) }) |
|||
} |
|||
} |
|||
|
|||
pub struct SetupInstance(ComPtr<ISetupInstance>); |
|||
|
|||
impl SetupInstance { |
|||
pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance { |
|||
SetupInstance(ComPtr::from_raw(obj)) |
|||
} |
|||
pub fn instance_id(&self) -> Result<OsString, i32> { |
|||
let mut s = null_mut(); |
|||
let err = unsafe { self.0.GetInstanceId(&mut s) }; |
|||
let bstr = unsafe { BStr::from_raw(s) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(bstr.to_osstring()) |
|||
} |
|||
pub fn installation_name(&self) -> Result<OsString, i32> { |
|||
let mut s = null_mut(); |
|||
let err = unsafe { self.0.GetInstallationName(&mut s) }; |
|||
let bstr = unsafe { BStr::from_raw(s) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(bstr.to_osstring()) |
|||
} |
|||
pub fn installation_path(&self) -> Result<OsString, i32> { |
|||
let mut s = null_mut(); |
|||
let err = unsafe { self.0.GetInstallationPath(&mut s) }; |
|||
let bstr = unsafe { BStr::from_raw(s) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(bstr.to_osstring()) |
|||
} |
|||
pub fn installation_version(&self) -> Result<OsString, i32> { |
|||
let mut s = null_mut(); |
|||
let err = unsafe { self.0.GetInstallationVersion(&mut s) }; |
|||
let bstr = unsafe { BStr::from_raw(s) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(bstr.to_osstring()) |
|||
} |
|||
pub fn product_path(&self) -> Result<OsString, i32> { |
|||
let mut s = null_mut(); |
|||
let this = try!(self.0.cast::<ISetupInstance2>()); |
|||
let err = unsafe { this.GetProductPath(&mut s) }; |
|||
let bstr = unsafe { BStr::from_raw(s) }; |
|||
if err < 0 { return Err(err); } |
|||
Ok(bstr.to_osstring()) |
|||
} |
|||
} |
|||
|
|||
pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>); |
|||
|
|||
impl EnumSetupInstances { |
|||
pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances { |
|||
EnumSetupInstances(ComPtr::from_raw(obj)) |
|||
} |
|||
} |
|||
|
|||
impl Iterator for EnumSetupInstances { |
|||
type Item = Result<SetupInstance, i32>; |
|||
fn next(&mut self) -> Option<Result<SetupInstance, i32>> { |
|||
let mut obj = null_mut(); |
|||
let err = unsafe { self.0.Next(1, &mut obj, null_mut()) }; |
|||
if err < 0 { return Some(Err(err)); } |
|||
if err == S_FALSE { return None; } |
|||
Some(Ok(unsafe { SetupInstance::from_raw(obj) })) |
|||
} |
|||
} |
|||
|
@ -0,0 +1,214 @@ |
|||
// Copyright © 2015-2017 winapi-rs developers
|
|||
// Licensed under the Apache License, Version 2.0
|
|||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
|
|||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
|||
// except according to those terms.
|
|||
|
|||
#![allow(bad_style)] |
|||
|
|||
use std::os::raw; |
|||
|
|||
pub type wchar_t = u16; |
|||
|
|||
pub type UINT = raw::c_uint; |
|||
pub type LPUNKNOWN = *mut IUnknown; |
|||
pub type REFIID = *const IID; |
|||
pub type IID = GUID; |
|||
pub type REFCLSID = *const IID; |
|||
pub type PVOID = *mut raw::c_void; |
|||
pub type USHORT = raw::c_ushort; |
|||
pub type ULONG = raw::c_ulong; |
|||
pub type LONG = raw::c_long; |
|||
pub type DWORD = u32; |
|||
pub type LPVOID = *mut raw::c_void; |
|||
pub type HRESULT = raw::c_long; |
|||
pub type LPFILETIME = *mut FILETIME; |
|||
pub type BSTR = *mut OLECHAR; |
|||
pub type OLECHAR = WCHAR; |
|||
pub type WCHAR = wchar_t; |
|||
pub type LPCOLESTR = *const OLECHAR; |
|||
pub type LCID = DWORD; |
|||
pub type LPCWSTR = *const WCHAR; |
|||
pub type PULONGLONG = *mut ULONGLONG; |
|||
pub type ULONGLONG = u64; |
|||
|
|||
pub const S_OK: HRESULT = 0; |
|||
pub const S_FALSE: HRESULT = 1; |
|||
pub const COINIT_MULTITHREADED: u32 = 0x0; |
|||
|
|||
pub type CLSCTX = u32; |
|||
|
|||
pub const CLSCTX_INPROC_SERVER: CLSCTX = 0x1; |
|||
pub const CLSCTX_INPROC_HANDLER: CLSCTX = 0x2; |
|||
pub const CLSCTX_LOCAL_SERVER: CLSCTX = 0x4; |
|||
pub const CLSCTX_REMOTE_SERVER: CLSCTX = 0x10; |
|||
|
|||
pub const CLSCTX_ALL: CLSCTX = CLSCTX_INPROC_SERVER | |
|||
CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER; |
|||
|
|||
#[repr(C)] |
|||
#[derive(Copy, Clone)] |
|||
pub struct GUID { |
|||
pub Data1: raw::c_ulong, |
|||
pub Data2: raw::c_ushort, |
|||
pub Data3: raw::c_ushort, |
|||
pub Data4: [raw::c_uchar; 8], |
|||
} |
|||
|
|||
#[repr(C)] |
|||
#[derive(Copy, Clone)] |
|||
pub struct FILETIME { |
|||
pub dwLowDateTime: DWORD, |
|||
pub dwHighDateTime: DWORD, |
|||
} |
|||
|
|||
pub trait Interface { |
|||
fn uuidof() -> GUID; |
|||
} |
|||
|
|||
#[link(name = "Ole32")] |
|||
#[link(name = "OleAut32")] |
|||
extern { } |
|||
|
|||
extern "system" { |
|||
pub fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT; |
|||
pub fn CoCreateInstance(rclsid: REFCLSID, pUnkOuter: LPUNKNOWN, |
|||
dwClsContext: DWORD, riid: REFIID, |
|||
ppv: *mut LPVOID) -> HRESULT; |
|||
pub fn SysFreeString(bstrString: BSTR); |
|||
pub fn SysStringLen(pbstr: BSTR) -> UINT; |
|||
} |
|||
|
|||
#[repr(C)] |
|||
#[derive(Copy, Clone)] |
|||
pub struct SAFEARRAYBOUND { |
|||
pub cElements: ULONG, |
|||
pub lLbound: LONG, |
|||
} |
|||
|
|||
#[repr(C)] |
|||
#[derive(Copy, Clone)] |
|||
pub struct SAFEARRAY { |
|||
pub cDims: USHORT, |
|||
pub fFeatures: USHORT, |
|||
pub cbElements: ULONG, |
|||
pub cLocks: ULONG, |
|||
pub pvData: PVOID, |
|||
pub rgsabound: [SAFEARRAYBOUND; 1], |
|||
} |
|||
|
|||
pub type LPSAFEARRAY = *mut SAFEARRAY; |
|||
|
|||
macro_rules! DEFINE_GUID { |
|||
( |
|||
$name:ident, $l:expr, $w1:expr, $w2:expr, |
|||
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr |
|||
) => { |
|||
pub const $name: $crate::winapi::GUID = $crate::winapi::GUID { |
|||
Data1: $l, |
|||
Data2: $w1, |
|||
Data3: $w2, |
|||
Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], |
|||
}; |
|||
} |
|||
} |
|||
|
|||
macro_rules! RIDL { |
|||
(#[uuid($($uuid:expr),+)] |
|||
interface $interface:ident ($vtbl:ident) {$( |
|||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, |
|||
)+}) => ( |
|||
#[repr(C)] |
|||
pub struct $vtbl { |
|||
$(pub $method: unsafe extern "system" fn( |
|||
This: *mut $interface, |
|||
$($p: $t),* |
|||
) -> $rtr,)+ |
|||
} |
|||
#[repr(C)] |
|||
pub struct $interface { |
|||
pub lpVtbl: *const $vtbl, |
|||
} |
|||
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}} |
|||
RIDL!{@uuid $interface $($uuid),+} |
|||
); |
|||
(#[uuid($($uuid:expr),+)] |
|||
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) { |
|||
}) => ( |
|||
#[repr(C)] |
|||
pub struct $vtbl { |
|||
pub parent: $pvtbl, |
|||
} |
|||
#[repr(C)] |
|||
pub struct $interface { |
|||
pub lpVtbl: *const $vtbl, |
|||
} |
|||
RIDL!{@deref $interface $pinterface} |
|||
RIDL!{@uuid $interface $($uuid),+} |
|||
); |
|||
(#[uuid($($uuid:expr),+)] |
|||
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$( |
|||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, |
|||
)+}) => ( |
|||
#[repr(C)] |
|||
pub struct $vtbl { |
|||
pub parent: $pvtbl, |
|||
$(pub $method: unsafe extern "system" fn( |
|||
This: *mut $interface, |
|||
$($p: $t,)* |
|||
) -> $rtr,)+ |
|||
} |
|||
#[repr(C)] |
|||
pub struct $interface { |
|||
pub lpVtbl: *const $vtbl, |
|||
} |
|||
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}} |
|||
RIDL!{@deref $interface $pinterface} |
|||
RIDL!{@uuid $interface $($uuid),+} |
|||
); |
|||
(@deref $interface:ident $pinterface:ident) => ( |
|||
impl ::std::ops::Deref for $interface { |
|||
type Target = $pinterface; |
|||
#[inline] |
|||
fn deref(&self) -> &$pinterface { |
|||
unsafe { &*(self as *const $interface as *const $pinterface) } |
|||
} |
|||
} |
|||
); |
|||
(@impl $interface:ident {$( |
|||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, |
|||
)+}) => ( |
|||
impl $interface { |
|||
$(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr { |
|||
((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*) |
|||
})+ |
|||
} |
|||
); |
|||
(@uuid $interface:ident |
|||
$l:expr, $w1:expr, $w2:expr, |
|||
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr |
|||
) => ( |
|||
impl $crate::winapi::Interface for $interface { |
|||
#[inline] |
|||
fn uuidof() -> $crate::winapi::GUID { |
|||
$crate::winapi::GUID { |
|||
Data1: $l, |
|||
Data2: $w1, |
|||
Data3: $w2, |
|||
Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], |
|||
} |
|||
} |
|||
} |
|||
); |
|||
} |
|||
|
|||
RIDL!{#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)] |
|||
interface IUnknown(IUnknownVtbl) { |
|||
fn QueryInterface( |
|||
riid: REFIID, |
|||
ppvObject: *mut *mut raw::c_void, |
|||
) -> HRESULT, |
|||
fn AddRef() -> ULONG, |
|||
fn Release() -> ULONG, |
|||
}} |
Loading…
Reference in new issue