Search code examples
.netwinapipinvoke

IOCTL_DISK_GET_DRIVE_LAYOUT_EX call never returns


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?


Solution

  • 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.)