#![allow(dead_code, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::kernel::ffi_types::*;
use crate::prelude::*;
const_values_num_privs! {
ATTACH_PARENT_PROCESS u32 = 0xffff_ffff
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS u32 = 0x0000_0004
GMEM_INVALID_HANDLE u32 = 0x8000
INFINITE u32 = 0xffff_ffff
INVALID_FILE_ATTRIBUTES i32 = -1
LMEM_INVALID_HANDLE u32 = 0x8000
MAX_COMPUTERNAME_LENGTH usize = 15
MAX_MODULE_NAME32 usize = 255
MAX_PATH usize = 260
SECURITY_SQOS_PRESENT u32 = 0x0010_0000
}
#[must_use]
pub(crate) fn IS_INTRESOURCE(val: *const u16) -> bool {
(unsafe { std::mem::transmute::<_, usize>(val) } >> 16) == 0
}
#[must_use]
pub(crate) const fn MAKEINTRESOURCE(val: isize) -> *const u16 {
val as u16 as _
}
pub(crate) struct BoolRet(pub(crate) BOOL);
impl BoolRet {
#[must_use]
pub(crate) fn to_sysresult(self) -> SysResult<()> {
match self.0 {
0 => Err(GetLastError()),
_ => Ok(()),
}
}
#[must_use]
pub(crate) const fn to_invalidparm(self) -> SysResult<()> {
match self.0 {
0 => Err(co::ERROR::INVALID_PARAMETER),
_ => Ok(()),
}
}
}
pub(crate) struct PtrRet(pub(crate) *mut std::ffi::c_void);
impl PtrRet {
#[must_use]
pub(crate) fn to_sysresult(self) -> SysResult<*mut std::ffi::c_void> {
if self.0.is_null() { Err(GetLastError()) } else { Ok(self.0) }
}
#[must_use]
pub(crate) const fn to_invalidparm(self) -> SysResult<HANDLE> {
if self.0.is_null() { Err(co::ERROR::INVALID_PARAMETER) } else { Ok(self.0) }
}
#[must_use]
pub(crate) fn to_sysresult_handle<H: Handle>(self) -> SysResult<H> {
self.to_invalidparm_handle().map_err(|_| GetLastError())
}
#[must_use]
pub(crate) fn to_invalidparm_handle<H: Handle>(self) -> SysResult<H> {
let ptr = unsafe { H::from_ptr(self.0) };
if ptr == H::NULL || ptr == H::INVALID {
Err(co::ERROR::INVALID_PARAMETER)
} else {
Ok(ptr)
}
}
#[must_use]
pub(crate) fn to_opt_handle<H: Handle>(self) -> Option<H> {
self.to_invalidparm_handle().ok()
}
}
pub(crate) struct ErrorRet(pub(crate) i32);
impl ErrorRet {
#[must_use]
pub(crate) const fn to_sysresult(self) -> SysResult<()> {
match unsafe { co::ERROR::from_raw(self.0 as _) } {
co::ERROR::SUCCESS => Ok(()),
err => Err(err),
}
}
}
#[must_use]
pub(crate) fn minus1_as_error(dword: u32) -> SysResult<u32> {
const MINUS_ONE: u32 = -1i32 as u32;
match dword {
MINUS_ONE => Err(GetLastError()),
dword => Ok(dword),
}
}
#[must_use]
pub(crate) const fn pcvoid<T>(reference: &T) -> PCVOID {
reference as *const _ as _
}
#[must_use]
pub(crate) const fn pcvoid_or_null<T>(reference: Option<&T>) -> PCVOID {
match reference {
Some(p) => pcvoid(p),
None => std::ptr::null(),
}
}
#[must_use]
pub(crate) const fn pvoid<T>(reference: &mut T) -> PVOID {
reference as *mut _ as _
}
#[must_use]
pub(crate) const fn pvoid_or_null<T>(reference: Option<&mut T>) -> PVOID {
match reference {
Some(p) => pvoid(p),
None => std::ptr::null_mut(),
}
}
#[must_use]
pub(crate) const fn vec_ptr<T>(v: &[T]) -> *const T {
if v.is_empty() { std::ptr::null() } else { v.as_ptr() }
}
pub(crate) enum DoubleIter<T> {
Yield(T),
YieldLast(T),
Halt,
}
pub(crate) struct DoubleIterIndex {
front_idx: u32,
past_back_idx: u32,
}
impl DoubleIterIndex {
#[must_use]
pub(crate) const fn new(item_count: u32) -> Self {
Self { front_idx: 0, past_back_idx: item_count }
}
#[must_use]
pub(crate) fn grab<F, T>(&mut self, is_front: bool, f: F) -> Option<T>
where
F: FnOnce(u32) -> DoubleIter<T>,
{
if self.front_idx == self.past_back_idx {
return None; }
let cur_idx = if is_front { self.front_idx } else { self.past_back_idx - 1 };
match f(cur_idx) {
DoubleIter::Yield(val) => {
if is_front {
self.front_idx += 1;
} else {
self.past_back_idx -= 1;
}
Some(val)
},
DoubleIter::YieldLast(val) => {
(self.front_idx, self.past_back_idx) = (0, 0); Some(val)
},
DoubleIter::Halt => {
(self.front_idx, self.past_back_idx) = (0, 0); None
},
}
}
}
#[must_use]
pub(crate) unsafe fn parse_multi_z_str(src: *const u16, len: Option<usize>) -> Vec<String> {
let given_len = len.unwrap_or(usize::MAX);
let mut src = src;
let mut strings = Vec::<String>::new();
let mut ch = 0; let mut tot_ch = 0;
loop {
if unsafe { *src.add(ch) } == 0 || tot_ch == given_len {
let slice = unsafe { std::slice::from_raw_parts(src, ch) };
if slice.is_empty() {
break; }
strings.push(WString::from_wchars_slice(slice).to_string());
src = unsafe { src.add(ch + 1) };
ch = 0;
} else {
ch += 1;
}
if len.is_some() && tot_ch == given_len {
break;
}
tot_ch += 1;
}
strings
}
#[must_use]
pub(crate) fn create_wstr_ptr_vecs(strings: &[impl AsRef<str>]) -> (Vec<WString>, Vec<*const u16>) {
if strings.is_empty() {
(Vec::new(), Vec::new())
} else {
let wstrs = strings
.iter()
.map(|s| WString::from_str(s))
.collect::<Vec<_>>();
let pwstrs = wstrs.iter().map(|w| w.as_ptr()).collect::<Vec<_>>();
(wstrs, pwstrs)
}
}