I\'ve a problem trying to call SetupDiGetDeviceInterfaceDetail from C#. It always returns 1784 error code (\"The supplied user buffer is not valid for the requested operation\")
The struct is a variable sized structure which cannot be marshalled automatically. You'll need to do so yourself.
You'll need to remove the SP_DEVICE_INTERFACE_DETAIL_DATA
type. It's no use to you. Change the declaration of SetupDiGetDeviceInterfaceDetail
to:
[DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean SetupDiGetDeviceInterfaceDetail(
IntPtr hDevInfo,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
uint deviceInterfaceDetailDataSize,
out uint requiredSize,
SP_DEVINFO_DATA deviceInfoData
);
Pass IntPtr.Zero
in the first call to SetupDiGetDeviceInterfaceDetail
. Then allocate a buffer of the required size by calling Marshal.AllocHGlobal
. Then write the size into the first 4 bytes of that buffer. Then call SetupDiGetDeviceInterfaceDetail
again.
Something along these lines:
bool result3 = Win32.SetupDiGetDeviceInterfaceDetail(hDevInfo, ifData, IntPtr.Zero, 0,
out needed, null);
if(!result3)
{
int error = Marshal.GetLastWin32Error();
}
// expect that result3 is false and that error is ERROR_INSUFFICIENT_BUFFER = 122,
// and needed is the required size
IntPtr DeviceInterfaceDetailData = Marshal.AllocHGlobal((int)needed);
try
{
uint size = needed;
Marshal.WriteInt32(DeviceInterfaceDetailData, (int)size);
bool result4 = Win32.SetupDiGetDeviceInterfaceDetail(hDevInfo, ifData,
DeviceInterfaceDetailData, size, out needed, null);
if(!result4)
{
int error = Marshal.GetLastWin32Error();
}
// do whatever you need with DeviceInterfaceDetailData
}
finally
{
Marshal.FreeHGlobal(DeviceInterfaceDetailData);
}