Page 1 of 1

Getting USB device (interface) information problem

Posted: Mon Jun 18, 2007 1:50 pm
by Ramihyn_
I am trying to find the driveletters of currently plugged in USB drives (USB storage devices like hard disk or flash drives).

Using the MSDN doku it seems a call to SetupDiGetDeviceInterfaceDetail delivers the drivepath. This is the MSDN example i tried to follow: http://msdn2.microsoft.com/en-us/library/aa476413.aspx

My problem is that it keeps telling me that "no more data is available" as if there are no USB drives (interfaces) found. It may just be the wrong GUID but so far i have tried the DEVCLASS my USB hubs and my USB flash drive reports (by using SetupDiEnumDeviceInfo and SetupDiGetDeviceRegistryProperty which works as expected), the GUID in the sample code and the GUID_DEVCLASS_USB freaks GUID viewer (http://freak.purearea.net/tools/tools.html).

This is the code written in the PB 4.02 windows version. I verirfied the macro DEFINE_GUID from the MSDN sample and the data format should be correct.

Does anybody know what the problem is? Help would be much appreciated :)

Code: Select all

Structure SP_DEVINFO_DATA
  cbSize.l
  ClassGuid.GUID
  DevInst.l
  Reserved.l
EndStructure

Structure SP_DEVICE_INTERFACE_DATA
  cbSize.l
  InterfaceClassGuid.GUID
  Flags.l
  *Reserved.l
EndStructure

Structure SP_DEVICE_INTERFACE_DETAIL_DATA
  cbSize.l
  DevicePath.s[256]
EndStructure

DataSection

GUID_DEVCLASS_USB:      ; {36FC9E60-C465-11CF-8056-444553540000}
;   Data.l $36FC9E60
;   Data.w $C465, $11CF
;   Data.b $80, $56, $44, $45, $53, $54, $00, $00

  Data.l $058815b2
  Data.w $9805, $47d3
  Data.b $b7, $d5, $ab, $c4, $64, $d3, $ca, $06

EndDataSection

#DIGCF_PRESENT          = 2
#DIGCF_ALLCLASSES       = 4
#DIGCF_DEVICEINTERFACE  = 16

#SPDRP_DEVICEDESC                  =   0 ; ECP-Druckeranschluss
#SPDRP_HARDWAREID                  =   1 ; ACPI\PNP0401
#SPDRP_COMPATIBLEIDS               =   2 ; (err13)
#SPDRP_SERVICE                     =   4 ; Parport
#SPDRP_CLASS                       =   7 ; Ports
#SPDRP_CLASSGUID                   =   8 ; {4D36E978-E325-11CE-BFC1-08002BE10318}
#SPDRP_DRIVER                      =   9 ; {4D36E978-E325-11CE-BFC1-08002BE10318}\0000
#SPDRP_CONFIGFLAGS                 =  10 ; 127 (Zahl=Long)
#SPDRP_MFG                         =  11 ; (Standardanschlusstypen)
#SPDRP_FRIENDLYNAME                =  12 ; ECP-Druckeranschluss (LPT1)
#SPDRP_LOCATION_INFORMATION        =  13 ; (err13)
#SPDRP_PHYSICAL_DEVICE_OBJECT_NAME =  14 ; \Device\0000005c
#SPDRP_CAPABILITIES                =  15 ; 48 (Zahl=Long)
#SPDRP_UI_NUMBER                   =  16 ; (err13)
#SPDRP_UPPERFILTERS                =  17 ; (err13)
#SPDRP_LOWERFILTERS                =  18
#SPDRP_BUSTYPEGUID                 =  19
#SPDRP_LEGACYBUSTYPE               =  20
#SPDRP_BUSNUMBER                   =  21
#SPDRP_ENUMERATOR_NAME             =  22 ; ACPI
#SPDRP_SECURITY                    =  23
#SPDRP_SECURITY_SDS                =  24
#SPDRP_DEVTYPE                     =  25
#SPDRP_EXCLUSIVE                   =  26
#SPDRP_CHARACTERISTICS             =  27
#SPDRP_ADDRESS                     =  28
#SPDRP_UI_NUMBER_DESC_FORMAT       =  30

Prototype.l ProtoSetupDiGetDeviceInterfaceDetailA(DeviceInfoSet.l, *DeviceInterfaceData.l, *DeviceInterfaceDetailData.l, DeviceInterfaceDetailDataSize.l, *RequiredSize.l, *DeviceInfoData.l)
Prototype.l ProtoSetupDiEnumDeviceInterfaces(DeviceInfoSet.l, *DeviceInfoData.l, *InterfaceClassGuid.l, MemberIndex.l, *DeviceInterfaceData.l)

Procedure USB_Test()

  DeviceInfoData.SP_DEVINFO_DATA
  DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA
  DeviceInterfaceDetailData.SP_DEVICE_INTERFACE_DETAIL_DATA

  Debug "Start test"

  ; get DeviceInterface Api entries which arent natively supported by PB 4.x

  libHandle = OpenLibrary(#PB_Any, "Setupapi.dll")

  If (libHandle)
    SetupDiGetDeviceInterfaceDetail.ProtoSetupDiGetDeviceInterfaceDetailA = GetFunction(libHandle, "SetupDiGetDeviceInterfaceDetailA")
    SetupDiEnumDeviceInterfaces.ProtoSetupDiEnumDeviceInterfaces          = GetFunction(libHandle, "SetupDiEnumDeviceInterfaces")

    If ((SetupDiGetDeviceInterfaceDetail = 0) Or (SetupDiEnumDeviceInterfaces = 0))
      Debug "SetupApi interface initialisation failed"
      ProcedureReturn
    EndIf

;      If (ExamineLibraryFunctions(res))
;        While (NextLibraryFunction())
;          Debug "-> " + LibraryFunctionName()
;        Wend
;      EndIf
  Else
    Debug "Opening SetupApi failed"
    ProcedureReturn
  EndIf

  hDevInfo = SetupDiGetClassDevs_(?GUID_DEVCLASS_USB, #Null, #Null, #DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)

  If (hDevInfo = #INVALID_HANDLE_VALUE)
    Debug "Inv handle"

    ProcedureReturn
  EndIf

  ; -- DeviceInterface --

  DeviceInterfaceData\cbSize  = SizeOf(SP_DEVICE_INTERFACE_DATA)

  nstatus.l = SetupDiEnumDeviceInterfaces(hDevInfo, #Null, ?GUID_DEVCLASS_USB, 0, @DeviceInterfaceData)

  If (nstatus = #False)
    lerr = GetLastError_()
    msg$ = Space(4000)
    nchars.l = FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, lerr, 0, @msg$, 3500, 0)
    If (nchars > 2)
      Debug "Error (" + Str(lerr) + "): " + Left(msg$, nchars - 2)
    EndIf
  Else
    Debug "EnumDeviceInterface status: " + Str(nstatus)

    DeviceInterfaceDetailData\cbSize = SizeOf(SP_DEVICE_INTERFACE_DETAIL_DATA)
    nstatus = SetupDiGetDeviceInterfaceDetail(hDevInfo, @DeviceInterfaceData, @DeviceInterfaceDetailData, 248, 0, @DeviceInfoData)

    If (nstatus = 0)
      lerr = GetLastError_()
      msg$ = Space(4000)
      nchars.l = FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, lerr, 0, @msg$, 3500, 0)
      If (nchars > 2)
        Debug "Error: " + Left(msg$, nchars - 2)
      EndIf
    EndIf
    
  EndIf

  SetupDiDestroyDeviceInfoList_(hDevInfo)

  ProcedureReturn

EndProcedure


USB_Test()

Some other links you might need to verify infos:

http://msdn2.microsoft.com/en-us/library/ms791242.aspx
http://msdn2.microsoft.com/en-us/library/ms791134.aspx