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.

879 lines
30 KiB

  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <basetyps.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <wtypes.h>
  7. #include <wtypes.h>
  8. #include "hidsdi.h"
  9. #include "hid.h"
  10. #define INSTRUCTIONS "\nCommands:\n" \
  11. "\t?,h Display this message\n" \
  12. "\t<N> Enter device number \n" \
  13. "\tL LOOP read \n" \
  14. "\tx exit\n"
  15. #define PROMPT "Command!>"
  16. void PrintDeviceinfo(PHID_DEVICE HidDevices, LONG ulCount);
  17. int __cdecl main(int argc, char **argv)
  18. {
  19. PHID_DEVICE HidDevices, pWalk;
  20. LONG ulCount;
  21. BOOL bReturn, bDone, bOK;
  22. int uiLoop;
  23. PHID_DEVICE pDevice;
  24. PHID_DATA pData;
  25. unsigned uLoop;
  26. char sz[256], cCode;
  27. int i;
  28. DWORD dwDelay=100;
  29. bDone = FALSE;
  30. bReturn=FindKnownHidDevices(&HidDevices,&ulCount);
  31. printf("\n");
  32. if(argc > 1)
  33. dwDelay = atoi(argv[1]);
  34. if(!bReturn)
  35. {
  36. printf("Error FindKnownHidDevices returned FALSE\n");
  37. exit(0);
  38. }
  39. pDevice = HidDevices;
  40. if(!pDevice){
  41. printf("Hid Devices are not availabel\n");
  42. exit(0);
  43. }
  44. PrintDeviceinfo(HidDevices, ulCount);
  45. printf (INSTRUCTIONS);
  46. while (!bDone) {
  47. printf (PROMPT);
  48. if (gets (sz) == NULL) {
  49. sz[0] = 'x';
  50. sz[1] = '\0';
  51. }
  52. cCode = sz[0]; // if user types a blank before the command, too bad
  53. switch (cCode) {
  54. case 'h':
  55. case '?':
  56. printf (INSTRUCTIONS);
  57. break;
  58. case '0': case '1': case '2': case '3':
  59. case '4': case '5': case '6' : case '7':
  60. case '8': case '9':{
  61. if( cCode - '0' >= ulCount ) {
  62. printf("Error invalid input try again\n");
  63. continue;
  64. }
  65. pDevice = HidDevices + cCode - '0' ;
  66. Read(pDevice);
  67. pData=pDevice->InputData;
  68. for(uLoop=0;uLoop<pDevice->InputDataLength;uLoop++)
  69. {
  70. ReportToString(pData);
  71. pData++;
  72. } /*end for*/
  73. break;
  74. }
  75. case 'L': // loop read
  76. printf ("Loop read device %d\n", pDevice->HidDevice);
  77. Sleep(1000);
  78. for (i = 0; i < 1000; i++) {
  79. if(!Read(pDevice))
  80. // printf("Read returned false\n");
  81. pData=pDevice->InputData;
  82. printf("-------------------------------------------\n");
  83. for(uLoop=0;uLoop<pDevice->InputDataLength;uLoop++)
  84. {
  85. ReportToString(pData);
  86. pData++;
  87. } /*end for*/
  88. Sleep(dwDelay);
  89. }
  90. break;
  91. case 'x': // done
  92. bDone = TRUE;
  93. break;
  94. default:
  95. printf ("Huh? >%s<\n", sz);
  96. printf (INSTRUCTIONS);
  97. break;
  98. }
  99. } // end of while
  100. pWalk= HidDevices;
  101. for(uiLoop=0;uiLoop<ulCount;uiLoop++,pWalk++)
  102. CloseHandle(pWalk->HidDevice);
  103. return 0;
  104. }
  105. void
  106. PrintDeviceinfo(
  107. PHID_DEVICE HidDevices,
  108. LONG ulCount
  109. )
  110. {
  111. PHID_DEVICE pWalk;
  112. LONG uiLoop, i, num;
  113. PHIDP_VALUE_CAPS pValue;
  114. PHIDP_BUTTON_CAPS pButton;
  115. pWalk=HidDevices;
  116. for(uiLoop=0;uiLoop<ulCount;uiLoop++, pWalk++)
  117. {
  118. if(pWalk->Caps.UsagePage == HID_USAGE_PAGE_GENERIC) {
  119. switch(pWalk->Caps.Usage){
  120. case HID_USAGE_GENERIC_POINTER:
  121. printf("Device (%d) Pointer", uiLoop);break;
  122. case HID_USAGE_GENERIC_MOUSE:
  123. printf("Device (%d) Mouse", uiLoop);break;
  124. case HID_USAGE_GENERIC_PEN:
  125. printf("Device (%d) PEN", uiLoop);break;
  126. case HID_USAGE_GENERIC_JOYSTICK:
  127. printf("Device (%d) Joystick", uiLoop);break;
  128. case HID_USAGE_GENERIC_GAMEPAD:
  129. printf("Device (%d) GamePad", uiLoop);break;
  130. case HID_USAGE_GENERIC_KEYBOARD :
  131. printf("Device (%d) Keyboard", uiLoop);break;
  132. case HID_USAGE_GENERIC_KEYPAD :
  133. printf("Device (%d) Keypad", uiLoop);break;
  134. case HID_USAGE_GENERIC_STYLUS2:
  135. printf("Device (%d) Stylus2", uiLoop);break;
  136. case HID_USAGE_GENERIC_PUCK :
  137. printf("Device (%d) Pointer", uiLoop);break;
  138. case HID_USAGE_GENERIC_SYSTEM_CTL :
  139. printf("Device (%d) System Control", uiLoop);break;
  140. default: goto PRN;
  141. }// end of switch
  142. }
  143. else {
  144. PRN: printf("Device (%d) UsagePage:0%x Usage:0%x",
  145. uiLoop,pWalk->Caps.UsagePage,pWalk->Caps.Usage);
  146. }
  147. //pValue = pWalk->InputValueCaps;
  148. if(pWalk->Caps.NumberInputButtonCaps){
  149. pButton = pWalk->InputButtonCaps;
  150. for(num=0,i=0;i<pWalk->Caps.NumberInputButtonCaps;i++,pButton++)
  151. {
  152. num += (pButton->Range.UsageMax -
  153. pButton->Range.UsageMin + 1);
  154. }
  155. printf("\tNumInpBut(%d):%d",pWalk->Caps.NumberInputButtonCaps, num);
  156. }
  157. if(pWalk->Caps.NumberInputValueCaps){
  158. printf("\tInpValCaps:%d",pWalk->Caps.NumberInputValueCaps);
  159. }
  160. if(pWalk->Caps.NumberOutputButtonCaps){
  161. pButton = pWalk->OutputButtonCaps;
  162. for(num=0,i=0;i<pWalk->Caps.NumberOutputButtonCaps;i++,pButton++)
  163. {
  164. num += (pButton->Range.UsageMax -
  165. pButton->Range.UsageMin + 1);
  166. }
  167. printf("\tNumOutBut(%d):%d",pWalk->Caps.NumberOutputButtonCaps, num);
  168. }
  169. if(pWalk->Caps.NumberOutputValueCaps){
  170. printf("\tOutButCaps:%d\n",pWalk->Caps.NumberOutputValueCaps);
  171. }
  172. if(pWalk->Caps.NumberFeatureButtonCaps){
  173. pButton = pWalk->FeatureButtonCaps;
  174. for(num=0,i=0;i<pWalk->Caps.NumberFeatureButtonCaps;i++,pButton++)
  175. {
  176. num += (pButton->Range.UsageMax -
  177. pButton->Range.UsageMin + 1);
  178. }
  179. printf("\tNumFeatBut(%d):%d",pWalk->Caps.NumberFeatureButtonCaps, num);
  180. }
  181. if(pWalk->Caps.NumberFeatureValueCaps){
  182. printf("\tFeatButCaps:%d\n",pWalk->Caps.NumberFeatureValueCaps);
  183. }
  184. printf("\n");
  185. } /*end for*/
  186. }
  187. BOOLEAN
  188. FindKnownHidDevices (
  189. OUT PHID_DEVICE * HidDevices, // A array of struct _HID_DEVICE
  190. OUT PULONG NumberDevices // the length of this array.
  191. )
  192. /*++
  193. Routine Description:
  194. Do the required PnP things in order to find, the all the HID devices in
  195. the system at this time.
  196. --*/
  197. {
  198. HDEVINFO hardwareDeviceInfo;
  199. SP_DEVICE_INTERFACE_DATA deviceInfoData;
  200. ULONG i;
  201. BOOL done;
  202. PHID_DEVICE hidDeviceInst;
  203. GUID hidGuid;
  204. HidD_GetHidGuid (&hidGuid);
  205. *HidDevices = NULL;
  206. *NumberDevices = 0;
  207. //
  208. // Open a handle to the plug and play dev node.
  209. //
  210. hardwareDeviceInfo = SetupDiGetClassDevs (
  211. &hidGuid,
  212. NULL, // Define no enumerator (global)
  213. NULL, // Define no
  214. (DIGCF_PRESENT | // Only Devices present
  215. DIGCF_DEVICEINTERFACE)); // Function class devices.
  216. //
  217. // Take a wild guess to start
  218. //
  219. *NumberDevices = 4;
  220. done = FALSE;
  221. deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
  222. i=0;
  223. while (!done) {
  224. *NumberDevices *= 2;
  225. if (*HidDevices) {
  226. *HidDevices =
  227. realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE)));
  228. } else {
  229. *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE));
  230. }
  231. if (NULL == *HidDevices) {
  232. SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  233. return FALSE;
  234. }
  235. hidDeviceInst = *HidDevices + i;
  236. for (; i < *NumberDevices; i++, hidDeviceInst++) {
  237. if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
  238. 0, // No care about specific PDOs
  239. &hidGuid,
  240. i,
  241. &deviceInfoData)) {
  242. OpenHidDevice (hardwareDeviceInfo, &deviceInfoData, hidDeviceInst);
  243. } else {
  244. if (ERROR_NO_MORE_ITEMS == GetLastError()) {
  245. done = TRUE;
  246. break;
  247. }
  248. }
  249. }
  250. }
  251. *NumberDevices = i;
  252. SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  253. return TRUE;
  254. }
  255. VOID
  256. ReportToString(
  257. PHID_DATA pData
  258. )
  259. {
  260. PUSAGE pUsage;
  261. ULONG i;
  262. if (pData->IsButtonData && pData->UsagePage == HID_USAGE_PAGE_BUTTON )
  263. {
  264. printf (" Buttons :");
  265. for (i=0, pUsage = pData->ButtonData.Usages;
  266. i < pData->ButtonData.MaxUsageLength;
  267. i++, pUsage++) {
  268. if (0 == *pUsage) {
  269. break; // A usage of zero is a non button.
  270. }
  271. printf (" 0x%x", *pUsage);
  272. }
  273. printf("\n");
  274. }
  275. else
  276. {
  277. switch(pData->UsagePage) {
  278. case HID_USAGE_PAGE_GENERIC :
  279. case HID_USAGE_PAGE_VEHICLE :
  280. switch(pData->ValueData.Usage) {
  281. case HID_USAGE_VEHICLE_THROTTLE:
  282. printf(" THROTTLE(%4d) :%4d\n",
  283. pData->ValueData.ScaledValue,
  284. pData->ValueData.Value);
  285. break;
  286. case HID_USAGE_VEHICLE_RUDDER:
  287. printf(" RUDDER(%4d) :%4d\n",
  288. pData->ValueData.ScaledValue,
  289. pData->ValueData.Value);
  290. break;
  291. case HID_USAGE_GENERIC_X:
  292. printf(" X(%4d) :%4d\n",
  293. pData->ValueData.ScaledValue,
  294. pData->ValueData.Value);
  295. break;
  296. case HID_USAGE_GENERIC_Y:
  297. printf(" Y(%4d) :%4d\n",
  298. pData->ValueData.ScaledValue,
  299. pData->ValueData.Value);
  300. break;
  301. case HID_USAGE_GENERIC_Z:
  302. printf(" Z(%4d) :%4d\n",
  303. pData->ValueData.ScaledValue,
  304. pData->ValueData.Value);
  305. break;
  306. case HID_USAGE_GENERIC_RX:
  307. printf(" RX(%4d) :%4d\n",
  308. pData->ValueData.ScaledValue,
  309. pData->ValueData.Value);
  310. break;
  311. case HID_USAGE_GENERIC_RY:
  312. printf(" RY(%4d) :%4d\n",
  313. pData->ValueData.ScaledValue,
  314. pData->ValueData.Value);
  315. break;
  316. case HID_USAGE_GENERIC_RZ:
  317. printf(" RZ(%4d) :%4d\n",
  318. pData->ValueData.ScaledValue,
  319. pData->ValueData.Value);
  320. break;
  321. case HID_USAGE_GENERIC_SLIDER:
  322. printf(" SLIDDER(%4d) :%4d\n",
  323. pData->ValueData.ScaledValue,
  324. pData->ValueData.Value);
  325. break;
  326. case HID_USAGE_GENERIC_DIAL:
  327. printf(" DIAL(%4d) :%4d\n",
  328. pData->ValueData.ScaledValue,
  329. pData->ValueData.Value);
  330. break;
  331. case HID_USAGE_GENERIC_WHEEL:
  332. printf(" WHEEL(%4d) :%4d\n",
  333. pData->ValueData.ScaledValue,
  334. pData->ValueData.Value);
  335. break;
  336. case HID_USAGE_GENERIC_HATSWITCH:
  337. printf(" HATSWITCH(%4d):%4d\n",
  338. pData->ValueData.ScaledValue,
  339. pData->ValueData.Value);
  340. break;
  341. default:
  342. goto END;
  343. break;
  344. }// end of switch
  345. break;
  346. case HID_USAGE_PAGE_KEYBOARD:
  347. switch(pData->ValueData.Usage) {
  348. case HID_USAGE_GENERIC_KEYBOARD:
  349. printf(" KEYBOARD(%4d) :%4d\n",
  350. pData->ValueData.ScaledValue,
  351. pData->ValueData.Value);
  352. break;
  353. case HID_USAGE_GENERIC_KEYPAD:
  354. printf(" KEYPAD(%4d) :%4d\n",
  355. pData->ValueData.ScaledValue,
  356. pData->ValueData.Value);
  357. break;
  358. default:
  359. goto END;
  360. break;
  361. }// end of switch
  362. default:
  363. END: printf ("Usage Page: 0x%x, Usage: 0x%x, Scaled: %d Value:%d\n",
  364. pData->UsagePage,
  365. pData->ValueData.Usage,
  366. pData->ValueData.ScaledValue,
  367. pData->ValueData.Value);
  368. }//end of switch
  369. }
  370. }
  371. BOOLEAN
  372. Read (
  373. PHID_DEVICE HidDevice
  374. )
  375. /*++
  376. RoutineDescription:
  377. Given a struct _HID_DEVICE, obtain a read report and unpack the values
  378. into to InputData array.
  379. --*/
  380. {
  381. DWORD bytesRead;
  382. if (!ReadFile (HidDevice->HidDevice,
  383. HidDevice->InputReportBuffer,
  384. HidDevice->Caps.InputReportByteLength,
  385. &bytesRead,
  386. NULL)) { // No overlapped structure. HidClass buffers for us.
  387. return FALSE;
  388. }
  389. ASSERT (bytesRead == hidDevice->Caps.InputReportByteLength);
  390. return UnpackReport (HidDevice->InputReportBuffer,
  391. HidDevice->Caps.InputReportByteLength,
  392. HidP_Input,
  393. HidDevice->InputData,
  394. HidDevice->InputDataLength,
  395. HidDevice->Ppd);
  396. }
  397. BOOL
  398. UnpackReport (
  399. IN PCHAR ReportBuffer,
  400. IN USHORT ReportBufferLength,
  401. IN HIDP_REPORT_TYPE ReportType,
  402. IN OUT PHID_DATA Data,
  403. IN ULONG DataLength,
  404. IN PHIDP_PREPARSED_DATA Ppd
  405. )
  406. /*++
  407. Routine Description:
  408. --*/
  409. {
  410. ULONG numUsages; // Number of usages returned from GetUsages.
  411. ULONG i;
  412. for (i = 0; i < DataLength; i++, Data++) {
  413. if (Data->IsButtonData) {
  414. numUsages = Data->ButtonData.MaxUsageLength;
  415. Data->Status = HidP_GetUsages (
  416. ReportType,
  417. Data->UsagePage,
  418. 0, // All collections
  419. Data->ButtonData.Usages,
  420. &numUsages,
  421. Ppd,
  422. ReportBuffer,
  423. ReportBufferLength);
  424. //
  425. // Get usages writes the list of usages into the buffer
  426. // Data->ButtonData.Usages newUsage is set to the number of usages
  427. // written into this array.
  428. // We assume that there will not be a usage of zero.
  429. // (None have been defined to date.)
  430. // So lets assume that a zero indicates an end of the list of usages.
  431. //
  432. if (numUsages < Data->ButtonData.MaxUsageLength) {
  433. Data->ButtonData.Usages[numUsages] = 0;
  434. }
  435. } else {
  436. Data->Status = HidP_GetUsageValue (
  437. ReportType,
  438. Data->UsagePage,
  439. 0, // All Collections.
  440. Data->ValueData.Usage,
  441. &Data->ValueData.Value,
  442. Ppd,
  443. ReportBuffer,
  444. ReportBufferLength);
  445. Data->Status = HidP_GetScaledUsageValue (
  446. ReportType,
  447. Data->UsagePage,
  448. 0, // All Collections.
  449. Data->ValueData.Usage,
  450. &Data->ValueData.ScaledValue,
  451. Ppd,
  452. ReportBuffer,
  453. ReportBufferLength);
  454. }
  455. }
  456. return (HIDP_STATUS_SUCCESS == Data->Status);
  457. }
  458. BOOLEAN
  459. OpenHidDevice (
  460. IN HDEVINFO HardwareDeviceInfo,
  461. IN PSP_DEVICE_INTERFACE_DATA DeviceInfoData,
  462. IN OUT PHID_DEVICE HidDevice
  463. )
  464. /*++
  465. RoutineDescription:
  466. Given the HardwareDeviceInfo, representing a handle to the plug and
  467. play information, and deviceInfoData, representing a specific hid device,
  468. open that device and fill in all the relivant information in the given
  469. HID_DEVICE structure.
  470. return if the open and initialization was successfull or not.
  471. --*/
  472. {
  473. PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL;
  474. ULONG predictedLength = 0;
  475. ULONG requiredLength = 0;
  476. ULONG i;
  477. ULONG numValues;
  478. USHORT numCaps;
  479. PHIDP_BUTTON_CAPS buttonCaps;
  480. PHIDP_VALUE_CAPS valueCaps;
  481. PHID_DATA data;
  482. USAGE usage;
  483. static ULONG NumberDevices = 0;
  484. //
  485. // allocate a function class device data structure to receive the
  486. // goods about this particular device.
  487. //
  488. SetupDiGetDeviceInterfaceDetail (
  489. HardwareDeviceInfo,
  490. DeviceInfoData,
  491. NULL, // probing so no output buffer yet
  492. 0, // probing so output buffer length of zero
  493. &requiredLength,
  494. NULL); // not interested in the specific dev-node
  495. predictedLength = requiredLength;
  496. functionClassDeviceData = malloc (predictedLength);
  497. functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
  498. //
  499. // Retrieve the information from Plug and Play.
  500. //
  501. if (! SetupDiGetDeviceInterfaceDetail (
  502. HardwareDeviceInfo,
  503. DeviceInfoData,
  504. functionClassDeviceData,
  505. predictedLength,
  506. &requiredLength,
  507. NULL)) {
  508. return FALSE;
  509. }
  510. //printf("\nDevicePath of %d HID device: %s\n", NumberDevices,
  511. // functionClassDeviceData->DevicePath);
  512. HidDevice->HidDevice = CreateFile (
  513. functionClassDeviceData->DevicePath,
  514. GENERIC_READ | GENERIC_WRITE,
  515. 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
  516. NULL, // no SECURITY_ATTRIBUTES structure
  517. OPEN_EXISTING, // No special create flags
  518. 0, // No special attributes
  519. NULL); // No template file
  520. if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) {
  521. return FALSE;
  522. }
  523. if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) {
  524. return FALSE;
  525. }
  526. if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps)) {
  527. HidD_FreePreparsedData (HidDevice->Ppd);
  528. return FALSE;
  529. }
  530. NumberDevices++;
  531. //
  532. // At this point the client has a choise. It may chose to look at the
  533. // Usage and Page of the top level collection found in the HIDP_CAPS
  534. // structure. In this way it could just use the usages it knows about.
  535. // If either HidP_GetUsages or HidP_GetUsageValue return an error then
  536. // that particular usage does not exist in the report.
  537. // This is most likely the preferred method as the application can only
  538. // use usages of which it already knows.
  539. // In this case the app need not even call GetButtonCaps or GetValueCaps.
  540. //
  541. // In this example, however, we look for all of the usages in the device.
  542. //
  543. //
  544. // setup Input Data buffers.
  545. //
  546. //
  547. // Allocate memory to hold on input report
  548. //
  549. HidDevice->InputReportBuffer = (PCHAR)
  550. calloc (HidDevice->Caps.InputReportByteLength, sizeof (CHAR));
  551. //
  552. // Allocate memory to hold the button and value capabilities.
  553. // NumberXXCaps is in terms of array elements.
  554. //
  555. HidDevice->InputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
  556. calloc (HidDevice->Caps.NumberInputButtonCaps, sizeof (HIDP_BUTTON_CAPS));
  557. HidDevice->InputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
  558. calloc (HidDevice->Caps.NumberInputValueCaps, sizeof (HIDP_VALUE_CAPS));
  559. //
  560. // Have the HidP_X functions fill in the capability structure arrays.
  561. //
  562. numCaps = HidDevice->Caps.NumberInputButtonCaps;
  563. HidP_GetButtonCaps (HidP_Input,
  564. buttonCaps,
  565. &numCaps,
  566. HidDevice->Ppd);
  567. numCaps = HidDevice->Caps.NumberInputValueCaps;
  568. HidP_GetValueCaps (HidP_Input,
  569. valueCaps,
  570. &numCaps,
  571. HidDevice->Ppd);
  572. //
  573. // Depending on the device, some value caps structures may represent more
  574. // than one value. (A range). In the interest of being verbose, over
  575. // efficient we will expand these so that we have one and only one
  576. // struct _HID_DATA for each value.
  577. //
  578. // To do this we need to count up the total number of values are listed
  579. // in the value caps structure. For each element in the array we test
  580. // for range if it is a range then UsageMax and UsageMin describe the
  581. // usages for this range INCLUSIVE.
  582. //
  583. numValues = 0;
  584. for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++) {
  585. if (valueCaps->IsRange) {
  586. numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
  587. } else {
  588. numValues++;
  589. }
  590. }
  591. valueCaps = HidDevice->InputValueCaps;
  592. //
  593. // Allocate a buffer to hold the struct _HID_DATA structures.
  594. // One element for each set of buttons, and one element for each value
  595. // found.
  596. //
  597. HidDevice->InputDataLength = HidDevice->Caps.NumberInputButtonCaps
  598. + numValues;
  599. HidDevice->InputData = data = (PHID_DATA)
  600. calloc (HidDevice->InputDataLength, sizeof (HID_DATA));
  601. //
  602. // Fill in the button data
  603. //
  604. for (i = 0;
  605. i < HidDevice->Caps.NumberInputButtonCaps;
  606. i++, data++, buttonCaps++) {
  607. data->IsButtonData = TRUE;
  608. data->Status = HIDP_STATUS_SUCCESS;
  609. data->UsagePage = buttonCaps->UsagePage;
  610. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  611. HidP_Input,
  612. buttonCaps->UsagePage,
  613. HidDevice->Ppd);
  614. data->ButtonData.Usages = (PUSAGE)
  615. calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
  616. }
  617. //
  618. // Fill in the value data
  619. //
  620. for (i = 0; i < numValues; i++, valueCaps++) {
  621. if (valueCaps->IsRange) {
  622. for (usage = valueCaps->Range.UsageMin;
  623. usage <= valueCaps->Range.UsageMax;
  624. usage++) {
  625. data->IsButtonData = FALSE;
  626. data->Status = HIDP_STATUS_SUCCESS;
  627. data->UsagePage = valueCaps->UsagePage;
  628. data->ValueData.Usage = usage;
  629. data++;
  630. }
  631. } else {
  632. data->IsButtonData = FALSE;
  633. data->Status = HIDP_STATUS_SUCCESS;
  634. data->UsagePage = valueCaps->UsagePage;
  635. data->ValueData.Usage = valueCaps->NotRange.Usage;
  636. data++;
  637. }
  638. }
  639. //return TRUE; // no need to get other info
  640. //
  641. // setup Output Data buffers.
  642. //
  643. HidDevice->OutputReportBuffer = (PCHAR)
  644. calloc (HidDevice->Caps.OutputReportByteLength, sizeof (CHAR));
  645. HidDevice->OutputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
  646. calloc (HidDevice->Caps.NumberOutputButtonCaps, sizeof (HIDP_BUTTON_CAPS));
  647. HidDevice->OutputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
  648. calloc (HidDevice->Caps.NumberOutputValueCaps, sizeof (HIDP_VALUE_CAPS));
  649. numCaps = HidDevice->Caps.NumberOutputButtonCaps;
  650. HidP_GetButtonCaps (HidP_Output,
  651. buttonCaps,
  652. &numCaps,
  653. HidDevice->Ppd);
  654. numCaps = HidDevice->Caps.NumberOutputValueCaps;
  655. HidP_GetValueCaps (HidP_Output,
  656. valueCaps,
  657. &numCaps,
  658. HidDevice->Ppd);
  659. numValues = 0;
  660. for (i = 0; i < HidDevice->Caps.NumberOutputValueCaps; i++, valueCaps++) {
  661. if (valueCaps->IsRange) {
  662. numValues += valueCaps->Range.UsageMax
  663. - valueCaps->Range.UsageMin + 1;
  664. } else {
  665. numValues++;
  666. }
  667. }
  668. valueCaps = HidDevice->OutputValueCaps;
  669. HidDevice->OutputDataLength = HidDevice->Caps.NumberOutputButtonCaps
  670. + numValues;
  671. HidDevice->OutputData = data = (PHID_DATA)
  672. calloc (HidDevice->OutputDataLength, sizeof (HID_DATA));
  673. for (i = 0;
  674. i < HidDevice->Caps.NumberOutputButtonCaps;
  675. i++, data++, buttonCaps++) {
  676. data->IsButtonData = TRUE;
  677. data->Status = HIDP_STATUS_SUCCESS;
  678. data->UsagePage = buttonCaps->UsagePage;
  679. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  680. HidP_Output,
  681. buttonCaps->UsagePage,
  682. HidDevice->Ppd);
  683. data->ButtonData.Usages = (PUSAGE)
  684. calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
  685. }
  686. for (i = 0; i < numValues; i++, valueCaps++) {
  687. if (valueCaps->IsRange) {
  688. for (usage = valueCaps->Range.UsageMin;
  689. usage <= valueCaps->Range.UsageMax;
  690. usage++) {
  691. data->IsButtonData = FALSE;
  692. data->Status = HIDP_STATUS_SUCCESS;
  693. data->UsagePage = valueCaps->UsagePage;
  694. data->ValueData.Usage = usage;
  695. data++;
  696. }
  697. } else {
  698. data->IsButtonData = FALSE;
  699. data->Status = HIDP_STATUS_SUCCESS;
  700. data->UsagePage = valueCaps->UsagePage;
  701. data->ValueData.Usage = valueCaps->NotRange.Usage;
  702. data++;
  703. }
  704. }
  705. //
  706. // setup Feature Data buffers.
  707. //
  708. HidDevice->FeatureReportBuffer = (PCHAR)
  709. calloc (HidDevice->Caps.FeatureReportByteLength, sizeof (CHAR));
  710. HidDevice->FeatureButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
  711. calloc (HidDevice->Caps.NumberFeatureButtonCaps, sizeof (HIDP_BUTTON_CAPS));
  712. HidDevice->FeatureValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
  713. calloc (HidDevice->Caps.NumberFeatureValueCaps, sizeof (HIDP_VALUE_CAPS));
  714. numCaps = HidDevice->Caps.NumberFeatureButtonCaps;
  715. HidP_GetButtonCaps (HidP_Feature,
  716. buttonCaps,
  717. &numCaps,
  718. HidDevice->Ppd);
  719. numCaps = HidDevice->Caps.NumberFeatureValueCaps;
  720. HidP_GetValueCaps (HidP_Feature,
  721. valueCaps,
  722. &numCaps,
  723. HidDevice->Ppd);
  724. numValues = 0;
  725. for (i = 0; i < HidDevice->Caps.NumberFeatureValueCaps; i++, valueCaps++) {
  726. if (valueCaps->IsRange) {
  727. numValues += valueCaps->Range.UsageMax
  728. - valueCaps->Range.UsageMin + 1;
  729. } else {
  730. numValues++;
  731. }
  732. }
  733. valueCaps = HidDevice->FeatureValueCaps;
  734. HidDevice->FeatureDataLength = HidDevice->Caps.NumberFeatureButtonCaps
  735. + numValues;
  736. HidDevice->FeatureData = data = (PHID_DATA)
  737. calloc (HidDevice->FeatureDataLength, sizeof (HID_DATA));
  738. for (i = 0;
  739. i < HidDevice->Caps.NumberFeatureButtonCaps;
  740. i++, data++, buttonCaps++) {
  741. data->IsButtonData = TRUE;
  742. data->Status = HIDP_STATUS_SUCCESS;
  743. data->UsagePage = buttonCaps->UsagePage;
  744. data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
  745. HidP_Feature,
  746. buttonCaps->UsagePage,
  747. HidDevice->Ppd);
  748. data->ButtonData.Usages = (PUSAGE)
  749. calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
  750. }
  751. for (i = 0; i < numValues; i++, valueCaps++) {
  752. if (valueCaps->IsRange) {
  753. for (usage = valueCaps->Range.UsageMin;
  754. usage <= valueCaps->Range.UsageMax;
  755. usage++) {
  756. data->IsButtonData = FALSE;
  757. data->Status = HIDP_STATUS_SUCCESS;
  758. data->UsagePage = valueCaps->UsagePage;
  759. data->ValueData.Usage = usage;
  760. data++;
  761. }
  762. } else {
  763. data->IsButtonData = FALSE;
  764. data->Status = HIDP_STATUS_SUCCESS;
  765. data->UsagePage = valueCaps->UsagePage;
  766. data->ValueData.Usage = valueCaps->NotRange.Usage;
  767. data++;
  768. }
  769. }
  770. return TRUE;
  771. }