📄 usbhid.cpp
字号:
#include "/winddk/2600/inc/w2k/setupapi.h"
#include <dbt.h>
#endif
#ifdef DDK_SERVER_2003_DDK
#include "/winddk/3790/inc/w2k/initguid.h"
//#include "/winddk/3790/inc/wxp/initguid.h"
#define MAX_LOADSTRING 256
extern "C" {
#include "/winddk/3790/inc/w2k/hidsdi.h"
//#include "/winddk/3790/inc/ddk/wdm/w2k/hidsdi.h"
//#include "/winddk/3790/inc/wxp/hidsdi.h"
//#include "/winddk/3790/inc/ddk/wdm/wxp/hidsdi.h"
}
#include "/winddk/3790/inc/w2k/setupapi.h"
//#include "/winddk/3790/inc/wxp/setupapi.h"
#include <dbt.h>
#endif
static GUID HidGuid;
static HANDLE hDevInfo;
static PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
static HANDLE DeviceHandle;
static HIDD_ATTRIBUTES Attributes;
static void hid_getdevcaps(unsigned* usage,unsigned *usagepage,unsigned* inputreportlength,unsigned* outputreportlength,unsigned* featurereportlength) {
//Get the Capabilities structure for the device.
PHIDP_PREPARSED_DATA PreparsedData;
HIDP_CAPS Capabilities;
/*
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
*/
/*
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);
/*
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);
//Display the capabilities
if(usage) *usage=Capabilities.Usage;
if(usagepage) *usagepage=Capabilities.UsagePage;
if(inputreportlength) *inputreportlength=Capabilities.InputReportByteLength;
if(outputreportlength) *outputreportlength=Capabilities.OutputReportByteLength;
if(featurereportlength) *featurereportlength=Capabilities.FeatureReportByteLength;
//No need for PreparsedData any more, so free the memory it's using.
HidD_FreePreparsedData(PreparsedData);
}
int hid_open(const CWnd* pWndNotify,HANDLE* hDevNotify,HANDLE* DeviceHandleRead,HANDLE* DeviceHandleWrite,unsigned VendorID,unsigned ProductID,unsigned* versionnr,unsigned* usage,unsigned *usagepage,unsigned* inputreportlength,unsigned* outputreportlength,unsigned* featurereportlength) {
if(!DeviceHandleRead || !DeviceHandleWrite) return 0;
//Use a series of API calls to find a HID with a matching Vendor and Product ID.
if(versionnr) *versionnr=0;
/*
API function: HidD_GetHidGuid
Get the GUID for all system HIDs.
Returns: the GUID in HidGuid.
*/
HidD_GetHidGuid(&HidGuid);
DEV_BROADCAST_DEVICEINTERFACE DevHdr;
DevHdr.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE;
DevHdr.dbcc_classguid=HidGuid;
DevHdr.dbcc_name[0]=0;
DevHdr.dbcc_size=sizeof(DEV_BROADCAST_DEVICEINTERFACE);
if(hDevNotify)
*hDevNotify=RegisterDeviceNotification(pWndNotify->m_hWnd,&DevHdr,DEVICE_NOTIFY_WINDOW_HANDLE);
/*
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);
SP_DEVICE_INTERFACE_DATA devInfoData;
devInfoData.cbSize = sizeof(devInfoData);
ULONG Length = 0,Required;
detailData = NULL;
DeviceHandle=NULL;
bool MyDeviceDetected = FALSE;
int MemberIndex = 0;
LONG Result;
//Step through the available devices looking for the one we want.
//Quit on detecting the desired device or checking all available devices without success.
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.
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.
*/
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.
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) && (Attributes.ProductID == ProductID)) {
//Both the Product and Vendor IDs match.
MyDeviceDetected = TRUE;
*DeviceHandleWrite=DeviceHandle;
*DeviceHandleRead=CreateFile(detailData->DevicePath,
GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(versionnr) *versionnr=Attributes.VersionNumber;
// DisplayData("Device detected");
//Get the device's capablities.
hid_getdevcaps(usage,usagepage,inputreportlength,outputreportlength,featurereportlength);
/*
// Increase the size of the report buffers (usually not necessary).
DWORD k=0,l=0;
HidD_GetNumInputBuffers(*DeviceHandleRead,&k);
do {
l=k;
HidD_SetNumInputBuffers(*DeviceHandleRead,l*2);
HidD_GetNumInputBuffers(*DeviceHandleRead,&k);
} while(k!=l);
HidD_GetNumInputBuffers(*DeviceHandleWrite,&k);
do {
l=k;
HidD_SetNumInputBuffers(*DeviceHandleWrite,l*2);
HidD_GetNumInputBuffers(*DeviceHandleWrite,&k);
} while(k!=l);
*/
} else {
// This device doesn't match requested vendorID/productID
CloseHandle(DeviceHandle);
}
//Free the memory used by the detailData structure (no longer needed).
free(detailData);
} else {
break; //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
}
//If we haven't found the device yet, and haven't tried every available device,
//try the next one.
MemberIndex++;
} while (MyDeviceDetected == FALSE);
//Free the memory reserved for hDevInfo by SetupDiClassDevs.
SetupDiDestroyDeviceInfoList(hDevInfo);
return MyDeviceDetected?(int)DeviceHandle:0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -