Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1354 lines
41 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. pnp.c
  5. Abstract:
  6. This module contains the code
  7. for finding, adding, removing, and identifying hid devices.
  8. Environment:
  9. Kernel & user mode
  10. Revision History:
  11. Nov-96 : Created by Kenneth D. Ray
  12. --*/
  13. #include <basetyps.h>
  14. #include <stdlib.h>
  15. #include <wtypes.h>
  16. #include <setupapi.h>
  17. #include "hidsdi.h"
  18. #include "hid.h"
  19. #include "mylog.h"
  20. #include "mymem.h"
  21. PHID_DEVICE gpHidDevices = NULL;
  22. LONG
  23. OpenHidDevice (
  24. IN HDEVINFO HardwareDeviceInfo,
  25. IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
  26. IN OUT PHID_DEVICE HidDevice
  27. );
  28. VOID
  29. CloseHidDevice (
  30. IN OUT PHID_DEVICE HidDevice
  31. );
  32. VOID
  33. AddHidDevice (
  34. IN PHID_DEVICE HidDevice
  35. );
  36. VOID
  37. RemoveHidDevice (
  38. IN PHID_DEVICE HidDevice
  39. );
  40. PHID_DEVICE
  41. FindHidDeviceByDevInst (
  42. IN DWORD DevInst
  43. );
  44. LONG
  45. FindKnownHidDevices (
  46. OUT PHID_DEVICE *pHidDevices,
  47. OUT PULONG pNumberHidDevices
  48. )
  49. /*++
  50. Routine Description:
  51. Do the required PnP things in order to find all the HID devices in
  52. the system at this time.
  53. --*/
  54. {
  55. HDEVINFO hardwareDeviceInfo;
  56. SP_DEVICE_INTERFACE_DATA hidDeviceInterfaceData;
  57. SP_DEVINFO_DATA hidDeviceInfoData;
  58. ULONG i;
  59. PHID_DEVICE hidDevice;
  60. GUID hidGuid;
  61. LONG lResult;
  62. LOG((PHONESP_TRACE, "FindKnownHidDevices - enter"));
  63. HidD_GetHidGuid (&hidGuid);
  64. *pHidDevices = NULL;
  65. *pNumberHidDevices = 0;
  66. //
  67. // Open a handle to the dev info list
  68. //
  69. hardwareDeviceInfo = SetupDiGetClassDevs (
  70. &hidGuid,
  71. NULL, // Define no enumerator (global)
  72. NULL, // Define no
  73. (DIGCF_PRESENT | // Only Devices present
  74. DIGCF_INTERFACEDEVICE)); // Function class devices.
  75. if(hardwareDeviceInfo == INVALID_HANDLE_VALUE)
  76. {
  77. return GetLastError();
  78. }
  79. //
  80. // Mark all existing hid devices as removed. Any of these that are still present
  81. // will have this mark removed during enumeration below.
  82. //
  83. hidDevice = gpHidDevices;
  84. while (hidDevice != NULL)
  85. {
  86. //
  87. // Include existing devices in out count of hid devices
  88. //
  89. (*pNumberHidDevices)++;
  90. hidDevice->bRemoved = TRUE;
  91. hidDevice = hidDevice->Next;
  92. }
  93. i = 0;
  94. hidDeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  95. while (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
  96. 0, // No care about specific PDOs
  97. &hidGuid,
  98. i++,
  99. &hidDeviceInterfaceData))
  100. {
  101. //
  102. // We enumerated a hid device, first lets get the device instance
  103. //
  104. hidDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  105. if (SetupDiGetDeviceInterfaceDetail(hardwareDeviceInfo,
  106. &hidDeviceInterfaceData,
  107. NULL,
  108. 0,
  109. NULL,
  110. &hidDeviceInfoData)
  111. // ERROR_INSUFFICIENT_BUFFER is alright because we passed in NULL
  112. // for the device interface detail data structure.
  113. || (GetLastError() == ERROR_INSUFFICIENT_BUFFER) )
  114. {
  115. LOG((PHONESP_TRACE, "FindKnownHidDevices - device instance %08x", hidDeviceInfoData.DevInst ));
  116. //
  117. // Check that the hid device is not already in our list
  118. //
  119. if ((hidDevice = FindHidDeviceByDevInst(hidDeviceInfoData.DevInst)) == NULL)
  120. {
  121. //
  122. // This is a new hid device
  123. //
  124. // Allocate a HID_DEVICE structure
  125. //
  126. hidDevice = (PHID_DEVICE) MemAlloc(sizeof(HID_DEVICE));
  127. if(hidDevice == NULL)
  128. {
  129. LOG((PHONESP_TRACE, "FindKnownHidDevices - unable to allocate hid device"));
  130. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  131. return ERROR_OUTOFMEMORY;
  132. }
  133. ZeroMemory(hidDevice, sizeof(HID_DEVICE));
  134. //
  135. // Mark this as new, so we can create a new phone for it later
  136. //
  137. hidDevice->bNew = TRUE;
  138. hidDevice->dwDevInst = hidDeviceInfoData.DevInst;
  139. //
  140. // Open the hid device
  141. //
  142. lResult = OpenHidDevice (hardwareDeviceInfo, &hidDeviceInterfaceData, hidDevice);
  143. if(lResult == ERROR_SUCCESS)
  144. {
  145. //
  146. // This is a good hid device
  147. //
  148. (*pNumberHidDevices)++;
  149. //
  150. // So add it to our hid list
  151. //
  152. AddHidDevice(hidDevice);
  153. LOG((PHONESP_TRACE, "FindKnownHidDevices - new hid devive added"));
  154. }
  155. else
  156. {
  157. LOG((PHONESP_TRACE, "FindKnownHidDevices - OpenHidDevice failed %08x", lResult ));
  158. MemFree(hidDevice);
  159. }
  160. }
  161. else
  162. {
  163. LOG((PHONESP_TRACE, "FindKnownHidDevices - hid device already enumerated"));
  164. //
  165. // Clear the removed mark on this device, so we don't remove its phone later
  166. //
  167. hidDevice->bRemoved = FALSE;
  168. }
  169. }
  170. else
  171. {
  172. LOG((PHONESP_TRACE, "FindKnownHidDevices - SetupDiGetDeviceInterfaceDetail failed %08x", GetLastError() ));
  173. }
  174. }
  175. lResult = GetLastError();
  176. if (ERROR_NO_MORE_ITEMS != lResult)
  177. {
  178. LOG((PHONESP_TRACE, "FindKnownHidDevices - SetupDiEnumDeviceInterfaces failed %08x", lResult ));
  179. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  180. return lResult;
  181. }
  182. LOG((PHONESP_TRACE, "FindKnownHidDevices - exit"));
  183. *pHidDevices = gpHidDevices;
  184. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  185. return ERROR_SUCCESS;
  186. }
  187. LONG
  188. OpenHidDevice (
  189. IN HDEVINFO HardwareDeviceInfo,
  190. IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
  191. IN OUT PHID_DEVICE HidDevice
  192. )
  193. /*++
  194. RoutineDescription:
  195. Given the HardwareDeviceInfo, representing a handle to the plug and
  196. play information, and deviceInfoData, representing a specific hid device,
  197. open that device and fill in all the relivant information in the given
  198. HID_DEVICE structure.
  199. return if the open and initialization was successfull or not.
  200. --*/
  201. {
  202. ULONG predictedLength = 0;
  203. ULONG requiredLength = 0;
  204. LONG lResult;
  205. //
  206. // allocate a function class device data structure to receive the
  207. // goods about this particular device.
  208. //
  209. LOG((PHONESP_TRACE,"OpenHidDevice - enter"));
  210. SetupDiGetDeviceInterfaceDetail(
  211. HardwareDeviceInfo,
  212. DeviceInterfaceData,
  213. NULL, // probing so no output buffer yet
  214. 0, // probing so output buffer length of zero
  215. &requiredLength,
  216. NULL // not interested in the specific dev-node
  217. );
  218. predictedLength = requiredLength;
  219. HidDevice->functionClassDeviceData = MemAlloc (predictedLength);
  220. if (HidDevice->functionClassDeviceData == NULL)
  221. {
  222. LOG((PHONESP_TRACE,"OpenHidDevice - out of memory"));
  223. return ERROR_OUTOFMEMORY;
  224. }
  225. HidDevice->functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
  226. //
  227. // Retrieve the information from Plug and Play.
  228. //
  229. if (! SetupDiGetDeviceInterfaceDetail (
  230. HardwareDeviceInfo,
  231. DeviceInterfaceData,
  232. HidDevice->functionClassDeviceData,
  233. predictedLength,
  234. &requiredLength,
  235. NULL))
  236. {
  237. MemFree(HidDevice->functionClassDeviceData);
  238. HidDevice->functionClassDeviceData = NULL;
  239. LOG((PHONESP_TRACE,"OpenHidDevice - SetupDiGetDeviceInterfaceDetail 2"
  240. " Failed: %d", GetLastError()));
  241. return GetLastError();
  242. }
  243. HidDevice->HidDevice = CreateFile (
  244. HidDevice->functionClassDeviceData->DevicePath,
  245. GENERIC_READ | GENERIC_WRITE,
  246. FILE_SHARE_READ | FILE_SHARE_WRITE,
  247. NULL, // no SECURITY_ATTRIBUTES structure
  248. OPEN_EXISTING, // No special create flags
  249. FILE_FLAG_OVERLAPPED, // No special attributes
  250. NULL); // No template file
  251. if (INVALID_HANDLE_VALUE == HidDevice->HidDevice)
  252. {
  253. LOG((PHONESP_TRACE,"OpenHidDevice - CreateFile Failed: %d", GetLastError()));
  254. MemFree(HidDevice->functionClassDeviceData);
  255. HidDevice->functionClassDeviceData = NULL;
  256. return GetLastError();
  257. }
  258. if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd))
  259. {
  260. LOG((PHONESP_ERROR, "OpenHidDevice - HidD_GetPreparsedData failed"));
  261. CloseHandle(HidDevice->HidDevice);
  262. HidDevice->HidDevice = NULL;
  263. MemFree(HidDevice->functionClassDeviceData);
  264. HidDevice->functionClassDeviceData = NULL;
  265. return ERROR_INVALID_DATA;
  266. }
  267. if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes))
  268. {
  269. LOG((PHONESP_ERROR, "OpenHidDevice - HidD_GetAttributes failed"));
  270. CloseHandle(HidDevice->HidDevice);
  271. HidDevice->HidDevice = NULL;
  272. MemFree(HidDevice->functionClassDeviceData);
  273. HidDevice->functionClassDeviceData = NULL;
  274. HidD_FreePreparsedData (HidDevice->Ppd);
  275. return ERROR_INVALID_DATA;
  276. }
  277. if ((!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps)) ||
  278. (HidDevice->Caps.UsagePage != HID_USAGE_PAGE_TELEPHONY) ||
  279. (HidDevice->Caps.Usage != HID_USAGE_TELEPHONY_PHONE) )
  280. {
  281. LOG((PHONESP_TRACE, " HID USAGE PAGE NOT TELEPHONY " ));
  282. CloseHandle(HidDevice->HidDevice);
  283. HidDevice->HidDevice = NULL;
  284. MemFree(HidDevice->functionClassDeviceData);
  285. HidDevice->functionClassDeviceData = NULL;
  286. HidD_FreePreparsedData (HidDevice->Ppd);
  287. return ERROR_INVALID_DATA;
  288. }
  289. else
  290. {
  291. LOG((PHONESP_TRACE, " HID USAGE PAGE TELEPHONY " ));
  292. }
  293. //
  294. // At this point the client has a choice. It may chose to look at the
  295. // Usage and Page of the top level collection found in the HIDP_CAPS
  296. // structure. In this way it could just use the usages it knows about.
  297. // If either HidP_GetUsages or HidP_GetUsageValue return an error then
  298. // that particular usage does not exist in the report.
  299. // This is most likely the preferred method as the application can only
  300. // use usages of which it already knows.
  301. // In this case the app need not even call GetButtonCaps or GetValueCaps.
  302. //
  303. // In this example, however, we will call FillDeviceInfo to look for all
  304. // of the usages in the device.
  305. //
  306. lResult = FillDeviceInfo(HidDevice);
  307. if(lResult != ERROR_SUCCESS)
  308. {
  309. LOG((PHONESP_ERROR, "OpenHidDevice - FillDeviceInfo failed"));
  310. CloseHandle(HidDevice->HidDevice);
  311. HidDevice->HidDevice = NULL;
  312. MemFree(HidDevice->functionClassDeviceData);
  313. HidDevice->functionClassDeviceData = NULL;
  314. HidD_FreePreparsedData (HidDevice->Ppd);
  315. return lResult;
  316. }
  317. LOG((PHONESP_TRACE,"OpenHidDevice - exit"));
  318. return ERROR_SUCCESS;
  319. }
  320. LONG
  321. FillDeviceInfo(
  322. IN PHID_DEVICE HidDevice
  323. )
  324. {
  325. USHORT numValues;
  326. USHORT numCaps;
  327. PHIDP_BUTTON_CAPS buttonCaps;
  328. PHIDP_VALUE_CAPS valueCaps;
  329. PHID_DATA data;
  330. ULONG i;
  331. USAGE usage;
  332. //
  333. // setup Input Data buffers.
  334. //
  335. //
  336. // Allocate memory to hold on input report
  337. //
  338. LOG((PHONESP_TRACE,"FillDeviceInfo - enter"));
  339. if ( ! ( HidDevice->InputReportBuffer = (PCHAR)
  340. MemAlloc (HidDevice->Caps.InputReportByteLength * sizeof (CHAR)) ) )
  341. {
  342. return ERROR_OUTOFMEMORY;
  343. }
  344. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberInputButtonCaps %d", HidDevice->Caps.NumberInputButtonCaps));
  345. //
  346. // Allocate memory to hold the button and value capabilities.
  347. // NumberXXCaps is in terms of array elements.
  348. //
  349. HidDevice->InputButtonCaps =
  350. buttonCaps = (PHIDP_BUTTON_CAPS)
  351. MemAlloc (HidDevice->Caps.NumberInputButtonCaps
  352. * sizeof (HIDP_BUTTON_CAPS));
  353. if ( ! buttonCaps)
  354. {
  355. MemFree(HidDevice->InputReportBuffer);
  356. return ERROR_OUTOFMEMORY;
  357. }
  358. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberInputValueCaps %d", HidDevice->Caps.NumberInputValueCaps));
  359. HidDevice->InputValueCaps =
  360. valueCaps = (PHIDP_VALUE_CAPS)
  361. MemAlloc (HidDevice->Caps.NumberInputValueCaps *
  362. sizeof (HIDP_VALUE_CAPS));
  363. if ( ! valueCaps)
  364. {
  365. MemFree(HidDevice->InputReportBuffer);
  366. MemFree(HidDevice->InputButtonCaps);
  367. return ERROR_OUTOFMEMORY;
  368. }
  369. //
  370. // Have the HidP_X functions fill in the capability structure arrays.
  371. //
  372. numCaps = HidDevice->Caps.NumberInputButtonCaps;
  373. HidP_GetButtonCaps (HidP_Input,
  374. buttonCaps,
  375. &numCaps,
  376. HidDevice->Ppd);
  377. numCaps = HidDevice->Caps.NumberInputValueCaps;
  378. HidP_GetValueCaps (HidP_Input,
  379. valueCaps,
  380. &numCaps,
  381. HidDevice->Ppd);
  382. //
  383. // Depending on the device, some value caps structures may represent more
  384. // than one value. (A range). In the interest of being verbose, over
  385. // efficient, we will expand these so that we have one and only one
  386. // struct _HID_DATA for each value.
  387. //
  388. // To do this we need to count up the total number of values are listed
  389. // in the value caps structure. For each element in the array we test
  390. // for range if it is a range then UsageMax and UsageMin describe the
  391. // usages for this range INCLUSIVE.
  392. //
  393. numValues = 0;
  394. for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++)
  395. {
  396. if (valueCaps->IsRange)
  397. {
  398. numValues += valueCaps->Range.UsageMax -
  399. valueCaps->Range.UsageMin + 1;
  400. }
  401. else
  402. {
  403. numValues++;
  404. }
  405. }
  406. valueCaps = HidDevice->InputValueCaps;
  407. //
  408. // Allocate a buffer to hold the struct _HID_DATA structures.
  409. // One element for each set of buttons, and one element for each value
  410. // found.
  411. //
  412. HidDevice->InputDataLength = HidDevice->Caps.NumberInputButtonCaps +
  413. numValues;
  414. HidDevice->InputData =
  415. data = (PHID_DATA) MemAlloc (HidDevice->InputDataLength *
  416. sizeof (HID_DATA));
  417. if( ! data )
  418. {
  419. MemFree(HidDevice->InputReportBuffer);
  420. MemFree(HidDevice->InputButtonCaps);
  421. MemFree(HidDevice->InputValueCaps);
  422. return ERROR_OUTOFMEMORY;
  423. }
  424. //
  425. // Fill in the button data
  426. //
  427. for (i = 0; i < HidDevice->Caps.NumberInputButtonCaps;
  428. i++, data++, buttonCaps++)
  429. {
  430. data->IsButtonData = TRUE;
  431. data->Status = HIDP_STATUS_SUCCESS;
  432. data->UsagePage = buttonCaps->UsagePage;
  433. if (buttonCaps->IsRange)
  434. {
  435. data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin;
  436. data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax;
  437. }
  438. else
  439. {
  440. data->ButtonData.UsageMin =
  441. data->ButtonData.UsageMax = buttonCaps -> NotRange.Usage;
  442. }
  443. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  444. HidP_Input,
  445. buttonCaps->UsagePage,
  446. HidDevice->Ppd);
  447. data->ButtonData.Usages = (PUSAGE)
  448. MemAlloc (data->ButtonData.MaxUsageLength *
  449. sizeof (USAGE));
  450. // if MemAlloc fails release all previous allocated memory and return
  451. // error
  452. if ( data->ButtonData.Usages == NULL)
  453. {
  454. DWORD dwCnt;
  455. for(dwCnt = 0; dwCnt < i; dwCnt++)
  456. {
  457. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  458. }
  459. MemFree(HidDevice->InputData);
  460. MemFree(HidDevice->InputReportBuffer);
  461. MemFree(HidDevice->InputButtonCaps);
  462. MemFree(HidDevice->InputValueCaps);
  463. return ERROR_OUTOFMEMORY;
  464. }
  465. data->ReportID = buttonCaps->ReportID;
  466. }
  467. //
  468. // Fill in the value data
  469. //
  470. for (i = 0; i < numValues; i++, valueCaps++)
  471. {
  472. if (valueCaps->IsRange)
  473. {
  474. for (usage = valueCaps->Range.UsageMin;
  475. usage <= valueCaps->Range.UsageMax;
  476. usage++)
  477. {
  478. data->IsButtonData = FALSE;
  479. data->Status = HIDP_STATUS_SUCCESS;
  480. data->UsagePage = valueCaps->UsagePage;
  481. data->ValueData.Usage = usage;
  482. data->ReportID = valueCaps->ReportID;
  483. data++;
  484. }
  485. }
  486. else
  487. {
  488. data->IsButtonData = FALSE;
  489. data->Status = HIDP_STATUS_SUCCESS;
  490. data->UsagePage = valueCaps->UsagePage;
  491. data->ValueData.Usage = valueCaps->NotRange.Usage;
  492. data->ReportID = valueCaps->ReportID;
  493. data++;
  494. }
  495. }
  496. //
  497. // setup Output Data buffers.
  498. //
  499. if ( ! ( HidDevice->OutputReportBuffer = (PCHAR)
  500. MemAlloc (HidDevice->Caps.OutputReportByteLength *
  501. sizeof (CHAR)) ) )
  502. {
  503. DWORD dwCnt;
  504. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  505. {
  506. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  507. }
  508. MemFree(HidDevice->InputData);
  509. MemFree(HidDevice->InputReportBuffer);
  510. MemFree(HidDevice->InputButtonCaps);
  511. MemFree(HidDevice->InputValueCaps);
  512. return ERROR_OUTOFMEMORY;
  513. }
  514. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberOutputButtonCaps %d", HidDevice->Caps.NumberOutputButtonCaps));
  515. HidDevice->OutputButtonCaps =
  516. buttonCaps = (PHIDP_BUTTON_CAPS)
  517. MemAlloc(HidDevice->Caps.NumberOutputButtonCaps *
  518. sizeof (HIDP_BUTTON_CAPS));
  519. if ( ! buttonCaps )
  520. {
  521. DWORD dwCnt;
  522. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  523. {
  524. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  525. }
  526. MemFree(HidDevice->InputData);
  527. MemFree(HidDevice->InputReportBuffer);
  528. MemFree(HidDevice->InputButtonCaps);
  529. MemFree(HidDevice->InputValueCaps);
  530. MemFree(HidDevice->OutputReportBuffer);
  531. return ERROR_OUTOFMEMORY;
  532. }
  533. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberOutputValueCaps %d", HidDevice->Caps.NumberOutputValueCaps));
  534. HidDevice->OutputValueCaps =
  535. valueCaps = (PHIDP_VALUE_CAPS)
  536. MemAlloc (HidDevice->Caps.NumberOutputValueCaps *
  537. sizeof (HIDP_VALUE_CAPS));
  538. if ( ! valueCaps )
  539. {
  540. DWORD dwCnt;
  541. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  542. {
  543. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  544. }
  545. MemFree(HidDevice->InputData);
  546. MemFree(HidDevice->InputReportBuffer);
  547. MemFree(HidDevice->InputButtonCaps);
  548. MemFree(HidDevice->InputValueCaps);
  549. MemFree(HidDevice->OutputReportBuffer);
  550. MemFree(HidDevice->OutputButtonCaps);
  551. return ERROR_OUTOFMEMORY;
  552. }
  553. numCaps = HidDevice->Caps.NumberOutputButtonCaps;
  554. HidP_GetButtonCaps (HidP_Output,
  555. buttonCaps,
  556. &numCaps,
  557. HidDevice->Ppd);
  558. numCaps = HidDevice->Caps.NumberOutputValueCaps;
  559. HidP_GetValueCaps (HidP_Output,
  560. valueCaps,
  561. &numCaps,
  562. HidDevice->Ppd);
  563. numValues = 0;
  564. for (i = 0; i < HidDevice->Caps.NumberOutputValueCaps; i++, valueCaps++)
  565. {
  566. if (valueCaps->IsRange)
  567. {
  568. numValues += valueCaps->Range.UsageMax -
  569. valueCaps->Range.UsageMin + 1;
  570. }
  571. else
  572. {
  573. numValues++;
  574. }
  575. }
  576. valueCaps = HidDevice->OutputValueCaps;
  577. HidDevice->OutputDataLength = HidDevice->Caps.NumberOutputButtonCaps
  578. + numValues;
  579. HidDevice->OutputData =
  580. data = (PHID_DATA) MemAlloc (HidDevice->OutputDataLength *
  581. sizeof (HID_DATA));
  582. if ( ! data )
  583. {
  584. DWORD dwCnt;
  585. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  586. {
  587. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  588. }
  589. MemFree(HidDevice->InputData);
  590. MemFree(HidDevice->InputReportBuffer);
  591. MemFree(HidDevice->InputButtonCaps);
  592. MemFree(HidDevice->InputValueCaps);
  593. MemFree(HidDevice->OutputReportBuffer);
  594. MemFree(HidDevice->OutputButtonCaps);
  595. MemFree(HidDevice->OutputValueCaps);
  596. return ERROR_OUTOFMEMORY;
  597. }
  598. for (i = 0; i < HidDevice->Caps.NumberOutputButtonCaps;
  599. i++, data++, buttonCaps++)
  600. {
  601. data->IsButtonData = TRUE;
  602. data->Status = HIDP_STATUS_SUCCESS;
  603. data->UsagePage = buttonCaps->UsagePage;
  604. if (buttonCaps->IsRange)
  605. {
  606. data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin;
  607. data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax;
  608. }
  609. else
  610. {
  611. data->ButtonData.UsageMin =
  612. data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;
  613. }
  614. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  615. HidP_Output,
  616. buttonCaps->UsagePage,
  617. HidDevice->Ppd);
  618. data->ButtonData.Usages = (PUSAGE)
  619. MemAlloc (data->ButtonData.MaxUsageLength *
  620. sizeof (USAGE));
  621. if( ! data)
  622. {
  623. DWORD dwCnt;
  624. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  625. {
  626. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  627. }
  628. MemFree(HidDevice->InputData);
  629. MemFree(HidDevice->InputReportBuffer);
  630. MemFree(HidDevice->InputButtonCaps);
  631. MemFree(HidDevice->InputValueCaps);
  632. for(dwCnt = 0; dwCnt < i; dwCnt++)
  633. {
  634. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  635. }
  636. MemFree(HidDevice->OutputData);
  637. MemFree(HidDevice->OutputReportBuffer);
  638. MemFree(HidDevice->OutputButtonCaps);
  639. MemFree(HidDevice->OutputValueCaps);
  640. return ERROR_OUTOFMEMORY;
  641. }
  642. data->ReportID = buttonCaps->ReportID;
  643. }
  644. for (i = 0; i < numValues; i++, valueCaps++)
  645. {
  646. if (valueCaps->IsRange)
  647. {
  648. for (usage = valueCaps->Range.UsageMin;
  649. usage <= valueCaps->Range.UsageMax; usage++)
  650. {
  651. data->IsButtonData = FALSE;
  652. data->Status = HIDP_STATUS_SUCCESS;
  653. data->UsagePage = valueCaps->UsagePage;
  654. data->ValueData.Usage = usage;
  655. data->ReportID = valueCaps -> ReportID;
  656. data++;
  657. }
  658. }
  659. else
  660. {
  661. data->IsButtonData = FALSE;
  662. data->Status = HIDP_STATUS_SUCCESS;
  663. data->UsagePage = valueCaps->UsagePage;
  664. data->ValueData.Usage = valueCaps->NotRange.Usage;
  665. data->ReportID = valueCaps -> ReportID;
  666. data++;
  667. }
  668. }
  669. //
  670. // setup Feature Data buffers.
  671. //
  672. if ( ! ( HidDevice->FeatureReportBuffer = (PCHAR)
  673. MemAlloc (HidDevice->Caps.FeatureReportByteLength *
  674. sizeof (CHAR)) ) )
  675. {
  676. DWORD dwCnt;
  677. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  678. {
  679. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  680. }
  681. MemFree(HidDevice->InputData);
  682. MemFree(HidDevice->InputReportBuffer);
  683. MemFree(HidDevice->InputButtonCaps);
  684. MemFree(HidDevice->InputValueCaps);
  685. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  686. {
  687. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  688. }
  689. MemFree(HidDevice->OutputData);
  690. MemFree(HidDevice->OutputReportBuffer);
  691. MemFree(HidDevice->OutputButtonCaps);
  692. MemFree(HidDevice->OutputValueCaps);
  693. return ERROR_OUTOFMEMORY;
  694. }
  695. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberFeatureButtonCaps %d", HidDevice->Caps.NumberFeatureButtonCaps));
  696. if ( ! ( HidDevice->FeatureButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
  697. MemAlloc (HidDevice->Caps.NumberFeatureButtonCaps *
  698. sizeof (HIDP_BUTTON_CAPS)) ) )
  699. {
  700. DWORD dwCnt;
  701. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  702. {
  703. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  704. }
  705. MemFree(HidDevice->InputData);
  706. MemFree(HidDevice->InputReportBuffer);
  707. MemFree(HidDevice->InputButtonCaps);
  708. MemFree(HidDevice->InputValueCaps);
  709. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  710. {
  711. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  712. }
  713. MemFree(HidDevice->OutputData);
  714. MemFree(HidDevice->OutputReportBuffer);
  715. MemFree(HidDevice->OutputButtonCaps);
  716. MemFree(HidDevice->OutputValueCaps);
  717. MemFree(HidDevice->FeatureReportBuffer);
  718. return ERROR_OUTOFMEMORY;
  719. }
  720. LOG((PHONESP_TRACE,"FillDeviceInfo - NumberFeatureValueCaps %d", HidDevice->Caps.NumberFeatureValueCaps));
  721. HidDevice->FeatureValueCaps =
  722. valueCaps = (PHIDP_VALUE_CAPS)
  723. MemAlloc (HidDevice->Caps.NumberFeatureValueCaps *
  724. sizeof (HIDP_VALUE_CAPS));
  725. if ( ! valueCaps)
  726. {
  727. DWORD dwCnt;
  728. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  729. {
  730. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  731. }
  732. MemFree(HidDevice->InputData);
  733. MemFree(HidDevice->InputReportBuffer);
  734. MemFree(HidDevice->InputButtonCaps);
  735. MemFree(HidDevice->InputValueCaps);
  736. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  737. {
  738. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  739. }
  740. MemFree(HidDevice->OutputData);
  741. MemFree(HidDevice->OutputReportBuffer);
  742. MemFree(HidDevice->OutputButtonCaps);
  743. MemFree(HidDevice->OutputValueCaps);
  744. MemFree(HidDevice->FeatureReportBuffer);
  745. MemFree(HidDevice->FeatureButtonCaps);
  746. return ERROR_OUTOFMEMORY;
  747. }
  748. numCaps = HidDevice->Caps.NumberFeatureButtonCaps;
  749. HidP_GetButtonCaps (HidP_Feature,
  750. buttonCaps,
  751. &numCaps,
  752. HidDevice->Ppd);
  753. numCaps = HidDevice->Caps.NumberFeatureValueCaps;
  754. HidP_GetValueCaps (HidP_Feature,
  755. valueCaps,
  756. &numCaps,
  757. HidDevice->Ppd);
  758. numValues = 0;
  759. for (i = 0; i < HidDevice->Caps.NumberFeatureValueCaps; i++, valueCaps++)
  760. {
  761. if (valueCaps->IsRange)
  762. {
  763. numValues += valueCaps->Range.UsageMax
  764. - valueCaps->Range.UsageMin + 1;
  765. }
  766. else
  767. {
  768. numValues++;
  769. }
  770. }
  771. valueCaps = HidDevice->FeatureValueCaps;
  772. HidDevice->FeatureDataLength = HidDevice->Caps.NumberFeatureButtonCaps
  773. + numValues;
  774. HidDevice->FeatureData =
  775. data = (PHID_DATA)
  776. MemAlloc (HidDevice->FeatureDataLength * sizeof (HID_DATA));
  777. if ( ! data )
  778. {
  779. DWORD dwCnt;
  780. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  781. {
  782. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  783. }
  784. MemFree(HidDevice->InputData);
  785. MemFree(HidDevice->InputReportBuffer);
  786. MemFree(HidDevice->InputButtonCaps);
  787. MemFree(HidDevice->InputValueCaps);
  788. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  789. {
  790. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  791. }
  792. MemFree(HidDevice->OutputData);
  793. MemFree(HidDevice->OutputReportBuffer);
  794. MemFree(HidDevice->OutputButtonCaps);
  795. MemFree(HidDevice->OutputValueCaps);
  796. MemFree(HidDevice->FeatureReportBuffer);
  797. MemFree(HidDevice->FeatureButtonCaps);
  798. MemFree(HidDevice->FeatureValueCaps);
  799. return ERROR_OUTOFMEMORY;
  800. }
  801. for ( i = 0; i < HidDevice->Caps.NumberFeatureButtonCaps;
  802. i++, data++, buttonCaps++)
  803. {
  804. data->IsButtonData = TRUE;
  805. data->Status = HIDP_STATUS_SUCCESS;
  806. data->UsagePage = buttonCaps->UsagePage;
  807. if (buttonCaps->IsRange)
  808. {
  809. data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;
  810. data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;
  811. }
  812. else
  813. {
  814. data->ButtonData.UsageMin =
  815. data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;
  816. }
  817. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  818. HidP_Feature,
  819. buttonCaps->UsagePage,
  820. HidDevice->Ppd);
  821. data->ButtonData.Usages = (PUSAGE)
  822. MemAlloc (data->ButtonData.MaxUsageLength *
  823. sizeof (USAGE));
  824. if ( ! data->ButtonData.Usages )
  825. {
  826. DWORD dwCnt;
  827. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  828. {
  829. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  830. }
  831. MemFree(HidDevice->InputData);
  832. MemFree(HidDevice->InputReportBuffer);
  833. MemFree(HidDevice->InputButtonCaps);
  834. MemFree(HidDevice->InputValueCaps);
  835. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  836. {
  837. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  838. }
  839. MemFree(HidDevice->OutputData);
  840. MemFree(HidDevice->OutputReportBuffer);
  841. MemFree(HidDevice->OutputButtonCaps);
  842. MemFree(HidDevice->OutputValueCaps);
  843. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberFeatureButtonCaps; dwCnt++)
  844. {
  845. MemFree(HidDevice->FeatureData[dwCnt].ButtonData.Usages);
  846. }
  847. MemFree(HidDevice->FeatureData);
  848. MemFree(HidDevice->FeatureReportBuffer);
  849. MemFree(HidDevice->FeatureButtonCaps);
  850. MemFree(HidDevice->FeatureValueCaps);
  851. return ERROR_OUTOFMEMORY;
  852. }
  853. data->ReportID = buttonCaps->ReportID;
  854. }
  855. for (i = 0; i < numValues; i++, valueCaps++)
  856. {
  857. if (valueCaps->IsRange)
  858. {
  859. for (usage = valueCaps->Range.UsageMin;
  860. usage <= valueCaps->Range.UsageMax;
  861. usage++)
  862. {
  863. data->IsButtonData = FALSE;
  864. data->Status = HIDP_STATUS_SUCCESS;
  865. data->UsagePage = valueCaps->UsagePage;
  866. data->ValueData.Usage = usage;
  867. data->ReportID = valueCaps->ReportID;
  868. data++;
  869. }
  870. }
  871. else
  872. {
  873. data->IsButtonData = FALSE;
  874. data->Status = HIDP_STATUS_SUCCESS;
  875. data->UsagePage = valueCaps->UsagePage;
  876. data->ValueData.Usage = valueCaps->NotRange.Usage;
  877. data->ReportID = valueCaps -> ReportID;
  878. data++;
  879. }
  880. }
  881. LOG((PHONESP_TRACE,"FillDeviceInfo - exit"));
  882. return ERROR_SUCCESS;
  883. }
  884. VOID
  885. CloseHidDevices()
  886. {
  887. LOG((PHONESP_TRACE, "CloseHidDevices - enter"));
  888. while (gpHidDevices != NULL)
  889. {
  890. CloseHidDevice(gpHidDevices);
  891. }
  892. LOG((PHONESP_TRACE, "CloseHidDevices - exit"));
  893. return;
  894. }
  895. BOOL
  896. OpenHidFile (
  897. IN PHID_DEVICE HidDevice
  898. )
  899. {
  900. LOG((PHONESP_TRACE, "OpenHidFile - enter"));
  901. if (HidDevice != NULL)
  902. {
  903. if (HidDevice->functionClassDeviceData != NULL)
  904. {
  905. HidDevice->HidDevice = CreateFile (
  906. HidDevice->functionClassDeviceData->DevicePath,
  907. GENERIC_READ | GENERIC_WRITE,
  908. FILE_SHARE_READ | FILE_SHARE_WRITE,
  909. NULL, // no SECURITY_ATTRIBUTES structure
  910. OPEN_EXISTING, // No special create flags
  911. FILE_FLAG_OVERLAPPED, // No special attributes
  912. NULL); // No template file
  913. if (INVALID_HANDLE_VALUE == HidDevice->HidDevice)
  914. {
  915. LOG((PHONESP_ERROR,"OpenHidFile - CreateFile failed: %d", GetLastError()));
  916. return FALSE;
  917. }
  918. LOG((PHONESP_TRACE, "OpenHidFile - exit"));
  919. return TRUE;
  920. }
  921. }
  922. LOG((PHONESP_WARN, "OpenHidFile - no device"));
  923. return FALSE;
  924. }
  925. BOOL
  926. CloseHidFile (
  927. IN PHID_DEVICE HidDevice
  928. )
  929. {
  930. LOG((PHONESP_TRACE, "CloseHidFile - enter"));
  931. if (HidDevice != NULL)
  932. {
  933. if ((NULL != HidDevice->HidDevice) &&
  934. (INVALID_HANDLE_VALUE != HidDevice->HidDevice))
  935. {
  936. CloseHandle(HidDevice->HidDevice);
  937. HidDevice->HidDevice = NULL;
  938. LOG((PHONESP_TRACE, "CloseHidFile - exit"));
  939. return TRUE;
  940. }
  941. }
  942. LOG((PHONESP_WARN, "CloseHidFile - no device"));
  943. return FALSE;
  944. }
  945. VOID
  946. CloseHidDevice (
  947. IN PHID_DEVICE HidDevice
  948. )
  949. {
  950. LOG((PHONESP_TRACE, "CloseHidDevice - enter"));
  951. if (HidDevice != NULL)
  952. {
  953. if (NULL != HidDevice->functionClassDeviceData)
  954. {
  955. MemFree(HidDevice->functionClassDeviceData);
  956. }
  957. if ((NULL != HidDevice -> HidDevice) &&
  958. (INVALID_HANDLE_VALUE != HidDevice -> HidDevice))
  959. {
  960. CloseHandle(HidDevice->HidDevice);
  961. HidDevice->HidDevice = NULL;
  962. }
  963. if (NULL != HidDevice->Ppd)
  964. {
  965. HidD_FreePreparsedData(HidDevice->Ppd);
  966. HidDevice->Ppd = NULL;
  967. }
  968. if (NULL != HidDevice->InputReportBuffer)
  969. {
  970. MemFree(HidDevice->InputReportBuffer);
  971. HidDevice->InputReportBuffer = NULL;
  972. }
  973. if (NULL != HidDevice->InputData)
  974. {
  975. DWORD dwCnt;
  976. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberInputButtonCaps; dwCnt++)
  977. {
  978. MemFree(HidDevice->InputData[dwCnt].ButtonData.Usages);
  979. HidDevice->InputData[dwCnt].ButtonData.Usages = NULL;
  980. }
  981. MemFree(HidDevice->InputData);
  982. HidDevice->InputData = NULL;
  983. }
  984. if (NULL != HidDevice->InputButtonCaps)
  985. {
  986. MemFree(HidDevice->InputButtonCaps);
  987. HidDevice->InputButtonCaps = NULL;
  988. }
  989. if (NULL != HidDevice->InputValueCaps)
  990. {
  991. MemFree(HidDevice->InputValueCaps);
  992. HidDevice->InputValueCaps = NULL;
  993. }
  994. if (NULL != HidDevice->OutputReportBuffer)
  995. {
  996. MemFree(HidDevice->OutputReportBuffer);
  997. HidDevice->OutputReportBuffer = NULL;
  998. }
  999. if (NULL != HidDevice->OutputData)
  1000. {
  1001. DWORD dwCnt;
  1002. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberOutputButtonCaps; dwCnt++)
  1003. {
  1004. MemFree(HidDevice->OutputData[dwCnt].ButtonData.Usages);
  1005. HidDevice->OutputData[dwCnt].ButtonData.Usages = NULL;
  1006. }
  1007. MemFree(HidDevice->OutputData);
  1008. HidDevice->OutputData = NULL;
  1009. }
  1010. if (NULL != HidDevice->OutputButtonCaps)
  1011. {
  1012. MemFree(HidDevice->OutputButtonCaps);
  1013. HidDevice->OutputButtonCaps = NULL;
  1014. }
  1015. if (NULL != HidDevice->OutputValueCaps)
  1016. {
  1017. MemFree(HidDevice->OutputValueCaps);
  1018. HidDevice->OutputValueCaps = NULL;
  1019. }
  1020. if (NULL != HidDevice->FeatureReportBuffer)
  1021. {
  1022. MemFree(HidDevice->FeatureReportBuffer);
  1023. HidDevice->FeatureReportBuffer = NULL;
  1024. }
  1025. if (NULL != HidDevice->FeatureData)
  1026. {
  1027. DWORD dwCnt;
  1028. for(dwCnt = 0; dwCnt < HidDevice->Caps.NumberFeatureButtonCaps; dwCnt++)
  1029. {
  1030. MemFree(HidDevice->FeatureData[dwCnt].ButtonData.Usages);
  1031. HidDevice->FeatureData[dwCnt].ButtonData.Usages = NULL;
  1032. }
  1033. MemFree(HidDevice->FeatureData);
  1034. HidDevice->FeatureData = NULL;
  1035. }
  1036. if (NULL != HidDevice->FeatureButtonCaps)
  1037. {
  1038. MemFree(HidDevice->FeatureButtonCaps);
  1039. HidDevice->FeatureButtonCaps = NULL;
  1040. }
  1041. if (NULL != HidDevice->FeatureValueCaps)
  1042. {
  1043. MemFree(HidDevice->FeatureValueCaps);
  1044. HidDevice->FeatureValueCaps = NULL;
  1045. }
  1046. RemoveHidDevice(HidDevice);
  1047. MemFree(HidDevice);
  1048. }
  1049. LOG((PHONESP_TRACE, "CloseHidDevice - exit"));
  1050. return;
  1051. }
  1052. VOID
  1053. AddHidDevice (
  1054. IN PHID_DEVICE HidDevice
  1055. )
  1056. {
  1057. LOG((PHONESP_TRACE, "AddHidDevice - enter"));
  1058. HidDevice->Next = gpHidDevices;
  1059. HidDevice->Prev = NULL;
  1060. if (gpHidDevices)
  1061. {
  1062. gpHidDevices->Prev = HidDevice;
  1063. }
  1064. gpHidDevices = HidDevice;
  1065. LOG((PHONESP_TRACE, "AddHidDevice - exit"));
  1066. }
  1067. VOID
  1068. RemoveHidDevice (
  1069. IN PHID_DEVICE HidDevice
  1070. )
  1071. {
  1072. LOG((PHONESP_TRACE, "RemoveHidDevice - enter"));
  1073. if (HidDevice->Prev)
  1074. {
  1075. HidDevice->Prev->Next = HidDevice->Next;
  1076. }
  1077. else
  1078. {
  1079. // first in list
  1080. gpHidDevices = HidDevice->Next;
  1081. }
  1082. if (HidDevice->Next)
  1083. {
  1084. HidDevice->Next->Prev = HidDevice->Prev;
  1085. }
  1086. HidDevice->Next = NULL;
  1087. HidDevice->Prev = NULL;
  1088. LOG((PHONESP_TRACE, "RemoveHidDevice - exit"));
  1089. }
  1090. PHID_DEVICE
  1091. FindHidDeviceByDevInst (
  1092. IN DWORD DevInst
  1093. )
  1094. {
  1095. PHID_DEVICE HidDevice = gpHidDevices;
  1096. LOG((PHONESP_TRACE, "FindHidDeviceByDevInst - enter"));
  1097. while (HidDevice != NULL)
  1098. {
  1099. if (HidDevice->dwDevInst == DevInst)
  1100. {
  1101. LOG((PHONESP_TRACE, "FindHidDeviceByDevInst - exit"));
  1102. return HidDevice;
  1103. }
  1104. HidDevice = HidDevice->Next;
  1105. }
  1106. LOG((PHONESP_WARN, "FindHidDeviceByDevInst - not found"));
  1107. return NULL;
  1108. }