VB.NET HID: SetupDiGetDeviceInterfaceDetail GetLastError() shows 1784 (ERROR_INVALID_USER_BUFFER) both times it is called

一笑奈何 提交于 2021-01-29 05:30:50

问题


I've been struggling with this for a while now, trying all sorts of things to get this to work. It's my understanding that SetupDiGetDeviceInterfaceDetail is supposed to give the 1784 error the first time around because the sole purpose of calling it the first time is to get RequiredSize set to the right value. The second time it's called, it's supposed to actually work and give me a valid DeviceInterfaceDetailData structure. I'm not sure what is causing this to fail on the second call.

Structure Definitions:

<StructLayout(LayoutKind.Sequential)> _
Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA
    Public cbSize As UInt32
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    Public DevicePath As String
End Structure

Public Structure SP_DEVICE_INTERFACE_DATA
    Public cbSize As Integer
    Public InterfaceClassGuid As System.Guid
    Public Flags As Integer
    Public Reserved As UIntPtr
End Structure

Public Structure SP_DEVINFO_DATA
    Public cbSize As Integer
    Public ClassGuid As System.Guid
    Public DevInst As Integer
    Public Reserved As UIntPtr
End Structure

Function Declarations:

Public Declare Auto Function SetupDiGetClassDevs Lib "setupapi.dll" (ByRef ClassGuid As System.Guid, ByVal Enumerator As Integer, ByVal hwndParent As IntPtr, ByVal Flags As Integer) As IntPtr

Public Declare Auto Function SetupDiEnumDeviceInfo Lib "setupapi.dll" (ByVal DeviceInfoSet As Integer, ByVal MemberIndex As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean

Public Declare Auto Function SetupDiEnumDeviceInterfaces Lib "setupapi.dll" (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInfoData As SP_DEVINFO_DATA, ByRef InterfaceClassGuid As System.Guid, ByVal MemberIndex As UInteger, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA) As Boolean

//For the first call
Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib "setupapi.dll" (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, ByVal DeviceInterfaceDetailData As IntPtr, ByVal DeviceInterfaceDetailDataSize As Integer, ByRef RequiredSize As Integer, ByRef DeviceInfoData As IntPtr) As Boolean

//For the second call
Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib "setupapi.dll" (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, ByRef DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, ByVal DeviceInterfaceDetailDataSize As Integer, ByRef RequiredSize As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean

Function Calls:

    Dim DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA
    Dim DeviceInterfaceDetailDataSize As Integer
    Dim DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA = Nothing
    Dim DeviceInfoSet As IntPtr
    Dim RequiredSize As Integer
    Dim HidGuid As System.Guid
    HidD_GetHidGuid(HidGuid)
    Dim LastError As Integer

    DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData)
    DeviceInterfaceDetailData.cbSize = Marshal.SizeOf(DeviceInterfaceDetailData
    DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData)


    DeviceInfoSet = SetupDiGetClassDevs(HidGuid, 0, IntPtr.Zero, DIGCF_PRESENT + DIGCF_DEVICEINTERFACE)

    success = SetupDiEnumDeviceInfo(DeviceInfoSet, 0, DeviceInfoData)
    LastError = GetLastError()

    success = SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, HidGuid, 0, DeviceInterfaceData)

    success = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, DeviceInterfaceData, IntPtr.Zero, 0, RequiredSize, IntPtr.Zero)
    //Success is false. GetLastError() shows 1784, but RequiredSize gets set to 166

    DeviceInterfaceDetailDataSize = RequiredSize + 16

    success = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData)
    //Success is false. GetLastError() shows 1784, and DeviceInterfaceDetailData does not get set, so I can't get DeviceInterfaceDetailData.DevicePath

回答1:


Private Structure SP_DEVICE_INTERFACE_DETAIL_DATA
    Dim cbSize As UInteger
    Dim DevicePath() As Char
End Structure

For target CPU x86: DetailedInterfaceDataStructure.cbSize = 6
For target CPU x64: DetailedInterfaceDataStructure.cbSize = 8



回答2:


You have to set

DeviceInterfaceDetailData.cbSize = Marshal.SizeOf(UInt32) + Marshal.SizeOf(Char)

and ignore the first result code returned from SetupDiGetDeviceInterfaceDetail.

The structure DeviceInterfaceDetailData is declared as

typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
  DWORD cbSize;
  TCHAR DevicePath[ANYSIZE_ARRAY];
} SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA;

with ANYSIZE_ARRAY is ONE!



来源:https://stackoverflow.com/questions/10405193/vb-net-hid-setupdigetdeviceinterfacedetail-getlasterror-shows-1784-error-inv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!