Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Return handle to device set from SetupDiGetClassDevs
Message
From
29/09/2006 10:32:54
 
 
To
27/09/2006 20:31:45
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:
01158131
Views:
213
Thank you Carlos, yes it helps alot. I cannot believe you found that link at MSFT - I swear I searched all of MSFT (and even sent emails to MSFT Employees) looking for more examples of enumerating devices using the setupapi.dll (in any language) and never found that MSFT link.

Thanks again!
Tracy


>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
>
.·*´¨)
.·`TCH
(..·*

010000110101001101101000011000010111001001110000010011110111001001000010011101010111001101110100
"When the debate is lost, slander becomes the tool of the loser." - Socrates
Vita contingit, Vive cum eo. (Life Happens, Live With it.)
"Life is not measured by the number of breaths we take, but by the moments that take our breath away." -- author unknown
"De omnibus dubitandum"
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform