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.

2247 lines
82 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. descript.c
  5. Abstract:
  6. This module contains the code for parsing HID descriptors.
  7. Environment:
  8. Kernel & user mode
  9. Revision History:
  10. Aug-96 : created by Kenneth Ray
  11. --*/
  12. #include "wdm.h"
  13. #include "hidpddi.h"
  14. #include "hidusage.h"
  15. #define FAR
  16. #include "poclass.h"
  17. #include "hidparse.h"
  18. #define HIDP_LINK_COLLECTION_NODE use internal "private" only
  19. #define PHIDP_LINK_COLLECTION_NODE use internal "private" only
  20. typedef struct _HIDP_COLLECTION_DESC_LIST
  21. {
  22. struct _HIDP_COLLECTION_DESC;
  23. struct _HIDP_COLLECTION_DESC_LIST * NextCollection;
  24. } HIDP_COLLECTION_DESC_LIST, *PHIDP_COLLECTION_DESC_LIST;
  25. typedef struct _HIDP_PARSE_GLOBAL_PUSH
  26. {
  27. USHORT UsagePage;
  28. USHORT ReportSize, ReportCount;
  29. USHORT NumGlobalUnknowns;
  30. LONG LogicalMin, LogicalMax;
  31. LONG PhysicalMin, PhysicalMax;
  32. ULONG UnitExp, Unit;
  33. HIDP_UNKNOWN_TOKEN GlobalUnknowns [HIDP_MAX_UNKNOWN_ITEMS];
  34. struct _HIDP_REPORT_IDS * ReportIDs;
  35. struct _HIDP_PARSE_GLOBAL_PUSH * Pop;
  36. } HIDP_PARSE_GLOBAL_PUSH, *PHIDP_PARSE_GLOBAL_PUSH;
  37. typedef struct _HIDP_PARSE_LOCAL_RANGE
  38. {
  39. BOOLEAN Range;
  40. BOOLEAN IsAlias;
  41. // This usage is an alias (as declaired with a delimiter)
  42. // An alias of the next LOCAL_RANGE on the LOCAL_RANGE stack
  43. USHORT UsagePage;
  44. USHORT Value, Min, Max;
  45. } HIDP_PARSE_LOCAL_RANGE, *PHIDP_PARSE_LOCAL_RANGE;
  46. typedef struct _HIDP_PARSE_LOCAL_RANGE_LIST
  47. {
  48. HIDP_PARSE_LOCAL_RANGE;
  49. UCHAR Depth;
  50. UCHAR Reserved2[1];
  51. struct _HIDP_PARSE_LOCAL_RANGE_LIST * Next;
  52. } HIDP_PARSE_LOCAL_RANGE_LIST, *PHIDP_PARSE_LOCAL_RANGE_LIST;
  53. NTSTATUS HidP_AllocateCollections (PHIDP_REPORT_DESCRIPTOR, ULONG, POOL_TYPE, PHIDP_COLLECTION_DESC_LIST *, PULONG, PHIDP_GETCOLDESC_DBG, PHIDP_DEVICE_DESC);
  54. NTSTATUS HidP_ParseCollections (PHIDP_REPORT_DESCRIPTOR, ULONG, POOL_TYPE, PHIDP_COLLECTION_DESC_LIST, ULONG, PHIDP_GETCOLDESC_DBG, PHIDP_DEVICE_DESC);
  55. void HidP_AssignDataIndices (PHIDP_PREPARSED_DATA, PHIDP_GETCOLDESC_DBG);
  56. PHIDP_PARSE_LOCAL_RANGE_LIST HidP_FreeUsageList (PHIDP_PARSE_LOCAL_RANGE_LIST);
  57. PHIDP_PARSE_LOCAL_RANGE_LIST HidP_PushUsageList (PHIDP_PARSE_LOCAL_RANGE_LIST, POOL_TYPE, BOOLEAN);
  58. PHIDP_PARSE_LOCAL_RANGE_LIST HidP_PopUsageList (PHIDP_PARSE_LOCAL_RANGE_LIST);
  59. #ifdef ALLOC_PRAGMA
  60. #pragma alloc_text(PAGE, HidP_AllocateCollections)
  61. #pragma alloc_text(PAGE, HidP_ParseCollections)
  62. #pragma alloc_text(PAGE, HidP_AssignDataIndices)
  63. #pragma alloc_text(PAGE, HidP_GetCollectionDescription)
  64. #pragma alloc_text(PAGE, HidP_FreeUsageList)
  65. #pragma alloc_text(PAGE, HidP_PushUsageList)
  66. #pragma alloc_text(PAGE, HidP_PopUsageList)
  67. #endif
  68. NTSTATUS
  69. HidP_GetCollectionDescription(
  70. IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
  71. IN ULONG DescLength,
  72. IN POOL_TYPE PoolType,
  73. OUT PHIDP_DEVICE_DESC DeviceDesc
  74. )
  75. /*++
  76. Routine Description:
  77. see hidpi.h for a description of this function.
  78. GetCollectionDescription is a one time cost.
  79. The following function and its support functions were put together
  80. in as straight forward (as HID will allow) manner.
  81. Not major opt. has been made.
  82. --*/
  83. {
  84. NTSTATUS status = STATUS_SUCCESS;
  85. PHIDP_COLLECTION_DESC_LIST collectDesc = 0;
  86. PHIDP_COLLECTION_DESC_LIST nextCollectDesc = 0;
  87. ULONG numCols = 0;
  88. ULONG collectionDescLength = 0;
  89. // First Pass allocate memory for the collections.
  90. DeviceDesc->Dbg.ErrorCode = HIDP_GETCOLDESC_SUCCESS;
  91. RtlZeroMemory (DeviceDesc, sizeof (HIDP_DEVICE_DESC));
  92. HidP_KdPrint(0, ("'Preparing to Allocate memory\n"));
  93. status = HidP_AllocateCollections (ReportDesc,
  94. DescLength,
  95. PoolType,
  96. &collectDesc,
  97. &numCols,
  98. &DeviceDesc->Dbg,
  99. DeviceDesc);
  100. if (0 == numCols)
  101. {
  102. // No collections were reported. That means that this device did not
  103. // report any top level collections in its report descriptor.
  104. // This is most bad.
  105. status = STATUS_NO_DATA_DETECTED;
  106. goto HIDP_GETCOLLECTIONS_REJECT;
  107. }
  108. if (!NT_SUCCESS(status))
  109. {
  110. // Something went wrong in the allocation of the memory.
  111. goto HIDP_GETCOLLECTIONS_REJECT;
  112. }
  113. // Second Pass fill in the data.
  114. HidP_KdPrint(0, ("'Starting Parsing Pass\n"));
  115. status = HidP_ParseCollections(ReportDesc,
  116. DescLength,
  117. PoolType,
  118. collectDesc,
  119. numCols,
  120. &DeviceDesc->Dbg,
  121. DeviceDesc);
  122. if (NT_SUCCESS (status))
  123. {
  124. DeviceDesc->CollectionDesc =
  125. (PHIDP_COLLECTION_DESC)
  126. ExAllocatePool (PoolType, numCols * sizeof (HIDP_COLLECTION_DESC));
  127. if (! (DeviceDesc->CollectionDesc))
  128. {
  129. status = STATUS_INSUFFICIENT_RESOURCES;
  130. HidP_KdPrint(2, ("Insufficitent Resources at VERY END\n"));
  131. DeviceDesc->Dbg.BreakOffset = DescLength;
  132. DeviceDesc->Dbg.ErrorCode = HIDP_GETCOLDESC_RESOURCES;
  133. goto HIDP_GETCOLLECTIONS_REJECT;
  134. }
  135. //
  136. // Here we flatten out the collection descriptions but we never
  137. // flatten the PHIDP_PREPARSED_DATA data. We could (should) do that as
  138. // well if we ever optimize.
  139. //
  140. DeviceDesc->CollectionDescLength = numCols;
  141. numCols = 0;
  142. while (collectDesc)
  143. {
  144. nextCollectDesc = collectDesc->NextCollection;
  145. RtlCopyMemory (DeviceDesc->CollectionDesc + (numCols++),
  146. collectDesc,
  147. sizeof (HIDP_COLLECTION_DESC));
  148. HidP_AssignDataIndices (collectDesc->PreparsedData, &DeviceDesc->Dbg);
  149. ExFreePool (collectDesc);
  150. collectDesc = nextCollectDesc;
  151. }
  152. return STATUS_SUCCESS;
  153. }
  154. HIDP_GETCOLLECTIONS_REJECT:
  155. while (collectDesc)
  156. {
  157. nextCollectDesc = collectDesc->NextCollection;
  158. if (collectDesc->PreparsedData)
  159. {
  160. ExFreePool (collectDesc->PreparsedData);
  161. }
  162. ExFreePool (collectDesc);
  163. collectDesc = nextCollectDesc;
  164. }
  165. if (DeviceDesc->ReportIDs)
  166. {
  167. ExFreePool (DeviceDesc->ReportIDs);
  168. }
  169. return status;
  170. }
  171. #define MORE_DATA(_pos_, _len_) \
  172. if (!((_pos_) < (_len_))) \
  173. { \
  174. DeviceDesc->Dbg.BreakOffset = descIndex; \
  175. DeviceDesc->Dbg.ErrorCode = HIDP_GETCOLDESC_BUFFER; \
  176. return STATUS_BUFFER_TOO_SMALL; \
  177. }
  178. NTSTATUS
  179. HidP_AllocateCollections (
  180. IN PHIDP_REPORT_DESCRIPTOR RepDesc,
  181. IN ULONG RepDescLen,
  182. IN POOL_TYPE PoolType,
  183. OUT PHIDP_COLLECTION_DESC_LIST * ColsRet,
  184. OUT PULONG NumCols,
  185. OUT PHIDP_GETCOLDESC_DBG Dbg,
  186. OUT PHIDP_DEVICE_DESC DeviceDesc)
  187. /*++
  188. Routine Description:
  189. Allocate a link list of Collection descriptors for use by the preparser.
  190. Each collection descriptor represents a top level app collection found
  191. in the given report descriptor, and contains enough memory (scratch space)
  192. into which to write the preparsed data.
  193. Return a linked list of such collections.
  194. In each collection also allocate enough space for the preparsed data, based
  195. on the number of channels required.
  196. Also allocate memory for the three report ID structures.
  197. Parameters:
  198. Rep The given raw report descriptor.
  199. RepLen Length of this said descriptor.
  200. ColsRet The head of the list of collection descriptors.
  201. NumCols Then number of collection descriptors in said list.
  202. --*/
  203. {
  204. PHIDP_COLLECTION_DESC_LIST preCol = 0;
  205. PHIDP_COLLECTION_DESC_LIST curCol = 0;
  206. PHIDP_PREPARSED_DATA preparsed = 0;
  207. HIDP_ITEM item;
  208. ULONG descIndex = 0;
  209. LONG colDepth = 0; // nested collections
  210. SHORT usageDepth = 0; // How many usages for each main item
  211. USHORT inputChannels = 0;
  212. USHORT outputChannels = 0;
  213. USHORT featureChannels = 0;
  214. USHORT length;
  215. USHORT numLinkCollections = 0;
  216. // Link Collections within a top level collection.
  217. UCHAR tmpBitField = 0;
  218. BOOLEAN newReportID = FALSE;
  219. UCHAR numReports = 0;
  220. BOOLEAN defaultReportIDUsed = FALSE;
  221. BOOLEAN noDefaultReportIDAllowed = FALSE;
  222. //
  223. // numReports indicates the number of HIDP_REPORT_IDS structures needed
  224. // to describe this device. If the device has only one top level collection
  225. // then the report descriptor need not contain a report id declaration, and
  226. // the given device will not prepend a report ID to the input report packets.
  227. // newReportID indicates the parser has found no report id declaration thus
  228. // far in the report descriptor.
  229. //
  230. // newReportID is set to TRUE with each entrance of a top level collection,
  231. // this allocation routine sets this to FALSE when it see a report ID
  232. // declaration.
  233. //
  234. // We start newReportID as FALSE so that we can test for TRUE on entering
  235. // a top level collection. If, for some reason, we enter an additional top
  236. // level collection and newReportID is still set to TRUE then we have a
  237. // violation of the HID spec. `No report may span a top level collection.'
  238. //
  239. // Also a report ID of zero is not allowed. If there is no declaration
  240. // of a report id then (1) all channels will have there report id field set
  241. // to zero (aka none) (2) only one top level collection may be encountered.
  242. // We track this with the defaultReportIDUsed noDefaultReportIDAllowed
  243. // locals.
  244. //
  245. *NumCols = 0;
  246. // currentTopCollection = 1;
  247. //
  248. // each collection returned from the preparser has a unique collection number
  249. // associated with it. The preparser only concerns itself with top-level
  250. // collections. This number DOES NOT in any way correspond with the
  251. // accessor functions, used by the client, described in hidpi.h. The client
  252. // receives only one collection at a time, and within each top level
  253. // collection there are subcollections (link collections) which are
  254. // given another set of numberings.
  255. // We track the current collection number by the number of collections,
  256. // argument passed in by the caller.
  257. //
  258. while (descIndex < RepDescLen)
  259. {
  260. item = *(RepDesc + descIndex++);
  261. switch (item)
  262. {
  263. case HIDP_MAIN_COLLECTION:
  264. MORE_DATA (descIndex, RepDescLen);
  265. item = *(RepDesc + descIndex++);
  266. if (1 == ++colDepth)
  267. { // We will regard any top level collection as an application
  268. // collection.
  269. // We will regard second level collections as a linked collection
  270. // (or sub collection defined by the HIDP_PRIVATE_LINK_COLLECTION_NODE)
  271. //
  272. inputChannels = outputChannels = featureChannels = 0;
  273. numLinkCollections = 1;
  274. // Link collection zero is understood to be the top level
  275. // collection so we need to start out with at least one node
  276. // allocated.
  277. if (0 == usageDepth) {
  278. HidP_KdPrint (2, ("No usage for top level collection: %d!\n",
  279. *NumCols));
  280. Dbg->BreakOffset = descIndex;
  281. Dbg->ErrorCode = HIDP_GETCOLDESC_TOP_COLLECTION_USAGE;
  282. Dbg->Args[0] = *NumCols;
  283. return STATUS_COULD_NOT_INTERPRET;
  284. } else if (1 < usageDepth) {
  285. HidP_KdPrint (2, ("Multiple usages for top level collection: %d\n",
  286. *NumCols));
  287. Dbg->BreakOffset = descIndex;
  288. Dbg->ErrorCode = HIDP_GETCOLDESC_TOP_COLLECTION_USAGE;
  289. Dbg->Args[0] = *NumCols;
  290. return STATUS_COULD_NOT_INTERPRET;
  291. }
  292. if (newReportID) {
  293. // This is not the first top collection since this variable is
  294. // initialized to false.
  295. // Seeing this set means we have parsed an entire top level
  296. // collection without seing a report id. This is bad.
  297. // A device with more than one top level colletion must have
  298. // more than one report. And the last top level collection
  299. // declared no such report.
  300. HidP_KdPrint (2, ("No report ID for collection: %d\n", *NumCols));
  301. Dbg->BreakOffset = descIndex;
  302. Dbg->ErrorCode = HIDP_GETCOLDESC_NO_REPORT_ID;
  303. Dbg->Args[0] = *NumCols;
  304. return STATUS_COULD_NOT_INTERPRET;
  305. } else if (defaultReportIDUsed) {
  306. // This is not the first top collection since this variable is
  307. // initialized to FALSE;
  308. // So if ever we see this as true we are starting a new top
  309. // level collection which means there must be report ID from the
  310. // device and therefore there cannot exist a single channel
  311. // that has no declared report ID.
  312. HidP_KdPrint (2, ("Default report ID used inappropriately\n"));
  313. Dbg->BreakOffset = descIndex;
  314. Dbg->ErrorCode = HIDP_GETCOLDESC_DEFAULT_ID_ERROR;
  315. Dbg->Args[0] = *NumCols;
  316. return STATUS_COULD_NOT_INTERPRET;
  317. }
  318. numReports++;
  319. newReportID = TRUE;
  320. (*NumCols)++; // One more top level collection found.
  321. HidP_KdPrint(2, ("'Top Level Collection %d found\n", *NumCols));
  322. preCol = curCol;
  323. curCol = (PHIDP_COLLECTION_DESC_LIST)
  324. ExAllocatePool (PoolType, sizeof (HIDP_COLLECTION_DESC_LIST));
  325. if (!curCol) {
  326. HidP_KdPrint(2, ("No Resources to make Top level collection\n"));
  327. Dbg->BreakOffset = descIndex;
  328. Dbg->ErrorCode = HIDP_GETCOLDESC_LINK_RESOURCES;
  329. return STATUS_INSUFFICIENT_RESOURCES;
  330. }
  331. RtlZeroMemory (curCol, sizeof (HIDP_COLLECTION_DESC_LIST));
  332. if (preCol) {
  333. preCol->NextCollection = curCol;
  334. } else {
  335. *ColsRet = curCol;
  336. }
  337. } else if (1 < colDepth) { // a linked collection
  338. HidP_KdPrint(0, ("'Enter Link Collection\n"));
  339. if (0 == usageDepth) {
  340. HidP_KdPrint (1, ("***************************************\n"));
  341. HidP_KdPrint (1, ("Warning! Link collection without usage \n"));
  342. HidP_KdPrint (1, ("Pos (%d), depth (%d)\n", descIndex, colDepth));
  343. HidP_KdPrint (1, ("***************************************\n"));
  344. usageDepth = 1;
  345. } else if (1 < usageDepth) {
  346. HidP_KdPrint (1, ("Link Collection with multiple usage decls\n"));
  347. }
  348. numLinkCollections += usageDepth;
  349. }
  350. usageDepth = 0;
  351. break;
  352. case HIDP_MAIN_ENDCOLLECTION:
  353. usageDepth = 0;
  354. if (--colDepth < 0) {
  355. HidP_KdPrint(2, ("Extra End Collection\n"));
  356. Dbg->BreakOffset = descIndex;
  357. Dbg->ErrorCode = HIDP_GETCOLDESC_UNEXP_END_COL;
  358. return STATUS_COULD_NOT_INTERPRET;
  359. }
  360. if (0 < colDepth) {
  361. HidP_KdPrint(0, ("'Exit Link Collection\n"));
  362. continue;
  363. }
  364. HidP_KdPrint (0, ("'Collection %d exit\n", *NumCols));
  365. curCol->CollectionNumber = (UCHAR) *NumCols;
  366. length = sizeof (HIDP_PREPARSED_DATA)
  367. + (sizeof (HIDP_CHANNEL_DESC)
  368. * (inputChannels
  369. + outputChannels
  370. + featureChannels))
  371. + (sizeof (HIDP_PRIVATE_LINK_COLLECTION_NODE))
  372. * numLinkCollections;
  373. curCol->PreparsedDataLength = length;
  374. curCol->PreparsedData =
  375. (PHIDP_PREPARSED_DATA) ExAllocatePool (PoolType, length);
  376. if (!curCol->PreparsedData) {
  377. HidP_KdPrint(2, ("Could not allocate space for PreparsedData\n"));
  378. Dbg->BreakOffset = descIndex;
  379. Dbg->ErrorCode = HIDP_GETCOLDESC_PREPARSE_RESOURCES;
  380. return STATUS_INSUFFICIENT_RESOURCES;
  381. }
  382. RtlZeroMemory (curCol->PreparsedData, curCol->PreparsedDataLength);
  383. // Set the offsets
  384. preparsed = curCol->PreparsedData;
  385. preparsed->Signature1 = HIDP_PREPARSED_DATA_SIGNATURE1;
  386. preparsed->Signature2 = HIDP_PREPARSED_DATA_SIGNATURE2;
  387. preparsed->Input.Index = (UCHAR) preparsed->Input.Offset = 0;
  388. length = preparsed->Input.Size = inputChannels;
  389. preparsed->Output.Index = preparsed->Output.Offset = (UCHAR) length;
  390. length += (preparsed->Output.Size = outputChannels);
  391. preparsed->Feature.Index = preparsed->Feature.Offset = (UCHAR) length;
  392. length += (preparsed->Feature.Size = featureChannels);
  393. preparsed->LinkCollectionArrayOffset =
  394. length * sizeof (HIDP_CHANNEL_DESC);
  395. preparsed->LinkCollectionArrayLength = numLinkCollections;
  396. break;
  397. case HIDP_LOCAL_USAGE_4:
  398. case HIDP_LOCAL_USAGE_MIN_4:
  399. descIndex += 2;
  400. case HIDP_LOCAL_USAGE_2:
  401. case HIDP_LOCAL_USAGE_MIN_2:
  402. descIndex++;
  403. case HIDP_LOCAL_USAGE_1:
  404. case HIDP_LOCAL_USAGE_MIN_1:
  405. MORE_DATA (descIndex++, RepDescLen);
  406. usageDepth++;
  407. break;
  408. case HIDP_LOCAL_DELIMITER:
  409. if (1 != (item = *(RepDesc + descIndex))) {
  410. HidP_KdPrint (2, ("Delimiter not start %x\n", item));
  411. Dbg->BreakOffset = descIndex;
  412. Dbg->ErrorCode = HIDP_GETCOLDESC_MISMATCH_OC_DELIMITER;
  413. Dbg->Args[0] = item;
  414. return STATUS_COULD_NOT_INTERPRET;
  415. }
  416. MORE_DATA (descIndex++, RepDescLen);
  417. while (TRUE) {
  418. if (descIndex >= RepDescLen) {
  419. HidP_KdPrint (2, ("End delimiter NOT found!\n"));
  420. Dbg->BreakOffset = descIndex;
  421. Dbg->ErrorCode = HIDP_GETCOLDESC_NO_CLOSE_DELIMITER;
  422. return STATUS_COULD_NOT_INTERPRET;
  423. }
  424. item = *(RepDesc + descIndex++);
  425. if (HIDP_LOCAL_DELIMITER == item) {
  426. if (0 != (item = *(RepDesc + descIndex))) {
  427. HidP_KdPrint (2, ("Delimiter not stop %x\n", item));
  428. Dbg->BreakOffset = descIndex;
  429. Dbg->ErrorCode = HIDP_GETCOLDESC_MISMATCH_OC_DELIMITER;
  430. Dbg->Args[0] = item;
  431. return STATUS_COULD_NOT_INTERPRET;
  432. }
  433. MORE_DATA (descIndex++, RepDescLen);
  434. break;
  435. }
  436. switch (item) {
  437. //
  438. // TODO: kenray
  439. //
  440. // Usage Min / Max not yet supported within delimiter.
  441. //
  442. // case HIDP_LOCAL_USAGE_MAX_4:
  443. // descIndex += 2;
  444. // case HIDP_LOCAL_USAGE_MAX_2:
  445. // descIndex++;
  446. // case HIDP_LOCAL_USAGE_MAX_1:
  447. // descIndex++;
  448. // break;
  449. case HIDP_LOCAL_USAGE_4:
  450. // case HIDP_LOCAL_USAGE_MIN_4:
  451. descIndex += 2;
  452. case HIDP_LOCAL_USAGE_2:
  453. // case HIDP_LOCAL_USAGE_MIN_2:
  454. descIndex++;
  455. case HIDP_LOCAL_USAGE_1:
  456. // case HIDP_LOCAL_USAGE_MIN_1:
  457. MORE_DATA (descIndex++, RepDescLen);
  458. usageDepth++;
  459. break;
  460. default:
  461. HidP_KdPrint (2, ("Invalid token found within delimiter!\n"));
  462. HidP_KdPrint (2, ("Only Usages are allowed within a delimiter\n"));
  463. // HidP_KdPrint (("IE: Only Usage, UsageMin, UsageMax tokens\n"));
  464. HidP_KdPrint (2, ("IE: Only Usage token allowes (no min or max)\n"));
  465. Dbg->BreakOffset = descIndex;
  466. Dbg->ErrorCode = HIDP_GETCOLDESC_NOT_VALID_DELIMITER;
  467. Dbg->Args[0] = item;
  468. return STATUS_COULD_NOT_INTERPRET;
  469. }
  470. }
  471. break;
  472. case HIDP_MAIN_INPUT_2:
  473. MORE_DATA (descIndex + 1, RepDescLen);
  474. tmpBitField = *(RepDesc + descIndex++);
  475. descIndex++;
  476. goto HIDP_ALLOC_MAIN_INPUT;
  477. case HIDP_MAIN_INPUT_1:
  478. MORE_DATA (descIndex, RepDescLen);
  479. tmpBitField = *(RepDesc + descIndex++);
  480. HIDP_ALLOC_MAIN_INPUT:
  481. if (0 == usageDepth) {
  482. if (HIDP_ISCONST(tmpBitField)) {
  483. break;
  484. }
  485. HidP_KdPrint (2, ("Non constant main item found without usage decl\n"));
  486. Dbg->BreakOffset = descIndex;
  487. Dbg->ErrorCode = HIDP_GETCOLDESC_MAIN_ITEM_NO_USAGE;
  488. return STATUS_COULD_NOT_INTERPRET;
  489. }
  490. inputChannels += (usageDepth ? usageDepth : 1);
  491. if (newReportID) {
  492. if (noDefaultReportIDAllowed) {
  493. // A report ID declaration was found somewhere earlier in this
  494. // report descriptor. This means that ALL main items must
  495. // have a declared report ID.
  496. HidP_KdPrint (2, ("Default report ID used inappropriately\n"));
  497. Dbg->BreakOffset = descIndex;
  498. Dbg->ErrorCode = HIDP_GETCOLDESC_DEFAULT_ID_ERROR;
  499. Dbg->Args[0] = *NumCols;
  500. return STATUS_COULD_NOT_INTERPRET;
  501. }
  502. defaultReportIDUsed = TRUE;
  503. }
  504. if (0 == colDepth) {
  505. HidP_KdPrint (2, ("Main item found not in top level collection\n"));
  506. Dbg->BreakOffset = descIndex;
  507. Dbg->ErrorCode = HIDP_GETCOLDESC_INVALID_MAIN_ITEM;
  508. return STATUS_COULD_NOT_INTERPRET;
  509. }
  510. usageDepth = 0;
  511. break;
  512. case HIDP_MAIN_OUTPUT_2:
  513. MORE_DATA (descIndex + 1, RepDescLen);
  514. tmpBitField = *(RepDesc + descIndex++);
  515. descIndex++;
  516. goto HIDP_ALLOC_MAIN_OUTPUT;
  517. case HIDP_MAIN_OUTPUT_1:
  518. MORE_DATA (descIndex, RepDescLen);
  519. tmpBitField = *(RepDesc + descIndex++);
  520. HIDP_ALLOC_MAIN_OUTPUT:
  521. if (0 == usageDepth) {
  522. if (HIDP_ISCONST(tmpBitField)) {
  523. break;
  524. }
  525. HidP_KdPrint (2, ("Non constant main item found without usage decl\n"));
  526. Dbg->BreakOffset = descIndex;
  527. Dbg->ErrorCode = HIDP_GETCOLDESC_MAIN_ITEM_NO_USAGE;
  528. return STATUS_COULD_NOT_INTERPRET;
  529. }
  530. outputChannels += (usageDepth ? usageDepth : 1);
  531. if (newReportID) {
  532. if (noDefaultReportIDAllowed) {
  533. // A report ID declaration was found somewhere earlier in this
  534. // report descriptor. This means that ALL main items must
  535. // have a declared report ID.
  536. HidP_KdPrint (2, ("Default report ID used inappropriately\n"));
  537. Dbg->BreakOffset = descIndex;
  538. Dbg->ErrorCode = HIDP_GETCOLDESC_DEFAULT_ID_ERROR;
  539. Dbg->Args[0] = *NumCols;
  540. return STATUS_COULD_NOT_INTERPRET;
  541. }
  542. defaultReportIDUsed = TRUE;
  543. }
  544. if (0 == colDepth) {
  545. HidP_KdPrint (2, ("Main item found not in top level collection\n"));
  546. Dbg->BreakOffset = descIndex;
  547. Dbg->ErrorCode = HIDP_GETCOLDESC_INVALID_MAIN_ITEM;
  548. return STATUS_COULD_NOT_INTERPRET;
  549. }
  550. usageDepth = 0;
  551. break;
  552. case HIDP_MAIN_FEATURE_2:
  553. MORE_DATA (descIndex + 1, RepDescLen);
  554. tmpBitField = *(RepDesc + descIndex++);
  555. descIndex++;
  556. goto HIDP_ALLOC_MAIN_FEATURE;
  557. case HIDP_MAIN_FEATURE_1:
  558. MORE_DATA (descIndex, RepDescLen);
  559. tmpBitField = *(RepDesc + descIndex++);
  560. HIDP_ALLOC_MAIN_FEATURE:
  561. if (0 == usageDepth) {
  562. if (HIDP_ISCONST(tmpBitField)) {
  563. break;
  564. }
  565. HidP_KdPrint (2, ("Non constant main item found without usage decl\n"));
  566. Dbg->BreakOffset = descIndex;
  567. Dbg->ErrorCode = HIDP_GETCOLDESC_MAIN_ITEM_NO_USAGE;
  568. return STATUS_COULD_NOT_INTERPRET;
  569. }
  570. featureChannels += (usageDepth ? usageDepth : 1);
  571. if (newReportID) {
  572. if (noDefaultReportIDAllowed) {
  573. // A report ID declaration was found somewhere earlier in this
  574. // report descriptor. This means that ALL main items must
  575. // have a declared report ID.
  576. HidP_KdPrint (2, ("Default report ID used inappropriately\n"));
  577. Dbg->BreakOffset = descIndex;
  578. Dbg->ErrorCode = HIDP_GETCOLDESC_DEFAULT_ID_ERROR;
  579. Dbg->Args[0] = *NumCols;
  580. return STATUS_COULD_NOT_INTERPRET;
  581. }
  582. defaultReportIDUsed = TRUE;
  583. }
  584. if (0 == colDepth) {
  585. HidP_KdPrint (2, ("Main item found not in top level collection\n"));
  586. Dbg->BreakOffset = descIndex;
  587. Dbg->ErrorCode = HIDP_GETCOLDESC_INVALID_MAIN_ITEM;
  588. return STATUS_COULD_NOT_INTERPRET;
  589. }
  590. usageDepth = 0;
  591. break;
  592. case HIDP_GLOBAL_REPORT_ID:
  593. MORE_DATA (descIndex, RepDescLen);
  594. item = *(RepDesc + descIndex++);
  595. if (0 < colDepth) {
  596. ASSERT (curCol);
  597. } else {
  598. HidP_KdPrint(2, ("Report ID outside of Top level collection\n"));
  599. HidP_KdPrint(2, ("Reports cannot span more than one top level \n"));
  600. HidP_KdPrint(2, ("Report ID found: %d", (ULONG) item));
  601. Dbg->BreakOffset = descIndex;
  602. Dbg->ErrorCode = HIDP_GETCOLDESC_REPORT_ID;
  603. Dbg->Args[0] = item;
  604. return STATUS_COULD_NOT_INTERPRET;
  605. }
  606. if (newReportID) {
  607. newReportID = FALSE;
  608. } else {
  609. numReports++;
  610. }
  611. noDefaultReportIDAllowed = TRUE;
  612. if (defaultReportIDUsed) {
  613. // A report ID declaration was found somewhere earlier in this
  614. // report descriptor. This means that ALL main items must
  615. // have a declared report ID.
  616. HidP_KdPrint (2, ("Default report ID used inappropriately\n"));
  617. Dbg->BreakOffset = descIndex;
  618. Dbg->ErrorCode = HIDP_GETCOLDESC_DEFAULT_ID_ERROR;
  619. Dbg->Args[0] = *NumCols;
  620. return STATUS_COULD_NOT_INTERPRET;
  621. }
  622. break;
  623. case HIDP_ITEM_LONG:
  624. HidP_KdPrint (2, ("Long Items not supported %x\n", item));
  625. Dbg->BreakOffset = descIndex;
  626. Dbg->ErrorCode = HIDP_GETCOLDESC_ITEM_UNKNOWN;
  627. Dbg->Args[0] = item;
  628. return STATUS_COULD_NOT_INTERPRET;
  629. default:
  630. // Bump past the data bytes in the descriptor.
  631. length = (item & HIDP_ITEM_LENGTH_DATA);
  632. length = (3 == length) ? 4 : length;
  633. if (!((descIndex + length) <= RepDescLen)) {
  634. // OK the lower 2 bits in the item represent the length of the
  635. // data if this is 3 then there are 4 data bytes following this
  636. // item. DescPos already points to the next data item.
  637. Dbg->BreakOffset = descIndex;
  638. Dbg->ErrorCode = HIDP_GETCOLDESC_ONE_BYTE;
  639. return STATUS_BUFFER_TOO_SMALL;
  640. }
  641. descIndex += length;
  642. break;
  643. }
  644. }
  645. //
  646. // According to the HID spec no report id may span a top level collection.
  647. // which means that each collection must have at least one report, and there
  648. // should be at least as many report IDs as collections. Unless there is
  649. // only one report (therefore only one collection). In this case no report
  650. // ID will be sent from the device. But in this case we return saying there
  651. // was indeed one report anyway. The ReportID decsriptor was of length one.
  652. // Therefore numReports must always be greater than or equal to the number
  653. // of collections.
  654. //
  655. // For output and feature reports, report ids are sent as an extra argument
  656. // so they will always be present even if they are zero. (Zero means that
  657. // the device did not list a report ID in the descriptor.)
  658. //
  659. // However with input packets the report ID is part of the packet itself:
  660. // the first byte. UNLESS there is only one report, and then it is not
  661. // present.
  662. //
  663. // __For input packets___
  664. // the device can have a report ID even if it has only one
  665. // report. This is odd, as it wastes a byte, but then again who knows the
  666. // mind of an IHV. For this reason, hidparse must check to see if the
  667. // reportID list is of length one and the report id itself (in the one and
  668. // only one space) is zero in order to determine if the device sends no
  669. // reports ids.
  670. // If it is zero (the device is not allowed to send report ids of zero)
  671. // than that report id was simulated meaning the number of bytes in the
  672. // packet from the device is one less than the number of byte given to the
  673. // user.
  674. // If is is non-zero, then the number of bytes from the device is the same
  675. // as the number of bytes given to the user.
  676. //
  677. if (numReports < *NumCols) {
  678. HidP_KdPrint (2, ("Report IDS cannot span collections.\n"));
  679. HidP_KdPrint (2, ("This means that you must have at least one report ID\n"));
  680. HidP_KdPrint (2, ("For each TOP level collection, unless you have only\n"));
  681. HidP_KdPrint (2, ("report.\n"));
  682. Dbg->BreakOffset = descIndex;
  683. Dbg->ErrorCode = HIDP_GETCOLDESC_NO_REPORT_ID;
  684. return STATUS_COULD_NOT_INTERPRET;
  685. }
  686. if (0 < colDepth) {
  687. HidP_KdPrint(2, ("End Collection not found\n"));
  688. Dbg->BreakOffset = descIndex;
  689. Dbg->ErrorCode = HIDP_GETCOLDESC_UNEXP_END_COL;
  690. return STATUS_COULD_NOT_INTERPRET;
  691. }
  692. //
  693. // Now that we have seen the entire structure, allocate the structure for
  694. // holding the report id switch table.
  695. //
  696. if (0 == numReports) {
  697. HidP_KdPrint (2, ("No top level collections were found! \n"));
  698. Dbg->BreakOffset = descIndex;
  699. Dbg->ErrorCode = HIDP_GETCOLDESC_NO_DATA;
  700. return STATUS_NO_DATA_DETECTED;
  701. }
  702. DeviceDesc->ReportIDsLength = numReports;
  703. DeviceDesc->ReportIDs = (PHIDP_REPORT_IDS)
  704. ExAllocatePool (PoolType, numReports * sizeof (HIDP_REPORT_IDS));
  705. if (!DeviceDesc->ReportIDs) {
  706. return STATUS_INSUFFICIENT_RESOURCES;
  707. }
  708. RtlZeroMemory (DeviceDesc->ReportIDs, numReports * sizeof (HIDP_REPORT_IDS));
  709. return STATUS_SUCCESS;
  710. }
  711. PHIDP_PARSE_LOCAL_RANGE_LIST
  712. HidP_FreeUsageList (
  713. PHIDP_PARSE_LOCAL_RANGE_LIST Usage
  714. )
  715. /*++
  716. RoutineDescription:
  717. clear off all the usages in the linked list
  718. But do not free the first element in the list.
  719. --*/
  720. {
  721. PHIDP_PARSE_LOCAL_RANGE_LIST curUsage;
  722. while (Usage->Next) {
  723. curUsage = Usage;
  724. Usage = curUsage->Next;
  725. ExFreePool (curUsage);
  726. }
  727. RtlZeroMemory (Usage, sizeof (HIDP_PARSE_LOCAL_RANGE_LIST));
  728. return Usage;
  729. }
  730. PHIDP_PARSE_LOCAL_RANGE_LIST
  731. HidP_PushUsageList (
  732. PHIDP_PARSE_LOCAL_RANGE_LIST Usage,
  733. POOL_TYPE PoolType,
  734. BOOLEAN WithinDelimiter
  735. )
  736. /*++
  737. RoutineDescription:
  738. allocate another Usage node and add it to the top O the list.
  739. --*/
  740. {
  741. PHIDP_PARSE_LOCAL_RANGE_LIST newUsage;
  742. newUsage = (PHIDP_PARSE_LOCAL_RANGE_LIST)
  743. ExAllocatePool (PoolType, sizeof (HIDP_PARSE_LOCAL_RANGE_LIST));
  744. if (newUsage) {
  745. RtlZeroMemory (newUsage, sizeof (HIDP_PARSE_LOCAL_RANGE_LIST));
  746. newUsage->Next = Usage;
  747. if (!WithinDelimiter) {
  748. newUsage->Depth = Usage->Depth
  749. + (Usage->Range ? (Usage->Max - Usage->Min + 1) : 1);
  750. } else {
  751. newUsage->Depth = Usage->Depth;
  752. //
  753. // Note ranges are not allowed in delimiters therefore we know
  754. // that all entries in the delimiter are equal and are length 1
  755. //
  756. }
  757. } else {
  758. HidP_FreeUsageList (Usage);
  759. }
  760. return newUsage;
  761. }
  762. PHIDP_PARSE_LOCAL_RANGE_LIST
  763. HidP_PopUsageList (
  764. PHIDP_PARSE_LOCAL_RANGE_LIST Usage
  765. )
  766. {
  767. PHIDP_PARSE_LOCAL_RANGE_LIST newUsage;
  768. if (Usage->Next) {
  769. newUsage = Usage->Next;
  770. ExFreePool (Usage);
  771. } else {
  772. newUsage = Usage;
  773. #if DBG
  774. RtlFillMemory (newUsage, sizeof (HIDP_PARSE_LOCAL_RANGE_LIST), 0xDB);
  775. newUsage->Depth = 0;
  776. #endif
  777. }
  778. return newUsage;
  779. }
  780. #define ONE_BYTE_DATA(_data_, _pos_, _dbg_) \
  781. if (!((_pos_) < RepDescLen)) { \
  782. status = STATUS_BUFFER_TOO_SMALL; \
  783. KdPrint(("More Data Expected\n")); \
  784. _dbg_->ErrorCode = HIDP_GETCOLDESC_ONE_BYTE; \
  785. _dbg_->BreakOffset = descIndex; \
  786. goto HIDP_PARSE_REJECT; \
  787. } \
  788. (_data_) = *(RepDesc + (_pos_)++);
  789. #define TWO_BYTE_DATA(_data_, _pos_, _dbg_) \
  790. if (!((_pos_) + 1 < RepDescLen)) { \
  791. status = STATUS_BUFFER_TOO_SMALL; \
  792. KdPrint(("More Data Expected\n")); \
  793. _dbg_->ErrorCode = HIDP_GETCOLDESC_TWO_BYTE; \
  794. _dbg_->BreakOffset = descIndex; \
  795. goto HIDP_PARSE_REJECT; \
  796. } \
  797. (_data_) = *(RepDesc + (_pos_)++); \
  798. (_data_) |= *(RepDesc + (_pos_)++) << 8;
  799. #define FOUR_BYTE_DATA(_data_, _pos_, _dbg_) \
  800. if (!((_pos_) + 3 < RepDescLen)) { \
  801. status = STATUS_BUFFER_TOO_SMALL; \
  802. KdPrint(("More Data Expected\n")); \
  803. _dbg_->ErrorCode = HIDP_GETCOLDESC_FOUR_BYTE; \
  804. _dbg_->BreakOffset = descIndex; \
  805. goto HIDP_PARSE_REJECT; \
  806. } \
  807. (_data_) = *(RepDesc + (_pos_)++); \
  808. (_data_) |= *(RepDesc + (_pos_)++) << 8; \
  809. (_data_) |= *(RepDesc + (_pos_)++) << 16; \
  810. (_data_) |= *(RepDesc + (_pos_)++) << 24;
  811. #define BIT_EXTEND_1(_data_) \
  812. (_data_) = ((_data_) & 0xFF) \
  813. | (((_data_) & 0x80) ? 0xFFFFFF00 : 0)
  814. #define BIT_EXTEND_2(_data_) \
  815. (_data_) = ((_data_) & 0xFFFF) \
  816. | (((_data_) & 0x8000) ? 0xFFFF0000 : 0)
  817. NTSTATUS
  818. HidP_ParseCollections (
  819. IN PHIDP_REPORT_DESCRIPTOR RepDesc,
  820. IN ULONG RepDescLen,
  821. IN POOL_TYPE PoolType,
  822. IN OUT PHIDP_COLLECTION_DESC_LIST Cols,
  823. IN ULONG NumCols,
  824. OUT PHIDP_GETCOLDESC_DBG Dbg,
  825. IN OUT PHIDP_DEVICE_DESC DeviceDesc)
  826. /*++
  827. Routine Description:
  828. Given a nice linked list of collection descriptors parse into those
  829. descriptors the information descerned from the Raw Report Descriptor.
  830. Each given CollectionDescriptor already has the proper amount of memory
  831. in the PreparsedData field.
  832. Parameters:
  833. Rep The given raw report descriptor.
  834. RepLen Length of this said descriptor.
  835. ColsRet The head of the list of collection descriptors.
  836. NumCols Then number of collection descriptors in said list.
  837. --*/
  838. {
  839. HIDP_PREPARSED_DATA safeData;
  840. HIDP_PARSE_GLOBAL_PUSH firstPush = {0,0,0,0,0,0,0,0,0,0,0};
  841. HIDP_PARSE_LOCAL_RANGE_LIST firstUsage = {0,0,0,0,0};
  842. HIDP_PARSE_LOCAL_RANGE designator = {0,0,0,0};
  843. HIDP_PARSE_LOCAL_RANGE string = {0,0,0,0};
  844. HIDP_PARSE_LOCAL_RANGE zeroLocal = {0,0,0,0};
  845. PHIDP_COLLECTION_DESC_LIST appCol = 0;
  846. PHIDP_PREPARSED_DATA preparsed = &safeData;
  847. PHIDP_PARSE_GLOBAL_PUSH push = &firstPush;
  848. PHIDP_PARSE_GLOBAL_PUSH tmpPush = 0;
  849. PHIDP_PARSE_LOCAL_RANGE_LIST usage = &firstUsage;
  850. PHIDP_PARSE_LOCAL_RANGE_LIST tmpUsage = 0;
  851. PHIDP_CHANNEL_DESC channel = 0;
  852. PHIDP_PRIVATE_LINK_COLLECTION_NODE linkNodeArray = 0;
  853. PHIDP_PRIVATE_LINK_COLLECTION_NODE parentLCNode = 0;
  854. PHIDP_PRIVATE_LINK_COLLECTION_NODE currentLCNode = 0;
  855. struct _HIDP_UNKNOWN_TOKEN * unknownToken;
  856. USHORT linkNodeIndex = 0;
  857. ULONG descIndex = 0;
  858. ULONG colDepth = 0;
  859. NTSTATUS status = STATUS_SUCCESS;
  860. USHORT bitPos;
  861. HIDP_ITEM item;
  862. USHORT tmpBitField = 0;
  863. USHORT tmpCount = 0;
  864. USHORT i;
  865. PUSHORT channelIndex = 0;
  866. PHIDP_REPORT_IDS currentReportIDs = DeviceDesc->ReportIDs;
  867. PHIDP_REPORT_IDS tmpReportIDs;
  868. BOOLEAN isFirstReportID = TRUE;
  869. BOOLEAN withinDelimiter = FALSE;
  870. BOOLEAN firstUsageWithinDelimiter = TRUE;
  871. BOOLEAN isAlias = FALSE;
  872. UCHAR collectionType;
  873. UCHAR tmpID;
  874. UNREFERENCED_PARAMETER (NumCols);
  875. while (descIndex < RepDescLen)
  876. {
  877. item = *(RepDesc + descIndex++);
  878. switch (item)
  879. {
  880. case HIDP_MAIN_COLLECTION:
  881. ONE_BYTE_DATA (collectionType, descIndex, Dbg);
  882. if (1 == ++colDepth)
  883. {
  884. //
  885. // We will regard any top level collection as an application
  886. // collection as approved by the HID committee
  887. //
  888. // we will regard second level collections as a link collection.
  889. //
  890. if (appCol)
  891. {
  892. appCol = appCol->NextCollection;
  893. } else
  894. {
  895. appCol = Cols;
  896. }
  897. ASSERT (appCol);
  898. HidP_KdPrint(0, ("'Parse Collection %d \n", appCol->CollectionNumber));
  899. preparsed = appCol->PreparsedData;
  900. ASSERT (preparsed);
  901. //
  902. // Set up the report IDs for this collection
  903. // There is one report ID array for all top level collections
  904. //
  905. push->ReportIDs = currentReportIDs;
  906. isFirstReportID = TRUE;
  907. // Make room for the Report ID as the first byte.
  908. currentReportIDs->InputLength = 8;
  909. currentReportIDs->OutputLength = 8;
  910. currentReportIDs->FeatureLength = 8;
  911. currentReportIDs->ReportID = 0;
  912. currentReportIDs->CollectionNumber = appCol->CollectionNumber;
  913. currentReportIDs++;
  914. preparsed->UsagePage = appCol->UsagePage = usage->UsagePage ?
  915. usage->UsagePage :
  916. push->UsagePage;
  917. if (usage->Range){
  918. preparsed->Usage = appCol->Usage = usage->Min;
  919. } else {
  920. preparsed->Usage = appCol->Usage = usage->Value;
  921. }
  922. designator = string = zeroLocal;
  923. usage = HidP_FreeUsageList (usage);
  924. if (0 == appCol->Usage) {
  925. //
  926. // Explicitly check for Usage ID (0) which is reserved
  927. //
  928. HidP_KdPrint(2, ("Top Level Collection %x defined with Report ID 0! (UP: %x)\n",
  929. appCol->CollectionNumber,
  930. appCol->UsagePage));
  931. #if 0
  932. Dbg->BreakOffset = descIndex;
  933. Dbg->ErrorCode = HIDP_GETCOLDESC_TOP_COLLECTION_USAGE;
  934. Dbg->Args[0] = appCol->CollectionNumber;
  935. status = STATUS_COULD_NOT_INTERPRET;
  936. goto HIDP_PARSE_REJECT;
  937. #endif
  938. }
  939. //
  940. // Initialize the Link node array for this top level collection.
  941. // There is a link node array for each top level collection
  942. //
  943. linkNodeArray = (PHIDP_PRIVATE_LINK_COLLECTION_NODE)
  944. (preparsed->RawBytes +
  945. preparsed->LinkCollectionArrayOffset);
  946. ASSERT (0 < preparsed->LinkCollectionArrayLength);
  947. parentLCNode = &(linkNodeArray[0]);
  948. currentLCNode = &(linkNodeArray[0]);
  949. linkNodeIndex = 0;
  950. parentLCNode->LinkUsagePage = appCol->UsagePage;
  951. parentLCNode->LinkUsage = appCol->Usage;
  952. parentLCNode->Parent = 0;
  953. parentLCNode->NumberOfChildren = 0;
  954. parentLCNode->NextSibling = 0;
  955. parentLCNode->FirstChild = 0;
  956. parentLCNode->CollectionType = collectionType;
  957. } else if (1 < colDepth)
  958. {
  959. linkNodeIndex++;
  960. parentLCNode = currentLCNode;
  961. ASSERT (linkNodeIndex < preparsed->LinkCollectionArrayLength);
  962. currentLCNode = &linkNodeArray[linkNodeIndex];
  963. //
  964. // Pop of the usage stack all the usages which are aliases, and
  965. // create a link collection node for each one.
  966. // Each allias link collection node has the IsAlias bit set.
  967. // The last one does not have the bit set, and becomes the
  968. // collection number for all controls list within this aliased
  969. // link collection.
  970. //
  971. //
  972. while (TRUE) {
  973. currentLCNode->LinkUsagePage = usage->UsagePage ?
  974. usage->UsagePage :
  975. push->UsagePage;
  976. currentLCNode->LinkUsage = usage->Range ?
  977. usage->Min :
  978. usage->Value;
  979. currentLCNode->Parent = (USHORT)(parentLCNode - linkNodeArray);
  980. ASSERT (currentLCNode->Parent < preparsed->LinkCollectionArrayLength);
  981. currentLCNode->NumberOfChildren = 0;
  982. currentLCNode->FirstChild = 0;
  983. currentLCNode->NextSibling = parentLCNode->FirstChild;
  984. parentLCNode->FirstChild = linkNodeIndex;
  985. parentLCNode->NumberOfChildren++;
  986. currentLCNode->CollectionType = collectionType;
  987. if (usage->IsAlias) {
  988. currentLCNode->IsAlias = TRUE;
  989. linkNodeIndex++;
  990. ASSERT (linkNodeIndex < preparsed->LinkCollectionArrayLength);
  991. currentLCNode = &linkNodeArray[linkNodeIndex];
  992. } else {
  993. break;
  994. }
  995. }
  996. designator = string = zeroLocal;
  997. usage = HidP_FreeUsageList (usage);
  998. }
  999. break;
  1000. case HIDP_MAIN_ENDCOLLECTION:
  1001. if (0 == colDepth--) {
  1002. status = STATUS_COULD_NOT_INTERPRET;
  1003. goto HIDP_PARSE_REJECT;
  1004. } else if (0 < colDepth) {
  1005. ASSERT ((parentLCNode - linkNodeArray) == currentLCNode->Parent);
  1006. currentLCNode = parentLCNode;
  1007. ASSERT (currentLCNode->Parent < preparsed->LinkCollectionArrayLength);
  1008. parentLCNode = &linkNodeArray[currentLCNode->Parent];
  1009. break;
  1010. }
  1011. HidP_KdPrint(0, ("'X Parse Collection %d \n", appCol->CollectionNumber));
  1012. //
  1013. // Walk the report IDs for this collection
  1014. //
  1015. for (tmpReportIDs = currentReportIDs - 1;
  1016. tmpReportIDs != DeviceDesc->ReportIDs - 1;
  1017. tmpReportIDs--)
  1018. {
  1019. if (tmpReportIDs->CollectionNumber != appCol->CollectionNumber)
  1020. {
  1021. continue;
  1022. }
  1023. if ((0 != (tmpReportIDs->InputLength & 7)) ||
  1024. (0 != (tmpReportIDs->OutputLength & 7)) ||
  1025. (0 != (tmpReportIDs->FeatureLength & 7)))
  1026. {
  1027. HidP_KdPrint(2, ("Col %x Report %x NOT byte alligned!! %x %x %x\n",
  1028. appCol->CollectionNumber,
  1029. tmpReportIDs->ReportID,
  1030. tmpReportIDs->InputLength,
  1031. tmpReportIDs->OutputLength,
  1032. tmpReportIDs->FeatureLength));
  1033. Dbg->BreakOffset = descIndex;
  1034. Dbg->ErrorCode = HIDP_GETCOLDESC_BYTE_ALLIGN;
  1035. Dbg->Args[0] = appCol->CollectionNumber,
  1036. Dbg->Args[1] = tmpReportIDs->ReportID,
  1037. Dbg->Args[2] = tmpReportIDs->InputLength;
  1038. Dbg->Args[3] = tmpReportIDs->OutputLength;
  1039. Dbg->Args[4] = tmpReportIDs->FeatureLength;
  1040. status = STATUS_COULD_NOT_INTERPRET;
  1041. goto HIDP_PARSE_REJECT;
  1042. }
  1043. preparsed->Input.ByteLen = MAX (preparsed->Input.ByteLen,
  1044. tmpReportIDs->InputLength >> 3);
  1045. preparsed->Output.ByteLen = MAX (preparsed->Output.ByteLen,
  1046. tmpReportIDs->OutputLength >> 3);
  1047. preparsed->Feature.ByteLen = MAX (preparsed->Feature.ByteLen,
  1048. tmpReportIDs->FeatureLength >> 3);
  1049. //
  1050. // We are now done with this report so convert the length to
  1051. // bytes instead of bits, and remove the report id, if the
  1052. // device will not send one.
  1053. //
  1054. if (0 == tmpReportIDs->ReportID)
  1055. {
  1056. // The report ID was never set; therefore, for input the device
  1057. // will not send a report id.
  1058. tmpReportIDs->InputLength = (tmpReportIDs->InputLength >> 3) - 1;
  1059. tmpReportIDs->OutputLength = (tmpReportIDs->OutputLength >> 3) -1;
  1060. tmpReportIDs->FeatureLength = (tmpReportIDs->FeatureLength >> 3) -1;
  1061. } else
  1062. {
  1063. tmpReportIDs->InputLength = (8 == tmpReportIDs->InputLength)
  1064. ? 0
  1065. : tmpReportIDs->InputLength >> 3;
  1066. tmpReportIDs->OutputLength = (8 == tmpReportIDs->OutputLength)
  1067. ? 0
  1068. : tmpReportIDs->OutputLength >> 3;
  1069. tmpReportIDs->FeatureLength = (8 == tmpReportIDs->FeatureLength)
  1070. ? 0
  1071. : tmpReportIDs->FeatureLength >> 3;
  1072. }
  1073. }
  1074. //
  1075. // This field is adjusted and always accounts for a space for the
  1076. // included report ID, even if the device itslef has only one report
  1077. // and therefore sends no report ids. (The input report is one byte
  1078. // smaller.)
  1079. //
  1080. // BUT if the length is one, then only the report ID exists.
  1081. // This means that the device has no data to send for that field.
  1082. // Therefore return zero.
  1083. //
  1084. // Remember that the BitLen fields were spiked earlier with values
  1085. // of 8 (one byte).
  1086. //
  1087. // appCol->XXXLength is the length expected from/by the client
  1088. // currentReportID->XxLength == the length expected from/by the device
  1089. //
  1090. if (1 == (appCol->InputLength = preparsed->Input.ByteLen))
  1091. {
  1092. appCol->InputLength = preparsed->Input.ByteLen = 0;
  1093. }
  1094. if (1 == (appCol->OutputLength = preparsed->Output.ByteLen))
  1095. {
  1096. appCol->OutputLength = preparsed->Output.ByteLen = 0;
  1097. }
  1098. if (1 == (appCol->FeatureLength = preparsed->Feature.ByteLen))
  1099. {
  1100. appCol->FeatureLength = preparsed->Feature.ByteLen = 0;
  1101. }
  1102. break;
  1103. case HIDP_GLOBAL_USAGE_PAGE_1:
  1104. ONE_BYTE_DATA (push->UsagePage, descIndex, Dbg);
  1105. break;
  1106. case HIDP_GLOBAL_USAGE_PAGE_2:
  1107. TWO_BYTE_DATA (push->UsagePage, descIndex, Dbg);
  1108. break;
  1109. //
  1110. // 16 bits allowed only.
  1111. // case HIDP_GLOBAL_USAGE_PAGE_4:
  1112. // FOUR_BYTE_DATA (push->UsagePage, descIndex, Dbg);
  1113. // break;
  1114. //
  1115. case HIDP_GLOBAL_LOG_MIN_1:
  1116. ONE_BYTE_DATA (push->LogicalMin, descIndex, Dbg);
  1117. BIT_EXTEND_1 (push->LogicalMin);
  1118. break;
  1119. case HIDP_GLOBAL_LOG_MIN_2:
  1120. TWO_BYTE_DATA (push->LogicalMin, descIndex, Dbg);
  1121. BIT_EXTEND_2 (push->LogicalMin);
  1122. break;
  1123. case HIDP_GLOBAL_LOG_MIN_4:
  1124. FOUR_BYTE_DATA (push->LogicalMin, descIndex, Dbg);
  1125. break;
  1126. case HIDP_GLOBAL_LOG_MAX_1:
  1127. ONE_BYTE_DATA (push->LogicalMax, descIndex, Dbg);
  1128. BIT_EXTEND_1 (push->LogicalMax);
  1129. break;
  1130. case HIDP_GLOBAL_LOG_MAX_2:
  1131. TWO_BYTE_DATA (push->LogicalMax, descIndex, Dbg);
  1132. BIT_EXTEND_2 (push->LogicalMax);
  1133. break;
  1134. case HIDP_GLOBAL_LOG_MAX_4:
  1135. FOUR_BYTE_DATA (push->LogicalMax, descIndex, Dbg);
  1136. break;
  1137. case HIDP_GLOBAL_PHY_MIN_1:
  1138. ONE_BYTE_DATA (push->PhysicalMin, descIndex, Dbg);
  1139. BIT_EXTEND_1 (push->PhysicalMin);
  1140. break;
  1141. case HIDP_GLOBAL_PHY_MIN_2:
  1142. TWO_BYTE_DATA (push->PhysicalMin, descIndex, Dbg);
  1143. BIT_EXTEND_2 (push->PhysicalMin);
  1144. break;
  1145. case HIDP_GLOBAL_PHY_MIN_4:
  1146. FOUR_BYTE_DATA (push->PhysicalMin, descIndex, Dbg);
  1147. break;
  1148. case HIDP_GLOBAL_PHY_MAX_1:
  1149. ONE_BYTE_DATA (push->PhysicalMax, descIndex, Dbg);
  1150. BIT_EXTEND_1 (push->PhysicalMax);
  1151. break;
  1152. case HIDP_GLOBAL_PHY_MAX_2:
  1153. TWO_BYTE_DATA (push->PhysicalMax, descIndex, Dbg);
  1154. BIT_EXTEND_2 (push->PhysicalMax);
  1155. break;
  1156. case HIDP_GLOBAL_PHY_MAX_4:
  1157. FOUR_BYTE_DATA (push->PhysicalMax, descIndex, Dbg);
  1158. break;
  1159. case HIDP_GLOBAL_UNIT_EXP_1:
  1160. ONE_BYTE_DATA (push->UnitExp, descIndex, Dbg);
  1161. BIT_EXTEND_1 (push->UnitExp);
  1162. break;
  1163. case HIDP_GLOBAL_UNIT_EXP_2:
  1164. TWO_BYTE_DATA (push->UnitExp, descIndex, Dbg);
  1165. BIT_EXTEND_2 (push->UnitExp);
  1166. break;
  1167. case HIDP_GLOBAL_UNIT_EXP_4:
  1168. FOUR_BYTE_DATA (push->UnitExp, descIndex, Dbg);
  1169. break;
  1170. case HIDP_GLOBAL_UNIT_1:
  1171. ONE_BYTE_DATA (push->Unit, descIndex, Dbg);
  1172. break;
  1173. case HIDP_GLOBAL_UNIT_2:
  1174. TWO_BYTE_DATA (push->Unit, descIndex, Dbg);
  1175. break;
  1176. case HIDP_GLOBAL_UNIT_4:
  1177. FOUR_BYTE_DATA (push->Unit, descIndex, Dbg);
  1178. break;
  1179. case HIDP_GLOBAL_REPORT_SIZE:
  1180. ONE_BYTE_DATA (push->ReportSize, descIndex, Dbg);
  1181. break;
  1182. case HIDP_GLOBAL_REPORT_COUNT_1:
  1183. ONE_BYTE_DATA (push->ReportCount, descIndex, Dbg);
  1184. break;
  1185. case HIDP_GLOBAL_REPORT_COUNT_2:
  1186. TWO_BYTE_DATA (push->ReportCount, descIndex, Dbg);
  1187. break;
  1188. case HIDP_GLOBAL_REPORT_ID:
  1189. //
  1190. // If a device has no report GLOBAL_REPORT_ID token in its descriptor
  1191. // then it will never transmit a report ID in its input reports,
  1192. // and the report ID for each channel will be set to zero.
  1193. //
  1194. // But, if anywhere in the report, a device declares a report ID
  1195. // that device must always transmit a report ID with input reports,
  1196. // AND more importantly that report ID MUST NOT BE ZERO.
  1197. //
  1198. // This means that if we find a report id token, that we can just
  1199. // overwrite the first report ID structure with the given report ID
  1200. // because we know that the first ID structure (initialized to zero
  1201. // and therefore not valid) will not be used for any of the channels.
  1202. //
  1203. ONE_BYTE_DATA (tmpID, descIndex, Dbg);
  1204. //
  1205. // Search to see if this report id has been used before.
  1206. //
  1207. for (tmpReportIDs = DeviceDesc->ReportIDs;
  1208. tmpReportIDs != currentReportIDs;
  1209. tmpReportIDs++) {
  1210. if (tmpReportIDs->ReportID == tmpID) {
  1211. //
  1212. // A duplicate!
  1213. // Make sure that it is for this same collection
  1214. //
  1215. if (tmpReportIDs->CollectionNumber != appCol->CollectionNumber) {
  1216. HidP_KdPrint(2, ("Reports cannot span more than one top level \n"));
  1217. HidP_KdPrint(2, ("Report ID %d found in collections [%d %d]",
  1218. (ULONG) tmpID,
  1219. (ULONG) tmpReportIDs->CollectionNumber,
  1220. (ULONG) appCol->CollectionNumber));
  1221. Dbg->BreakOffset = descIndex;
  1222. Dbg->ErrorCode = HIDP_GETCOLDESC_REPORT_ID;
  1223. Dbg->Args[0] = item;
  1224. status = HIDP_STATUS_INVALID_REPORT_TYPE;
  1225. goto HIDP_PARSE_REJECT;
  1226. }
  1227. //
  1228. // Use this report ID.
  1229. //
  1230. push->ReportIDs = tmpReportIDs;
  1231. break;
  1232. }
  1233. } // continue looking.
  1234. if (isFirstReportID) {
  1235. isFirstReportID = FALSE;
  1236. } else if (tmpReportIDs == currentReportIDs) {
  1237. //
  1238. // We have not seen this report ID before.
  1239. // make a new container.
  1240. //
  1241. push->ReportIDs = currentReportIDs;
  1242. // Make room for the Report ID as the first byte.
  1243. currentReportIDs->InputLength = 8;
  1244. currentReportIDs->OutputLength = 8;
  1245. currentReportIDs->FeatureLength = 8;
  1246. currentReportIDs->CollectionNumber = appCol->CollectionNumber;
  1247. currentReportIDs++;
  1248. }
  1249. push->ReportIDs->ReportID = tmpID;
  1250. if (0 == push->ReportIDs->ReportID) {
  1251. status = HIDP_STATUS_INVALID_REPORT_TYPE;
  1252. HidP_KdPrint(2, ("Report IDs cannot be zero (0)\n"));
  1253. Dbg->ErrorCode = HIDP_GETCOLDESC_BAD_REPORT_ID;
  1254. Dbg->BreakOffset = descIndex;
  1255. goto HIDP_PARSE_REJECT;
  1256. }
  1257. break;
  1258. case HIDP_GLOBAL_PUSH:
  1259. tmpPush = (PHIDP_PARSE_GLOBAL_PUSH)
  1260. ExAllocatePool (PoolType, sizeof (HIDP_PARSE_GLOBAL_PUSH));
  1261. if (!tmpPush)
  1262. {
  1263. status = STATUS_INSUFFICIENT_RESOURCES;
  1264. HidP_KdPrint(2, ("No Resources to Push global stack\n"));
  1265. Dbg->BreakOffset = descIndex;
  1266. Dbg->ErrorCode = HIDP_GETCOLDESC_PUSH_RESOURCES;
  1267. goto HIDP_PARSE_REJECT;
  1268. }
  1269. HidP_KdPrint(0, ("Push Global Stack\n"));
  1270. *tmpPush = *push;
  1271. tmpPush->Pop = push;
  1272. push = tmpPush;
  1273. break;
  1274. case HIDP_GLOBAL_POP:
  1275. tmpPush = push->Pop;
  1276. ExFreePool (push);
  1277. push = tmpPush;
  1278. HidP_KdPrint(0, ("Pop Global Stack\n"));
  1279. break;
  1280. //
  1281. // Local Items
  1282. //
  1283. //
  1284. // We already verified that only "approved" tokens will be within
  1285. // the open / close of the following delimiter. This simplifies
  1286. // our parsing here tremendously.
  1287. //
  1288. case HIDP_LOCAL_DELIMITER:
  1289. ONE_BYTE_DATA (item, descIndex, Dbg);
  1290. if (1 == item) {
  1291. withinDelimiter = TRUE;
  1292. firstUsageWithinDelimiter = TRUE;
  1293. } else if (0 == item) {
  1294. withinDelimiter = FALSE;
  1295. } else {
  1296. TRAP ();
  1297. }
  1298. break;
  1299. case HIDP_LOCAL_USAGE_1:
  1300. case HIDP_LOCAL_USAGE_2:
  1301. case HIDP_LOCAL_USAGE_4:
  1302. if ((&firstUsage == usage) || usage->Value || usage->Max || usage->Min) {
  1303. usage = HidP_PushUsageList (usage, PoolType, withinDelimiter);
  1304. if (!usage) {
  1305. status = STATUS_INSUFFICIENT_RESOURCES;
  1306. HidP_KdPrint(2, ("No Resources to Push Usage stack\n"));
  1307. Dbg->BreakOffset = descIndex;
  1308. Dbg->ErrorCode = HIDP_GETCOLDESC_PUSH_RESOURCES;
  1309. goto HIDP_PARSE_REJECT;
  1310. }
  1311. }
  1312. usage->Range = FALSE;
  1313. if (HIDP_LOCAL_USAGE_1 == item) {
  1314. ONE_BYTE_DATA (usage->Value, descIndex, Dbg);
  1315. } else if (HIDP_LOCAL_USAGE_2 == item) {
  1316. TWO_BYTE_DATA (usage->Value, descIndex, Dbg);
  1317. } else {
  1318. TWO_BYTE_DATA (usage->Value, descIndex, Dbg);
  1319. TWO_BYTE_DATA (usage->UsagePage, descIndex, Dbg);
  1320. // upper 16 bits overwrite the default usage page.
  1321. }
  1322. if (withinDelimiter) {
  1323. usage->IsAlias = !firstUsageWithinDelimiter;
  1324. firstUsageWithinDelimiter = FALSE;
  1325. }
  1326. if (0 == usage->Value) {
  1327. //
  1328. // Test to see if they have used Usage ID (0) which is reserved.
  1329. // But instead of breaking just print an error
  1330. //
  1331. HidP_KdPrint(2, ("Usage ID (0) explicitly usaged! This usage is reserved. Offset (%x)\n",
  1332. descIndex));
  1333. }
  1334. break;
  1335. //
  1336. // NB: before we can add delimiters to usage ranges we must insure
  1337. // that the range is identical for all entries within the delimiter.
  1338. //
  1339. case HIDP_LOCAL_USAGE_MIN_1:
  1340. case HIDP_LOCAL_USAGE_MIN_2:
  1341. case HIDP_LOCAL_USAGE_MIN_4:
  1342. if ((&firstUsage == usage) || (usage->Min) || (usage->Value)) {
  1343. usage = HidP_PushUsageList (usage, PoolType, FALSE);
  1344. if (!usage) {
  1345. status = STATUS_INSUFFICIENT_RESOURCES;
  1346. HidP_KdPrint(2, ("No Resources to Push Usage stack\n"));
  1347. Dbg->BreakOffset = descIndex;
  1348. Dbg->ErrorCode = HIDP_GETCOLDESC_PUSH_RESOURCES;
  1349. goto HIDP_PARSE_REJECT;
  1350. }
  1351. }
  1352. usage->Range = TRUE;
  1353. if (HIDP_LOCAL_USAGE_MIN_1 == item) {
  1354. ONE_BYTE_DATA (usage->Min, descIndex, Dbg);
  1355. } else if (HIDP_LOCAL_USAGE_MIN_2 == item) {
  1356. TWO_BYTE_DATA (usage->Min, descIndex, Dbg);
  1357. } else {
  1358. TWO_BYTE_DATA (usage->Min, descIndex, Dbg);
  1359. TWO_BYTE_DATA (usage->UsagePage, descIndex, Dbg);
  1360. // upper 16 bits overwrite the default usage page.
  1361. }
  1362. break;
  1363. case HIDP_LOCAL_USAGE_MAX_1:
  1364. case HIDP_LOCAL_USAGE_MAX_2:
  1365. case HIDP_LOCAL_USAGE_MAX_4:
  1366. if ((&firstUsage == usage) || (usage->Max) || (usage->Value)) {
  1367. usage = HidP_PushUsageList (usage, PoolType, FALSE);
  1368. if (!usage) {
  1369. status = STATUS_INSUFFICIENT_RESOURCES;
  1370. HidP_KdPrint(2, ("No Resources to Push Usage stack\n"));
  1371. Dbg->BreakOffset = descIndex;
  1372. Dbg->ErrorCode = HIDP_GETCOLDESC_PUSH_RESOURCES;
  1373. goto HIDP_PARSE_REJECT;
  1374. }
  1375. }
  1376. usage->Range = TRUE;
  1377. if (HIDP_LOCAL_USAGE_MAX_1 == item) {
  1378. ONE_BYTE_DATA (usage->Max, descIndex, Dbg);
  1379. } else if (HIDP_LOCAL_USAGE_MAX_2 == item) {
  1380. TWO_BYTE_DATA (usage->Max, descIndex, Dbg);
  1381. } else {
  1382. TWO_BYTE_DATA (usage->Max, descIndex, Dbg);
  1383. TWO_BYTE_DATA (usage->UsagePage, descIndex, Dbg);
  1384. // upper 16 bits overwrite the default usage page.
  1385. }
  1386. break;
  1387. case HIDP_LOCAL_DESIG_INDEX:
  1388. designator.Range = FALSE;
  1389. ONE_BYTE_DATA (designator.Value, descIndex, Dbg);
  1390. break;
  1391. case HIDP_LOCAL_DESIG_MIN:
  1392. designator.Range = TRUE;
  1393. ONE_BYTE_DATA (designator.Min, descIndex, Dbg);
  1394. break;
  1395. case HIDP_LOCAL_DESIG_MAX:
  1396. designator.Range = TRUE;
  1397. ONE_BYTE_DATA (designator.Max, descIndex, Dbg);
  1398. break;
  1399. case HIDP_LOCAL_STRING_INDEX:
  1400. string.Range = FALSE;
  1401. ONE_BYTE_DATA (string.Value, descIndex, Dbg);
  1402. break;
  1403. case HIDP_LOCAL_STRING_MIN:
  1404. string.Range = TRUE;
  1405. ONE_BYTE_DATA (string.Min, descIndex, Dbg);
  1406. break;
  1407. case HIDP_LOCAL_STRING_MAX:
  1408. string.Range = TRUE;
  1409. ONE_BYTE_DATA (string.Max, descIndex, Dbg);
  1410. break;
  1411. case HIDP_MAIN_INPUT_1:
  1412. tmpReportIDs = push->ReportIDs;
  1413. bitPos = tmpReportIDs->InputLength; // The distance into the report
  1414. HidP_KdPrint(0, ("'Main Offset:%x \n", bitPos));
  1415. tmpReportIDs->InputLength += push->ReportSize * push->ReportCount;
  1416. channelIndex = &(preparsed->Input.Index);
  1417. ONE_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1418. goto HIDP_PARSE_MAIN_ITEM;
  1419. case HIDP_MAIN_INPUT_2:
  1420. tmpReportIDs = push->ReportIDs;
  1421. bitPos = tmpReportIDs->InputLength; // The distance into the report
  1422. HidP_KdPrint(0, ("'Main2 offset:%x \n", bitPos));
  1423. tmpReportIDs->InputLength += push->ReportSize * push->ReportCount;
  1424. channelIndex = &(preparsed->Input.Index);
  1425. TWO_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1426. goto HIDP_PARSE_MAIN_ITEM;
  1427. case HIDP_MAIN_OUTPUT_1:
  1428. tmpReportIDs = push->ReportIDs;
  1429. bitPos = tmpReportIDs->OutputLength; // The distance into the report
  1430. HidP_KdPrint(0, ("'Out offset:%x \n", bitPos));
  1431. tmpReportIDs->OutputLength += push->ReportSize * push->ReportCount;
  1432. channelIndex = &(preparsed->Output.Index);
  1433. ONE_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1434. goto HIDP_PARSE_MAIN_ITEM;
  1435. case HIDP_MAIN_OUTPUT_2:
  1436. tmpReportIDs = push->ReportIDs;
  1437. bitPos = tmpReportIDs->OutputLength; // The distance into the report
  1438. HidP_KdPrint(0, ("'Out2 offset:%x \n", bitPos));
  1439. tmpReportIDs->OutputLength += push->ReportSize * push->ReportCount;
  1440. channelIndex = &(preparsed->Output.Index);
  1441. TWO_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1442. goto HIDP_PARSE_MAIN_ITEM;
  1443. case HIDP_MAIN_FEATURE_1:
  1444. tmpReportIDs = push->ReportIDs;
  1445. bitPos = tmpReportIDs->FeatureLength; // The distance into the report
  1446. HidP_KdPrint(0, ("'Feature offset:%x \n", bitPos));
  1447. tmpReportIDs->FeatureLength += push->ReportSize * push->ReportCount;
  1448. channelIndex = &(preparsed->Feature.Index);
  1449. ONE_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1450. goto HIDP_PARSE_MAIN_ITEM;
  1451. case HIDP_MAIN_FEATURE_2:
  1452. tmpReportIDs = push->ReportIDs;
  1453. bitPos = tmpReportIDs->FeatureLength; // The distance into the report
  1454. HidP_KdPrint(0, ("'Feature2 offset:%x \n", bitPos));
  1455. tmpReportIDs->FeatureLength += push->ReportSize * push->ReportCount;
  1456. channelIndex = &(preparsed->Feature.Index);
  1457. TWO_BYTE_DATA (tmpBitField, descIndex, Dbg);
  1458. HIDP_PARSE_MAIN_ITEM:
  1459. // You can have a constant field that does return data.
  1460. // so we probably shouldn't skip it.
  1461. // BUT it should NOT be an array style button field.
  1462. if (HIDP_ISARRAY (tmpBitField)) {
  1463. if (HIDP_ISCONST(tmpBitField)) {
  1464. break;
  1465. }
  1466. //
  1467. // Here we have a list of indices that refer to the usages
  1468. // described prior. For each of the prior usages, up to the depth
  1469. // found, we allocate a channel structure to describe the given
  1470. // usages. These channels are linked so that we will later know
  1471. // that they all describe the same filled.
  1472. //
  1473. //
  1474. // We do no support delimiteres in array declairations.
  1475. // To do so would require a large change to Index2Usage which
  1476. // instead of returning only one usage would have to return
  1477. // several.
  1478. //
  1479. if (usage->IsAlias) {
  1480. status = STATUS_COULD_NOT_INTERPRET;
  1481. HidP_KdPrint(2, ("Currently this parser does not support\n"));
  1482. HidP_KdPrint(2, ("Delimiters for array declairations\n"));
  1483. Dbg->BreakOffset = descIndex;
  1484. Dbg->ErrorCode = HIDP_GETCOLDESC_UNSUPPORTED;
  1485. goto HIDP_PARSE_REJECT;
  1486. }
  1487. for ( ;
  1488. usage != &firstUsage;
  1489. (*channelIndex)++,
  1490. usage = HidP_PopUsageList (usage)) {
  1491. channel = &(preparsed->Data[*channelIndex]);
  1492. channel->BitField = tmpBitField;
  1493. // field that says this channel is linked
  1494. channel->MoreChannels = TRUE;
  1495. // say what link collection number we are in.
  1496. channel->LinkCollection = (USHORT)(currentLCNode - linkNodeArray);
  1497. channel->LinkUsage = currentLCNode->LinkUsage;
  1498. channel->LinkUsagePage = currentLCNode->LinkUsagePage;
  1499. if (usage->UsagePage) {
  1500. // The default usage page been overwritten.
  1501. channel->UsagePage = usage->UsagePage;
  1502. } else {
  1503. channel->UsagePage = push->UsagePage;
  1504. }
  1505. channel->BitOffset = (UCHAR) bitPos & 7;
  1506. channel->ByteOffset = (USHORT) bitPos >> 3;
  1507. channel->ReportSize = push->ReportSize;
  1508. channel->ReportCount = push->ReportCount;
  1509. channel->BitLength = push->ReportSize * push->ReportCount;
  1510. channel->ByteEnd = (channel->BitOffset + channel->BitLength);
  1511. channel->ByteEnd = (channel->ByteEnd >> 3)
  1512. + ((channel->ByteEnd & 7) ? 1 : 0)
  1513. + channel->ByteOffset;
  1514. channel->ReportID = push->ReportIDs->ReportID;
  1515. channel->Units = push->Unit;
  1516. channel->UnitExp = push->UnitExp;
  1517. channel->IsConst = FALSE;
  1518. channel->IsButton = TRUE;
  1519. channel->IsAbsolute = HIDP_ISABSOLUTE(tmpBitField);
  1520. channel->button.LogicalMin = push->LogicalMin;
  1521. channel->button.LogicalMax = push->LogicalMax;
  1522. channel->IsRange = usage->Range;
  1523. channel->IsDesignatorRange = designator.Range;
  1524. channel->IsStringRange = string.Range;
  1525. if (usage->Range) {
  1526. channel->Range.UsageMin = usage->Min;
  1527. channel->Range.UsageMax = usage->Max;
  1528. } else {
  1529. channel->Range.UsageMin =
  1530. channel->Range.UsageMax = usage->Value;
  1531. }
  1532. if (designator.Range) {
  1533. channel->Range.DesignatorMin = designator.Min;
  1534. channel->Range.DesignatorMax = designator.Max;
  1535. } else {
  1536. channel->Range.DesignatorMin =
  1537. channel->Range.DesignatorMax = designator.Value;
  1538. }
  1539. if (string.Range) {
  1540. channel->Range.StringMin = string.Min;
  1541. channel->Range.StringMax = string.Max;
  1542. } else {
  1543. channel->Range.StringMin =
  1544. channel->Range.StringMax = string.Value;
  1545. }
  1546. channel->NumGlobalUnknowns = push->NumGlobalUnknowns;
  1547. if (push->NumGlobalUnknowns) {
  1548. RtlCopyMemory (channel->GlobalUnknowns,
  1549. push->GlobalUnknowns,
  1550. push->NumGlobalUnknowns
  1551. * sizeof (HIDP_UNKNOWN_TOKEN));
  1552. }
  1553. //
  1554. // Check for power buttons
  1555. //
  1556. if (HIDP_USAGE_SYSCTL_PAGE == channel->UsagePage) {
  1557. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_POWER) &&
  1558. (HIDP_USAGE_SYSCTL_POWER <= channel->Range.UsageMax)) {
  1559. preparsed->PowerButtonMask |= SYS_BUTTON_POWER;
  1560. }
  1561. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_SLEEP) &&
  1562. (HIDP_USAGE_SYSCTL_SLEEP <= channel->Range.UsageMax)) {
  1563. preparsed->PowerButtonMask |= SYS_BUTTON_SLEEP;
  1564. }
  1565. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_WAKE) &&
  1566. (HIDP_USAGE_SYSCTL_WAKE <= channel->Range.UsageMax)) {
  1567. preparsed->PowerButtonMask |= SYS_BUTTON_WAKE;
  1568. }
  1569. }
  1570. }
  1571. ASSERT (0 == usage->Depth);
  1572. channel->MoreChannels = FALSE;
  1573. designator = string = zeroLocal;
  1574. break;
  1575. } // end array style channel
  1576. channel = &(preparsed->Data[*channelIndex]);
  1577. if (HIDP_ISCONST(tmpBitField)) {
  1578. if ((0 == usage->Depth) ||
  1579. ((0 == usage->Value) && (0 == usage->Min)
  1580. && (0 == usage->Max))) {
  1581. //
  1582. // A constant channel with no usage. Skip it.
  1583. //
  1584. usage = HidP_FreeUsageList (usage);
  1585. ASSERT (usage == &firstUsage);
  1586. ASSERT (0 == usage->Depth);
  1587. break;
  1588. }
  1589. channel->IsConst = TRUE;
  1590. } else {
  1591. channel->IsConst = FALSE;
  1592. }
  1593. tmpCount = usage->Depth // - 1
  1594. + (usage->Range ? (usage->Max - usage->Min) : 0); // + 1
  1595. #if 0
  1596. while (tmpCount > push->ReportCount) {
  1597. // Get rid of excess usages.
  1598. tmpCount = usage->Depth - 1;
  1599. usage = HidP_PopUsageList (usage);
  1600. ASSERT (tmpCount == (usage->Depth +
  1601. (usage->Range ? (usage->Max - usage->Min) : 0)));
  1602. }
  1603. #else
  1604. while (tmpCount > push->ReportCount) {
  1605. // Get rid of excess usages.
  1606. if (tmpCount <= usage->Depth) {
  1607. // We've got enough in the linked usages to fulfill this request
  1608. tmpCount = usage->Depth - 1;
  1609. usage = HidP_PopUsageList (usage);
  1610. ASSERT (tmpCount ==
  1611. (usage->Depth +
  1612. (usage->Range ? (usage->Max - usage->Min) : 0)));
  1613. } else {
  1614. // We don't have enough in the linked usages, but we've too
  1615. // much in this range. So, adjust the max value of the
  1616. // range so that it won't be too many usages.
  1617. ASSERT (usage->Range);
  1618. usage->Max = push->ReportCount - usage->Depth + usage->Min;
  1619. tmpCount = usage->Depth + (usage->Max - usage->Min);
  1620. }
  1621. }
  1622. ASSERT (tmpCount <= push->ReportCount);
  1623. // Now we should no longer have too many usages.
  1624. //
  1625. #endif
  1626. //
  1627. // The last value in the link (aka the top) must be
  1628. // repeated if there are less usages than there are
  1629. // report counts. That particular usage applies to all
  1630. // field in this main item not yet accounted for. In this
  1631. // case a single channel descriptor is allocated and
  1632. // report count is set to the number of fields referenced
  1633. // by this usage.
  1634. //
  1635. // Not the usages are listed in reverse order of there appearence
  1636. // in the report descriptor, so the first usage found in this list
  1637. // is the one that should be repeated.
  1638. //
  1639. // tmpCount is the number of field to which this first usage applies.
  1640. //
  1641. tmpCount = 1 + push->ReportCount - tmpCount
  1642. + usage->Max - usage->Min;
  1643. //
  1644. // The following loop assigns the usage to the fields in this main
  1645. // item in reverse order.
  1646. //
  1647. bitPos += push->ReportSize * (push->ReportCount - tmpCount);
  1648. for (i = 0;
  1649. i < push->ReportCount;
  1650. i += tmpCount, // Bump i by the number of fields for this channel
  1651. tmpCount = 1 + (usage->Range ? (usage->Max - usage->Min) : 0),
  1652. bitPos -= (push->ReportSize * tmpCount)) {
  1653. do { // do for all the aliases.
  1654. channel = &(preparsed->Data[(*channelIndex)++]);
  1655. // set the IsAlias flag now and then clear the last one
  1656. // at the close of this Do while loop.
  1657. channel->IsAlias = TRUE;
  1658. channel->BitField = tmpBitField;
  1659. channel->MoreChannels = FALSE; // only valid for arrays
  1660. channel->LinkCollection = (USHORT)(currentLCNode - linkNodeArray);
  1661. channel->LinkUsage = currentLCNode->LinkUsage;
  1662. channel->LinkUsagePage = currentLCNode->LinkUsagePage;
  1663. if (usage->UsagePage) {
  1664. // The default usage page been overwritten.
  1665. channel->UsagePage = usage->UsagePage;
  1666. } else {
  1667. channel->UsagePage = push->UsagePage;
  1668. }
  1669. channel->BitOffset = (UCHAR) bitPos & 7;
  1670. channel->ByteOffset = (USHORT) bitPos >> 3;
  1671. channel->ReportSize = push->ReportSize;
  1672. channel->ReportCount = tmpCount;
  1673. channel->BitLength = push->ReportSize * tmpCount;
  1674. channel->ByteEnd = (channel->BitOffset + channel->BitLength);
  1675. channel->ByteEnd = (channel->ByteEnd >> 3)
  1676. + ((channel->ByteEnd & 7) ? 1 : 0)
  1677. + channel->ByteOffset;
  1678. channel->ReportID = push->ReportIDs->ReportID;
  1679. channel->IsAbsolute = HIDP_ISABSOLUTE(tmpBitField);
  1680. channel->Units = push->Unit;
  1681. channel->UnitExp = push->UnitExp;
  1682. if (1 == push->ReportSize) {
  1683. channel->IsButton = TRUE;
  1684. } else {
  1685. channel->IsButton = FALSE;
  1686. channel->Data.HasNull = HIDP_HASNULL(channel->BitField);
  1687. channel->Data.LogicalMin = push->LogicalMin;
  1688. channel->Data.LogicalMax = push->LogicalMax;
  1689. channel->Data.PhysicalMin = push->PhysicalMin;
  1690. channel->Data.PhysicalMax = push->PhysicalMax;
  1691. }
  1692. channel->IsDesignatorRange = designator.Range;
  1693. channel->IsStringRange = string.Range;
  1694. channel->IsRange = usage->Range;
  1695. if (usage->Range) {
  1696. channel->Range.UsageMin = usage->Min;
  1697. channel->Range.UsageMax = usage->Max;
  1698. } else {
  1699. channel->Range.UsageMin =
  1700. channel->Range.UsageMax = usage->Value;
  1701. }
  1702. if (designator.Range) {
  1703. channel->Range.DesignatorMin = designator.Min;
  1704. channel->Range.DesignatorMax = designator.Max;
  1705. } else {
  1706. channel->Range.DesignatorMin =
  1707. channel->Range.DesignatorMax = designator.Value;
  1708. }
  1709. if (string.Range) {
  1710. channel->Range.StringMin = string.Min;
  1711. channel->Range.StringMax = string.Max;
  1712. } else {
  1713. channel->Range.StringMin =
  1714. channel->Range.StringMax = string.Value;
  1715. }
  1716. isAlias = usage->IsAlias;
  1717. usage = HidP_PopUsageList (usage); // discard used usage
  1718. channel->NumGlobalUnknowns = push->NumGlobalUnknowns;
  1719. if (push->NumGlobalUnknowns) {
  1720. RtlCopyMemory (channel->GlobalUnknowns,
  1721. push->GlobalUnknowns,
  1722. push->NumGlobalUnknowns
  1723. * sizeof (HIDP_UNKNOWN_TOKEN));
  1724. }
  1725. //
  1726. // Check for power buttons
  1727. //
  1728. if (HIDP_USAGE_SYSCTL_PAGE == channel->UsagePage) {
  1729. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_POWER) &&
  1730. (HIDP_USAGE_SYSCTL_POWER <= channel->Range.UsageMax)) {
  1731. preparsed->PowerButtonMask |= SYS_BUTTON_POWER;
  1732. }
  1733. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_SLEEP) &&
  1734. (HIDP_USAGE_SYSCTL_SLEEP <= channel->Range.UsageMax)) {
  1735. preparsed->PowerButtonMask |= SYS_BUTTON_SLEEP;
  1736. }
  1737. if ((channel->Range.UsageMin <= HIDP_USAGE_SYSCTL_WAKE) &&
  1738. (HIDP_USAGE_SYSCTL_WAKE <= channel->Range.UsageMax)) {
  1739. preparsed->PowerButtonMask |= SYS_BUTTON_WAKE;
  1740. }
  1741. }
  1742. } while (isAlias);
  1743. channel->IsAlias = FALSE;
  1744. } // for all channels in this main item
  1745. // Zero out the locals.
  1746. designator = string = zeroLocal;
  1747. // Hopefully we have used all the local usages now
  1748. ASSERT (usage == &firstUsage);
  1749. break;
  1750. default:
  1751. #ifdef HIDP_REJECT_UNDEFINED
  1752. HidP_KdPrint (2, ("Item Unknown %x\n", item));
  1753. Dbg->BreakOffset = descIndex;
  1754. Dbg->ErrorCode = HIDP_GETCOLDESC_ITEM_UNKNOWN;
  1755. Dbg->Args[0] = item;
  1756. status = STATUS_ILLEGAL_INSTRUCTION;
  1757. goto HIDP_PARSE_REJECT;
  1758. #else
  1759. if (HIDP_IS_MAIN_ITEM (item)) {
  1760. HidP_KdPrint (2, ("Unknown MAIN item: %x\n", item));
  1761. Dbg->BreakOffset = descIndex;
  1762. Dbg->ErrorCode = HIDP_GETCOLDESC_ITEM_UNKNOWN;
  1763. Dbg->Args[0] = item;
  1764. status = STATUS_ILLEGAL_INSTRUCTION;
  1765. goto HIDP_PARSE_REJECT;
  1766. } else if (HIDP_IS_GLOBAL_ITEM (item)) {
  1767. if (HIDP_MAX_UNKNOWN_ITEMS == push->NumGlobalUnknowns) {
  1768. push->NumGlobalUnknowns--;
  1769. // overwrite the last entry;
  1770. }
  1771. unknownToken = &push->GlobalUnknowns[push->NumGlobalUnknowns];
  1772. unknownToken->Token = item;
  1773. switch (item & HIDP_ITEM_LENGTH_DATA) {
  1774. case 0:
  1775. break;
  1776. case 1:
  1777. ONE_BYTE_DATA (unknownToken->BitField, descIndex, Dbg);
  1778. break;
  1779. case 2:
  1780. TWO_BYTE_DATA (unknownToken->BitField, descIndex, Dbg);
  1781. break;
  1782. case 3:
  1783. FOUR_BYTE_DATA (unknownToken->BitField, descIndex, Dbg);
  1784. break;
  1785. }
  1786. push->NumGlobalUnknowns++;
  1787. } else if (HIDP_IS_LOCAL_ITEM (item)) {
  1788. HidP_KdPrint (2, ("Unknown LOCAL item: %x\n", item));
  1789. Dbg->BreakOffset = descIndex;
  1790. Dbg->ErrorCode = HIDP_GETCOLDESC_ITEM_UNKNOWN;
  1791. Dbg->Args[0] = item;
  1792. status = STATUS_ILLEGAL_INSTRUCTION;
  1793. goto HIDP_PARSE_REJECT;
  1794. } else if (HIDP_IS_RESERVED_ITEM (item)) {
  1795. HidP_KdPrint (2, ("Unknown RESERVED item: %x\n", item));
  1796. Dbg->BreakOffset = descIndex;
  1797. Dbg->ErrorCode = HIDP_GETCOLDESC_ITEM_UNKNOWN;
  1798. Dbg->Args[0] = item;
  1799. status = STATUS_ILLEGAL_INSTRUCTION;
  1800. goto HIDP_PARSE_REJECT;
  1801. }
  1802. #endif
  1803. break;
  1804. }
  1805. }
  1806. HidP_FreeUsageList (usage);
  1807. //
  1808. // Since the number of report IDs could be less than the total allocated,
  1809. // due to the fact that some might be repeated, reset the length of the
  1810. // array to reflect the total amount which we found.
  1811. //
  1812. DeviceDesc->ReportIDsLength =
  1813. (ULONG)(currentReportIDs - DeviceDesc->ReportIDs);
  1814. return status;
  1815. HIDP_PARSE_REJECT:
  1816. while (push != &firstPush)
  1817. {
  1818. tmpPush = push;
  1819. push = push->Pop;
  1820. ExFreePool (tmpPush);
  1821. }
  1822. if (NULL != usage) {
  1823. //
  1824. // If usage is null, that means that something went wrong. (probably
  1825. // in the push usage routine). In this case the usage memory should
  1826. // have already been freed.
  1827. //
  1828. HidP_FreeUsageList (usage);
  1829. }
  1830. return status;
  1831. }
  1832. VOID
  1833. HidP_FreeCollectionDescription (
  1834. IN PHIDP_DEVICE_DESC Desc
  1835. )
  1836. {
  1837. ULONG i;
  1838. for (i=0; i < Desc->CollectionDescLength; i++) {
  1839. ExFreePool (Desc->CollectionDesc[i].PreparsedData);
  1840. }
  1841. ExFreePool (Desc->CollectionDesc);
  1842. ExFreePool (Desc->ReportIDs);
  1843. //
  1844. // Do NOT free Desc itself.
  1845. //
  1846. }
  1847. #define PHIDP_SYS_POWER_EVENT_BUTTON_LENGTH 0x20
  1848. NTSTATUS
  1849. HidP_SysPowerEvent (
  1850. IN PCHAR HidPacket,
  1851. IN USHORT HidPacketLength,
  1852. IN PHIDP_PREPARSED_DATA Ppd,
  1853. OUT PULONG OutputBuffer
  1854. )
  1855. {
  1856. USAGE buttonList [PHIDP_SYS_POWER_EVENT_BUTTON_LENGTH];
  1857. ULONG length = PHIDP_SYS_POWER_EVENT_BUTTON_LENGTH;
  1858. NTSTATUS status = STATUS_NOT_SUPPORTED;
  1859. ULONG i;
  1860. *OutputBuffer = 0;
  1861. if (Ppd->PowerButtonMask) {
  1862. status = HidP_GetUsages (HidP_Input,
  1863. HIDP_USAGE_SYSCTL_PAGE,
  1864. 0,
  1865. buttonList,
  1866. &length,
  1867. Ppd,
  1868. HidPacket,
  1869. HidPacketLength);
  1870. if (NT_SUCCESS (status)) {
  1871. for (i = 0; i < length; i++) {
  1872. switch (buttonList[i]) {
  1873. case HIDP_USAGE_SYSCTL_POWER:
  1874. *OutputBuffer |= SYS_BUTTON_POWER;
  1875. break;
  1876. case HIDP_USAGE_SYSCTL_WAKE:
  1877. *OutputBuffer |= SYS_BUTTON_WAKE;
  1878. break;
  1879. case HIDP_USAGE_SYSCTL_SLEEP:
  1880. *OutputBuffer |= SYS_BUTTON_SLEEP;
  1881. break;
  1882. }
  1883. }
  1884. }
  1885. }
  1886. return status;
  1887. }
  1888. NTSTATUS
  1889. HidP_SysPowerCaps (
  1890. IN PHIDP_PREPARSED_DATA Ppd,
  1891. OUT PULONG OutputBuffer
  1892. )
  1893. {
  1894. *OutputBuffer = Ppd->PowerButtonMask;
  1895. return STATUS_SUCCESS;
  1896. }
  1897. void
  1898. HidP_AssignDataIndices (
  1899. PHIDP_PREPARSED_DATA Ppd,
  1900. PHIDP_GETCOLDESC_DBG Dbg
  1901. )
  1902. {
  1903. struct _CHANNEL_REPORT_HEADER * iof;
  1904. PHIDP_CHANNEL_DESC channel;
  1905. PHIDP_CHANNEL_DESC scan;
  1906. PHIDP_CHANNEL_DESC end;
  1907. USHORT i;
  1908. USHORT dataIndex;
  1909. PAGED_CODE();
  1910. UNREFERENCED_PARAMETER (Dbg);
  1911. iof = &Ppd->Input;
  1912. while (TRUE) {
  1913. dataIndex = 0;
  1914. for (i = iof->Offset, channel = &Ppd->Data[iof->Offset];
  1915. i < iof->Index ;
  1916. i++, channel++) {
  1917. if (!channel->MoreChannels) {
  1918. channel->Range.DataIndexMin = dataIndex;
  1919. dataIndex += channel->Range.UsageMax - channel->Range.UsageMin;
  1920. channel->Range.DataIndexMax = dataIndex;
  1921. dataIndex++;
  1922. } else {
  1923. //
  1924. // An array channel. We must number these backwards.
  1925. //
  1926. scan = channel;
  1927. while (scan->MoreChannels) {
  1928. scan++;
  1929. i++;
  1930. }
  1931. end = scan;
  1932. do {
  1933. scan->Range.DataIndexMin = dataIndex;
  1934. dataIndex += scan->Range.UsageMax
  1935. - scan->Range.UsageMin;
  1936. scan->Range.DataIndexMax = dataIndex;
  1937. dataIndex++;
  1938. scan--;
  1939. } while ( channel <= scan );
  1940. channel = end;
  1941. }
  1942. }
  1943. if (&Ppd->Input == iof) {
  1944. iof = &Ppd->Output;
  1945. } else if (&Ppd->Output == iof) {
  1946. iof = &Ppd->Feature;
  1947. } else {
  1948. ASSERT (&Ppd->Feature == iof);
  1949. break;
  1950. }
  1951. }
  1952. }