Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Enumerate all devices using API
Message
From
09/10/2006 14:06:06
 
 
To
All
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Title:
Enumerate all devices using API
Environment versions
Visual FoxPro:
VFP 9
OS:
Windows XP SP2
Network:
Windows 2003 Server
Database:
MS SQL Server
Miscellaneous
Thread ID:
01160658
Message ID:
01160658
Views:
114
Finally got it working thanks to help and ideas from Carlos Alloatti and Christian Ehlscheid. I can enumerate devices. I have a form which populates a tree with all devices. Now I am working on sending/receiving data. Below is the code to enumerate all devices (working copy not pretty and still more to do but does enumerate devices) for anyone interested:
*--Goal: Enumerate all devices and read from/write to USB Device
*--Tracy C Holzer - test code
*--To do: Replace GetRegistryProperty with SetupDiGetInterfaceDeviceDetail,
*         get port number from original guid, get handle to it (passing
*         device name to createfile(), use closehandle to close device,
*         use deviceiocontrol() generate a CTL_CODE, make command packet,
*         send using deviceiocontrol() send TXPacket and read from RXPacket
*          
*        
*References:
*http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/device_interface_classes.asp
*http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/setupdienumdeviceinterfaces.asp
*UT References: UT <B>Re: Pointers in VFP?</B> Thread #1158687 Message #1159601
*Courtesy Christian Ehlscheid
*<B>Re: Return handle to device set from SetupDiGetClassDevs</B> Thread #1157607 Message #1157717
*Courtesy Carlos Alloatti

ACTIVATE screen
CLEAR
*--Below is the USB Interface Devices - not necessary for getting all devices
* cguid = [{36FC9E60-C465-11CF-8056-444553540000}]
cguid = ''      && this value passed is ignored when retrieving all classes

#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

#Define INVALID_HANDLE_VALUE		-1
#DEFINE ERROR_NO_MORE_ITEMS        259
#DEFINE ERROR_INVALID_PARAMETER     87
#DEFINE ERROR_INVALID_FLAGS       1004
#DEFINE ERROR_INSUFFICIENT_BUFFER  122
#DEFINE DIGCF_INTERFACEDEVICE       16           && 0x00000010
#DEFINE DIGCF_PRESENT                2           && 0x00000002
#define DIGCF_ALLCLASSES             4

DECLARE SHORT StrToIntEx IN Shlwapi; 
	STRING pszString, INTEGER dwFlags, INTEGER @pllRet 

DECLARE INTEGER GetLastError IN kernel32

DECLARE INTEGER SetupDiGetClassDevs IN setupapi.dll ;
    STRING @cGuid, ;
    STRING Enumerator, ;
    INTEGER hwndParent, ;
    INTEGER nFlags
    
 nflags = 0   
 Enumerator = []
 hwndParent = 0
   
DECLARE INTEGER SetupDiEnumDeviceInterfaces IN setupapi;
	INTEGER DeviceInfoSet,;
	STRING @ DeviceInfoData,;
	STRING @ ByRefterfaceClassGuid,;
	INTEGER MemberIndex,;
	STRING @ DeviceInterfaceData
	
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

sizeof = REPLICATE(' ',2048)+CHR(0)
i = 1
nInfo = REPLICATE(' ',2048)+CHR(0)
PSP_DEVINFO_DATA = []
	
lnpointer = 0

LOCAL lcinterfacedata
lnx = 0
llDestroy = .F.  && needed for cleanup

DO WHILE .T.
	lnpointer =  setupdigetclassdevs(@cGuid, NULL, 0, DIGCF_ALLCLASSES)
	IF TYPE('m.lnpointer') = "N" .AND. m.lnpointer > 0
		If m.lnpointer = INVALID_HANDLE_VALUE
			? [SetupDiGetClassDevs FAILED]
			EXIT
		Endif
		lldestroy = .T.
		? '        Handle to Device Set: '
		?? ALLTRIM(STR(lnpointer))
		lndeviceinfoset = lnpointer

		lnx = 0 && first interface is retrieved by passing 0

		m.lnRetVal = -1
		iloop = 0

		Do While m.lnRetVal <> 0

			m.lcDeviceInfoData = Padr(BinToC(28, [4RS]), 4, Chr(0)) + Replicate(Chr(0), 24)

			m.lnRetVal = SetupDiEnumDeviceInfo( ;
				m.lnDeviceInfoSet, ;
				m.lnx, ;
				@m.lcDeviceInfoData)
			
			IF m.lnRetVal = 0

				m.errvalue = getlasterror()
				?m.errvalue
				IF m.errvalue = error_no_more_items
					EXIT
				ELSE
					EXIT
				ENDIF

			ELSE

				IF m.lnRetVal = 1
					iloop = iloop + 1
					
					DIMENSION devicearray(iloop,8)
				
					&&& extract the interface data here ... (CTOBIN, SUBSTR)
					devicearray(m.iloop,1) = m.lnx
					?[Device: ], m.lnx
					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_CLASS)
					?[Property:], [CLASS: ], m.lcDeviceProperty
					devicearray(m.iloop,2) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_DEVICEDESC)
					?[Property:], [DEVICEDESC: ], m.lcDeviceProperty
					devicearray(m.iloop,3) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_ENUMERATOR_NAME)
					?[Property:], [ENUMERATOR_NAME: ], m.lcDeviceProperty
					devicearray(m.iloop,4) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_FRIENDLYNAME)
					?[Property:], [FRIENDLYNAME: ], m.lcDeviceProperty
					devicearray(m.iloop,5) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_HARDWAREID)
					?[Property:], [HARDWAREID: ], m.lcDeviceProperty
					devicearray(m.iloop,6) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_MFG)
					?[Property:], [MFG: ], m.lcDeviceProperty
					devicearray(m.iloop,7) = m.lcDeviceProperty

					m.lcDeviceProperty = GetRegistryProperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)
					?[Property:], [PHYSICAL_DEVICE_OBJECT_NAME: ], m.lcDeviceProperty
					devicearray(m.iloop,8) = m.lcDeviceProperty
								

				ENDIF
				&& increment i for next interface
				lnx = lnx + 1
			ENDIF
			IF lnx > 10000 && not likely but for testing do NOT go over this
				EXIT
			ENDIF

		ENDDO
	ELSE
		? [SetupDiGetClassDevs FAILED]
	ENDIF
	EXIT
ENDDO

? 'Found '+ALLTRIM(STR(m.lnx))+' devices.'

IF lldestroy
	*--Cleanup
	?'=================================================='
	?'Cleaning Up...'
	DECLARE INTEGER SetupDiDestroyDeviceInfoList IN setupapi;
	    INTEGER DeviceInfoSet
	llokay = SetupDiDestroyDeviceInfoList(lnpointer)
	?'        Releasing the handle - SetupDiDestroyDeviceInfoList Result: '
	?? llokay
	?'        Last Error: '
	?? GetLastError()
	
ENDIF
CLEAR DLLS
RETURN




*********************************************************************************
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"
Reply
Map
View

Click here to load this message in the networking platform