Help needed - porting node-ffi code over to rust


I am new tu rust and need help with the following function (trying to get printer info from the windows api):

fn enum_printers() {
    use std::ptr;
    use memalloc::allocate;
    use winapi::um::winspool::{ EnumPrintersW, PRINTER_ENUM_LOCAL };

    let flags = PRINTER_ENUM_LOCAL;
    let level = 4; // PRINTER_INFO_4W
    let mut bytes_needed = 0;
    let mut count_returned = 0;

    // 1st call: get bytes_needed value
    let mut result = unsafe {
        EnumPrintersW(flags, ptr::null_mut(), level, ptr::null_mut(), 0, &mut bytes_needed, &mut count_returned)

    if result != 0 {

    // 2nd call: fill the buffer with PRINTER_INFO data
    let p_buffer = unsafe{ allocate(bytes_needed as usize) };

    result = unsafe {
        EnumPrintersW(flags, ptr::null_mut(), level, p_buffer, bytes_needed, &mut bytes_needed, &mut count_returned)

    if result == 0 {

    println!("{:?} Printer discovered.", count_returned);
    println!("{:?} Bytes needed for buffer.", bytes_needed);

The first call to EnumPrintersW sets bytes_needed to the amount of bytes to be allocated for the output buffer.

After the second call the buffer should contain an array with count_returned PRINTER_INFO_4W, but how to access the data?

Related infos: EnumPrinters function (Winspool.h) - Win32 apps | Microsoft Docs

Any hints much appreciated!

Hi, since you have a buffer with an alignment of 1 byte, you can't make a slice out of it since your struct has an alignment of 8 bytes.

So you have to use read_unaligned to get individual values from this buffer, starting at p_buffer.

Or, allocate a bit more so you can skip a few bytes in the beginning and give windows an aligned pointer. This way you can make a slice using from_raw_parts and then profit.

Thanks, will try that!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.