246 lines
6.8 KiB
C
246 lines
6.8 KiB
C
/***************************************************************************
|
||
* 描 述: USBHID设备驱动代码
|
||
* 作 者: 詹力
|
||
* 时 间: 2016/10/29
|
||
***************************************************************************/
|
||
#include <Windows.h>
|
||
#include <Dbt.h>
|
||
#include <hidsdi.h>
|
||
#include <SetupAPI.h>
|
||
#include <stdio.h>
|
||
#include <usbioctl.h>
|
||
|
||
#include "USB_Win32_HIDDevice.h"
|
||
#include "MagCalibrate.h"
|
||
#include "SensorImpl.h"
|
||
|
||
#pragma comment(lib,"setupapi.lib")
|
||
#pragma comment(lib, "hid.lib")
|
||
|
||
unsigned char usb_output_buffer[65];
|
||
unsigned char usb_input_buffer[256];
|
||
unsigned char usb_feature_report_buffer[256];
|
||
|
||
unsigned char buffer[255];
|
||
/* 主函数,程序的入口 */
|
||
|
||
HANDLE dematrix_usb_handle = INVALID_HANDLE_VALUE;
|
||
HDEVINFO device_info_set;
|
||
GUID HidGuid;
|
||
SP_DEVICE_INTERFACE_DATA device_interface_data;
|
||
HIDP_CAPS dematrix_device_capabilities;
|
||
|
||
HANDLE DM_HID_Read_HANDLE;
|
||
HANDLE DM_HID_Write_HANDLE;
|
||
|
||
int i=5;
|
||
BOOL device_is_found;
|
||
OVERLAPPED usb_read_over_lapped;
|
||
PSP_DEVICE_INTERFACE_DETAIL_DATA pData;
|
||
|
||
|
||
BOOL HIDFindDeviceFromVendor(USHORT PID,USHORT VID,CHAR *Path)
|
||
{
|
||
HANDLE DM_USB_HANDLE;
|
||
HIDD_ATTRIBUTES Dev_Attr;
|
||
|
||
Dev_Attr.Size = sizeof(Dev_Attr);
|
||
|
||
DM_USB_HANDLE = CreateFileA(Path, (DWORD)NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||
OPEN_EXISTING, (DWORD)NULL, NULL);
|
||
if(DM_USB_HANDLE != INVALID_HANDLE_VALUE)
|
||
{
|
||
if (HidD_GetAttributes(DM_USB_HANDLE, &Dev_Attr) == FALSE) return FALSE;
|
||
|
||
HidD_GetNumInputBuffers(DM_USB_HANDLE, &i);
|
||
//printf("BufferSize[%d]\n",i);
|
||
dematrix_usb_get_capabilities(DM_USB_HANDLE);
|
||
//printf("Cap.out.length[%d]\n", dematrix_device_capabilities.OutputReportByteLength);
|
||
//printf("(PID=%x,VID=%x,VersionTest=%x)\n", Dev_Attr.ProductID, Dev_Attr.VendorID, Dev_Attr.VersionNumber);
|
||
if (Dev_Attr.ProductID == PID && Dev_Attr.VendorID == VID)
|
||
{
|
||
//printf("(PID=%x,VID=%x,VersionTest=%x)\n", Dev_Attr.ProductID, Dev_Attr.VendorID, Dev_Attr.VersionNumber);
|
||
return TRUE;
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
BOOL InitPathFromInterfaceData(HDEVINFO hdevInfoSet, SP_DEVICE_INTERFACE_DATA* pidata)
|
||
{
|
||
DWORD detailSize = 0;
|
||
BOOL Result;
|
||
|
||
Result = SetupDiGetDeviceInterfaceDetail(hdevInfoSet,pidata, NULL, (DWORD)NULL, &detailSize, NULL);
|
||
|
||
pData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(detailSize);
|
||
if (pData == NULL){
|
||
printf("内存不足!\n");
|
||
SetupDiDestroyDeviceInfoList(hdevInfoSet);
|
||
return FALSE;
|
||
}
|
||
pData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||
|
||
Result = SetupDiGetDeviceInterfaceDetail(hdevInfoSet, pidata, pData, detailSize, NULL, NULL);
|
||
if(Result==TRUE)
|
||
{
|
||
//printf("Path = %s\n",(char *)(pData->DevicePath));
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
/*给定USB设备,对USB设备进行枚举,如果PID和VID都符合,就打开USB设备并创建句柄*/
|
||
BOOL DM_HIDDeviceEnumerate(USHORT PID,USHORT VID)
|
||
{
|
||
HDEVINFO hdevInfoSet;
|
||
SP_DEVICE_INTERFACE_DATA interfaceData;
|
||
|
||
|
||
int deviceIndex = 0;
|
||
interfaceData.cbSize = sizeof(interfaceData);
|
||
|
||
/* 先取得GUID */
|
||
HidD_GetHidGuid(&HidGuid);
|
||
|
||
hdevInfoSet = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_INTERFACEDEVICE | DIGCF_PRESENT);
|
||
|
||
if (hdevInfoSet == INVALID_HANDLE_VALUE) return FALSE;
|
||
|
||
for(deviceIndex = 0;
|
||
SetupDiEnumDeviceInterfaces(hdevInfoSet, NULL, &HidGuid, deviceIndex, &interfaceData);
|
||
deviceIndex++)
|
||
{
|
||
//printf("index = %d\n",deviceIndex);
|
||
|
||
if (!InitPathFromInterfaceData(hdevInfoSet, &interfaceData))
|
||
continue;
|
||
// 下面的函数需要路径
|
||
if(HIDFindDeviceFromVendor(PID,VID,(CHAR*)(pData->DevicePath)))
|
||
{
|
||
//printf("Path = %s\n",(char *)(pData->DevicePath));
|
||
|
||
DM_HID_Read_HANDLE = CreateFileA((char *)(pData->DevicePath), (DWORD)GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |
|
||
FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||
|
||
DM_HID_Write_HANDLE = CreateFileA((char *)(pData->DevicePath), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
(LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
|
||
|
||
|
||
device_is_found = TRUE;
|
||
SetEvent(usb_read_over_lapped.hEvent);
|
||
printf("打开设备成功!\n");
|
||
break;
|
||
}else
|
||
continue;
|
||
}
|
||
SetupDiDestroyDeviceInfoList(hdevInfoSet);
|
||
|
||
if(device_is_found==TRUE)return TRUE;
|
||
else
|
||
return FALSE;
|
||
}
|
||
|
||
void USB_HID_Init()
|
||
{
|
||
//初始化读报告时用的Overlapped结构体
|
||
//偏移量设置为0
|
||
usb_read_over_lapped.Offset = 0;
|
||
usb_read_over_lapped.OffsetHigh = 0;
|
||
//创建一个事件,提供给ReadFile使用,当ReadFile完成时,
|
||
//会设置该事件为触发状态。
|
||
usb_read_over_lapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
||
start_thread(dematrix_usb_private_read_thread, NULL);
|
||
}
|
||
|
||
|
||
|
||
int globalpacklen = 0;
|
||
DWORD dematrix_usb_private_read_thread(LPVOID param)
|
||
{
|
||
DWORD length;
|
||
|
||
//该线程是个死循环,直到程序退出时,它才退出
|
||
while (1)
|
||
{
|
||
//设置事件为无效状态
|
||
ResetEvent(usb_read_over_lapped.hEvent);
|
||
|
||
//如果设备已经找到
|
||
if (device_is_found == TRUE)
|
||
{
|
||
|
||
if (DM_HID_Read_HANDLE == INVALID_HANDLE_VALUE) {
|
||
printf("无效的读报告句柄,可能是打开设备时失败");
|
||
}
|
||
else {
|
||
|
||
CancelIo(DM_HID_Read_HANDLE);
|
||
// DKHD2这里使用62,DK2一定要使用64,否则无法读取数据
|
||
ReadFile(DM_HID_Read_HANDLE, usb_input_buffer,globalpacklen, NULL, &usb_read_over_lapped);
|
||
}
|
||
|
||
//等待事件触发
|
||
WaitForSingleObject(usb_read_over_lapped.hEvent, INFINITE);
|
||
|
||
//如果等待过程中设备被拔出,也会导致事件触发,但此时MyDevFound
|
||
//被设置为假,因此在这里判断MyDevFound为假的话就进入下一轮循环。
|
||
if (device_is_found == FALSE) continue;
|
||
|
||
//如果设备没有被拔下,则是ReadFile函数正常操作完成。
|
||
//通过GetOverlappedResult函数来获取实际读取到的字节数。
|
||
GetOverlappedResult(DM_HID_Read_HANDLE, &usb_read_over_lapped, &length, TRUE);
|
||
|
||
//如果字节数不为0,则将读到的数据显示到信息框中
|
||
if (length != 0)
|
||
{
|
||
int useful_length = usb_input_buffer[1];
|
||
|
||
GetControllerSensor(usb_input_buffer);
|
||
}
|
||
}
|
||
else {
|
||
//阻塞线程,直到下次事件被触发
|
||
WaitForSingleObject(usb_read_over_lapped.hEvent, INFINITE);
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
void dematrix_usb_get_capabilities(HANDLE hid_usb_handle)
|
||
{
|
||
PHIDP_PREPARSED_DATA PreparsedData;
|
||
|
||
if (hid_usb_handle == NULL) return;
|
||
|
||
HidD_GetPreparsedData(hid_usb_handle, &PreparsedData);
|
||
|
||
HidP_GetCaps(PreparsedData, &dematrix_device_capabilities);
|
||
|
||
HidD_FreePreparsedData(PreparsedData);
|
||
}
|
||
|
||
DWORD start_thread(void *function_address, void *param)
|
||
{
|
||
DWORD temp;
|
||
#ifdef _WIN32
|
||
HANDLE hThread;
|
||
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function_address, param, 0, &temp);
|
||
if (hThread != NULL) return (DWORD)hThread;
|
||
else return 0x00;
|
||
#else
|
||
#ifdef linux
|
||
pthread_t hThread;
|
||
int Result;
|
||
Result = pthread_create(&hThread, NULL, (void *)function_address, param);
|
||
if (Result != NULL) return Result;
|
||
else return -NULL;
|
||
#endif
|
||
#endif
|
||
} |