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 { let encoded = raw.encode_utf16().collect::>(); unsafe { let mut p = null_mut::(); 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::() 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(); } }