>*!* http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q264203 >*!* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setupdienumdeviceinterfaces.asp > > >*!* typedef struct _SP_DEVINFO_DATA { >*!* DWORD cbSize; 4 >*!* GUID ClassGuid; 16 >*!* DWORD DevInst; 4 >*!* ULONG_PTR Reserved; 4 >*!* } SP_DEVINFO_DATA 28 > >*!* Private Type Guid >*!* Data1 As Long 4 >*!* Data2 As Integer 2 >*!* Data3 As Integer 2 >*!* Data4(0 To 7) As Byte 8 >*!* End Type 16 > > >********************************************************************************* >*!* Defines >********************************************************************************* >#Define DIGCF_ALLCLASSES 0x0004 >#Define DIGCF_DEVICEINTERFACE 0x0010 >#Define DIGCF_PRESENT 0x0002 >#Define DIGCF_PROFILE 0x0008 >#Define DIGCF_INTERFACEDEVICE DIGCF_DEVICEINTERFACE > >#Define ERROR_INSUFFICIENT_BUFFER 122 >#Define ERROR_NO_MORE_ITEMS 259 >#Define INVALID_HANDLE_VALUE -1 > >#Define SPDRP_ADDRESS 0x001C >#Define SPDRP_BUSTYPEGUID 0x0013 >#Define SPDRP_CAPABILITIES 0x000F >#Define SPDRP_CHARACTERISTICS 0x001B >#Define SPDRP_CLASS 0x0007 >#Define SPDRP_CLASSGUID 0x0008 >#Define SPDRP_COMPATIBLEIDS 0x0002 >#Define SPDRP_CONFIGFLAGS 0x000A >#Define SPDRP_DEVICE_POWER_DATA 0x000E >#Define SPDRP_DEVICEDESC 0x0000 >#Define SPDRP_DEVTYPE 0x0019 >#Define SPDRP_DRIVER 0x0009 >#Define SPDRP_ENUMERATOR_NAME 0x0016 >#Define SPDRP_FRIENDLYNAME 0x000C >#Define SPDRP_HARDWAREID 0x0001 >#Define SPDRP_LOCATION_INFORMATION 0x000D >#Define SPDRP_LOWERFILTERS 0x0012 >#Define SPDRP_MFG 0x000B >#Define SPDRP_PHYSICAL_DEVICE_OBJECT_NAME 0x000E >#Define SPDRP_REMOVAL_POLICY 0x001F >#Define SPDRP_REMOVAL_POLICY_HW_DEFAULT 0x0020 >#Define SPDRP_REMOVAL_POLICY_OVERRIDE 0x0021 >#Define SPDRP_SECURITY 0x0017 >#Define SPDRP_SECURITY_SDS 0x0018 >#Define SPDRP_SERVICE 0x0004 >#Define SPDRP_UI_NUMBER 0x0010 >#Define SPDRP_UI_NUMBER_DESC_FORMAT 0x001E >#Define SPDRP_UPPERFILTERS 0x0011 > > >*!* GUID_DEVCLASS_DISKDRIVE, 0x4d36e967L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 >#Define GUID_DEVCLASS_DISKDRIVE ; > Chr(0x67) + Chr(0xE9) + Chr(0x36) + Chr(0x4D) + ; > Chr(0x25) + Chr(0xE3) + ; > Chr(0xCE) + Chr(0x11) + ; > Chr(0xBF) + Chr(0xC1) + Chr(0x08) + Chr(0x00) + Chr(0x2B) + Chr(0xE1) + Chr(0x03) + Chr(0x18) > >********************************************************************************* >*!* Declarations, in order of use >********************************************************************************* >Declare Integer SetupDiGetClassDevs In setupapi; > String @ClassGuid,; > Integer Enumerator,; > Integer hwndParent,; > Integer _Flags > >Declare Integer SetupDiEnumDeviceInfo In setupapi; > Integer DeviceInfoSet,; > Integer MemberIndex,; > String @DeviceInfoData > >Declare Integer SetupDiGetDeviceRegistryProperty In setupapi; > Integer DeviceInfoSet,; > String @DeviceInfoData,; > Integer _Property,; > String @PropertyRegDataType,; > String @PropertyBuffer,; > Integer PropertyBufferSize,; > String @RequiredSize > >Declare Integer GetLastError In win32api > >Declare Integer SetupDiDestroyDeviceInfoList In setupapi; > Integer DeviceInfoSet > >********************************************************************************* >*!* Start >********************************************************************************* > >*!* This routine enumerates the disk devices using the Setup class interface >*!* GUID GUID_DEVCLASS_DISKDRIVE. Gets the Device ID from the Registry >*!* property. > >Clear > >Local ; > lnDeviceInfoSet, ; > lnEnumerator, ; > lnhwndParent, ; > lnFlags, ; > lcClassGuid, ; > lnRetVal, ; > lcDeviceInfoData, ; > lnx, ; > lcDeviceProperty > >*!* We will first obtain a handle to a list of all disk drives available: > >*!* "The SetupDiGetClassDevs function retrieves a device information set >*!* that contains all the devices of a specified class." > >m.lcClassGuid = GUID_DEVCLASS_DISKDRIVE >m.lnEnumerator = 0 >m.lnhwndParent = 0 >m.lnFlags = DIGCF_PRESENT > >m.lnDeviceInfoSet = SetupDiGetClassDevs( ; > @m.lcClassGuid, ; > m.lnEnumerator, ; > m.lnhwndParent, ; > m.lnFlags) && All devices present on system > >*!* If the return value is -1 something went wrong >If m.lnDeviceInfoSet = INVALID_HANDLE_VALUE Then > ? [SetupDiGetClassDevs FAILED] > Return >Endif > >*!* Now that we have a handle to the list of disk drives, we will go thru >*!* that list one device at a time: > >*!* "The SetupDiEnumDeviceInfo function retrieves a context structure for >*!* a device information element of the specified device information set. >*!* Each call returns information about one device. The function can be >*!* called repeatedly to get information about several devices." > >*!* When SetupDiEnumDeviceInfo fails, we get out of the loop, and check why it failed >*!* It will probably fail because we iterated trhu all devices > >m.lnx = 0 > >m.lnRetVal = -1 > >Do While m.lnRetVal <> 0 > *!* Initialize empty SP_DEVINFO_DATA structure > m.lcDeviceInfoData = Padr(BinToC(28, [4RS]), 4, Chr(0)) + Replicate(Chr(0), 24) > > m.lnRetVal = SetupDiEnumDeviceInfo( ; > m.lnDeviceInfoSet, ; > m.lnx, ; > @m.lcDeviceInfoData) > > *!* If we got a handle to one disk drive, now we will retrieve some properties for it: > > If m.lnRetVal = 1 Then > ?[Device: ], m.lnx > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_CLASS) > ?[Property:], [CLASS: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_DEVICEDESC) > ?[Property:], [DEVICEDESC: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_ENUMERATOR_NAME) > ?[Property:], [ENUMERATOR_NAME: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_FRIENDLYNAME) > ?[Property:], [FRIENDLYNAME: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_HARDWAREID) > ?[Property:], [HARDWAREID: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_MFG) > ?[Property:], [MFG: ], m.lcDeviceProperty > > m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME) > ?[Property:], [PHYSICAL_DEVICE_OBJECT_NAME: ], m.lcDeviceProperty > Endif > m.lnx = m.lnx + 1 >Enddo > >If GetLastError() = ERROR_NO_MORE_ITEMS Then > ?[No more devices] >Else > ?[SetupDiEnumDeviceInfo FAILED] >Endif > >*!* The SetupDiDestroyDeviceInfoList function destroys a device >*!* information set and frees all associated memory. > >If m.lnDeviceInfoSet <> INVALID_HANDLE_VALUE Then > If SetupDiDestroyDeviceInfoList(m.lnDeviceInfoSet) = 0 Then > ? [SetupDiDestroyDeviceInfoList lnDeviceInfoSet FAILED] > Endif >Endif > > >********************************************************************************* >Procedure GetRegistryProperty >********************************************************************************* > >Lparameters tnDeviceInfoSet, tcDeviceInfoData, tnProperty > >Local lnRetVal, lcPropertyBuffer, lcRequiredSize > >m.lcPropertyBuffer = Space(0) >m.lcRequiredSize = Space(4) >m.PropertyRegDataType = Space(4) > >*!* "The SetupDiGetDeviceRegistryProperty function retrieves the specified device property." >*!* We don't know the size of the required string buffer for the property until we call the >*!* function, so we first call it with a null string to get the required buffer size, then >*!* we call again with the proper buffer size > >m.lnRetVal = SetupDiGetDeviceRegistryProperty( ; > m.tnDeviceInfoSet, ; > @m.tcDeviceInfoData, ; > m.tnProperty, ; > @m.PropertyRegDataType, ; > @m.lcPropertyBuffer, ; > LEN(m.lcPropertyBuffer), ; > @m.lcRequiredSize) > >If m.lnRetVal = 0 And GetLastError() = ERROR_INSUFFICIENT_BUFFER Then > m.lcPropertyBuffer = Space(CToBin(m.lcRequiredSize, [4RS])) > > m.lnRetVal = SetupDiGetDeviceRegistryProperty( ; > m.tnDeviceInfoSet, ; > @m.tcDeviceInfoData, ; > m.tnProperty, ; > 0, ; > @m.lcPropertyBuffer, ; > LEN(m.lcPropertyBuffer), ; > @m.lcRequiredSize) >Endif > >If m.lnRetVal = 0 Then > ? [SetupDiGetDeviceRegistryProperty ERROR] > m.lcPropertyBuffer = [SetupDiGetDeviceRegistryProperty ERROR] >Else > m.lcPropertyBuffer = Left(m.lcPropertyBuffer, At(Chr(0), m.lcPropertyBuffer) - 1) >Endif > >Return m.lcPropertyBuffer >