Solved

Help calling SetupDiEnumDeviceInterfaces  from VB.NET

Posted on 2007-03-30
2
1,425 Views
Last Modified: 2013-11-26
I've been pounding on this pretty hard, and have yet to find a solution.
I need to call the SetupDiEnumDeviceInterfaces API function from VB.NET (Not C#). I get a PInvoke error which usually results from not having declared something properly. Any help would be greatly appreciated!!!

Public Structure SP_DEVINFO_DATA
      Public cbSize As Long
      Public ClassGuid As Guid
      Public DevInst As Long
      Public Reserved As Long
End Structure

Public Structure SP_DEVICE_INTERFACE_DATA
        Dim cbSize As Int64
        Dim InterfaceClassGuid As Guid
        Dim Flags As Integer
        Dim Reserved As UInt32
End Structure

Public Enum DEVICEFLAGS
    DIGCF_ALLCLASSES = &H4&
    DIGCF_DEVICEINTERFACE = &H10
    DIGCF_PRESENT = &H2
    DIGCF_PROFILE = &H8
End Enum

Public Declare Function SetupDiGetDeviceInterfaceDetail  lib "setupapi.dll" Alias  "SetupDiGetDeviceInterfaceDetailA" (ByVal DeviceInfoSet As Integer, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, ByVal DeviceInterfaceDetailData As Integer,  ByVal DeviceInterfaceDetailDataSize As Integer, ByRef RequiredSize As Integer, ByVal DeviceInfoData As Integer) As Integer

Public Declare Auto Function SetupDiEnumDeviceInterfaces Lib "setupapi.dll" (ByVal Handle As Long, ByVal InfoPtr As IntPtr, ByRef GuidPtr As IntPtr,  ByVal MemberIndex As Integer, ByRef InterfaceDataPtr As IntPtr) As Boolean

Public Declare Function SetupDiGetClassDevs Lib "setupapi.dll"           Alias "SetupDiGetClassDevsA" (ByRef ClassGuid As IntPtr, ByVal Enumerator As String,  ByVal hwndParent As Int32, ByVal flags As DEVICEFLAGS) As Int64

    Private Sub Initialize()
        Try

   IOCTL_ASYNC_IN = CTL_CODE(FILE_DEVICE_UNKNOWN, 850,   METHOD_BUFFERED, FILE_ANY_ACCESS)
1010:       IOCTL_USB_PACKET_SIZE = CTL_CODE(FILE_DEVICE_UNKNOWN, 851, METHOD_BUFFERED, FILE_ANY_ACCESS)
            '// Make all the necessary Windows calls to get a handle to our USB device
1015:       Dim szOfPacket_T As Integer
            Dim theBytesReturned As Long = 0
            Dim theDevInfoData As Int64
            Dim theDevInfo As Int64
            Dim theInterfaceData As SP_DEVICE_INTERFACE_DATA
            Dim holderForSizeCalc As SP_DEVINFO_DATA
            Dim hldForSP_DEVINFO_DATA As New SP_DEVINFO_DATA
            Dim holderForPacket_t As Packet_T
            Dim devDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA
            Dim ptrToDevDetailData As IntPtr

1025:       theDevInfoData = Marshal.SizeOf(hldForSP_DEVINFO_DATA)
            hldForSP_DEVINFO_DATA.cbSize = Marshal.SizeOf(hldForSP_DEVINFO_DATA)

            Dim theStartSessionPacket As Packet_T
            theStartSessionPacket.mPacketId = 0
            theStartSessionPacket.mReserved3 = 5
            theStartSessionPacket.mDataSize = 0
            theStartSessionPacket.mData = 0
1040:
            szOfPacket_T = Marshal.SizeOf(holderForPacket_t)
1045:       Dim thePacket As IntPtr
            thePacket = Marshal.AllocHGlobal(szOfPacket_T)

1050:       Dim gd As Guid
            Dim devcFlags As DEVICEFLAGS
1060:       devcFlags = DEVICEFLAGS.DIGCF_PRESENT Or DEVICEFLAGS.DIGCF_DEVICEINTERFACE
            Dim GUID_DEVINTERFACE_GRMNUSB As New Guid(&H2C9C45C2L, &H8E7D, &H4C08, &HA1, &H2D, &H81, &H6B, &HBA, &HE7, &H22, &HC0)
            gd = GUID_DEVINTERFACE_GRMNUSB

            Dim s1 As String = DEVICE_CLASS_USB_DEVICE
            Dim ptr As IntPtr = Marshal.StringToHGlobalAuto(s1)
            Dim guidPtr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(gd))
            'The SetupDiGetClassDevs function retrieves a device information set
            'that contains all the devices of a specified class
1080:       theDevInfo = SetupDiGetClassDevs(guidPtr, 0&, callersHandle, devcFlags)

1090:       Dim ptrToTheIntfData As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(theInterfaceData))
            theInterfaceData.cbSize = Marshal.SizeOf(theInterfaceData)
1095:       Marshal.StructureToPtr(theInterfaceData, ptrToTheIntfData, False)

1100:       Dim result As Boolean
            'The SetupDiEnumDeviceInterfaces function retrieves a context structure for a device
            'interface of a device information set. Each call returns information about one device
            'interface. The function can be called repeatedly to get information about several
            'interfaces exposed by one or more devices.
            result = SetupDiEnumDeviceInterfaces(theDevInfo, 0&, guidPtr, 0, ptrToTheIntfData)
"ABOVE GIVES THE PINVOKE ERROR
            If Not result Then
                If GetLastError() = ERROR_NO_MORE_ITEMS Then
                    gHandle = 0
                    GoTo CommonExit
                End If
            End If
CommonExit:
        Catch ex As Exception
            Dim sNum As Long
            sNum = GetLastError()
            Dim errText As String
            errText = FormatError("Error initializing USB Device.")
            MsgBox(errText, MsgBoxStyle.Critical, "Error Initializing USB Device")
            LogError(errText, "USBComm::Initialize")
        End Try
    End Sub
0
Comment
Question by:CASorter
  • 2
2 Comments
 
LVL 41

Expert Comment

by:graye
ID: 18827500
Let's do a quick review on how to translate API documenation into VB.Net Declare statements...

    'WINSETUPAPI BOOL WINAPI
    'SetupDiEnumDeviceInterfaces(
    '    IN HDEVINFO  DeviceInfoSet,                                               <- "H" means handle (a pointer to a handle obtained by SetupDiGetClassDevs)
    '    IN SP_DEVINFO_DATA  DeviceInfoData, OPTIONAL              <- "P" means pointer to a SP_DEVINFO_DATA structure
    '    IN LPGUID  InterfaceClassGuid,                                           <- "LP" means a long pointer (in this case a GUID)
    '    IN DWORD  MemberIndex,                                                   <- Integer
    '    OUT SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData    <- "P" means pointer to a SP_DEVICE_INTERFACE_DATA  structure
    ');
    Declare Auto Function SetupDiEnumDeviceInterfaces Lib "" ( _
        ByVal DeviceInfoSet As IntPtr, _                                                    <- this might seem strange, but ByVal is correct for an IntPtr that is a pointer to a handle
        ByRef DeviceInfoData As SP_DEVINFO_DATA, _                            <- structures are value types, so a ByRef make is this a pointer
        ByRef InterfaceClassGuid As Guid, _                                             <- likewise, a ByRef makes this a pointer
        ByVal MemberIndex As Integer, _                                                 <- plain ole integer
        ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA _    <- ByRef makes this a pointer to a structure
    )

Optionally, you could substitute
       ByVal DeviceInfoSet As IntPtr         <- the preferred method
with
       ByRef DeviceInfoSet as Integer

As for the structures, all API-style structures are "packed", so we need to decorate the structures with the LayoutKind.Sequential attribute

    'typedef struct _SP_DEVINFO_DATA {
    '  DWORD  cbSize;                                           <- Integer
    '  GUID  ClassGuid;                                          <- GUID
    '  DWORD  DevInst;                                         <- Integer
    '  ULONG_PTR  Reserved;                                <- pointer to an usigned long
    '} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;
    <StructLayout(LayoutKind.Sequential)> _
        Structure SP_DEVINFO_DATA
        Dim cbSize As Integer
        Dim ClassGuid As Guid
        Dim DevInst As Integer
        Dim Reserved As IntPtr
    End Structure

I only did one API declare and one structure, but I bet you can take it from here.

... if not, let us know and we'll continue
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
ID: 18827517
I hate typo's...

I messed up the API documentation part (but not the VB.Net part!).   I just now saw that when I talk about the "P" in the API documenation that I had edited the first letter out (so there is no "P").  So my comment on how to determine if a parameter is a point didn't make much sence in that example, PSP_DEV... vs SP_DEV...  

Here is how the original API documentation had it before I edit out the "P"s

    'WINSETUPAPI BOOL WINAPI
    'SetupDiEnumDeviceInterfaces(
    '    IN HDEVINFO  DeviceInfoSet,
    '    IN PSP_DEVINFO_DATA  DeviceInfoData, OPTIONAL
    '    IN LPGUID  InterfaceClassGuid,
    '    IN DWORD  MemberIndex,
    '    OUT PSP_DEVICE_INTERFACE_DATA  DeviceInterfaceData
    ');
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now