C# USB driver from C++: SetupDiGetDeviceInterfaceDetail

前端 未结 1 397
心在旅途
心在旅途 2021-01-23 02:37

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\")

相关标签:
1条回答
  • 2021-01-23 03:05

    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);
    }
    
    0 讨论(0)
提交回复
热议问题