#![allow(non_snake_case)]
use std::{fmt, hash};
use crate::co;
use crate::decl::*;
pub trait Handle:
Sized
+ PartialEq
+ Eq
+ Send
+ hash::Hash
+ fmt::Debug
+ fmt::Display
+ fmt::LowerHex
+ fmt::UpperHex
{
const NULL: Self;
const INVALID: Self;
#[must_use]
unsafe fn from_ptr(p: *mut std::ffi::c_void) -> Self;
#[must_use]
unsafe fn raw_copy(&self) -> Self {
unsafe { Self::from_ptr(self.ptr()) }
}
#[must_use]
unsafe fn as_mut(&mut self) -> &mut *mut std::ffi::c_void;
#[must_use]
fn ptr(&self) -> *mut std::ffi::c_void;
#[must_use]
fn as_opt(&self) -> Option<&Self> {
if *self == Self::NULL || *self == Self::INVALID { None } else { Some(self) }
}
}
pub trait SystemError: Into<u32> {
#[must_use]
fn FormatMessage(self) -> String {
let err_code: u32 = self.into();
let is_wininet = err_code >= 12001 && err_code <= 12192;
let (wininet_flags, maybe_wininet_dll) = if is_wininet {
(
Some(co::FORMAT_MESSAGE::FROM_HMODULE),
Some(
HINSTANCE::GetModuleHandle(Some("wininet.dll"))
.expect("wininet.dll failed to load.") .ptr(),
),
)
} else {
(None, None)
};
match unsafe {
FormatMessage(
co::FORMAT_MESSAGE::ALLOCATE_BUFFER
| co::FORMAT_MESSAGE::FROM_SYSTEM
| co::FORMAT_MESSAGE::IGNORE_INSERTS
| wininet_flags.unwrap_or_default(),
maybe_wininet_dll,
err_code,
LANGID::USER_DEFAULT,
&[],
)
} {
Err(e) => match e {
co::ERROR::MR_MID_NOT_FOUND => {
"(The system cannot format this message error.)".to_owned()
},
e => format!(
"The system failed to format error {:#06x} with error {:#06x}.",
err_code, e
),
},
Ok(s) => s,
}
}
}