Files
vnt/switch/wintun/src/util.rs
T

67 lines
2.1 KiB
Rust

use winapi::{
shared::ntdef::{LANG_NEUTRAL, SUBLANG_DEFAULT},
um::{winbase, winnt::MAKELANGID},
};
use std::mem::MaybeUninit;
use std::ptr;
use widestring::U16Str;
/// A wrapper struct that allows a type to be Send and Sync
pub(crate) struct UnsafeHandle<T>(pub T);
/// We never read from the pointer. It only serves as a handle we pass to the kernel or C code that
/// doesn't have the same mutable aliasing restrictions we have in Rust
unsafe impl<T> Send for UnsafeHandle<T> {}
unsafe impl<T> Sync for UnsafeHandle<T> {}
/// Returns a a human readable error message from a windows error code
pub fn get_error_message(err_code: u32) -> String {
const LEN: usize = 256;
let mut buf = MaybeUninit::<[u16; LEN]>::uninit();
//SAFETY: name is a allocated on the stack above therefore it must be valid, non-null and
//aligned for u16
let first = unsafe { *buf.as_mut_ptr() }.as_mut_ptr();
//Write default null terminator in case WintunGetAdapterName leaves name unchanged
unsafe { first.write(0u16) };
let chars_written = unsafe {
winbase::FormatMessageW(
winbase::FORMAT_MESSAGE_FROM_SYSTEM | winbase::FORMAT_MESSAGE_IGNORE_INSERTS,
ptr::null(),
err_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) as u32,
first,
LEN as u32,
ptr::null_mut(),
)
};
//SAFETY: first is a valid, non-null, aligned, pointer
format!(
"{} ({})",
unsafe { U16Str::from_ptr(first, chars_written as usize) }.to_string_lossy(),
err_code
)
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Version {
pub major: u16,
pub minor: u16,
}
/// Returns the major and minor version of the wintun driver
pub fn get_running_driver_version(wintun: &crate::Wintun) -> Result<Version, ()> {
let version = unsafe { wintun.WintunGetRunningDriverVersion() };
if version == 0 {
Err(())
} else {
Ok(Version {
major: ((version >> 16) & 0xFF) as u16,
minor: (version & 0xFF) as u16,
})
}
}