Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Help calling SetupDiEnumDeviceInterfaces  from VB.NET

Posted on 2007-03-30
Medium Priority
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

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

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()

            '// 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
            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
            Dim GUID_DEVINTERFACE_GRMNUSB As New Guid(&H2C9C45C2L, &H8E7D, &H4C08, &HA1, &H2D, &H81, &H6B, &HBA, &HE7, &H22, &HC0)

            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)
            If Not result Then
                If GetLastError() = ERROR_NO_MORE_ITEMS Then
                    gHandle = 0
                    GoTo CommonExit
                End If
            End If
        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
Question by:CASorter
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
LVL 41

Expert Comment

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

    '    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
       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
    <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
LVL 41

Accepted Solution

graye earned 2000 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

    '    IN HDEVINFO  DeviceInfoSet,
    '    IN PSP_DEVINFO_DATA  DeviceInfoData, OPTIONAL
    '    IN LPGUID  InterfaceClassGuid,
    '    IN DWORD  MemberIndex,
    '    OUT PSP_DEVICE_INTERFACE_DATA  DeviceInterfaceData

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

715 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