Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Return handle to device set from SetupDiGetClassDevs
Message
From
27/09/2006 20:31:45
 
 
To
27/09/2006 14:46:04
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Environment versions
Visual FoxPro:
VFP 9
OS:
Windows XP SP2
Network:
Windows 2003 Server
Database:
MS SQL Server
Miscellaneous
Thread ID:
01157607
Message ID:
01157717
Views:
319
This message has been marked as a message which has helped to the initial question of the thread.
This works for me for storage devices (hard drives and usb drives), I am shure you will be able to see what is wrong in your code from checking this out. I think you have a couple of errors, not initializing certain structures right, the guid format maybe is wrong, etc. this code works.

I started working on this just last week!
*!* 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
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform