From ab03721b8ca332b09a3ff1a38729bbdf0c691282 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Wed, 3 Jul 2024 11:31:03 -0500 Subject: [PATCH] Make new `windows-strings` crate Windows-only (#3143) --- crates/libs/core/src/inspectable.rs | 21 ++++++--- crates/libs/core/src/lib.rs | 1 - crates/libs/core/src/param.rs | 24 ---------- crates/libs/core/src/runtime_type.rs | 4 -- crates/libs/core/src/type.rs | 24 ---------- crates/libs/core/src/windows.rs | 54 +++++++++++++++++++++++ crates/libs/strings/src/hstring.rs | 38 ++++++++-------- crates/libs/strings/src/hstring_header.rs | 20 --------- crates/libs/strings/src/lib.rs | 1 + crates/libs/windows/src/lib.rs | 1 + 10 files changed, 90 insertions(+), 98 deletions(-) diff --git a/crates/libs/core/src/inspectable.rs b/crates/libs/core/src/inspectable.rs index 9e1904cfdd..a84305ba8e 100644 --- a/crates/libs/core/src/inspectable.rs +++ b/crates/libs/core/src/inspectable.rs @@ -1,6 +1,5 @@ use super::*; use core::ffi::c_void; -use core::mem::{transmute, transmute_copy}; use core::ptr::null_mut; /// A WinRT object that may be used as a polymorphic stand-in for any WinRT class, interface, or boxed value. @@ -15,11 +14,12 @@ interface_hierarchy!(IInspectable, IUnknown); impl IInspectable { /// Returns the canonical type name for the underlying object. + #[cfg(windows)] pub fn GetRuntimeClassName(&self) -> Result { unsafe { let mut abi = null_mut(); - (self.vtable().GetRuntimeClassName)(transmute_copy(self), &mut abi).ok()?; - Ok(transmute::<*mut c_void, HSTRING>(abi)) + (self.vtable().GetRuntimeClassName)(core::mem::transmute_copy(self), &mut abi).ok()?; + Ok(core::mem::transmute::<*mut c_void, HSTRING>(abi)) } } @@ -27,7 +27,7 @@ impl IInspectable { pub fn GetTrustLevel(&self) -> Result { unsafe { let mut value = 0; - (self.vtable().GetTrustLevel)(transmute_copy(self), &mut value).ok()?; + (self.vtable().GetTrustLevel)(core::mem::transmute_copy(self), &mut value).ok()?; Ok(value) } } @@ -82,8 +82,17 @@ impl IInspectable_Vtbl { if value.is_null() { return imp::E_POINTER; } - let h: HSTRING = T::NAME.into(); // TODO: should be try_into - *value = transmute::(h); + + #[cfg(windows)] + { + *value = core::mem::transmute::(T::NAME.into()); + } + + #[cfg(not(windows))] + { + *value = core::ptr::null_mut(); + } + HRESULT(0) } unsafe extern "system" fn GetTrustLevel( diff --git a/crates/libs/core/src/lib.rs b/crates/libs/core/src/lib.rs index ae2e35f2cd..d8a2b77f87 100644 --- a/crates/libs/core/src/lib.rs +++ b/crates/libs/core/src/lib.rs @@ -58,4 +58,3 @@ pub use weak::*; pub use windows_implement::implement; pub use windows_interface::interface; pub use windows_result::*; -pub use windows_strings::*; diff --git a/crates/libs/core/src/param.rs b/crates/libs/core/src/param.rs index 39b69cdb8d..9c853bed47 100644 --- a/crates/libs/core/src/param.rs +++ b/crates/libs/core/src/param.rs @@ -61,27 +61,3 @@ where ParamValue::Owned(transmute_copy(&self)) } } - -impl Param for &BSTR { - unsafe fn param(self) -> ParamValue { - ParamValue::Owned(PCWSTR(self.as_ptr())) - } -} - -impl Param for &HSTRING { - unsafe fn param(self) -> ParamValue { - ParamValue::Owned(PCWSTR(self.as_ptr())) - } -} - -impl Param for PWSTR { - unsafe fn param(self) -> ParamValue { - ParamValue::Owned(PCWSTR(self.0)) - } -} - -impl Param for PSTR { - unsafe fn param(self) -> ParamValue { - ParamValue::Owned(PCSTR(self.0)) - } -} diff --git a/crates/libs/core/src/runtime_type.rs b/crates/libs/core/src/runtime_type.rs index 1fe725b9eb..f28ded853e 100644 --- a/crates/libs/core/src/runtime_type.rs +++ b/crates/libs/core/src/runtime_type.rs @@ -28,7 +28,3 @@ primitives! { (f32, b"f4"), (f64, b"f8") } - -impl RuntimeType for HSTRING { - const SIGNATURE: imp::ConstBuffer = imp::ConstBuffer::from_slice(b"string"); -} diff --git a/crates/libs/core/src/type.rs b/crates/libs/core/src/type.rs index 215c20135d..92326a0ae2 100644 --- a/crates/libs/core/src/type.rs +++ b/crates/libs/core/src/type.rs @@ -98,27 +98,3 @@ primitives!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, usize, isize); #[doc(hidden)] pub type AbiType = >::Abi; - -impl TypeKind for PWSTR { - type TypeKind = CopyType; -} - -impl TypeKind for PSTR { - type TypeKind = CopyType; -} - -impl TypeKind for PCWSTR { - type TypeKind = CopyType; -} - -impl TypeKind for PCSTR { - type TypeKind = CopyType; -} - -impl TypeKind for HSTRING { - type TypeKind = CloneType; -} - -impl TypeKind for BSTR { - type TypeKind = CloneType; -} diff --git a/crates/libs/core/src/windows.rs b/crates/libs/core/src/windows.rs index 9b2bc0938e..76cd45b9de 100644 --- a/crates/libs/core/src/windows.rs +++ b/crates/libs/core/src/windows.rs @@ -15,8 +15,62 @@ pub use handles::*; mod variant; pub use variant::*; +pub use windows_strings::*; + /// Attempts to load the factory object for the given WinRT class. /// This can be used to access COM interfaces implemented on a Windows Runtime class factory. pub fn factory() -> Result { imp::factory::() } + +impl Param for &BSTR { + unsafe fn param(self) -> ParamValue { + ParamValue::Owned(PCWSTR(self.as_ptr())) + } +} + +impl Param for &HSTRING { + unsafe fn param(self) -> ParamValue { + ParamValue::Owned(PCWSTR(self.as_ptr())) + } +} + +impl Param for PWSTR { + unsafe fn param(self) -> ParamValue { + ParamValue::Owned(PCWSTR(self.0)) + } +} + +impl Param for PSTR { + unsafe fn param(self) -> ParamValue { + ParamValue::Owned(PCSTR(self.0)) + } +} + +impl RuntimeType for HSTRING { + const SIGNATURE: imp::ConstBuffer = imp::ConstBuffer::from_slice(b"string"); +} + +impl TypeKind for PWSTR { + type TypeKind = CopyType; +} + +impl TypeKind for PSTR { + type TypeKind = CopyType; +} + +impl TypeKind for PCWSTR { + type TypeKind = CopyType; +} + +impl TypeKind for PCSTR { + type TypeKind = CopyType; +} + +impl TypeKind for HSTRING { + type TypeKind = CloneType; +} + +impl TypeKind for BSTR { + type TypeKind = CloneType; +} diff --git a/crates/libs/strings/src/hstring.rs b/crates/libs/strings/src/hstring.rs index b6766b89f2..6cd0a1ebc4 100644 --- a/crates/libs/strings/src/hstring.rs +++ b/crates/libs/strings/src/hstring.rs @@ -54,7 +54,7 @@ impl HSTRING { } /// Get the contents of this `HSTRING` as a OsString. - #[cfg(all(feature = "std", windows))] + #[cfg(feature = "std")] pub fn to_os_string(&self) -> std::ffi::OsString { std::os::windows::ffi::OsStringExt::from_wide(self.as_wide()) } @@ -154,14 +154,14 @@ impl From<&String> for HSTRING { } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl From<&std::path::Path> for HSTRING { fn from(value: &std::path::Path) -> Self { value.as_os_str().into() } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl From<&std::ffi::OsStr> for HSTRING { fn from(value: &std::ffi::OsStr) -> Self { unsafe { @@ -174,14 +174,14 @@ impl From<&std::ffi::OsStr> for HSTRING { } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl From for HSTRING { fn from(value: std::ffi::OsString) -> Self { value.as_os_str().into() } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl From<&std::ffi::OsString> for HSTRING { fn from(value: &std::ffi::OsString) -> Self { value.as_os_str().into() @@ -286,28 +286,28 @@ impl PartialEq<&HSTRING> for String { } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for HSTRING { fn eq(&self, other: &std::ffi::OsString) -> bool { *self == **other } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for &HSTRING { fn eq(&self, other: &std::ffi::OsString) -> bool { **self == **other } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq<&std::ffi::OsString> for HSTRING { fn eq(&self, other: &&std::ffi::OsString) -> bool { *self == ***other } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for HSTRING { fn eq(&self, other: &std::ffi::OsStr) -> bool { self.as_wide() @@ -317,56 +317,56 @@ impl PartialEq for HSTRING { } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for &HSTRING { fn eq(&self, other: &std::ffi::OsStr) -> bool { **self == *other } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq<&std::ffi::OsStr> for HSTRING { fn eq(&self, other: &&std::ffi::OsStr) -> bool { *self == **other } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for std::ffi::OsStr { fn eq(&self, other: &HSTRING) -> bool { *other == *self } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for &std::ffi::OsStr { fn eq(&self, other: &HSTRING) -> bool { *other == **self } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq<&HSTRING> for std::ffi::OsStr { fn eq(&self, other: &&HSTRING) -> bool { **other == *self } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for std::ffi::OsString { fn eq(&self, other: &HSTRING) -> bool { *other == **self } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq for &std::ffi::OsString { fn eq(&self, other: &HSTRING) -> bool { *other == ***self } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl PartialEq<&HSTRING> for std::ffi::OsString { fn eq(&self, other: &&HSTRING) -> bool { **other == **self @@ -389,14 +389,14 @@ impl TryFrom for String { } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl<'a> From<&'a HSTRING> for std::ffi::OsString { fn from(hstring: &HSTRING) -> Self { hstring.to_os_string() } } -#[cfg(all(feature = "std", windows))] +#[cfg(feature = "std")] impl From for std::ffi::OsString { fn from(hstring: HSTRING) -> Self { Self::from(&hstring) diff --git a/crates/libs/strings/src/hstring_header.rs b/crates/libs/strings/src/hstring_header.rs index dac8760a12..afae2c112f 100644 --- a/crates/libs/strings/src/hstring_header.rs +++ b/crates/libs/strings/src/hstring_header.rs @@ -23,19 +23,9 @@ impl HStringHeader { // The space for the terminating null character is already accounted for inside of `HStringHeader`. let bytes = core::mem::size_of::() + 2 * len as usize; - #[cfg(windows)] let header = unsafe { bindings::HeapAlloc(bindings::GetProcessHeap(), 0, bytes) } as *mut Self; - #[cfg(not(windows))] - let header = unsafe { - extern "C" { - fn malloc(bytes: usize) -> *mut core::ffi::c_void; - } - - malloc(bytes) as *mut Self - }; - if header.is_null() { return Err(Error::from_hresult(HRESULT(bindings::E_OUTOFMEMORY))); } @@ -56,17 +46,7 @@ impl HStringHeader { return; } - #[cfg(windows)] bindings::HeapFree(bindings::GetProcessHeap(), 0, header as *mut _); - - #[cfg(not(windows))] - { - extern "C" { - fn free(ptr: *mut core::ffi::c_void); - } - - free(header as *mut _); - } } pub fn duplicate(&self) -> Result<*mut Self> { diff --git a/crates/libs/strings/src/lib.rs b/crates/libs/strings/src/lib.rs index 88e5c89c83..19f84039ad 100644 --- a/crates/libs/strings/src/lib.rs +++ b/crates/libs/strings/src/lib.rs @@ -2,6 +2,7 @@ Learn more about Rust for Windows here: */ +#![cfg(windows)] #![allow(non_snake_case)] #![cfg_attr( windows_debugger_visualizer, diff --git a/crates/libs/windows/src/lib.rs b/crates/libs/windows/src/lib.rs index 9cb770d101..3260d1f60a 100644 --- a/crates/libs/windows/src/lib.rs +++ b/crates/libs/windows/src/lib.rs @@ -6,6 +6,7 @@ Learn more about Rust for Windows here: