Pinvoke DeviceIoControl parameters

前端 未结 1 1276
渐次进展
渐次进展 2020-12-10 04:02

I\'m working on a C# project using DeviceIoControl. I\'ve consulted the related Pinvoke.net page for my signature:

[DllImport(\"Kernel32.dll\", SetLastError         


        
1条回答
  •  醉梦人生
    2020-12-10 04:24

    DeviceIoControl is quite unfriendly. But you can make it less painful, you don't have to marshal structures yourself. Two things you can take advantage of: C# supports method overloads and the pinvoke marshaller will believe you, even if you lie through you teeth about the declaration. Which is perfect for structures, they are already marshaled as a blob of bytes. Just what DeviceIoControl() needs.

    So the general declaration would look like this:

    [DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool DeviceIoControl(
        SafeFileHandle hDevice,
        int IoControlCode,
        byte[] InBuffer,
        int nInBufferSize,
        byte[] OutBuffer,
        int nOutBufferSize,
        out int pBytesReturned,
        IntPtr Overlapped
    );
    

    And you'd add an overload that's perfect for IOCTL_STORAGE_QUERY_PROPERTY, assuming you're interested in it returning a STORAGE_DEVICE_DESCRIPTOR:

    [DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool DeviceIoControl(
        SafeFileHandle hDevice,
        EIOControlCode IoControlCode,
        ref STORAGE_PROPERTY_QUERY InBuffer,
        int nInBufferSize,
        out STORAGE_DEVICE_DESCRIPTOR OutBuffer,
        int nOutBufferSize,
        out int pBytesReturned,
        IntPtr Overlapped
    );
    

    And you'd call it like this:

    var query = new STORAGE_PROPERTY_QUERY { PropertyId = 0, QueryType = 0 };
    var qsize = Marshal.SizeOf(query);
    STORAGE_DEVICE_DESCRIPTOR result;
    var rsize = Marshal.SizeOf(result);
    int written;
    bool ok = DeviceIoControl(handle, EIOControlCode.QueryProperty, 
                 ref query, qsize, out result, rsize, out written, IntPtr.Zero);
    if (!ok) throw new Win32Exception();
    if (written != rsize) throw new InvalidOperationException("Bad structure declaration");
    

    Which ought to look prettier and a lot more diagnosable than what you've got. Untested, ought to be close.

    0 讨论(0)
提交回复
热议问题