diff --git a/.gitignore b/.gitignore index c456844..8cf1ab7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ Cargo.lock .metadata/bin obj bin -.vs \ No newline at end of file +.vs +*.sln \ No newline at end of file diff --git a/.metadata/idl/state.idl b/.metadata/idl/state.idl index 84c1fe7..fd01a1e 100644 --- a/.metadata/idl/state.idl +++ b/.metadata/idl/state.idl @@ -1,6 +1,20 @@ import "objidl.idl"; import "oaidl.idl"; import "propidl.idl"; +// import "wtypes.idl"; + +typedef struct StateData +{ + BOOLEAN Ok; + BOOL Ok2; + LPCWSTR Name; + LPCSTR Name2; + ULONG Number; + LONG Number2; + DWORD Flags; + BYTE* Data; + void* Reserved; +} StateData; [ object, @@ -12,4 +26,11 @@ import "propidl.idl"; interface IState: IUnknown { HRESULT GetFlower([out, retval] BSTR* flower); + + // If the above StateData struct is removed + // This works for bindgen. It correctly references to the windows crate. + // BOOLEAN GetBool(); + DWORD GetBool(); + + StateData* GetData(); } diff --git a/.windows/winmd/Microsoft.States.winmd b/.windows/winmd/Microsoft.States.winmd index 38fb72f..b52c9ef 100644 Binary files a/.windows/winmd/Microsoft.States.winmd and b/.windows/winmd/Microsoft.States.winmd differ diff --git a/Cargo.toml b/Cargo.toml index 1235158..559ed13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,9 +21,15 @@ targets = [] [dependencies.windows] version = "0.58.0" +features = ["Win32"] [dependencies.windows-core] version = "0.58.0" [build-dependencies.windows-bindgen] version = "0.58.0" + +[patch.crates-io] +windows-bindgen = { git = "https://github.com/microsoft/windows-rs.git", rev = "8ebef12cf50c71cf4b0054fbc4b74cc8c37bc72f"} +windows = { git = "https://github.com/microsoft/windows-rs.git", rev = "8ebef12cf50c71cf4b0054fbc4b74cc8c37bc72f"} +windows-core = { git = "https://github.com/microsoft/windows-rs.git", rev = "8ebef12cf50c71cf4b0054fbc4b74cc8c37bc72f"} diff --git a/build.rs b/build.rs index 59bce50..c187124 100644 --- a/build.rs +++ b/build.rs @@ -5,12 +5,13 @@ fn main() { windows_bindgen::bindgen([ "--in", ".windows/winmd/Microsoft.States.winmd", + "--in", + "default", "--out", "src/bindings.rs", "--filter", "Microsoft.States", - "--config", - "implement" - ]) - .unwrap(); + "--reference", + "windows,skip-root,Windows", + ]); } diff --git a/crates/samples/impl/src/main.rs b/crates/samples/impl/src/main.rs index 8344f17..aa579a8 100644 --- a/crates/samples/impl/src/main.rs +++ b/crates/samples/impl/src/main.rs @@ -1,5 +1,5 @@ -use washington_rs::States::*; -use windows::core::*; +use washington_rs::Microsoft::States::*; +use windows_core::{implement, Result, BSTR}; #[derive(Debug)] #[implement(IState)] @@ -10,12 +10,20 @@ impl IState_Impl for Atlantis_Impl { fn GetFlower(&self) -> Result { Ok("Red algae".into()) } + + fn GetBool(&self) -> u32 { + 1 + } + + fn GetData(&self) -> *mut StateData { + std::ptr::null_mut() + } } fn main() -> windows::core::Result<()> { - unsafe { - let state: IState = Atlantis.into(); - println!("{}", state.GetFlower()?); - } + let com: IState = Atlantis {}.into(); + let s = unsafe { com.GetFlower() }?; + println!("GetFlower: {}", s); + println!("GetBool: {}", unsafe { com.GetBool() }); Ok(()) } diff --git a/src/bindings.rs b/src/bindings.rs index abd0d0b..fbabb58 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -7,216 +7,242 @@ dead_code, clippy::all )] -pub mod States { - pub mod Washington { + +pub mod Microsoft { + pub mod States { windows_core::imp::define_interface!( - IWashington, - IWashington_Vtbl, - 0xa7c97d53_cf24_4453_bd17_55a48e1d0510 + IState, + IState_Vtbl, + 0x2f0cf45d_04a9_43cc_bc50_ebfe429fcecf ); - impl core::ops::Deref for IWashington { - type Target = windows_core::IUnknown; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } - } - windows_core::imp::interface_hierarchy!(IWashington, windows_core::IUnknown); - impl IWashington { - pub unsafe fn Load(&self) -> windows_core::Result<()> { - (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self)) - .ok() - } - pub unsafe fn LoadFrom(&self, path: P0) -> windows_core::Result<()> - where - P0: windows_core::Param, - { - (windows_core::Interface::vtable(self).LoadFrom)( + windows_core::imp::interface_hierarchy!(IState, windows_core::IUnknown); + impl IState { + pub unsafe fn GetFlower(&self) -> windows_core::Result { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFlower)( windows_core::Interface::as_raw(self), - path.param().abi(), + &mut result__, ) - .ok() + .map(|| core::mem::transmute(result__)) + } + pub unsafe fn GetBool(&self) -> u32 { + (windows_core::Interface::vtable(self).GetBool)(windows_core::Interface::as_raw( + self, + )) + } + pub unsafe fn GetData(&self) -> *mut StateData { + (windows_core::Interface::vtable(self).GetData)(windows_core::Interface::as_raw( + self, + )) } } #[repr(C)] - pub struct IWashington_Vtbl { + pub struct IState_Vtbl { pub base__: windows_core::IUnknown_Vtbl, - pub Load: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub LoadFrom: unsafe extern "system" fn( + pub GetFlower: unsafe extern "system" fn( *mut core::ffi::c_void, - windows_core::PCWSTR, + *mut *mut core::ffi::c_void, ) -> windows_core::HRESULT, + pub GetBool: unsafe extern "system" fn(*mut core::ffi::c_void) -> u32, + pub GetData: unsafe extern "system" fn(*mut core::ffi::c_void) -> *mut StateData, } - windows_core::imp::define_interface!( - IWashington2, - IWashington2_Vtbl, - 0xe27af699_bc37_47b8_ad97_1c6720389efd - ); - impl core::ops::Deref for IWashington2 { - type Target = IWashington; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } - } - windows_core::imp::interface_hierarchy!(IWashington2, windows_core::IUnknown, IWashington); - impl IWashington2 { - pub unsafe fn Load2(&self) -> windows_core::Result<()> { - (windows_core::Interface::vtable(self).Load2)(windows_core::Interface::as_raw(self)) - .ok() - } - } - #[repr(C)] - pub struct IWashington2_Vtbl { - pub base__: IWashington_Vtbl, - pub Load2: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - } - pub trait IWashington_Impl: Sized { - fn Load(&self) -> windows_core::Result<()>; - fn LoadFrom(&self, path: &windows_core::PCWSTR) -> windows_core::Result<()>; + pub trait IState_Impl: windows_core::IUnknownImpl { + fn GetFlower(&self) -> windows_core::Result; + fn GetBool(&self) -> u32; + fn GetData(&self) -> *mut StateData; } - impl windows_core::RuntimeName for IWashington {} - impl IWashington_Vtbl { - pub const fn new( - ) -> IWashington_Vtbl - where - Identity: IWashington_Impl, - { - unsafe extern "system" fn Load< - Identity: windows_core::IUnknownImpl, - const OFFSET: isize, - >( + impl IState_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFlower( this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT - where - Identity: IWashington_Impl, - { + flower: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IWashington_Impl::Load(this).into() + match IState_Impl::GetFlower(this) { + Ok(ok__) => { + flower.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } } - unsafe extern "system" fn LoadFrom< - Identity: windows_core::IUnknownImpl, - const OFFSET: isize, - >( + unsafe extern "system" fn GetBool( this: *mut core::ffi::c_void, - path: windows_core::PCWSTR, - ) -> windows_core::HRESULT - where - Identity: IWashington_Impl, - { + ) -> u32 { let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IWashington_Impl::LoadFrom(this, core::mem::transmute(&path)).into() + IState_Impl::GetBool(this) + } + unsafe extern "system" fn GetData( + this: *mut core::ffi::c_void, + ) -> *mut StateData { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IState_Impl::GetData(this) } Self { base__: windows_core::IUnknown_Vtbl::new::(), - Load: Load::, - LoadFrom: LoadFrom::, + GetFlower: GetFlower::, + GetBool: GetBool::, + GetData: GetData::, } } pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID + iid == &::IID } } - pub trait IWashington2_Impl: Sized + IWashington_Impl { - fn Load2(&self) -> windows_core::Result<()>; + impl windows_core::RuntimeName for IState {} + #[repr(C)] + #[derive(Clone, Copy, Debug, PartialEq)] + pub struct StateData { + pub Ok: windows::Win32::Foundation::BOOLEAN, + pub Ok2: windows::Win32::Foundation::BOOL, + pub Name: windows_core::PCWSTR, + pub Name2: windows_core::PCSTR, + pub Number: u32, + pub Number2: i32, + pub Flags: u32, + pub Data: *mut u8, + pub Reserved: *mut core::ffi::c_void, } - impl windows_core::RuntimeName for IWashington2 {} - impl IWashington2_Vtbl { - pub const fn new( - ) -> IWashington2_Vtbl - where - Identity: IWashington2_Impl, - { - unsafe extern "system" fn Load2< - Identity: windows_core::IUnknownImpl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT + impl Default for StateData { + fn default() -> Self { + unsafe { core::mem::zeroed() } + } + } + impl windows_core::TypeKind for StateData { + type TypeKind = windows_core::CopyType; + } + pub mod Washington { + windows_core::imp::define_interface!( + IWashington, + IWashington_Vtbl, + 0xa7c97d53_cf24_4453_bd17_55a48e1d0510 + ); + windows_core::imp::interface_hierarchy!(IWashington, windows_core::IUnknown); + impl IWashington { + pub unsafe fn Load(&self) -> windows_core::Result<()> { + (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw( + self, + )) + .ok() + } + pub unsafe fn LoadFrom(&self, path: P0) -> windows_core::Result<()> where - Identity: IWashington2_Impl, + P0: windows_core::Param, { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IWashington2_Impl::Load2(this).into() - } - Self { - base__: IWashington_Vtbl::new::(), - Load2: Load2::, + (windows_core::Interface::vtable(self).LoadFrom)( + windows_core::Interface::as_raw(self), + path.param().abi(), + ) + .ok() } } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - || iid == &::IID + #[repr(C)] + pub struct IWashington_Vtbl { + pub base__: windows_core::IUnknown_Vtbl, + pub Load: + unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub LoadFrom: unsafe extern "system" fn( + *mut core::ffi::c_void, + windows_core::PCWSTR, + ) -> windows_core::HRESULT, } - } - } - windows_core::imp::define_interface!( - IState, - IState_Vtbl, - 0x2f0cf45d_04a9_43cc_bc50_ebfe429fcecf - ); - impl core::ops::Deref for IState { - type Target = windows_core::IUnknown; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } - } - windows_core::imp::interface_hierarchy!(IState, windows_core::IUnknown); - impl IState { - pub unsafe fn GetFlower(&self) -> windows_core::Result { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).GetFlower)( - windows_core::Interface::as_raw(self), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - #[repr(C)] - pub struct IState_Vtbl { - pub base__: windows_core::IUnknown_Vtbl, - pub GetFlower: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::mem::MaybeUninit, - ) -> windows_core::HRESULT, - } - pub trait IState_Impl: Sized { - fn GetFlower(&self) -> windows_core::Result; - } - impl windows_core::RuntimeName for IState {} - impl IState_Vtbl { - pub const fn new() -> IState_Vtbl - where - Identity: IState_Impl, - { - unsafe extern "system" fn GetFlower< - Identity: windows_core::IUnknownImpl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - flower: *mut core::mem::MaybeUninit, - ) -> windows_core::HRESULT - where - Identity: IState_Impl, - { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IState_Impl::GetFlower(this) { - Ok(ok__) => { - flower.write(core::mem::transmute(ok__)); - windows_core::HRESULT(0) + pub trait IWashington_Impl: windows_core::IUnknownImpl { + fn Load(&self) -> windows_core::Result<()>; + fn LoadFrom(&self, path: &windows_core::PCWSTR) -> windows_core::Result<()>; + } + impl IWashington_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Load< + Identity: IWashington_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IWashington_Impl::Load(this).into() } - Err(err) => err.into(), + unsafe extern "system" fn LoadFrom< + Identity: IWashington_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + path: windows_core::PCWSTR, + ) -> windows_core::HRESULT { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IWashington_Impl::LoadFrom(this, core::mem::transmute(&path)).into() + } + Self { + base__: windows_core::IUnknown_Vtbl::new::(), + Load: Load::, + LoadFrom: LoadFrom::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } + } + impl windows_core::RuntimeName for IWashington {} + windows_core::imp::define_interface!( + IWashington2, + IWashington2_Vtbl, + 0xe27af699_bc37_47b8_ad97_1c6720389efd + ); + impl core::ops::Deref for IWashington2 { + type Target = IWashington; + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } } } - Self { - base__: windows_core::IUnknown_Vtbl::new::(), - GetFlower: GetFlower::, + windows_core::imp::interface_hierarchy!( + IWashington2, + windows_core::IUnknown, + IWashington + ); + impl IWashington2 { + pub unsafe fn Load2(&self) -> windows_core::Result<()> { + (windows_core::Interface::vtable(self).Load2)(windows_core::Interface::as_raw( + self, + )) + .ok() + } } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID + #[repr(C)] + pub struct IWashington2_Vtbl { + pub base__: IWashington_Vtbl, + pub Load2: + unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + } + pub trait IWashington2_Impl: IWashington_Impl { + fn Load2(&self) -> windows_core::Result<()>; + } + impl IWashington2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Load2< + Identity: IWashington2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IWashington2_Impl::Load2(this).into() + } + Self { + base__: IWashington_Vtbl::new::(), + Load2: Load2::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + || iid == &::IID + } + } + impl windows_core::RuntimeName for IWashington2 {} } } }