From 139ca3c88f8a3948deba4b9e79b6e6b420cc242d Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Mon, 17 Jun 2024 13:24:55 -0700 Subject: [PATCH] Support some edge cases for the next Win32 metadata update (#3109) --- crates/libs/bindgen/src/rust/handles.rs | 36 ++++++------ crates/libs/bindgen/src/rust/structs.rs | 56 ++++++++++--------- crates/libs/core/src/imp/waiter.rs | 6 +- .../src/Windows/Win32/Foundation/mod.rs | 4 +- .../Win32/Security/Cryptography/mod.rs | 4 +- .../windows/src/Windows/Win32/Security/mod.rs | 2 +- .../Win32/UI/WindowsAndMessaging/mod.rs | 2 +- 7 files changed, 58 insertions(+), 52 deletions(-) diff --git a/crates/libs/bindgen/src/rust/handles.rs b/crates/libs/bindgen/src/rust/handles.rs index 2cadef958a..4724f125e5 100644 --- a/crates/libs/bindgen/src/rust/handles.rs +++ b/crates/libs/bindgen/src/rust/handles.rs @@ -30,7 +30,9 @@ pub fn gen_win_handle(writer: &Writer, def: metadata::TypeDef) -> TokenStream { let ident = to_ident(name); let underlying_type = def.underlying_type(); let signature = writer.type_default_name(&underlying_type); - let is_invalid = if underlying_type.is_pointer() { + let invalid = metadata::type_def_invalid_values(def); + + let is_invalid = if underlying_type.is_pointer() && (invalid.is_empty() || invalid == [0]) { quote! { impl #ident { pub fn is_invalid(&self) -> bool { @@ -38,28 +40,24 @@ pub fn gen_win_handle(writer: &Writer, def: metadata::TypeDef) -> TokenStream { } } } + } else if invalid.is_empty() { + quote! {} } else { - let invalid = metadata::type_def_invalid_values(def); + let invalid = invalid.iter().map(|value| { + let literal = Literal::i64_unsuffixed(*value); - if !invalid.is_empty() { - let invalid = invalid.iter().map(|value| { - let literal = Literal::i64_unsuffixed(*value); - - if *value < 0 && underlying_type.is_unsigned() { - quote! { self.0 == #literal as _ } - } else { - quote! { self.0 == #literal } - } - }); - quote! { - impl #ident { - pub fn is_invalid(&self) -> bool { - #(#invalid)||* - } + if underlying_type.is_pointer() || (*value < 0 && underlying_type.is_unsigned()) { + quote! { self.0 == #literal as _ } + } else { + quote! { self.0 == #literal } + } + }); + quote! { + impl #ident { + pub fn is_invalid(&self) -> bool { + #(#invalid)||* } } - } else { - quote! {} } }; diff --git a/crates/libs/bindgen/src/rust/structs.rs b/crates/libs/bindgen/src/rust/structs.rs index 40a02251c0..4d5d7a6f94 100644 --- a/crates/libs/bindgen/src/rust/structs.rs +++ b/crates/libs/bindgen/src/rust/structs.rs @@ -43,34 +43,40 @@ fn gen_struct_with_name( quote! { #[repr(C)] } }; - let fields = def.fields().map(|f| { - let name = to_ident(f.name()); - let ty = f.ty(Some(def)); + let fields = if def.fields().next().is_none() { + quote! { (pub u8); } + } else { + let fields = def.fields().map(|f| { + let name = to_ident(f.name()); + let ty = f.ty(Some(def)); - if f.flags().contains(metadata::FieldAttributes::Literal) { - quote! {} - } else if !writer.sys - && flags.contains(metadata::TypeAttributes::ExplicitLayout) - && !metadata::field_is_copyable(f, def) - { - let ty = writer.type_default_name(&ty); - quote! { pub #name: core::mem::ManuallyDrop<#ty>, } - } else if !writer.sys - && !flags.contains(metadata::TypeAttributes::WindowsRuntime) - && !metadata::field_is_blittable(f, def) - { - if let metadata::Type::Win32Array(ty, len) = ty { - let ty = writer.type_default_name(&ty); - quote! { pub #name: [core::mem::ManuallyDrop<#ty>; #len], } - } else { + if f.flags().contains(metadata::FieldAttributes::Literal) { + quote! {} + } else if !writer.sys + && flags.contains(metadata::TypeAttributes::ExplicitLayout) + && !metadata::field_is_copyable(f, def) + { let ty = writer.type_default_name(&ty); quote! { pub #name: core::mem::ManuallyDrop<#ty>, } + } else if !writer.sys + && !flags.contains(metadata::TypeAttributes::WindowsRuntime) + && !metadata::field_is_blittable(f, def) + { + if let metadata::Type::Win32Array(ty, len) = ty { + let ty = writer.type_default_name(&ty); + quote! { pub #name: [core::mem::ManuallyDrop<#ty>; #len], } + } else { + let ty = writer.type_default_name(&ty); + quote! { pub #name: core::mem::ManuallyDrop<#ty>, } + } + } else { + let ty = writer.type_default_name(&ty); + quote! { pub #name: #ty, } } - } else { - let ty = writer.type_default_name(&ty); - quote! { pub #name: #ty, } - } - }); + }); + + quote! { {#(#fields)*} } + }; let struct_or_union = if flags.contains(metadata::TypeAttributes::ExplicitLayout) { quote! { union } @@ -85,7 +91,7 @@ fn gen_struct_with_name( #repr #features #derive - pub #struct_or_union #name {#(#fields)*} + pub #struct_or_union #name #fields }; tokens.combine(&gen_struct_constants(writer, def, &name, &cfg)); diff --git a/crates/libs/core/src/imp/waiter.rs b/crates/libs/core/src/imp/waiter.rs index 3f12eb9881..de36ed4eec 100644 --- a/crates/libs/core/src/imp/waiter.rs +++ b/crates/libs/core/src/imp/waiter.rs @@ -1,8 +1,10 @@ use super::*; #[doc(hidden)] -pub struct Waiter(isize); -pub struct WaiterSignaler(isize); +pub struct Waiter(HANDLE); +pub struct WaiterSignaler(HANDLE); + +unsafe impl Send for WaiterSignaler {} impl Waiter { pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> { diff --git a/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs b/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs index 236dbdf461..3cdd6f0f90 100644 --- a/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs @@ -10688,7 +10688,7 @@ impl windows_core::TypeKind for HANDLE_PTR { pub struct HGLOBAL(pub *mut core::ffi::c_void); impl HGLOBAL { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl windows_core::Free for HGLOBAL { @@ -10740,7 +10740,7 @@ impl From for HMODULE { pub struct HLOCAL(pub *mut core::ffi::c_void); impl HLOCAL { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl windows_core::Free for HLOCAL { diff --git a/crates/libs/windows/src/Windows/Win32/Security/Cryptography/mod.rs b/crates/libs/windows/src/Windows/Win32/Security/Cryptography/mod.rs index f4fdc7ce1b..fb5a6d7e49 100644 --- a/crates/libs/windows/src/Windows/Win32/Security/Cryptography/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/Security/Cryptography/mod.rs @@ -14306,7 +14306,7 @@ impl windows_core::TypeKind for HCERTCHAINENGINE { pub struct HCERTSTORE(pub *mut core::ffi::c_void); impl HCERTSTORE { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl Default for HCERTSTORE { @@ -14322,7 +14322,7 @@ impl windows_core::TypeKind for HCERTSTORE { pub struct HCERTSTOREPROV(pub *mut core::ffi::c_void); impl HCERTSTOREPROV { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl Default for HCERTSTOREPROV { diff --git a/crates/libs/windows/src/Windows/Win32/Security/mod.rs b/crates/libs/windows/src/Windows/Win32/Security/mod.rs index 9f01e27b1c..b501ab9d3b 100644 --- a/crates/libs/windows/src/Windows/Win32/Security/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/Security/mod.rs @@ -2671,7 +2671,7 @@ impl Default for PRIVILEGE_SET { pub struct PSECURITY_DESCRIPTOR(pub *mut core::ffi::c_void); impl PSECURITY_DESCRIPTOR { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl Default for PSECURITY_DESCRIPTOR { diff --git a/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs b/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs index edb22e7e01..918c9cef80 100644 --- a/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs @@ -8227,7 +8227,7 @@ impl From for HICON { pub struct HDEVNOTIFY(pub *mut core::ffi::c_void); impl HDEVNOTIFY { pub fn is_invalid(&self) -> bool { - self.0.is_null() + self.0 == -1 as _ || self.0 == 0 as _ } } impl windows_core::Free for HDEVNOTIFY {