Windows adress wrapper and error formatter; allocator wrapper
This commit is contained in:
parent
995bb2042d
commit
093b599882
11
Cargo.toml
11
Cargo.toml
@ -3,6 +3,9 @@ name = "bgtu-networks-2"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
rust = { nonstandard_style = "allow", unsafe_op_in_unsafe_fn = "allow" }
|
||||
|
||||
[dependencies]
|
||||
eframe = { version = "0.33.3", default-features = false, features = ["default_fonts", "glow"] }
|
||||
egui_extras = { version = "0.33.3" }
|
||||
@ -10,4 +13,10 @@ egui_extras = { version = "0.33.3" }
|
||||
[dependencies.windows]
|
||||
version = ">=0.41.0, <=0.62.2"
|
||||
registry = "crates-io"
|
||||
features = ["Win32_System_SystemInformation", "Win32_System_Memory"]
|
||||
features = [
|
||||
"Win32_System_IO",
|
||||
"Win32_Networking",
|
||||
"Win32_Networking_WinSock",
|
||||
"Win32_System_Diagnostics",
|
||||
"Win32_System_Diagnostics_Debug"
|
||||
]
|
||||
5
src/io/abstract/address.rs
Normal file
5
src/io/abstract/address.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub trait Address: Sized {
|
||||
fn parse(raw: &str) -> Result<Self, String>;
|
||||
|
||||
fn to_string(self) -> String;
|
||||
}
|
||||
3
src/io/abstract/mod.rs
Normal file
3
src/io/abstract/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod address;
|
||||
|
||||
pub use address::Address;
|
||||
27
src/io/allocator.rs
Normal file
27
src/io/allocator.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use std::collections::HashMap;
|
||||
use std::mem::uninitialized;
|
||||
use std::pin::Pin;
|
||||
use std::ptr;
|
||||
|
||||
pub struct Allocator<T> {
|
||||
map: HashMap<usize, Pin<Box<T>>>,
|
||||
}
|
||||
|
||||
impl<T> Allocator<T> {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
map: HashMap::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub unsafe fn alloc<'s>(&'s mut self) -> Pin<&'s mut T> {
|
||||
let ptr = Box::pin(uninitialized::<T>());
|
||||
let addr = ptr::from_ref(ptr.as_ref().get_ref()).addr();
|
||||
self.map.insert(addr, ptr);
|
||||
return self
|
||||
.map
|
||||
.get_mut(&addr)
|
||||
.unwrap_or_else(|| unreachable!())
|
||||
.as_mut();
|
||||
}
|
||||
}
|
||||
3
src/io/mod.rs
Normal file
3
src/io/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod windows;
|
||||
mod allocator;
|
||||
pub mod r#abstract;
|
||||
49
src/io/windows/address.rs
Normal file
49
src/io/windows/address.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use std::ffi::{c_char, c_void, OsString};
|
||||
use crate::io::r#abstract::Address;
|
||||
use crate::io::windows::errors::{format_windows_err_code_result, throw_from_windows_err_code};
|
||||
use std::mem::zeroed;
|
||||
use std::ptr;
|
||||
use std::ptr::{copy_nonoverlapping, null, null_mut};
|
||||
use windows::core::{PCWSTR, PWSTR};
|
||||
use windows::Win32::Networking::WinSock::{FreeAddrInfoW, GetAddrInfoW, WSAAddressToStringW, WSAGetLastError, ADDRINFOW, SOCKADDR_STORAGE};
|
||||
use std::mem::size_of;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
|
||||
pub struct WindowsAddress {
|
||||
native: SOCKADDR_STORAGE,
|
||||
}
|
||||
|
||||
impl Address for WindowsAddress {
|
||||
fn parse(raw: &str) -> Result<Self, String> {
|
||||
let encoded = raw.encode_utf16().collect::<Vec<_>>();
|
||||
unsafe {
|
||||
let mut p = null_mut::<ADDRINFOW>();
|
||||
|
||||
if (0 != GetAddrInfoW(PCWSTR(encoded.as_slice().as_ptr()), PCWSTR(null()), None, &mut p)) {
|
||||
format_windows_err_code_result(WSAGetLastError())?;
|
||||
}
|
||||
|
||||
let mut this = Self {
|
||||
native: zeroed()
|
||||
};
|
||||
|
||||
|
||||
copy_nonoverlapping((*p).ai_addr.cast(), &mut this.native, (*p).ai_addrlen);
|
||||
|
||||
FreeAddrInfoW(Some(p));
|
||||
return Result::Ok(this);
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(self) -> String {
|
||||
let mut buffer = [0u16; 1024];
|
||||
let mut buf_size = buffer.len() as u32;
|
||||
unsafe {
|
||||
if 0 != WSAAddressToStringW(ptr::from_ref(&self.native).cast(), size_of::<SOCKADDR_STORAGE>() as u32, None, PWSTR(buffer.as_mut_ptr()), &mut buf_size) {
|
||||
throw_from_windows_err_code(WSAGetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
return OsString::from_wide(&buffer).to_string_lossy().into_owned();
|
||||
}
|
||||
}
|
||||
80
src/io/windows/errors.rs
Normal file
80
src/io/windows/errors.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use std::ffi::{CStr, CString, c_char};
|
||||
use std::ptr;
|
||||
use std::ptr::null_mut;
|
||||
use std::slice::from_raw_parts_mut;
|
||||
use windows::Win32::Foundation::{HLOCAL, LocalFree};
|
||||
use windows::Win32::Networking::WinSock::WSA_ERROR;
|
||||
use windows::Win32::System::Diagnostics::Debug::{
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER, FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
FormatMessageA,
|
||||
};
|
||||
use windows::core::PSTR;
|
||||
|
||||
trait ErrCode {
|
||||
fn to_dword(&self) -> u32;
|
||||
}
|
||||
|
||||
impl ErrCode for WSA_ERROR {
|
||||
fn to_dword(&self) -> u32 {
|
||||
return 0u32
|
||||
.checked_add_signed(self.0)
|
||||
.unwrap_or_else(|| panic!("Cast i32 -> u32 overflow"));
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrCode for u32 {
|
||||
fn to_dword(&self) -> u32 {
|
||||
return *self;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn throw_from_windows_err_code(code: impl ErrCode) -> ! {
|
||||
panic!(
|
||||
"Windows error [{:X}]: {}",
|
||||
code.to_dword(),
|
||||
format_windows_err_code(code)
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn format_windows_err_code_result(code: impl ErrCode) -> Result<(), String> {
|
||||
return Result::Err(format_windows_err_code(code));
|
||||
}
|
||||
|
||||
pub(super) fn format_windows_err_code(code: impl ErrCode) -> String {
|
||||
unsafe {
|
||||
let mut msg = null_mut::<c_char>();
|
||||
FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
None,
|
||||
code.to_dword(),
|
||||
1 << 10,
|
||||
PSTR(ptr::from_mut(&mut msg).cast()),
|
||||
0,
|
||||
None,
|
||||
);
|
||||
|
||||
let mut trim_size = CStr::from_ptr(msg).count_bytes();
|
||||
let msg = from_raw_parts_mut(msg, trim_size + 1);
|
||||
while trim_size > 0 {
|
||||
trim_size -= 1;
|
||||
match msg[trim_size] {
|
||||
0x0A | 0x0D => msg[trim_size] = 0x00,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
let msg_owned = CStr::from_ptr(msg.as_ptr()).to_str().unwrap().to_owned();
|
||||
LocalFree(Some(HLOCAL(msg.as_mut_ptr().cast())));
|
||||
|
||||
return msg_owned;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _test_works() {
|
||||
format_windows_err_code(0u32);
|
||||
}
|
||||
2
src/io/windows/mod.rs
Normal file
2
src/io/windows/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod address;
|
||||
mod errors;
|
||||
@ -1,5 +1,5 @@
|
||||
mod data2;
|
||||
mod data;
|
||||
mod io;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user