Bläddra i källkod

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

wugren 8 månader sedan
förälder
incheckning
1a97d4b674
1 ändrade filer med 29 tillägg och 4 borttagningar
  1. 29 4
      hidapi/windows/hid.c

+ 29 - 4
hidapi/windows/hid.c

@@ -139,6 +139,7 @@ extern "C" {
 		void* last_error_str;
 		DWORD last_error_num;
 		BOOL read_pending;
+		BOOL has_report_id;
 		char* read_buf;
 		OVERLAPPED ol;
 	};
@@ -154,6 +155,7 @@ extern "C" {
 		dev->last_error_num = 0;
 		dev->read_pending = FALSE;
 		dev->read_buf = NULL;
+		dev->has_report_id = TRUE;
 		memset(&dev->ol, 0, sizeof(dev->ol));
 		dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
 
@@ -256,6 +258,28 @@ extern "C" {
 		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)
 	{
 #ifndef HIDAPI_USE_DDK
@@ -366,7 +390,7 @@ extern "C" {
 				if (!res)
 					goto cont;
 
-				
+
 				/* See if there's a driver bound. */
 				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
 					SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
@@ -566,6 +590,7 @@ extern "C" {
 			goto err;
 		}
 
+		dev->has_report_id = check_if_report_id_exists(dev->device_handle);
 		dev->read_buf = (char*)malloc(dev->input_report_length);
 
 		return dev;
@@ -680,7 +705,7 @@ extern "C" {
 		dev->read_pending = FALSE;
 
 		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
 				   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
@@ -780,7 +805,7 @@ extern "C" {
 	{
 		if (!dev)
 			return;
-		CancelIo(dev->device_handle);
+		CancelIoEx(dev->device_handle, NULL);
 		free_hid_device(dev);
 	}
 
@@ -846,7 +871,7 @@ extern "C" {
 	/*#define PICPGM*/
 	/*#define S11*/
 #define P32
-#ifdef S11 
+#ifdef S11
 	unsigned short VendorID = 0xa0a0;
 	unsigned short ProductID = 0x0001;
 #endif