Home > Back-end >  how can I cast LPVOID into struct
how can I cast LPVOID into struct

Time:10-04

I started learning Rust WinApi. I need to iterate over all network computers using winapi crate. This is my code:

fn enumerate_network_computers(lpnr: LPNETRESOURCEW) -> u32 {
    unsafe {
        let mut h_enum: HANDLE = 0 as PVOID;
        let mut cb_entries: DWORD = 9999;
        let mut cb_buffer: DWORD = 16384;
        let lpnr_local: LPVOID = GlobalAlloc(GPTR, cb_buffer.try_into().unwrap());

        let mut dw_err = WNetOpenEnumW(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, lpnr, &mut h_enum);
        
        if dw_err != NO_ERROR {
            return dw_err;
        }

        loop {
            dw_err = WNetEnumResourceW(h_enum, &mut cb_entries, lpnr_local, &mut cb_buffer);

            println!("{:#?}", lpnr_local);
            
            
            if dw_err == ERROR_NO_MORE_ITEMS {
                break;
            }
        }

        dw_err
    }
}

So, my code works great! But I can't cast LPVOID to NETRESOURCEW to iterate over structure... I've already tried .try_into(), lpnr_local as NETRESOURCEW. But I get error: the trait From<*mut winapi::ctypes::c_void> is not implemented for NETRESOURCEW

CodePudding user response:

LPVOID is a pointer but NETRESOURCEW is not so you cannot cast between them. Remember that the prefix LP stands for long pointer.

So try casting lpnr_local as LPNETRESOURCEW instead.

Alternatively you can avoid the Microsoft-ism and do lpnr_local as *const NETRESOURCEW.

Note that in order to access the members of that structure you have to dereference the pointer. I'd do something like this:

let nr = &*(lpnr_local as *const NETRESOURCEW);
println!("{:#?}", nr);
  • Related