Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make new windows-strings crate Windows-only #3143

Merged
merged 2 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions crates/libs/core/src/inspectable.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -15,19 +14,20 @@ interface_hierarchy!(IInspectable, IUnknown);

impl IInspectable {
/// Returns the canonical type name for the underlying object.
#[cfg(windows)]
pub fn GetRuntimeClassName(&self) -> Result<HSTRING> {
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))
}
}

/// Gets the trust level of the current object.
pub fn GetTrustLevel(&self) -> Result<i32> {
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)
}
}
Expand Down Expand Up @@ -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::<HSTRING, *mut c_void>(h);

#[cfg(windows)]
{
*value = core::mem::transmute::<HSTRING, *mut c_void>(T::NAME.into());
}

#[cfg(not(windows))]
{
*value = core::ptr::null_mut();
}

HRESULT(0)
}
unsafe extern "system" fn GetTrustLevel<T: IUnknownImpl, const OFFSET: isize>(
Expand Down
1 change: 0 additions & 1 deletion crates/libs/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
24 changes: 0 additions & 24 deletions crates/libs/core/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,3 @@ where
ParamValue::Owned(transmute_copy(&self))
}
}

impl Param<PCWSTR> for &BSTR {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.as_ptr()))
}
}

impl Param<PCWSTR> for &HSTRING {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.as_ptr()))
}
}

impl Param<PCWSTR> for PWSTR {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.0))
}
}

impl Param<PCSTR> for PSTR {
unsafe fn param(self) -> ParamValue<PCSTR> {
ParamValue::Owned(PCSTR(self.0))
}
}
4 changes: 0 additions & 4 deletions crates/libs/core/src/runtime_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
24 changes: 0 additions & 24 deletions crates/libs/core/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,3 @@ primitives!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, usize, isize);

#[doc(hidden)]
pub type AbiType<T> = <T as Type<T>>::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;
}
54 changes: 54 additions & 0 deletions crates/libs/core/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<C: RuntimeName, I: Interface>() -> Result<I> {
imp::factory::<C, I>()
}

impl Param<PCWSTR> for &BSTR {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.as_ptr()))
}
}

impl Param<PCWSTR> for &HSTRING {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.as_ptr()))
}
}

impl Param<PCWSTR> for PWSTR {
unsafe fn param(self) -> ParamValue<PCWSTR> {
ParamValue::Owned(PCWSTR(self.0))
}
}

impl Param<PCSTR> for PSTR {
unsafe fn param(self) -> ParamValue<PCSTR> {
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;
}
38 changes: 19 additions & 19 deletions crates/libs/strings/src/hstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down Expand Up @@ -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 {
Expand All @@ -174,14 +174,14 @@ impl From<&std::ffi::OsStr> for HSTRING {
}
}

#[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()
}
}

#[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()
Expand Down Expand Up @@ -286,28 +286,28 @@ impl PartialEq<&HSTRING> for String {
}
}

#[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<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<&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<std::ffi::OsStr> for HSTRING {
fn eq(&self, other: &std::ffi::OsStr) -> bool {
self.as_wide()
Expand All @@ -317,56 +317,56 @@ impl PartialEq<std::ffi::OsStr> for HSTRING {
}
}

#[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<&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<HSTRING> 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<&HSTRING> 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::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
}
}

#[cfg(all(feature = "std", windows))]
#[cfg(feature = "std")]
impl PartialEq<&HSTRING> for std::ffi::OsString {
fn eq(&self, other: &&HSTRING) -> bool {
**other == **self
Expand All @@ -389,14 +389,14 @@ impl TryFrom<HSTRING> 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<HSTRING> for std::ffi::OsString {
fn from(hstring: HSTRING) -> Self {
Self::from(&hstring)
Expand Down
20 changes: 0 additions & 20 deletions crates/libs/strings/src/hstring_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Self>() + 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)));
}
Expand All @@ -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> {
Expand Down
1 change: 1 addition & 0 deletions crates/libs/strings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs>
*/

#![cfg(windows)]
#![allow(non_snake_case)]
#![cfg_attr(
windows_debugger_visualizer,
Expand Down
1 change: 1 addition & 0 deletions crates/libs/windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs
[Feature search](https://microsoft.github.io/windows-rs/features/#/0.57.0)
*/

#![cfg(windows)]
kennykerr marked this conversation as resolved.
Show resolved Hide resolved
#![doc(html_no_source)]
#![allow(non_snake_case, clashing_extern_declarations, non_upper_case_globals, non_camel_case_types, missing_docs, clippy::all)]
#![cfg_attr(not(feature = "docs"), doc(hidden))]
Expand Down