USB finden



  • Hi

    ich soll ein programm schreiben, das testen soll ob ein usb device mit einer angegebenen VendorID und ProductID existiert oder nicht. bzw darauf wartet ob es gesteckt oder gezogen wird.

    Gibt es eine einfachere möglichkeit als den ganzen USB bus (baum) von den Roothubs aus aubzuskannen?

    gruss Termite



  • man schreibt.. "abzuscannen"

    mfG (c)h



  • cool chille! das hats jetzt echt gebraucht..
    wenn wir solche leute nicht hätten, die auf unsere schöne deutsche sprache aufpassen..
    hey, ich glaub, das ich würde bald selbstmord begehen..
    dir muss man echt einen orden verleihen:

    => RETTER DER DEUTSCHEN SPRACHE <=

    :live:    :live:    :live:
    


  • aber ob "scannen" nun wirklich DEUTSCH ist 🙄 , oder aus dem Englischen kommt :p ...

    mfG (c)h



  • Statt euch über Deutsch zu streiten, postet mal lieber eine Lösung!



  • *gg* würde ich ja wirklich sehr sehr gerne machen, wenn...
    ... ich eine Lösung wüsste 😃 😃 😃

    sorry, aber WinAPI ist nicht mein Spezialgebiet...

    mfG (c)h



  • Ja meins auch nicht 🙄 ,
    wüsste aber trotzdem gerne wie es geht!

    MfG,
    C+ Core



  • Nachdem du dich in Bezug auf das Gerät sehr zurückhälst, hier ein Beispielcode,
    um ein HID Device zu finden. Die HID Struktur bezieht sich hier nicht auf
    Keyboards oder Mäuse !!
    Es handelt sich um den Beispielcode der HIDPAGE. Der interressante Teil dürfte
    für dich wohl die Funktion FindTheHID sein ??

    bool CUsbhidiocDlg::FindTheHID()
    {
    	//Use a series of API calls to find a HID with a matching Vendor and Product ID.
    
    	HIDD_ATTRIBUTES						Attributes;
    	SP_DEVICE_INTERFACE_DATA			devInfoData;
    	bool								LastDevice = FALSE;
    	int									MemberIndex = 0;
    	bool								MyDeviceDetected = FALSE; 
    	LONG								Result;
    
    	//These are the vendor and product IDs to look for.
    	//Uses Lakeview Research's Vendor ID.
    	const unsigned int VendorID = 0x04D8;
    	const unsigned int ProductID = 0x1110;
    
    	Length = 0;
    	detailData = NULL;
    	DeviceHandle=NULL;
    
    	/*
    	API function: HidD_GetHidGuid
    	Get the GUID for all system HIDs.
    	Returns: the GUID in HidGuid.
    	*/
    
    	HidD_GetHidGuid(&HidGuid);	
    
    	/*
    	API function: SetupDiGetClassDevs
    	Returns: a handle to a device information set for all installed devices.
    	Requires: the GUID returned by GetHidGuid.
    	*/
    
    	hDevInfo=SetupDiGetClassDevs 
    		(&HidGuid, 
    		NULL, 
    		NULL, 
    		DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
    
    	devInfoData.cbSize = sizeof(devInfoData);
    
    	//Step through the available devices looking for the one we want. 
    	//Quit on detecting the desired device or checking all available devices without success.
    	MemberIndex = 0;
    	LastDevice = FALSE;
    
    	do
    	{
    		MyDeviceDetected=FALSE;
    
    		/*
    		API function: SetupDiEnumDeviceInterfaces
    		On return, MyDeviceInterfaceData contains the handle to a
    		SP_DEVICE_INTERFACE_DATA structure for a detected device.
    		Requires:
    		The DeviceInfoSet returned in SetupDiGetClassDevs.
    		The HidGuid returned in GetHidGuid.
    		An index to specify a device.
    		*/
    
    		Result=SetupDiEnumDeviceInterfaces 
    			(hDevInfo, 
    			0, 
    			&HidGuid, 
    			MemberIndex, 
    			&devInfoData);
    
    		if (Result != 0)
    		{
    			//A device has been detected, so get more information about it.
    
    			/*
    			API function: SetupDiGetDeviceInterfaceDetail
    			Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
    			containing information about a device.
    			To retrieve the information, call this function twice.
    			The first time returns the size of the structure in Length.
    			The second time returns a pointer to the data in DeviceInfoSet.
    			Requires:
    			A DeviceInfoSet returned by SetupDiGetClassDevs
    			The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
    
    			The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
    			This application doesn't retrieve or use the structure.			
    			If retrieving the structure, set 
    			MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
    			and pass the structure's address.
    			*/
    
    			//Get the Length value.
    			//The call will return with a "buffer too small" error which can be ignored.
    			Result = SetupDiGetDeviceInterfaceDetail 
    				(hDevInfo, 
    				&devInfoData, 
    				NULL, 
    				0, 
    				&Length, 
    				NULL);
    
    			//Allocate memory for the hDevInfo structure, using the returned Length.
    			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
    
    			//Set cbSize in the detailData structure.
    			detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
    			//Call the function again, this time passing it the returned buffer size.
    			Result = SetupDiGetDeviceInterfaceDetail 
    				(hDevInfo, 
    				&devInfoData, 
    				detailData, 
    				Length, 
    				&Required, 
    				NULL);
    
    			//Open a handle to the device.
    
    			/*
    			API function: CreateFile
    			Returns: a handle that enables reading and writing to the device.
    			Requires:
    			The DevicePath in the detailData structure
    			returned by SetupDiGetDeviceInterfaceDetail.
    			*/
    
    			DeviceHandle=CreateFile 
    				(detailData->DevicePath, 
    				GENERIC_READ|GENERIC_WRITE, 
    				FILE_SHARE_READ|FILE_SHARE_WRITE, 
    				(LPSECURITY_ATTRIBUTES)NULL,
    				OPEN_EXISTING, 
    				0, 
    				NULL);
    
    			DisplayLastError("CreateFile: ");
    
    			/*
    			API function: HidD_GetAttributes
    			Requests information from the device.
    			Requires: the handle returned by CreateFile.
    			Returns: a HIDD_ATTRIBUTES structure containing
    			the Vendor ID, Product ID, and Product Version Number.
    			Use this information to decide if the detected device is
    			the one we're looking for.
    			*/
    
    			//Set the Size to the number of bytes in the structure.
    			Attributes.Size = sizeof(Attributes);
    
    			Result = HidD_GetAttributes 
    				(DeviceHandle, 
    				&Attributes);
    
    			DisplayLastError("HidD_GetAttributes: ");
    
    			//Is it the desired device?
    			MyDeviceDetected = FALSE;
    
    			if (Attributes.VendorID == VendorID)
    			{
    				if (Attributes.ProductID == ProductID)
    				{
    					//Both the Product and Vendor IDs match.
    					MyDeviceDetected = TRUE;
    					DisplayData("Device detected");
    					//Get the device's capablities.
    					GetDeviceCapabilities();
    					PrepareForOverlappedTransfer();
    				} //if (Attributes.ProductID == ProductID)
    
    				else
    					//The Product ID doesn't match.
    					CloseHandle(DeviceHandle);
    			} //if (Attributes.VendorID == VendorID)
    
    			else
    				//The Vendor ID doesn't match.
    				CloseHandle(DeviceHandle);
    
    		//Free the memory used by the detailData structure (no longer needed).
    		free(detailData);
    		}  //if (Result != 0)
    
    		else
    			//SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
    			LastDevice=TRUE;
    
    		//If we haven't found the device yet, and haven't tried every available device,
    		//try the next one.
    		MemberIndex = MemberIndex + 1;
    
    	} //do
    	while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
    
    	if (MyDeviceDetected == FALSE)
    		DisplayData("Device not detected");
    	else
    		DisplayData("Device detected");
    
    	//Free the memory reserved for hDevInfo by SetupDiClassDevs.
    	SetupDiDestroyDeviceInfoList(hDevInfo);
    	DisplayLastError("SetupDiDestroyDeviceInfoList");
    
    	return MyDeviceDetected;
    }
    
    void CUsbhidiocDlg::GetDeviceCapabilities()
    {
    	//Get the Capabilities structure for the device.
    	PHIDP_PREPARSED_DATA	PreparsedData;
    
    	/*
    	API function: HidD_GetPreparsedData
    	Returns: a pointer to a buffer containing the information about the device's capabilities.
    	Requires: A handle returned by CreateFile.
    	There's no need to access the buffer directly,
    	but HidP_GetCaps and other API functions require a pointer to the buffer.
    	*/
    
    	HidD_GetPreparsedData 
    		(DeviceHandle, 
    		&PreparsedData);
    	DisplayLastError("HidD_GetPreparsedData: ");
    
    	/*
    	API function: HidP_GetCaps
    	Learn the device's capabilities.
    	For standard devices such as joysticks, you can find out the specific
    	capabilities of the device.
    	For a custom device, the software will probably know what the device is capable of,
    	and the call only verifies the information.
    	Requires: the pointer to the buffer returned by HidD_GetPreparsedData.
    	Returns: a Capabilities structure containing the information.
    	*/
    
    	HidP_GetCaps 
    		(PreparsedData, 
    		&Capabilities);
    	DisplayLastError("HidP_GetCaps: ");
    
    	//Display the capabilities
    
    	ValueToDisplay.Format("%s%X", "Usage Page: ", Capabilities.UsagePage);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Input Report Byte Length: ", Capabilities.InputReportByteLength);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Output Report Byte Length: ", Capabilities.OutputReportByteLength);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Feature Report Byte Length: ", Capabilities.FeatureReportByteLength);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Link Collection Nodes: ", Capabilities.NumberLinkCollectionNodes);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Input Button Caps: ", Capabilities.NumberInputButtonCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of InputValue Caps: ", Capabilities.NumberInputValueCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of InputData Indices: ", Capabilities.NumberInputDataIndices);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Output Button Caps: ", Capabilities.NumberOutputButtonCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Output Value Caps: ", Capabilities.NumberOutputValueCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Output Data Indices: ", Capabilities.NumberOutputDataIndices);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Feature Button Caps: ", Capabilities.NumberFeatureButtonCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Feature Value Caps: ", Capabilities.NumberFeatureValueCaps);
    	DisplayData(ValueToDisplay);
    	ValueToDisplay.Format("%s%d", "Number of Feature Data Indices: ", Capabilities.NumberFeatureDataIndices);
    	DisplayData(ValueToDisplay);
    
    	//No need for PreparsedData any more, so free the memory it's using.
    	HidD_FreePreparsedData(PreparsedData);
    	DisplayLastError("HidD_FreePreparsedData: ") ;
    }
    
    void CUsbhidiocDlg::PrepareForOverlappedTransfer()
    {
    	//Get another handle to the device for the overlapped ReadFiles.
    	ReadHandle=CreateFile 
    		(detailData->DevicePath, 
    		GENERIC_READ|GENERIC_WRITE, 
    		FILE_SHARE_READ|FILE_SHARE_WRITE,
    		(LPSECURITY_ATTRIBUTES)NULL, 
    		OPEN_EXISTING, 
    		FILE_FLAG_OVERLAPPED, 
    		NULL);
    	DisplayLastError("CreateFile (ReadHandle): ");
    
    	//Get an event object for the overlapped structure.
    
    	/*API function: CreateEvent
    	Requires:
    	  Security attributes or Null
    	  Manual reset (true). Use ResetEvent to set the event object's state to non-signaled.
    	  Initial state (true = signaled) 
    	  Event object name (optional)
    	Returns: a handle to the event object
    	*/
    
    	if (hEventObject == 0)
    	{
    		hEventObject = CreateEvent 
    			(NULL, 
    			TRUE, 
    			TRUE, 
    			"");
    	DisplayLastError("CreateEvent: ") ;
    
    	//Set the members of the overlapped structure.
    	HIDOverlapped.hEvent = hEventObject;
    	HIDOverlapped.Offset = 0;
    	HIDOverlapped.OffsetHigh = 0;
    	}
    }
    
    void CUsbhidiocDlg::ReadAndWriteToDevice()
    {
    	//If we haven't done so already, find the device and learn its capabilities.
    	//Then send a report and request a report.
    	//The test device firmware (usbhidio) adds 1 to each byte received in an OUT report
    	//and sends the results back in the next IN report.
    
    	//Clear the List Box (optional).
    	//m_ResultsList.ResetContent();
    
    	{
    	DisplayData("***HID Test Report***");
    	DisplayCurrentTime();
    
    	//If the device hasn't been detected already, look for it.
    	if (DeviceDetected==FALSE)
    		DeviceDetected=FindTheHID();
    
    	if (DeviceDetected==TRUE)
    		{
    			//Write a report to the device.
    			WriteReport();
    			//Read a report from the device.
    			ReadReport();
    		} 
    	}
    }
    
    void CUsbhidiocDlg::ReadReport()
    {
    	CString	ByteToDisplay = "";
    	CString	MessageToDisplay = "";
    	DWORD	Result;
    
    	//Read a report from the device.
    
    	/*API call:ReadFile
    	'Returns: the report in InputReport.
    	'Requires: a device handle returned by CreateFile
    	'(for overlapped I/O, CreateFile must be called with FILE_FLAG_OVERLAPPED),
    	'the Input report length in bytes returned by HidP_GetCaps,
    	'and an overlapped structure whose hEvent member is set to an event object.
    	*/
    
    	Result = ReadFile 
    		(ReadHandle, 
    		InputReport, 
    		Capabilities.InputReportByteLength, 
    		&NumberOfBytesRead,
    		(LPOVERLAPPED) &HIDOverlapped); 
    
    	DisplayLastError("ReadFile: ") ;
    
    	/*API call:WaitForSingleObject
    	'Used with overlapped ReadFile.
    	'Returns when ReadFile has received the requested amount of data or on timeout.
    	'Requires an event object created with CreateEvent
    	'and a timeout value in milliseconds.
    	*/
    
    	Result = WaitForSingleObject 
    		(hEventObject, 20000);
    	DisplayLastError("WaitForSingleObject: ") ;
    
    	switch (Result)
    	{
    	case WAIT_OBJECT_0:
    		{
    		ValueToDisplay.Format("%s", "ReadFile Completed");
    		DisplayData(ValueToDisplay);
    		break;
    		}
    	case WAIT_TIMEOUT:
    		{
    		ValueToDisplay.Format("%s", "ReadFile timeout");
    		DisplayData(ValueToDisplay);
    		//Cancel the Read operation.
    
    		/*API call: CancelIo
    		Cancels the ReadFile
            Requires the device handle.
            Returns non-zero on success.
    		*/
    
    		Result = CancelIo(ReadHandle);
    
    		//A timeout may mean that the device has been removed. 
    		//Close the device handles and set DeviceDetected = False 
    		//so the next access attempt will search for the device.
    		CloseHandle(ReadHandle);
    		CloseHandle(DeviceHandle);
    		DisplayData("Can't read from device");
    		DeviceDetected = FALSE;
    		break;
    	default:
    		ValueToDisplay.Format("%s", "Undefined error");
    		break;
    		}
    	}
    
    	/*
    	API call: ResetEvent
    	Sets the event object to non-signaled.
    	Requires a handle to the event object.
    	Returns non-zero on success.
    	*/
    
    	ResetEvent(hEventObject);
    
    	//Display the report data.
    	DisplayInputReport();
    }
    
    void CUsbhidiocDlg::WriteReport()
    {
    	//Send a report to the device.
    
    	//The maximum size of an output report. (This can be increased).
    	const unsigned short int	MAXREPORTSIZE = 256;
    
    	DWORD	BytesWritten = 0;
    	INT		Index =0;
    	CHAR	OutputReport[MAXREPORTSIZE];
    	ULONG	Result;
    	CString	strBytesWritten = "";
    
    	//The first byte is the report number.
    	OutputReport[0]=0;
    
    	//Can set the other report values here, or get them from the combo boxes.
    	//OutputReport[1]=33;
    	//OutputReport[2]=6;
    	//OutputReport[3]=15;
    
    	//Get the bytes to send from the combo boxes.
    
    	//If Autoincrement is checked, increment the selection.
    	if (m_cbutAutoIncrement.GetCheck()>0)
    	{
    		Index=m_cboByteToSend0.GetCurSel();
    		Index=Index+1;
    		m_cboByteToSend0.SetCurSel(Index);
    	}
    
    	if (m_cbutAutoIncrement.GetCheck()>0)
    	{
    		Index=m_cboByteToSend1.GetCurSel();
    		Index=Index+1;
    		m_cboByteToSend1.SetCurSel(Index);
    	}
    
    	//Get the values from the combo boxes.
    	OutputReport[1]=m_cboByteToSend0.GetCurSel();
    	OutputReport[2]=m_cboByteToSend1.GetCurSel();
    
    	/*
    	API Function: WriteFile
    	Sends a report to the device.
    	Returns: success or failure.
    	Requires:
    	The device handle returned by CreateFile.
    	The Output Report length returned by HidP_GetCaps,
    	A report to send.
    	*/
    
    }
    

    Den dritten Parameter kann man hier ebenfalls mit einfügen:
    Attributes.VersionNumber ...

    Viel Glück


Anmelden zum Antworten