I'm writing a managed wrapper for the IOCTL_DISK_GET_DRIVE_LAYOUT_EX function. It works fine on the flash drive that I've tested (using "\\.\PHYSICALDRIVE1" to get a handle). But when calling on \\.\PHYSICALDRIVE0 (the system drive), the function doesn't work properly, i.e.:
The first time it is called using the default buffer size, it returns the INSUFFICIENT_BUFFER error. When the buffer is automatically resized (using Marshal.GlobalHRealloc) and the function is called again, it never returns.
(I'm using a valid handle with no access permissions.)
What could be the problem?
I found my mistake.
When resizing the lpOutBuffer to accommodate the INSUFFICIENT_BUFFER error, I was using Marshal.ReAllocHGlobal without assigning the returned value to my lpOutBuffer. ReAllocHGlobal was releasing my pointer and giving me new one, which I had been ignoring, meaning that IOCTL was being called with an freed/invalid pointer. I don't know why Windows wasn't throwing an error, but I've solved my immediate issue.
(First I tried to enlarge the default buffer size, and it worked, that's how I realized that my follow-up calls must have a problem with the buffer/pointer, an viola! now everything works.)