浏览代码

修复windows下判断标识错误的问题以及关闭时取消io操作失败的问题

wugren 8 月之前
父节点
当前提交
1a97d4b674
共有 1 个文件被更改,包括 29 次插入4 次删除
  1. 29 4
      hidapi/windows/hid.c

+ 29 - 4
hidapi/windows/hid.c

@@ -139,6 +139,7 @@ extern "C" {
 		void* last_error_str;
 		void* last_error_str;
 		DWORD last_error_num;
 		DWORD last_error_num;
 		BOOL read_pending;
 		BOOL read_pending;
+		BOOL has_report_id;
 		char* read_buf;
 		char* read_buf;
 		OVERLAPPED ol;
 		OVERLAPPED ol;
 	};
 	};
@@ -154,6 +155,7 @@ extern "C" {
 		dev->last_error_num = 0;
 		dev->last_error_num = 0;
 		dev->read_pending = FALSE;
 		dev->read_pending = FALSE;
 		dev->read_buf = NULL;
 		dev->read_buf = NULL;
+		dev->has_report_id = TRUE;
 		memset(&dev->ol, 0, sizeof(dev->ol));
 		memset(&dev->ol, 0, sizeof(dev->ol));
 		dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
 		dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
 
 
@@ -256,6 +258,28 @@ extern "C" {
 		return 0;
 		return 0;
 	}
 	}
 
 
+	BOOL check_if_report_id_exists(HANDLE hidDevice) {
+	    // 获取HID描述符的大小
+	    PHIDP_PREPARSED_DATA preparsedData;
+	    if (!HidD_GetPreparsedData(hidDevice, &preparsedData)) {
+	        return FALSE;
+	    }
+
+	    HIDP_CAPS caps;
+	    if (HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) {
+	        HidD_FreePreparsedData(preparsedData);
+	        return FALSE;
+	    }
+
+	    // 检查是否有Report ID
+	    BOOL hasReportId = caps.InputReportByteLength > 0 || caps.OutputReportByteLength > 0 || caps.FeatureReportByteLength > 0;
+
+	    // 释放资源
+	    HidD_FreePreparsedData(preparsedData);
+
+	    return hasReportId;
+	}
+
 	int HID_API_EXPORT hid_exit(void)
 	int HID_API_EXPORT hid_exit(void)
 	{
 	{
 #ifndef HIDAPI_USE_DDK
 #ifndef HIDAPI_USE_DDK
@@ -366,7 +390,7 @@ extern "C" {
 				if (!res)
 				if (!res)
 					goto cont;
 					goto cont;
 
 
-				
+
 				/* See if there's a driver bound. */
 				/* See if there's a driver bound. */
 				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
 				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
 					SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
 					SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
@@ -566,6 +590,7 @@ extern "C" {
 			goto err;
 			goto err;
 		}
 		}
 
 
+		dev->has_report_id = check_if_report_id_exists(dev->device_handle);
 		dev->read_buf = (char*)malloc(dev->input_report_length);
 		dev->read_buf = (char*)malloc(dev->input_report_length);
 
 
 		return dev;
 		return dev;
@@ -680,7 +705,7 @@ extern "C" {
 		dev->read_pending = FALSE;
 		dev->read_pending = FALSE;
 
 
 		if (res && bytes_read > 0) {
 		if (res && bytes_read > 0) {
-			if (dev->read_buf[0] == 0x0) {
+			if (dev->has_report_id && dev->read_buf[0] == 0x0) {
 				/* If report numbers aren't being used, but Windows sticks a report
 				/* If report numbers aren't being used, but Windows sticks a report
 				   number (0x0) on the beginning of the report anyway. To make this
 				   number (0x0) on the beginning of the report anyway. To make this
 				   work like the other platforms, and to make it work more like the
 				   work like the other platforms, and to make it work more like the
@@ -780,7 +805,7 @@ extern "C" {
 	{
 	{
 		if (!dev)
 		if (!dev)
 			return;
 			return;
-		CancelIo(dev->device_handle);
+		CancelIoEx(dev->device_handle, NULL);
 		free_hid_device(dev);
 		free_hid_device(dev);
 	}
 	}
 
 
@@ -846,7 +871,7 @@ extern "C" {
 	/*#define PICPGM*/
 	/*#define PICPGM*/
 	/*#define S11*/
 	/*#define S11*/
 #define P32
 #define P32
-#ifdef S11 
+#ifdef S11
 	unsigned short VendorID = 0xa0a0;
 	unsigned short VendorID = 0xa0a0;
 	unsigned short ProductID = 0x0001;
 	unsigned short ProductID = 0x0001;
 #endif
 #endif