Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Passing Parameters DWORD PTR using API conundrum
Message
From
10/10/2006 14:35:24
 
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Miscellaneous
Thread ID:
01160919
Message ID:
01160992
Views:
14
For me it just returns 0 and 259 (No more devices) I am getting a valid handle to pass from SetupDigetClassDevs().
See the code at the far bottom - it works (all except the small portion inside *** BEGIN Test and *** END Test Brackets).
Try this form. When prompted insert the MSTreeview and then the MS Web Browser controls
Note: I had to remove the font commands used in the web browser control because the UT wouldn't let me save this message with any style attributes inside the PRE tag.
oform = CREATEOBJECT('DeviceInfoForm')
oform.show()
read events
return

DEFINE CLASS deviceinfoForm AS form
	Height = 554
	Width = 988
	DoCreate = .T.
	ShowTips = .T.
	AutoCenter = .T.
	Caption = "System Device Information"
	WindowType = 0
	WindowState = 0
	*-- The error message. Same as MESSAGE().Same as AERROR element 2.
	message = "Select a SubCategory"
	Name = "DEVICEINFO"
	DIMENSION devicearray[1,8]


	ADD OBJECT oletreeview AS olecontrol WITH ;
		Top = 33, ;
		Left = 2, ;
		Height = 519, ;
		Width = 427, ;
		TabIndex = 4, ;
		Name = "oleTreeView"


	ADD OBJECT owb AS olecontrol WITH ;
		Top = 33, ;
		Left = 432, ;
		Height = 519, ;
		Width = 552, ;
		Name = "oWB"


	ADD OBJECT cmdclose AS commandbutton WITH ;
		Top = 0, ;
		Left = 852, ;
		Height = 32, ;
		Width = 108, ;
		Caption = "Close", ;
		TabStop = .F., ;
		Name = "cmdClose"


	ADD OBJECT cmdsystem AS commandbutton WITH ;
		Top = 0, ;
		Left = 12, ;
		Height = 32, ;
		Width = 144, ;
		Caption = "Get All System Devices", ;
		TabStop = .F., ;
		Name = "cmdSystem"


	ADD OBJECT cmdpresent AS commandbutton WITH ;
		Top = 0, ;
		Left = 168, ;
		Height = 32, ;
		Width = 144, ;
		Caption = "Get All Devices Present", ;
		TabStop = .F., ;
		Name = "cmdPresent"


	PROCEDURE filltree
		LPARAMETERS cHeading
		IF TYPE('cHeading') <> "C" .or. EMPTY(cHeading)
			cHeading = 'Results'
		ENDIF
		IF TYPE('ALEN(thisform.devicearray,1)') <> "N" .OR. ALEN(thisform.devicearray,1) = 0
			RETURN
		ENDIF

		#define tvwFirst    0 && The Node is placed before all other nodes at the same level of the node named in relative. 
		#define tvwLast     1 && The Node is placed after all other nodes at the same level of the node named in relative. Any Node added subsequently may be placed after one added as Last. 
		#define tvwNext     2 && (Default) The Node is placed after the node named in relative. 
		#define tvwPrevious 3 && The Node is placed before the node named in relative. 
		#define tvwChild    4 && The Node becomes a child node of the node named in relative.#DEFINE tvwFirst	0
		#DEFINE cnLOG_PIXELS_X     88
		#DEFINE cnLOG_PIXELS_Y     90
		#DEFINE cnTWIPS_PER_INCH 1440

		PRIVATE onode, tnode, xnode, treetopkey, parentid, childid
		THIS.oletreeview.nodes.clear()
		treetopkey = ''
		parentid = ''
		childid = ''
		WITH THIS.oletreeview.nodes
			IF treetopkey = ''
				treetopkey = '0_0'
				nodeid = treetopkey
				tnode=.ADD(,tvwFirst,treetopkey,ALLTRIM(cHeading))
				xnode = tnode
			ENDIF
			IF TYPE('tnode')="O"
				tnode.expanded = .T.
			ELSE
				RETURN
			ENDIF
			FOR icount = 1 TO ALEN(thisform.devicearray,1)
				IF TYPE('thisform.devicearray(icount,1)') <> "N"
					LOOP
				ENDIF
				*--Device ID is parent node but we will display the device class instead
				parentid = ALLTRIM(STR(icount))+":"+ALLTRIM(STR(thisform.devicearray(icount,1)))
				IF TYPE('thisform.devicearray(icount,2)') = "N"
					tnode=.ADD(,tvwFirst,parentid,ALLTRIM(STR(thisform.devicearray(icount,2))))
				ELSE
					tnode=.ADD(,tvwFirst,parentid,ALLTRIM(thisform.devicearray(icount,2)))
				ENDIF
				*--Item Specifics 2 - 8 Child Node of Device ID
				IF TYPE('thisform.devicearray(icount,1)')= "C"
					childid = parentid+":"+"1"	&& 2nd column
					tnode=.ADD(parentid,tvwChild,childid,'ID: '+ALLTRIM(thisform.devicearray(icount,1)))
				ELSE
					childid = parentid+":"+"1"	&& 2nd column
					tnode=.ADD(parentid,tvwChild,childid,'ID: '+ALLTRIM(STR(thisform.devicearray(icount,1))))
				ENDIF
				childid = parentid+":"+"3"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,3)))
				childid = parentid+":"+"4"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,4)))
				childid = parentid+":"+"5"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,5)))
				childid = parentid+":"+"6"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,6)))
				childid = parentid+":"+"7"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,7)))
				childid = parentid+":"+"8"	&& 2nd column
				tnode=.ADD(parentid,tvwChild,childid,ALLTRIM(thisform.devicearray(icount,8)))
			ENDFOR
		ENDWITH
		*--Expand the very top parent only
		IF TYPE('xnode')="O" .and. TYPE('treetopkey')="C" .and. !EMPTY(treetopkey)
			THIS.oletreeview.nodes(treetopkey).Selected=.t.
			THIS.oletreeview.nodeclick(xnode)
		ENDIF

		THISFORM.REFRESH()
		THISFORM.RESIZE()
		THISFORM.REFRESH()
		WAIT WINDOW "Finished!" NOWAIT
		RETURN .T.
	ENDPROC


	PROCEDURE stuffdevarray
                *References: UT Message #1159601 Courtesy Christian Ehlscheid
                *Message #1157717 Courtesy Carlos Alloatti
                *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
		WAIT WINDOW "Gathering Device Information..." NOWAIT TIMEOUT 30
		cguid = '' && ignored for all values
		*!*	DIGCF_ALLCLASSES 
		*!*	Return a list of installed devices for all device setup classes or all device interface classes. 
		*!*	DIGCF_DEVICEINTERFACE 
		*!*	Return devices that support device interfaces for the specified device interface classes. 
		*!*	DIGCF_DEFAULT 
		*!*	Return only the device that is associated with the system default device interface, if one is set, for the specified device interface classes. 
		*!*	DIGCF_PRESENT 
		*!*	Return only devices that are currently present in a system. 
		*!*	DIGCF_PROFILE 
		*!*	Return only devices that are a part of the current hardware profile. 
		#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_DEFAULT           0x00000001  // only valid with DIGCF_DEVICEINTERFACE
		*!*	#define DIGCF_PRESENT           0x00000002
		*!*	#define DIGCF_ALLCLASSES        0x00000004
		*!*	#define DIGCF_PROFILE           0x00000008
		*!*	#define DIGCF_DEVICEINTERFACE   0x00000010

		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.

		DO WHILE .T.
		*	lnpointer =  setupdigetclassdevs(@cGuid, NULL, 0, DIGCF_INTERFACEDEVICE)
			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

		*		DO WHILE .T.
					&& setup a SP_DEVICE_INTERFACE_DATA structure,
					&& BINTOC sets dwSize member to 28, + SPACE(24) for the
					&& rest of the structure
					*lcinterfacedata = BINTOC(28,'RS') + SPACE(24)

					*?deviceinfoset
					*?ninfo
					*?cguid
					*?lcInterfacedata

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

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

					*?m.lnRetVal
					IF m.lnRetVal = 0
		*			IF !setupdienumdeviceinterfaces(deviceinfoset, @ninfo , @cGuid, i, @lcinterfacedata)

						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 = thisform.getregistryproperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_CLASS)
							*?[Property:], [CLASS: ], m.lcDeviceProperty
							devicearray(m.iloop,2) = m.lcDeviceProperty

							m.lcDeviceProperty = thisform.getregistryproperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_DEVICEDESC)
							*?[Property:], [DEVICEDESC: ], m.lcDeviceProperty
							devicearray(m.iloop,3) = m.lcDeviceProperty
							IF TYPE('m.lcDeviceProperty') = "C"
								WAIT WINDOW ALLTRIM(STR(iloop))+' - '+m.lcDeviceProperty+'...' NOWAIT
							ENDIF

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

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

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

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

							m.lcDeviceProperty = thisform.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
						EXIT
					ENDIF

				ENDDO
			ELSE
				*? [SetupDiGetClassDevs FAILED]
			ENDIF
			EXIT
		ENDDO

		*? 'Found '+ALLTRIM(STR(m.lnx))+' devices.'
		IF TYPE('ALEN(devicearray,1)') = "N" .and. ALEN(devicearray,1) > 0
		*!*		FOR icheck = 1 TO ALEN(devicearray,1)
		*!*			IF TYPE('devicearray(Icheck,1)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,1))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column1'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,2)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,2))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 2'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,3)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,3))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 3'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,4)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,4))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 4'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,5)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,5))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 5'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,6)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,6))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 6'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,7)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,7))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 7'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,8)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,8))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 8'
		*!*			ENDIF
		*!*		ENDFOR
			DIMENSION thisform.devicearray(ALEN(devicearray,1),8)
			=ACOPY(devicearray,thisform.devicearray)
		ELSE
			DIMENSION thisform.devicearray(1,8)
			thisform.devicearray(1,1) = 'No Information Available'
			thisform.devicearray(1,2) = 'No Information Available'
			thisform.devicearray(1,3) = 'No Information Available'
			thisform.devicearray(1,4) = 'No Information Available'
			thisform.devicearray(1,5) = 'No Information Available'
			thisform.devicearray(1,6) = 'No Information Available'
			thisform.devicearray(1,7) = 'No Information Available'
			thisform.devicearray(1,8) = 'No Information Available'
		ENDIF

		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
	ENDPROC


	PROCEDURE getregistryproperty
		*********************************************************************************
		*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]
			*m.lcPropertyBuffer = [No Value Returned]
		Else
			m.lcPropertyBuffer = Left(m.lcPropertyBuffer, At(Chr(0), m.lcPropertyBuffer) - 1)
		Endif

		Return m.lcPropertyBuffer
	ENDPROC


	PROCEDURE getallpresent
		WAIT WINDOW "Gathering Device Information..." NOWAIT TIMEOUT 30
		cguid = [{36FC9E60-C465-11CF-8056-444553540000}] && All USB Device Interfaces
		*!*	DIGCF_ALLCLASSES 
		*!*	Return a list of installed devices for all device setup classes or all device interface classes. 
		*!*	DIGCF_DEVICEINTERFACE 
		*!*	Return devices that support device interfaces for the specified device interface classes. 
		*!*	DIGCF_DEFAULT 
		*!*	Return only the device that is associated with the system default device interface, if one is set, for the specified device interface classes. 
		*!*	DIGCF_PRESENT 
		*!*	Return only devices that are currently present in a system. 
		*!*	DIGCF_PROFILE 
		*!*	Return only devices that are a part of the current hardware profile. 
		#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_DEFAULT           0x00000001  // only valid with DIGCF_DEVICEINTERFACE
		*!*	#define DIGCF_PRESENT           0x00000002
		*!*	#define DIGCF_ALLCLASSES        0x00000004
		*!*	#define DIGCF_PROFILE           0x00000008
		*!*	#define DIGCF_DEVICEINTERFACE   0x00000010

		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.

		DO WHILE .T.
			lnpointer =  setupdigetclassdevs(@cGuid, NULL, 0, DIGCF_DEVICEINTERFACE)
			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

		*		DO WHILE .T.
					&& setup a SP_DEVICE_INTERFACE_DATA structure,
					&& BINTOC sets dwSize member to 28, + SPACE(24) for the
					&& rest of the structure
					*lcinterfacedata = BINTOC(28,'RS') + SPACE(24)

					*?deviceinfoset
					*?ninfo
					*?cguid
					*?lcInterfacedata

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

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

					*?m.lnRetVal
					IF m.lnRetVal = 0
		*			IF !setupdienumdeviceinterfaces(deviceinfoset, @ninfo , @cGuid, i, @lcinterfacedata)

						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 = thisform.getregistryproperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_CLASS)
							*?[Property:], [CLASS: ], m.lcDeviceProperty
							devicearray(m.iloop,2) = m.lcDeviceProperty

							m.lcDeviceProperty = thisform.getregistryproperty(m.lnDeviceInfoSet, m.lcDeviceInfoData, SPDRP_DEVICEDESC)
							*?[Property:], [DEVICEDESC: ], m.lcDeviceProperty
							devicearray(m.iloop,3) = m.lcDeviceProperty
							IF TYPE('m.lcDeviceProperty') = "C"
								WAIT WINDOW ALLTRIM(STR(iloop))+' - '+m.lcDeviceProperty+'...' NOWAIT
							ENDIF

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

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

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

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

							m.lcDeviceProperty = thisform.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
						EXIT
					ENDIF

				ENDDO
			ELSE
				*? [SetupDiGetClassDevs FAILED]
			ENDIF
			EXIT
		ENDDO

		*? 'Found '+ALLTRIM(STR(m.lnx))+' devices.'
		IF TYPE('ALEN(devicearray,1)') = "N" .and. ALEN(devicearray,1) > 0
		*!*		FOR icheck = 1 TO ALEN(devicearray,1)
		*!*			IF TYPE('devicearray(Icheck,1)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,1))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column1'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,2)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,2))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 2'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,3)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,3))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 3'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,4)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,4))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 4'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,5)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,5))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 5'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,6)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,6))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 6'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,7)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,7))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 7'
		*!*			ENDIF
		*!*			IF TYPE('devicearray(Icheck,8)') = "C" .and. 'RW420' $ UPPER(devicearray(icheck,8))
		*!*				*? 'Found RW420 in element: '+ALLTRIM(STR(icheck))+' Column 8'
		*!*			ENDIF
		*!*		ENDFOR
			DIMENSION thisform.devicearray(ALEN(devicearray,1),8)
			=ACOPY(devicearray,thisform.devicearray)
		ELSE
			DIMENSION thisform.devicearray(1,8)
			thisform.devicearray(1,1) = 'No Information Available'
			thisform.devicearray(1,2) = 'No Information Available'
			thisform.devicearray(1,3) = 'No Information Available'
			thisform.devicearray(1,4) = 'No Information Available'
			thisform.devicearray(1,5) = 'No Information Available'
			thisform.devicearray(1,6) = 'No Information Available'
			thisform.devicearray(1,7) = 'No Information Available'
			thisform.devicearray(1,8) = 'No Information Available'
		ENDIF

		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
	ENDPROC


	PROCEDURE Init
		SET SAFETY OFF
		SET TALK OFF
		_VFP.AUTOYIELD = .T.
		sysalias = ALIAS()

		IF TYPE('ddir')="U"
			PUBLIC ddir
			ddir = SYS(2003)
			IF RIGHT(ddir,1) <> "\"
				ddir = ddir + "\"
			ENDIF
		ENDIF

		*!*	IF TYPE('oSysInfo') <> "O" .OR. ISNULL(oSysInfo)
		*!*		IF !USED('SYSINFO')
		*!*			SELE 0
		*!*			USE (ddir+"SYSINFO")
		*!*			IF !USED('SYSINFO')
		*!*				=MESSAGEBOX('Unable to access system information table.')
		*!*				IF !EMPTY(sysalias) .AND. USED(sysalias)
		*!*					SELECT (sysalias)
		*!*				ENDIF
		*!*				RETURN .F.
		*!*			ENDIF
		*!*		ENDIF
		*!*	ELSE
		*!*		IF !USED('SYSINFO')
		*!*			oSysInfo.setup()
		*!*		ENDIF
		*!*		oSysInfo.verify()
		*!*		*--Popuser is done only if forced refresh is set here or if blank
		*!*		*--Popcommon is always done here when loading this form
		*!*		oSysInfo.popcommon()
		*!*		oSysInfo.popuser()
		*!*	ENDIF

		*!*	SELE sysinfo
		*!*	SET ORDER TO TAG callfields
		*!*	GO TOP
		*!*	IF EOF('SYSINFO')
		*!*		=MESSAGEBOX('There are no records to view.')
		*!*		IF !EMPTY(sysalias) .AND. USED(sysalias)
		*!*			SELECT (sysalias)
		*!*		ENDIF
		*!*		RETURN .F.
		*!*	ENDIF

		*!*	SELE SysInfo

		DODEFAULT()

		IF TYPE("THIS.oleTreeView") # "O" OR ISNULL(THIS.oletreeview)
			RETURN .F.
		ENDIF

		WITH THIS.oletreeview
			.linestyle =1
			.labeledit =1
			.indentation = 5
			.PathSeparator = '\'
			.SCROLL = .T.
			.OLEDRAGMODE = 0
			.OLEDROPMODE = 0
		ENDWITH

		WITH THISFORM.oWB
			.Navigate("about:blank")
			lnStartSeconds = SECONDS()
			DO WHILE .ReadyState <> 4 ;
					AND (SECONDS()-lnStartSeconds <= 1 )
				DOEVENTS
			ENDDO
			.DOCUMENT.OPEN()
			.Document.Write('')
			.DOCUMENT.CLOSE()
		ENDWITH

		this.refresh()
		thisform.stuffdevarray()
		thisform.filltree('All System Devices')
		WAIT CLEAR
	ENDPROC


	PROCEDURE QueryUnload
		IF TYPE('oSysInfo') <> "O" .OR. ISNULL(oSysInfo)
			IF USED('SYSINFO')
				USE IN SYSINFO
			ENDIF
		ELSE
			oSysInfo.cleanup()
		ENDIF
		RETURN .T.
	ENDPROC


	PROCEDURE Unload
		CLEAR EVENTS
		DODEFAULT()
	ENDPROC


	PROCEDURE oletreeview.NodeClick
		*** ActiveX Control Event ***
		LPARAMETERS NODE

		NODE.ensurevisible
		IF '0_0' $ NODE.KEY .AND. ALEN(THISFORM.devicearray,1) > 0
			WITH THISFORM.oWB
				.NAVIGATE("about:blank")
				lnStartSeconds = SECONDS()
				DO WHILE .ReadyState <> 4 ;
						AND (SECONDS()-lnStartSeconds <= 1 )
					DOEVENTS
				ENDDO
				.DOCUMENT.OPEN()
				.DOCUMENT.WRITE('Click on any item for more information'+chr(13)+chr(13))
				.DOCUMENT.CLOSE()
			ENDWITH
		ELSE

			IF INT(VAL(LEFT(NODE.KEY,AT(":",NODE.KEY)-1))) > 0
				lnpos = INT(VAL(LEFT(NODE.KEY,AT(":",NODE.KEY)-1)))
				WITH THISFORM.oWB
					.NAVIGATE("about:blank")
					lnStartSeconds = SECONDS()
					DO WHILE .ReadyState <> 4 ;
							AND (SECONDS()-lnStartSeconds <= 1 )
						DOEVENTS
					ENDDO
					IF lnpos > 0
						.DOCUMENT.OPEN()
						myvalue = 'CLASS: '+THISFORM.devicearray(lnpos,2)+chr(13)+chr(13)
						myvalue = myvalue + 'DEVICE DESCRIPTION: '+THISFORM.devicearray(lnpos,3)+chr(13)+chr(13)
						myvalue = myvalue + 'ENUMERATOR NAME: '+THISFORM.devicearray(lnpos,4)+chr(13)+chr(13)
						myvalue = myvalue + 'FRIENDLY NAME: '+THISFORM.devicearray(lnpos,5)+chr(13)+chr(13)
						myvalue = myvalue + 'HARDWARE ID: '+THISFORM.devicearray(lnpos,6)+chr(13)+chr(13)
						myvalue = myvalue + 'MFG: '+THISFORM.devicearray(lnpos,7)+chr(13)+chr(13)
						myvalue = myvalue + 'PHYSICAL DEVICE OBJECT NAME: '+THISFORM.devicearray(lnpos,8)+chr(13)+chr(13)
						.DOCUMENT.WRITE(myvalue)
						.DOCUMENT.CLOSE()
					ELSE
						.DOCUMENT.OPEN()
						.DOCUMENT.WRITE('No Additional Information Available'+chr(13)+chr(13))
						.DOCUMENT.CLOSE()
					ENDIF
				ENDWITH
			ELSE
				WITH THISFORM.oWB
					.NAVIGATE("about:blank")
					lnStartSeconds = SECONDS()
					DO WHILE .ReadyState <> 4 ;
							AND (SECONDS()-lnStartSeconds <= 1 )
						DOEVENTS
					ENDDO
					.DOCUMENT.OPEN()
					.DOCUMENT.WRITE('No Additional Information Available'+chr(13)+chr(13))
					.DOCUMENT.CLOSE()
				ENDWITH
			ENDIF

		ENDIF
	ENDPROC


	PROCEDURE oletreeview.NodeCheck
		*** ActiveX Control Event ***
		LPARAMETERS node
	ENDPROC


	PROCEDURE owb.Refresh
		*** ActiveX Control Method ***
		NODEFAULT
	ENDPROC


	PROCEDURE cmdclose.Click
		IF THISFORM.queryunload()
			thisform.release()
		ENDIF
	ENDPROC


	PROCEDURE cmdsystem.Click
		thisform.stuffdevarray()
		thisform.filltree('All System Devices')
		WAIT CLEAR
	ENDPROC


	PROCEDURE cmdpresent.Click
		wait WINDOW "Clearing Results..." NOWAIT TIMEOUT 30
		THISFORM.oletreeview.nodes.clear()
		doevents
		thisform.refresh()
		thisform.getallpresent()
		thisform.filltree('All Devices Present')
		WAIT CLEAR
	ENDPROC


ENDDEFINE
Try this Program (works all the way until we get to SetupDiEnumDeviceInterfaces()
*References: UT Message #1159601 Courtesy Christian Ehlscheid
*Message #1157717 Courtesy Carlos Alloatti
*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 SetupDiEnumDeviceInterfaces IN setupapi;
	INTEGER DeviceInfoSet,;
	STRING @ DeviceInfoData,;
	STRING @ ByRefterfaceClassGuid,;
	INTEGER MemberIndex,;
	STRING @ DeviceInterfaceData

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

*** BEGIN Test Portion
	m.lcDeviceInfoData = Padr(BinToC(28, [4RS]), 4, Chr(0)) + Replicate(Chr(0), 24)
	m.lnx = 0
	*--Try the setupdienumdeviceinterfaces() instead 
	m.lcDeviceInterfaceData = Padr(BinToC(28, [4RS]), 4, Chr(0)) + Replicate(Chr(0), 24)
	m.lcDeviceInterfaceData = CHR(32)+CHR(0)+CHR(0)+CHR(0) &&dword only
	m.lcDeviceInterfaceData = long2str(32)+REPLICATE(CHR(0),28)
	m.lcDeviceInterfaceData = num2dword(32)+num2dword(0)+num2dword(0)+ ;
		num2dword(0)+num2dword(0)
	m.returnvalue =  SetupDiEnumDeviceInterfaces( ;
		m.lnDeviceInfoSet, ;
		@m.lcDeviceInfoData, ;
		@m.lcClassGuid, ;
		m.lnx,;
		@m.lcDeviceInterfaceData)
					
	IF m.returnvalue <> 0
	    ? [Success with SetupDiEnumDeviceInterfaces()]				
	ELSE
	    ? [Failure with SetupDiEnumDeviceInterfaces()]
	    m.errvalue = getlasterror()
	    ?m.errvalue
	    IF m.errvalue = error_no_more_items
	    ELSE
	    ENDIF
	ENDIF
*** END Test Portion

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


FUNCTION long2str
PARAMETERS m.longval
PRIVATE i, m.retstr
m.retstr = ""
FOR i = 24 TO 0 STEP -8
   m.retstr = CHR(INT(m.longval/(2^i))) + m.retstr
   m.longval = MOD(m.longval, (2^i))
ENDFOR
RETURN m.retstr


FUNCTION str2long
PARAMETERS m.longstr
PRIVATE i, m.retval
m.retval = 0
FOR i = 0 TO 24 STEP 8
   m.retval = m.retval + (ASC(m.longstr) * (2^i))
   m.longstr = RIGHT(m.longstr, LEN(m.longstr) - 1)
NEXT
RETURN m.retval

FUNCTION  num2dword (lnValue)
#DEFINE m0       256
#DEFINE m1     65536
#DEFINE m2  16777216
	LOCAL b0, b1, b2, b3
	b3 = Int(lnValue/m2)
	b2 = Int((lnValue - b3 * m2)/m1)
	b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
	b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)

FUNCTION  num2word (lnValue)
RETURN Chr(Mod(m.lnValue,256)) + Chr(Int(m.lnValue/256)) 
.·*´¨)
.·`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
Reply
Map
View

Click here to load this message in the networking platform