简体   繁体   English

如何分配空间以使用 windows 板条箱调用 GetInterfaceInfo?

[英]How do I allocate space to call GetInterfaceInfo using the windows crate?

I'm trying to fetch information regarding the network interfaces available on the system via GetInterfaceInfo using Microsoft's windows crate.我正在尝试使用 Microsoft 的windows板条箱通过GetInterfaceInfo获取有关系统上可用网络接口的信息。 This requires me to do some unsafe operations, and I get it to work for one interface, but not two:这需要我做一些不安全的操作,我让它为一个接口工作,但不是两个:

#[cfg(test)]
mod tests {
    use super::*;
    use windows::{
        core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::NetworkManagement::IpHelper::*,
        Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*,
    };

    #[test]
    fn main() {
        unsafe {
            let mut dw_out_buf_len: u32 = 0;

            let mut dw_ret_val =
                GetInterfaceInfo(std::ptr::null_mut(), &mut dw_out_buf_len as *mut u32);

            if dw_ret_val != ERROR_INSUFFICIENT_BUFFER.0 {
                panic!();
            }

            println!("Size: {}", dw_out_buf_len);
            // allocate that amount of memory, which will be used as a buffer
            let mut ip_interface_info = Vec::with_capacity(dw_out_buf_len as usize);
            let mut ptr = ip_interface_info.as_mut_ptr() as *mut IP_INTERFACE_INFO;

            dw_ret_val = GetInterfaceInfo(ptr, &mut dw_out_buf_len as *mut u32);

            println!("Num adapters: {}", (*ptr).NumAdapters);
            for i in 0..(*ptr).NumAdapters as usize {
                println!(
                    "\tAdapter index: {}\n\tAdapter name: {}",
                    (*ptr).Adapter[i].Index,
                    String::from_utf16(&(*ptr).Adapter[i].Name).unwrap()
                );
            }
        }
    }
}

It crashes when I'm trying to access the second entry (even though there should be two available):当我尝试访问第二个条目时它崩溃(即使应该有两个可用):

panicked at 'index out of bounds: the len is 1 but the index is 1'

The struct IP_INTERFACE_INFO containing all data has a field called Adapter which seems to be limited to only be array size of 1. Am I reading this correctly?包含所有数据的结构IP_INTERFACE_INFO有一个名为Adapter的字段,该字段似乎仅限于 1 的数组大小。我读对了吗? How is it then supposed to hold multiple adapters?那么它应该如何容纳多个适配器?

#[repr(C)]
#[doc = "*Required features: `\"Win32_NetworkManagement_IpHelper\"`*"]
pub struct IP_INTERFACE_INFO {
    pub NumAdapters: i32,
    pub Adapter: [IP_ADAPTER_INDEX_MAP; 1],
}

It appears that IP_INTERFACE_INFO uses a C flexible array member , which often uses the [1] syntax .似乎IP_INTERFACE_INFO使用了 C灵活数组成员,该成员通常使用[1]语法 The C++ example in Managing Interfaces Using GetInterfaceInfo corroborates this usage: 使用 GetInterfaceInfo 管理接口中的 C++ 示例证实了这种用法:

for (i = 0; i < (unsigned int) pInterfaceInfo->NumAdapters; i++) {
    printf("  Adapter Index[%d]: %ld\n", i,
           pInterfaceInfo->Adapter[i].Index);
    printf("  Adapter Name[%d]:  %ws\n\n", i,
           pInterfaceInfo->Adapter[i].Name);
}

The equivalent in Rust would be to take the single-element array, get the raw pointer to it, then iterate over that (untested as I'm not currently near Windows): Rust 中的等价物将采用单元素数组,获取指向它的原始指针,然后对其进行迭代(未经测试,因为我目前不在 Windows 附近):

for i in 0..(*ptr).NumAdapters as usize {
    let adapter = (*ptr).Adapter.as_ptr().add(i);
}

I might even use a tool like slice::from_raw_parts to convert the raw pointer and runtime length into a nice Rust slice.我什至可以使用slice::from_raw_parts之类的工具将原始指针和运行时长度转换为漂亮的 Rust 切片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM