diff --git a/crates/libs/bindgen/src/rust/extensions/mod.rs b/crates/libs/bindgen/src/rust/extensions/mod.rs index 8d8f71ed62..39faef9863 100644 --- a/crates/libs/bindgen/src/rust/extensions/mod.rs +++ b/crates/libs/bindgen/src/rust/extensions/mod.rs @@ -14,6 +14,7 @@ pub fn gen_mod(writer: &Writer, namespace: &str) -> TokenStream { "Windows.Foundation" => concat!(include_str!("mod/Foundation/TimeSpan.rs"),), "Windows.Win32.Foundation" => concat!(include_str!("mod/Win32/Foundation/BOOL.rs"), include_str!("mod/Win32/Foundation/BOOLEAN.rs"), include_str!("mod/Win32/Foundation/NTSTATUS.rs"), include_str!("mod/Win32/Foundation/VARIANT_BOOL.rs"), include_str!("mod/Win32/Foundation/WIN32_ERROR.rs"),), "Windows.Win32.Networking.WinSock" => concat!(include_str!("mod/Win32/Networking/WinSock/IN_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/IN6_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_INET.rs"),), + "Windows.Win32.System.Rpc" => include_str!("mod/Win32/System/Rpc/RPC_STATUS.rs"), "Windows.Win32.UI.WindowsAndMessaging" => { include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs") } diff --git a/crates/libs/bindgen/src/rust/extensions/mod/Win32/System/Rpc/RPC_STATUS.rs b/crates/libs/bindgen/src/rust/extensions/mod/Win32/System/Rpc/RPC_STATUS.rs new file mode 100644 index 0000000000..1b5e750c60 --- /dev/null +++ b/crates/libs/bindgen/src/rust/extensions/mod/Win32/System/Rpc/RPC_STATUS.rs @@ -0,0 +1,32 @@ +impl RPC_STATUS { + #[inline] + pub const fn is_ok(self) -> bool { + self.0 == 0 + } + #[inline] + pub const fn is_err(self) -> bool { + !self.is_ok() + } + #[inline] + pub const fn to_hresult(self) -> ::windows_core::HRESULT { + ::windows_core::HRESULT::from_win32(self.0 as u32) + } + #[inline] + pub fn ok(self) -> ::windows_core::Result<()> { + if self.is_ok() { + Ok(()) + } else { + Err(self.to_hresult().into()) + } + } +} +impl ::core::convert::From for ::windows_core::HRESULT { + fn from(value: RPC_STATUS) -> Self { + value.to_hresult() + } +} +impl ::core::convert::From for ::windows_core::Error { + fn from(value: RPC_STATUS) -> Self { + value.to_hresult().into() + } +} diff --git a/crates/libs/metadata/src/type_name.rs b/crates/libs/metadata/src/type_name.rs index 4f419d3387..2e2e563176 100644 --- a/crates/libs/metadata/src/type_name.rs +++ b/crates/libs/metadata/src/type_name.rs @@ -39,6 +39,7 @@ impl TypeName { pub const BOOL: Self = Self::from_const("Windows.Win32.Foundation", "BOOL"); pub const WIN32_ERROR: Self = Self::from_const("Windows.Win32.Foundation", "WIN32_ERROR"); pub const NTSTATUS: Self = Self::from_const("Windows.Win32.Foundation", "NTSTATUS"); + pub const RPC_STATUS: Self = Self::from_const("Windows.Win32.System.Rpc", "RPC_STATUS"); pub const D2D_MATRIX_3X2_F: Self = Self::from_const("Windows.Win32.Graphics.Direct2D.Common", "D2D_MATRIX_3X2_F"); pub const D3DMATRIX: Self = Self::from_const("Windows.Win32.Graphics.Direct3D", "D3DMATRIX"); diff --git a/crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs b/crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs index 83200e177b..81869e4239 100644 --- a/crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs @@ -9830,3 +9830,35 @@ pub type USER_MARSHAL_SIZING_ROUTINE = ::core::option::Option *mut u8>; #[cfg(feature = "Win32_System_Com")] pub type XMIT_HELPER_ROUTINE = ::core::option::Option; +impl RPC_STATUS { + #[inline] + pub const fn is_ok(self) -> bool { + self.0 == 0 + } + #[inline] + pub const fn is_err(self) -> bool { + !self.is_ok() + } + #[inline] + pub const fn to_hresult(self) -> ::windows_core::HRESULT { + ::windows_core::HRESULT::from_win32(self.0 as u32) + } + #[inline] + pub fn ok(self) -> ::windows_core::Result<()> { + if self.is_ok() { + Ok(()) + } else { + Err(self.to_hresult().into()) + } + } +} +impl ::core::convert::From for ::windows_core::HRESULT { + fn from(value: RPC_STATUS) -> Self { + value.to_hresult() + } +} +impl ::core::convert::From for ::windows_core::Error { + fn from(value: RPC_STATUS) -> Self { + value.to_hresult().into() + } +} diff --git a/crates/tests/error/Cargo.toml b/crates/tests/error/Cargo.toml index d3dfa790d6..ec46c0f29e 100644 --- a/crates/tests/error/Cargo.toml +++ b/crates/tests/error/Cargo.toml @@ -10,6 +10,7 @@ features = [ "implement", "Foundation", "Win32_Foundation", + "Win32_System_Rpc", ] [dev-dependencies] diff --git a/crates/tests/error/tests/test.rs b/crates/tests/error/tests/test.rs index 1f42b4b434..fdcc2339ed 100644 --- a/crates/tests/error/tests/test.rs +++ b/crates/tests/error/tests/test.rs @@ -1,4 +1,4 @@ -use windows::{core::*, Win32::Foundation::*}; +use windows::{core::*, Win32::Foundation::*, Win32::System::Rpc::*}; #[test] fn hresult() -> Result<()> { @@ -57,3 +57,40 @@ fn ntstatus() -> Result<()> { STATUS_SUCCESS.ok() } + +#[test] +fn rpc() -> Result<()> { + helpers::set_thread_ui_language(); + + let _: RPC_STATUS = RPC_S_OK; + assert!(RPC_S_OK.is_ok()); + assert!(!RPC_S_OK.is_err()); + + let r: Result<()> = RPC_S_OK.ok(); + assert!(r.is_ok()); + + assert_eq!(RPC_S_OK.to_hresult(), HRESULT(0)); + let hr: HRESULT = RPC_S_OK.into(); + assert_eq!(hr, HRESULT(0)); + + let _: RPC_STATUS = RPC_S_NOT_LISTENING; + assert!(!RPC_S_NOT_LISTENING.is_ok()); + assert!(RPC_S_NOT_LISTENING.is_err()); + + let r: Result<()> = RPC_S_NOT_LISTENING.ok(); + assert!(r.is_err()); + + assert_eq!(RPC_S_NOT_LISTENING.to_hresult(), HRESULT::from_win32(1715)); + let hr: HRESULT = RPC_S_NOT_LISTENING.into(); + assert_eq!(hr, HRESULT::from_win32(1715)); + + let e: Error = RPC_S_NOT_LISTENING.into(); + assert_eq!(r.unwrap_err(), e); + assert_eq!(e.code(), HRESULT::from_win32(1715)); + assert_eq!(e.message(), "The RPC server is not listening."); + + let r: Result<()> = unsafe { RpcServerListen(0, 0, 1).ok() }; + assert_eq!(r.unwrap_err().code(), RPC_S_MAX_CALLS_TOO_SMALL.into()); + + RPC_S_OK.ok() +}