2012-05-01 30 views
0

我一直在努力這一段時間了,嘗試各種事情來得到這個工作。我的理解是SetupDiGetDeviceInterfaceDetail應該第一次給出1784錯誤,因爲第一次調用它的唯一目的是將RequiredSize設置爲正確的值。第二次被調用時,它應該實際工作並給我一個有效的DeviceInterfaceDetailData結構。我不確定是什麼原因導致第二次通話失敗。VB.NET HID:SetupDiGetDeviceInterfaceDetail GetLastError()顯示1784(ERROR_INVALID_USER_BUFFER)這兩次它被稱爲

結構定義:

<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 

函數聲明:

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 

函數調用:

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 private As UIntPtr' should be'public'。 – GSerg

+0

謝謝GSerg,我沒注意到。這些結構是來自pinvoke.net的複製/粘貼。不幸的是,這一變化之後,問題仍然存在。 – user1172282

回答

0

你必須設置

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

並忽略從SetupDiGetDeviceInterfaceDetail返回的第一個結果代碼。

結構DeviceInterfaceDetailData聲明爲

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

與ANYSIZE_ARRAY是ONE!

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