use std::slice::from_raw_parts;
use windows::Win32::Foundation::FALSE;
use windows::Win32::NetworkManagement::IpHelper::{GetTcpTable2, MIB_TCPTABLE2};
use grob::{
GrowToNearestQuarterKibi, GrowableBuffer, RvIsError, StackBuffer, ToResult, WriteBuffer,
};
fn common(initial_buffer: &mut dyn WriteBuffer) -> Result<(), Box<dyn std::error::Error>> {
let grow_strategy = GrowToNearestQuarterKibi::new();
let mut growable_buffer =
GrowableBuffer::<MIB_TCPTABLE2, *mut MIB_TCPTABLE2>::new(initial_buffer, &grow_strategy);
loop {
let mut argument = growable_buffer.argument();
let rv = RvIsError::new(unsafe {
GetTcpTable2(Some(argument.pointer()), argument.size(), FALSE)
});
let fill_buffer_action = rv.to_result(&mut argument)?;
if argument.apply(fill_buffer_action) {
break;
}
}
let frozen_buffer = growable_buffer.freeze();
if let Some(p) = frozen_buffer.pointer() {
let number_of_entries: usize = unsafe { (*p).dwNumEntries }.try_into().unwrap();
println!(
"Number of entries in the returned data = {}",
number_of_entries
);
let table = unsafe { from_raw_parts((*p).table.as_ptr(), number_of_entries) };
for entry in table {
println!("{}", entry.dwRemoteAddr);
}
}
Ok(())
}
fn just_heap_buffer() -> Result<(), Box<dyn std::error::Error>> {
let mut initial_buffer = StackBuffer::<0>::new();
common(&mut initial_buffer)
}
fn start_with_stack_buffer() -> Result<(), Box<dyn std::error::Error>> {
let mut initial_buffer = StackBuffer::<8192>::new();
common(&mut initial_buffer)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!();
start_with_stack_buffer()?;
println!();
just_heap_buffer()?;
println!();
println!();
Ok(())
}