Hmm... I haven't looked very close at EnumPrinters, but here's my guess at what's happening:
- The
PRINTER_INFO_2
buffer contains a bunch of null-terminated strings.
- It's the responsibility of the application to allocate the buffer.
This is me just speculating, but these two facts point to that the reason you're getting such a large "needed" buffer is because you need to allocate enough for all the PRINTER_INFO_2
buffers and all the strings it will point to. EnumPrinters
will store all the PRINTER_INFO_2
nodes in the beginning of the buffer, and stick all the strings at the end.
If this is the case, here's the issue: You need to make sure that buffer
is large enough to hold all the PRINTER_INFO_2
nodes plus all the strings. You're getting a segfault because you're not allocating memory for the output buffer between the EnumPrinters
calls.
Just to see if this is the case, you can try to pre-allocate space in buffer
by using Vec::reserve()
. Just allocate a sufficient amount of nodes to make sure that it'll fit, in your example, 129296 bytes of data. Conceptually:
let nodes_needed = pcb_needed / std::mem::size_of::<PRINTER_INFO_2>();
buffer.reserve(nodes_needed+1); // one extra for good luck (and also if the sizes don't align)
But note that this is only to solve the memory allocation issue, you still need to set the number of elements in the Vec
to pcreturned
somehow.
In my last reply I didn't bother checking how EnumPrinter
works, and to be honest I just took a quick glance now, so I may be completely wrong.
Perhaps you should be using a Vec<u8>
instead, and resize it as appropriate before the second call to EnumPrinters
, and then use some unsafe pointer-trickery to point a PRINTER_INFO_2
pointer to the entries after the second call, and copy the data out to a Rust-native structure.
The only thing to make sure is that the internal Vec<u8>
buffer is aligned properly for a PRINTER_INFO_2
pointer.
I have done very little ffi, so there are probably even better ways to do it.
Oh, and also: Keep an eye out for packing/padding bugs in windows-rs. I have encountered an issue where a struct member is at the incorrect offset in the windows crate (it stems from a bug in the win32metadata project). I think these things are very rare, but don't automatically assume that the structs are entirely bug-free in the windows crate.