Hid_File.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #include "stdafx.h"
  2. #include "Hid_File.h"
  3. #include <stdlib.h>
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <hidsdi.h>
  8. #include <setupapi.h>
  9. #include <shlwapi.h>
  10. #include "AutoFunc.h"
  11. #pragma comment(lib, "shlwapi.lib")
  12. #pragma comment(lib, "hid.lib")
  13. //#pragma comment(lib, "hidclass.lib")
  14. //#pragma comment(lib, "hidparse.lib")
  15. #pragma comment(lib, "setupapi.lib")
  16. #define VENDOR_ID 0x413D//test device vendorId
  17. #define PRODUCT_ID 0x2107//test device productId
  18. #define DEVICE_UNIQ_KEY "mi_02"
  19. #define REPORT_ID_EXIST (1)
  20. #define REPORT_ID (0x00)
  21. #define HID_PACKET_SIZE (17)
  22. #define CLIENT_RUNNING_MSG
  23. Hid_File::Hid_File()
  24. {
  25. _hEventObject = CreateEvent(
  26. NULL,
  27. 0,
  28. 0,
  29. "");
  30. _hIDOverlapped.hEvent = _hEventObject;
  31. _hIDOverlapped.Offset = 0;
  32. _hIDOverlapped.OffsetHigh = 0;
  33. memset(&_hidDevice, 0, sizeof(HID_DEVICE));
  34. _hidDevice.ReportIDExist = REPORT_ID_EXIST;
  35. _hidDevice.ReportID = REPORT_ID;
  36. _hidDevice.HidDevice = INVALID_HANDLE_VALUE;
  37. }
  38. Hid_File::~Hid_File()
  39. {
  40. CloseHid();
  41. CloseHandle(_hEventObject);
  42. }
  43. bool Hid_File::OpenHid()
  44. {
  45. if (_hidDevice.HidDevice != INVALID_HANDLE_VALUE)
  46. {
  47. CloseHid();
  48. }
  49. if (_hidDevice.DevicePath[0] == 0)
  50. {
  51. if (FindHid() == false)
  52. {
  53. return false;
  54. }
  55. }
  56. _hidDevice.HidDevice = CreateFile(
  57. _hidDevice.DevicePath,
  58. GENERIC_READ | GENERIC_WRITE,
  59. FILE_SHARE_READ | FILE_SHARE_WRITE,
  60. (LPSECURITY_ATTRIBUTES)NULL,
  61. OPEN_EXISTING,
  62. FILE_ATTRIBUTE_NORMAL,
  63. //FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  64. NULL);
  65. if (_hidDevice.HidDevice == INVALID_HANDLE_VALUE)
  66. {
  67. return false;
  68. }
  69. return true;
  70. }
  71. void Hid_File::CloseHid()
  72. {
  73. if (_hidDevice.HidDevice != INVALID_HANDLE_VALUE)
  74. {
  75. CloseHandle(_hidDevice.HidDevice);
  76. _hidDevice.HidDevice = INVALID_HANDLE_VALUE;
  77. }
  78. }
  79. bool Hid_File::FindHid()
  80. {
  81. int vendorID = VENDOR_ID;
  82. int productID = PRODUCT_ID;
  83. DWORD required;
  84. GUID hidGuid;
  85. HDEVINFO hDevInfo;
  86. SP_DEVICE_INTERFACE_DATA devInfoData;
  87. int memberIndex = 0;
  88. LONG result;
  89. bool lastDevice = false;
  90. DWORD length;
  91. PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
  92. bool deviceDetected = false;
  93. HidD_GetHidGuid(&hidGuid);
  94. hDevInfo = SetupDiGetClassDevs
  95. (&hidGuid,
  96. NULL,
  97. NULL,
  98. DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
  99. //当应用程序不再需要使用SetupDiGetClassDevs函数的传回值hDevInfo所指的数组时,应该调用SetupDiDeStroyDeviceInfoList函数来释放资源
  100. if (hDevInfo == INVALID_HANDLE_VALUE)
  101. {
  102. //printf("Failed to open device handle!");
  103. return false;
  104. }
  105. devInfoData.cbSize = sizeof(devInfoData);
  106. do
  107. {
  108. result = SetupDiEnumDeviceInterfaces(
  109. hDevInfo,
  110. 0,
  111. &hidGuid,
  112. memberIndex,
  113. &devInfoData);
  114. if (result != 0)
  115. {
  116. result = SetupDiGetDeviceInterfaceDetail(
  117. hDevInfo,
  118. &devInfoData,
  119. NULL,
  120. 0,
  121. &length,
  122. NULL);
  123. detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(length);
  124. if (!detailData)
  125. {
  126. //printf("Device information allacation failed!");
  127. return false;
  128. }
  129. detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  130. result = SetupDiGetDeviceInterfaceDetail(
  131. hDevInfo,
  132. &devInfoData,
  133. detailData,
  134. length,
  135. &required,
  136. NULL);
  137. if (!result)
  138. {
  139. //printf("Device information reallocation failed!");
  140. free(detailData);
  141. break;
  142. }
  143. _hidDevice.HidDevice = CreateFile(
  144. detailData->DevicePath,
  145. GENERIC_READ | GENERIC_WRITE,
  146. FILE_SHARE_READ | FILE_SHARE_WRITE,
  147. (LPSECURITY_ATTRIBUTES)NULL,
  148. OPEN_EXISTING,
  149. FILE_ATTRIBUTE_NORMAL,
  150. //FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  151. NULL);
  152. //if (_hidDevice.HidDevice == INVALID_HANDLE_VALUE)
  153. //{
  154. // //wirte可以打开,带read属性就不能打开
  155. // _hidDevice.HidDevice = CreateFile(
  156. // detailData->DevicePath,
  157. // GENERIC_WRITE,
  158. // FILE_SHARE_READ | FILE_SHARE_WRITE,
  159. // (LPSECURITY_ATTRIBUTES)NULL,
  160. // OPEN_EXISTING,
  161. // //FILE_ATTRIBUTE_NORMAL,
  162. // FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  163. // NULL);
  164. //}
  165. //printf("Hid:%s\n", detailData->DevicePath);
  166. if (_hidDevice.HidDevice == INVALID_HANDLE_VALUE)
  167. {
  168. free(detailData);
  169. memberIndex = memberIndex + 1;
  170. continue;
  171. }
  172. //printf("Opened Hid:%s\n", detailData->DevicePath);
  173. _hidDevice.Attributes.Size = sizeof(HIDD_ATTRIBUTES);
  174. result = HidD_GetAttributes(
  175. _hidDevice.HidDevice,
  176. &_hidDevice.Attributes);
  177. if ((_hidDevice.Attributes.VendorID == vendorID) && (_hidDevice.Attributes.ProductID == productID)
  178. && (StrStr(detailData->DevicePath, DEVICE_UNIQ_KEY) != 0))
  179. {
  180. int status;
  181. PHIDP_PREPARSED_DATA PreparsedData;
  182. //获取USB设备的预解析数据
  183. result = HidD_GetPreparsedData(_hidDevice.HidDevice, &PreparsedData);
  184. if (!result)
  185. {
  186. //printf("无法获取USB设备的预解析数据!");
  187. free(detailData);
  188. CloseHid();
  189. break;
  190. }
  191. deviceDetected = true;
  192. //printf("Hid:%s\n", detailData->DevicePath);
  193. strcpy_s(_hidDevice.DevicePath,MAX_PATH, detailData->DevicePath);
  194. status = HidP_GetCaps(PreparsedData, &_hidDevice.Caps);
  195. HidD_FreePreparsedData(PreparsedData);
  196. PreparsedData = NULL;
  197. CloseHid();
  198. }
  199. else
  200. {
  201. //printf("没有找到设备!");
  202. CloseHid();
  203. }
  204. free(detailData);
  205. detailData = NULL;
  206. }
  207. else
  208. {
  209. lastDevice = true;
  210. }
  211. memberIndex = memberIndex + 1;
  212. } while ((lastDevice == false) && (deviceDetected == false));
  213. SetupDiDestroyDeviceInfoList(hDevInfo);
  214. return deviceDetected;
  215. }
  216. /*
  217. *写入数据为MCD设备状态通知,把标识位放在第1位
  218. */
  219. DWORD Hid_File::AddReportID(char *pInputBuff, DWORD BuffLen)
  220. {
  221. DWORD ret = 0;
  222. if (BuffLen + 1 >= MAX_PATH)
  223. {
  224. return ret;
  225. }
  226. if (_hidDevice.HidDevice != INVALID_HANDLE_VALUE)
  227. {
  228. if (_hidDevice.ReportIDExist)
  229. {
  230. _hidDevice.DataBuff[0] = _hidDevice.ReportID;
  231. memcpy(&(_hidDevice.DataBuff[1]), pInputBuff, BuffLen);
  232. ret = BuffLen + 1;
  233. }
  234. }
  235. return ret;
  236. }
  237. bool Hid_File::WriteToHid(char *pInputBuff, DWORD BuffLen)
  238. {
  239. bool ret = false;
  240. Sleep(5);
  241. if (OpenHid())
  242. {
  243. int result = 0;
  244. DWORD numberOfBytesWrite = 0;
  245. if (BuffLen > 10)
  246. {
  247. return ret;
  248. }
  249. memset(_hidDevice.DataBuff, 0, MAX_PATH);
  250. DWORD CopyLen = AddReportID(pInputBuff, BuffLen);
  251. //同步WRITE
  252. BOOL bWriteStat = WriteFile(_hidDevice.HidDevice,
  253. _hidDevice.DataBuff, HID_PACKET_SIZE, &numberOfBytesWrite, 0);
  254. if (!bWriteStat)
  255. {
  256. DWORD error = GetLastError();
  257. printf("HID IO WRITE FAILED.ERROR:%d\n", error);
  258. CloseHid();
  259. return ret;
  260. }
  261. CloseHid();
  262. return true;
  263. bWriteStat = WriteFile(_hidDevice.HidDevice,
  264. _hidDevice.DataBuff, HID_PACKET_SIZE, &numberOfBytesWrite, (LPOVERLAPPED)&_hIDOverlapped);
  265. if (!bWriteStat)
  266. {
  267. DWORD error = GetLastError();
  268. if (error == ERROR_IO_PENDING)
  269. {
  270. int waitResult = 0;
  271. waitResult = WaitForSingleObject(
  272. _hEventObject,
  273. MAX_DELAY);
  274. switch (waitResult)
  275. {
  276. case WAIT_OBJECT_0:
  277. {
  278. if (!GetOverlappedResult(_hidDevice.HidDevice, (LPOVERLAPPED)&_hIDOverlapped, &numberOfBytesWrite, FALSE))
  279. {
  280. //getlasterror
  281. CancelIo(_hidDevice.HidDevice);
  282. }
  283. else
  284. {
  285. //if (numberOfBytesWrite != _hidDevice.Caps.OutputReportByteLength)
  286. if (numberOfBytesWrite != HID_PACKET_SIZE)
  287. {
  288. //Warning!!
  289. CancelIo(_hidDevice.HidDevice);
  290. }
  291. else
  292. {
  293. ret = true;
  294. }
  295. }
  296. }
  297. break;
  298. case WAIT_TIMEOUT:
  299. {
  300. CancelIo(_hidDevice.HidDevice);
  301. }
  302. break;
  303. default:
  304. {
  305. break;
  306. }
  307. }
  308. //ResetEvent(_hEventObject);
  309. }
  310. else if (error == WAIT_TIMEOUT)
  311. {
  312. //timeout
  313. CancelIo(_hidDevice.HidDevice);
  314. }
  315. else
  316. {
  317. //unknown error
  318. CancelIo(_hidDevice.HidDevice);
  319. }
  320. }
  321. else
  322. {
  323. if (numberOfBytesWrite == HID_PACKET_SIZE)
  324. {
  325. ret = true;
  326. }
  327. }
  328. CloseHid();
  329. }
  330. return ret;
  331. }
  332. INT Hid_File::ReadFromHid(char *pOutputBuff, DWORD BuffLen,DWORD timeout)
  333. {
  334. INT ret = -1;
  335. Sleep(5);
  336. if (OpenHid())
  337. {
  338. BOOL result = 0;
  339. DWORD numberOfBytesRead;
  340. memset(_hidDevice.DataBuff, 0, MAX_PATH);
  341. //同步READ
  342. result = ReadFile(_hidDevice.HidDevice,
  343. _hidDevice.DataBuff,
  344. HID_PACKET_SIZE,
  345. &numberOfBytesRead,
  346. 0);
  347. if (!result)
  348. {
  349. DWORD error = GetLastError();
  350. printf("HID IO READ FAILED.ERROR:%d\n", error);
  351. CloseHid();
  352. return ret;
  353. }
  354. if (numberOfBytesRead == HID_PACKET_SIZE)
  355. {
  356. //according protocol,
  357. //[0] = report ID
  358. //[1] = packet size
  359. unsigned char PacketLen = (unsigned char)_hidDevice.DataBuff[1];
  360. memcpy(pOutputBuff, &(_hidDevice.DataBuff[1]), PacketLen);
  361. ret = PacketLen;
  362. }
  363. CloseHid();
  364. return ret;
  365. result = ReadFile(_hidDevice.HidDevice,
  366. _hidDevice.DataBuff,
  367. HID_PACKET_SIZE,
  368. &numberOfBytesRead,
  369. (LPOVERLAPPED)&_hIDOverlapped);
  370. if (!result)
  371. {
  372. DWORD error = GetLastError();
  373. if (error == ERROR_IO_PENDING)
  374. {
  375. int waitResult = 0;
  376. waitResult = WaitForSingleObject(
  377. _hEventObject,
  378. timeout);
  379. switch (waitResult)
  380. {
  381. case WAIT_OBJECT_0:
  382. {
  383. if (!GetOverlappedResult(_hidDevice.HidDevice, (LPOVERLAPPED)&_hIDOverlapped, &numberOfBytesRead, FALSE))
  384. {
  385. //getlasterror
  386. CancelIo(_hidDevice.HidDevice);
  387. }
  388. else
  389. {
  390. //if (numberOfBytesWrite != _hidDevice.Caps.OutputReportByteLength)
  391. if (numberOfBytesRead != HID_PACKET_SIZE)
  392. {
  393. //Warning!!
  394. CancelIo(_hidDevice.HidDevice);
  395. }
  396. else
  397. {
  398. ret = numberOfBytesRead;
  399. }
  400. }
  401. }
  402. break;
  403. case WAIT_TIMEOUT:
  404. {
  405. // CancelIo(_hidDevice.HidDevice);
  406. }
  407. break;
  408. default:
  409. {
  410. break;
  411. }
  412. }
  413. }
  414. else if (error == WAIT_TIMEOUT)
  415. {
  416. //timeout
  417. //CancelIo(_hidDevice.HidDevice);
  418. }
  419. else
  420. {
  421. //unknown error
  422. CancelIo(_hidDevice.HidDevice);
  423. }
  424. }
  425. else
  426. {
  427. if (numberOfBytesRead == HID_PACKET_SIZE)
  428. {
  429. ret = numberOfBytesRead;
  430. }
  431. }
  432. CloseHid();
  433. }
  434. if (ret == HID_PACKET_SIZE)
  435. {
  436. //according protocol,
  437. //[0] = report ID
  438. //[1] = packet size
  439. unsigned char PacketLen = (unsigned char)_hidDevice.DataBuff[1];
  440. memcpy(pOutputBuff, &(_hidDevice.DataBuff[1]), PacketLen);
  441. ret = PacketLen;
  442. }
  443. return ret;
  444. }