1#![allow(clippy::upper_case_acronyms)]
3
4#[cfg(windows)]
5mod os_defs {
6 pub use winapi::shared::{
7 ntdef::{HRESULT, LPCSTR, LPCWSTR, LPSTR, LPWSTR, WCHAR},
8 wtypes::BSTR,
9 };
10
11 pub use winapi::um::combaseapi::CoTaskMemFree;
12 pub use winapi::um::oleauto::{SysFreeString, SysStringLen};
13}
14
15#[cfg(not(windows))]
16mod os_defs {
17 pub type CHAR = std::os::raw::c_char;
18 pub type UINT = u32;
19 pub type WCHAR = widestring::WideChar;
20 pub type OLECHAR = WCHAR;
21 pub type LPSTR = *mut CHAR;
22 pub type LPWSTR = *mut WCHAR;
23 pub type LPCSTR = *const CHAR;
24 pub type LPCWSTR = *const WCHAR;
25 pub type BSTR = *mut OLECHAR;
26 pub type LPBSTR = *mut BSTR;
27 pub type HRESULT = i32;
28
29 fn len_ptr(p: BSTR) -> *mut UINT {
31 unsafe { p.cast::<UINT>().offset(-1) }
34 }
35
36 #[allow(non_snake_case)]
37 pub unsafe fn CoTaskMemFree(p: *mut libc::c_void) {
40 if !p.is_null() {
42 libc::free(p)
43 }
44 }
45
46 #[allow(non_snake_case)]
47 pub unsafe fn SysFreeString(p: BSTR) {
50 if !p.is_null() {
52 libc::free(len_ptr(p).cast::<_>())
53 }
54 }
55
56 #[allow(non_snake_case)]
57 pub unsafe fn SysStringByteLen(p: BSTR) -> UINT {
64 if p.is_null() {
65 0
66 } else {
67 *len_ptr(p)
68 }
69 }
70
71 #[allow(non_snake_case)]
72 pub unsafe fn SysStringLen(p: BSTR) -> UINT {
79 SysStringByteLen(p) / std::mem::size_of::<OLECHAR>() as UINT
80 }
81}
82
83pub use os_defs::*;
84
85#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
86#[repr(transparent)]
87#[must_use]
88pub struct HRESULT(pub os_defs::HRESULT);
89impl HRESULT {
90 pub fn is_err(&self) -> bool {
91 self.0 < 0
92 }
93}
94
95impl From<i32> for HRESULT {
96 fn from(v: i32) -> Self {
97 Self(v)
98 }
99}
100
101impl std::fmt::Debug for HRESULT {
102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 <Self as std::fmt::Display>::fmt(self, f)
104 }
105}
106
107impl std::fmt::Display for HRESULT {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 f.write_fmt(format_args!("{:#x}", self))
110 }
111}
112
113impl std::fmt::LowerHex for HRESULT {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 let prefix = if f.alternate() { "0x" } else { "" };
116 let bare_hex = format!("{:x}", self.0.abs());
117 f.pad_integral(self.0 >= 0, prefix, &bare_hex)
119 }
121}