//可以查看按游戲手柄按鈕時的情況.
//USB接口的游戲手柄
//編譯環境:Windows 2000 server+VC++ 6.0+Win2K DDK
#include
#include
#include
#include
extern "C"
{
#include
}
void main()
{
GUID HidGuid;
// 查找本系統中HID類的GUID標識
HidD_GetHidGuid(&HidGuid);
_tprintf("系統中HID類的GUID標識為:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ",
HidGuid.Data1,HidGuid.Data2 ,HidGuid.Data3 ,
HidGuid.Data4[0],HidGuid.Data4[1],HidGuid.Data4[2],
HidGuid.Data4[3],HidGuid.Data4[4],HidGuid.Data4[5],
HidGuid.Data4[6],HidGuid.Data4[7]);
// 准備查找符合HID規范的USB設備
HDEVINFO hDevInfo = SetupDiGetClassDevs(&HidGuid,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
_tprintf("符合HID規范的USB設備發生錯誤 ");
return;
}
_tprintf("正在查找可用的USB設備... ");
DWord MemberIndex = 0;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
BOOL bSuccess = FALSE;
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
do
{
bSuccess = SetupDIEnumDeviceInterfaces(hDevInfo,
NULL,
&HidGuid,
MemberIndex,
&DeviceInterfaceData);
if ((!bSuccess) && (GetLastError() == ERROR_NO_MORE_ITEMS))
{
if(MemberIndex == 0)
_tprintf("抱歉,未找到可用的USB設備! ");
else
_tprintf("沒有更多的可用的USB設備! ");
SetupDiDestroyDeviceInfoList(hDevInfo);
return;
}
_tprintf("找到了一個USB設備: ");
//若找到了一個USB設備,則獲取該設備的細節信息
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData;
DWord Length = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo,
&DeviceInterfaceData,
NULL,
0,
&Length,
NULL);
pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //MUST BE!!!
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,
&DeviceInterfaceData,
pDeviceInterfaceDetailData,
Length,
NULL,
NULL))
_tprintf("查找路徑設備時出錯! ");
else
_tprintf("設備路徑:%s ",pDeviceInterfaceDetailData->DevicePath );
//打開設備句柄
HANDLE hDeviceHandle = CreateFile(pDeviceInterfaceDetailData->DevicePath ,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hDeviceHandle == INVALID_HANDLE_VALUE)
_tprintf("打開設備路徑出錯! ");
else
{
HIDD_ATTRIBUTES Attributes;
HidD_GetAttributes(hDeviceHandle,&Attributes);
//將有關該設備的標識顯示出來
_tprintf("供應商ID :0X%04X ",Attributes.VendorID);
_tprintf("產品ID :0X%04X ",Attributes.ProductID);
_tprintf("產品版本號:0X%04X ",Attributes.VersionNumber);
WCHAR mString[256];
TCHAR Buffer[256];
HidD_GetManufacturerString(hDeviceHandle,mString,sizeof(mString));
if (wcstombs(Buffer,mString,256) == -1) // fail
Buffer[0] = NULL;
_tprintf("生產商: %s ",Buffer);
HidD_GetProductString(hDeviceHandle,mString,sizeof(mString));
if (wcstombs(Buffer,mString,256) == -1)
Buffer[0] = NULL;
_tprintf("產品名稱: %s ",Buffer);
// 通信:
PHIDP_PREPARSED_DATA pHidpPreparsedData;
HIDP_CAPS hidPCaps;
if (!HidD_GetPreparsedData(hDeviceHandle,&pHidpPreparsedData))
{
_tprintf("獲取 HID PREPARED DATA 失敗! ");
return;
}
NTSTATUS status = HidP_GetCaps(pHidpPreparsedData,&hidPCaps);
if (status == HIDP_STATUS_SUCCESS)
{
_tprintf("CAP信息如下: ");
_tprintf(" InputReportByteLength %d ", hidPCaps.InputReportByteLength);
_tprintf(" OutputReportByteLength %d ", hidPCaps.OutputReportByteLength);
}
DWord nReadBytes = 0;
BYTE *pInputReport = new BYTE[hidPCaps.InputReportByteLength];
memset(pInputReport,0,hidPCaps.InputReportByteLength);
do
{
ReadFile(hDeviceHandle,pInputReport,hidPCaps.InputReportByteLength,&nReadBytes,NULL);
if (hidPCaps.InputReportByteLength == nReadBytes)
{
for(unsigned int i=0; i<(nReadBytes-1);i++)
_tprintf("%02x-",pInputReport[i]);
_tprintf("%02x ",pInputReport[nReadBytes-1]);
}
if (pInputReport[nReadBytes-2] == 0x20) //break the loop when pressing a specific key
{
_tprintf(" ");
break;
}
Sleep(10);
}while(hidPCaps.InputReportByteLength == nReadBytes);
//釋放句柄資源
CloseHandle(hDeviceHandle);
}
MemberIndex++;
}while(bSuccess);
SetupDiDestroyDeviceInfoList(hDevInfo);
}