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"
|
version = "0.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
rust = { nonstandard_style = "allow", unsafe_op_in_unsafe_fn = "allow" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
eframe = { version = "0.33.3", default-features = false, features = ["default_fonts", "glow"] }
|
eframe = { version = "0.33.3", default-features = false, features = ["default_fonts", "glow"] }
|
||||||
egui_extras = { version = "0.33.3" }
|
egui_extras = { version = "0.33.3" }
|
||||||
@ -10,4 +13,10 @@ egui_extras = { version = "0.33.3" }
|
|||||||
[dependencies.windows]
|
[dependencies.windows]
|
||||||
version = ">=0.41.0, <=0.62.2"
|
version = ">=0.41.0, <=0.62.2"
|
||||||
registry = "crates-io"
|
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 data;
|
||||||
|
mod io;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user