T
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