1 /* 2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/usb/hidparse/hidparse.c 5 * PURPOSE: HID Parser 6 * PROGRAMMERS: 7 * Michael Martin (michael.martin@reactos.org) 8 * Johannes Anderwald (johannes.anderwald@reactos.org) 9 */ 10 11 #include "hidparse.h" 12 13 #define NDEBUG 14 #include <debug.h> 15 16 PVOID 17 NTAPI 18 AllocFunction( 19 IN ULONG ItemSize) 20 { 21 PVOID Item = ExAllocatePoolWithTag(NonPagedPool, ItemSize, HIDPARSE_TAG); 22 if (Item) 23 { 24 // 25 // zero item 26 // 27 RtlZeroMemory(Item, ItemSize); 28 } 29 30 // 31 // done 32 // 33 return Item; 34 } 35 36 VOID 37 NTAPI 38 FreeFunction( 39 IN PVOID Item) 40 { 41 // 42 // free item 43 // 44 ExFreePoolWithTag(Item, HIDPARSE_TAG); 45 } 46 47 VOID 48 NTAPI 49 ZeroFunction( 50 IN PVOID Item, 51 IN ULONG ItemSize) 52 { 53 // 54 // zero item 55 // 56 RtlZeroMemory(Item, ItemSize); 57 } 58 59 VOID 60 NTAPI 61 CopyFunction( 62 IN PVOID Target, 63 IN PVOID Source, 64 IN ULONG Length) 65 { 66 // 67 // copy item 68 // 69 RtlCopyMemory(Target, Source, Length); 70 } 71 72 VOID 73 __cdecl 74 DebugFunction( 75 IN LPCSTR FormatStr, ...) 76 { 77 #if HID_DBG 78 va_list args; 79 char printbuffer[1024]; 80 81 va_start(args, FormatStr); 82 vsprintf(printbuffer, FormatStr, args); 83 va_end(args); 84 85 DbgPrint(printbuffer); 86 #endif 87 } 88 89 VOID 90 NTAPI 91 HidP_FreeCollectionDescription( 92 IN PHIDP_DEVICE_DESC DeviceDescription) 93 { 94 HID_PARSER Parser; 95 96 // 97 // init parser 98 // 99 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 100 101 // 102 // free collection 103 // 104 HidParser_FreeCollectionDescription(&Parser, DeviceDescription); 105 } 106 107 108 HIDAPI 109 NTSTATUS 110 NTAPI 111 HidP_GetCaps( 112 IN PHIDP_PREPARSED_DATA PreparsedData, 113 OUT PHIDP_CAPS Capabilities) 114 { 115 HID_PARSER Parser; 116 117 // 118 // init parser 119 // 120 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 121 122 // 123 // get caps 124 // 125 return HidParser_GetCaps(&Parser, PreparsedData, Capabilities); 126 } 127 128 NTSTATUS 129 TranslateStatusForUpperLayer( 130 IN HIDPARSER_STATUS Status) 131 { 132 // 133 // now we are handling only this values, for others just return 134 // status as it is. 135 // 136 switch (Status) 137 { 138 case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES: 139 return STATUS_INSUFFICIENT_RESOURCES; 140 case HIDPARSER_STATUS_INVALID_REPORT_TYPE: 141 return HIDP_STATUS_INVALID_REPORT_TYPE; 142 case HIDPARSER_STATUS_BUFFER_TOO_SMALL: 143 return STATUS_BUFFER_TOO_SMALL; 144 case HIDPARSER_STATUS_COLLECTION_NOT_FOUND: 145 return STATUS_NO_DATA_DETECTED; 146 default: 147 return Status; 148 } 149 } 150 151 NTSTATUS 152 NTAPI 153 HidP_GetCollectionDescription( 154 IN PHIDP_REPORT_DESCRIPTOR ReportDesc, 155 IN ULONG DescLength, 156 IN POOL_TYPE PoolType, 157 OUT PHIDP_DEVICE_DESC DeviceDescription) 158 { 159 HID_PARSER Parser; 160 NTSTATUS Status; 161 162 // 163 // init parser 164 // 165 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 166 167 // 168 // get description; 169 // 170 Status = HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription); 171 return TranslateStatusForUpperLayer(Status); 172 } 173 174 HIDAPI 175 ULONG 176 NTAPI 177 HidP_MaxUsageListLength( 178 IN HIDP_REPORT_TYPE ReportType, 179 IN USAGE UsagePage OPTIONAL, 180 IN PHIDP_PREPARSED_DATA PreparsedData) 181 { 182 HID_PARSER Parser; 183 184 // 185 // sanity check 186 // 187 ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); 188 189 // 190 // init parser 191 // 192 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 193 194 195 // 196 // get usage length 197 // 198 return HidParser_MaxUsageListLength(&Parser, PreparsedData, ReportType, UsagePage); 199 } 200 201 HIDAPI 202 NTSTATUS 203 NTAPI 204 HidP_GetSpecificValueCaps( 205 IN HIDP_REPORT_TYPE ReportType, 206 IN USAGE UsagePage, 207 IN USHORT LinkCollection, 208 IN USAGE Usage, 209 OUT PHIDP_VALUE_CAPS ValueCaps, 210 IN OUT PUSHORT ValueCapsLength, 211 IN PHIDP_PREPARSED_DATA PreparsedData) 212 { 213 HID_PARSER Parser; 214 215 // 216 // sanity check 217 // 218 ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); 219 220 // 221 // init parser 222 // 223 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 224 225 // 226 // get value caps 227 // 228 return HidParser_GetSpecificValueCaps(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, ValueCaps, ValueCapsLength); 229 } 230 231 HIDAPI 232 NTSTATUS 233 NTAPI 234 HidP_GetUsages( 235 IN HIDP_REPORT_TYPE ReportType, 236 IN USAGE UsagePage, 237 IN USHORT LinkCollection OPTIONAL, 238 OUT PUSAGE UsageList, 239 IN OUT PULONG UsageLength, 240 IN PHIDP_PREPARSED_DATA PreparsedData, 241 IN PCHAR Report, 242 IN ULONG ReportLength) 243 { 244 HID_PARSER Parser; 245 246 // 247 // sanity check 248 // 249 ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); 250 251 // 252 // init parser 253 // 254 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 255 256 // 257 // get usages 258 // 259 return HidParser_GetUsages(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, UsageList, UsageLength, Report, ReportLength); 260 } 261 262 263 #undef HidP_GetButtonCaps 264 265 HIDAPI 266 NTSTATUS 267 NTAPI 268 HidP_UsageListDifference( 269 IN PUSAGE PreviousUsageList, 270 IN PUSAGE CurrentUsageList, 271 OUT PUSAGE BreakUsageList, 272 OUT PUSAGE MakeUsageList, 273 IN ULONG UsageListLength) 274 { 275 return HidParser_UsageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength); 276 } 277 278 HIDAPI 279 NTSTATUS 280 NTAPI 281 HidP_GetUsagesEx( 282 IN HIDP_REPORT_TYPE ReportType, 283 IN USHORT LinkCollection, 284 OUT PUSAGE_AND_PAGE ButtonList, 285 IN OUT ULONG *UsageLength, 286 IN PHIDP_PREPARSED_DATA PreparsedData, 287 IN PCHAR Report, 288 IN ULONG ReportLength) 289 { 290 return HidP_GetUsages(ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, &ButtonList->Usage, UsageLength, PreparsedData, Report, ReportLength); 291 } 292 293 HIDAPI 294 NTSTATUS 295 NTAPI 296 HidP_UsageAndPageListDifference( 297 IN PUSAGE_AND_PAGE PreviousUsageList, 298 IN PUSAGE_AND_PAGE CurrentUsageList, 299 OUT PUSAGE_AND_PAGE BreakUsageList, 300 OUT PUSAGE_AND_PAGE MakeUsageList, 301 IN ULONG UsageListLength) 302 { 303 return HidParser_UsageAndPageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength); 304 } 305 306 HIDAPI 307 NTSTATUS 308 NTAPI 309 HidP_GetScaledUsageValue( 310 IN HIDP_REPORT_TYPE ReportType, 311 IN USAGE UsagePage, 312 IN USHORT LinkCollection OPTIONAL, 313 IN USAGE Usage, 314 OUT PLONG UsageValue, 315 IN PHIDP_PREPARSED_DATA PreparsedData, 316 IN PCHAR Report, 317 IN ULONG ReportLength) 318 { 319 HID_PARSER Parser; 320 321 // 322 // sanity check 323 // 324 ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); 325 326 // 327 // init parser 328 // 329 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 330 331 // 332 // get scaled usage value 333 // 334 return HidParser_GetScaledUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength); 335 } 336 337 HIDAPI 338 NTSTATUS 339 NTAPI 340 HidP_GetUsageValue( 341 IN HIDP_REPORT_TYPE ReportType, 342 IN USAGE UsagePage, 343 IN USHORT LinkCollection, 344 IN USAGE Usage, 345 OUT PULONG UsageValue, 346 IN PHIDP_PREPARSED_DATA PreparsedData, 347 IN PCHAR Report, 348 IN ULONG ReportLength) 349 { 350 HID_PARSER Parser; 351 352 // 353 // sanity check 354 // 355 ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature); 356 357 // 358 // init parser 359 // 360 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 361 362 // 363 // get scaled usage value 364 // 365 return HidParser_GetUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength); 366 } 367 368 369 HIDAPI 370 NTSTATUS 371 NTAPI 372 HidP_TranslateUsageAndPagesToI8042ScanCodes( 373 IN PUSAGE_AND_PAGE ChangedUsageList, 374 IN ULONG UsageListLength, 375 IN HIDP_KEYBOARD_DIRECTION KeyAction, 376 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState, 377 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure, 378 IN PVOID InsertCodesContext) 379 { 380 HID_PARSER Parser; 381 382 // 383 // init parser 384 // 385 HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser); 386 387 // 388 // translate usage pages 389 // 390 return HidParser_TranslateUsageAndPagesToI8042ScanCodes(&Parser, ChangedUsageList, UsageListLength, KeyAction, ModifierState, InsertCodesProcedure, InsertCodesContext); 391 } 392 393 HIDAPI 394 NTSTATUS 395 NTAPI 396 HidP_GetButtonCaps( 397 HIDP_REPORT_TYPE ReportType, 398 PHIDP_BUTTON_CAPS ButtonCaps, 399 PUSHORT ButtonCapsLength, 400 PHIDP_PREPARSED_DATA PreparsedData) 401 { 402 return HidP_GetSpecificButtonCaps(ReportType, HID_USAGE_PAGE_UNDEFINED, 0, 0, ButtonCaps, ButtonCapsLength, PreparsedData); 403 } 404 405 HIDAPI 406 NTSTATUS 407 NTAPI 408 HidP_GetSpecificButtonCaps( 409 IN HIDP_REPORT_TYPE ReportType, 410 IN USAGE UsagePage, 411 IN USHORT LinkCollection, 412 IN USAGE Usage, 413 OUT PHIDP_BUTTON_CAPS ButtonCaps, 414 IN OUT PUSHORT ButtonCapsLength, 415 IN PHIDP_PREPARSED_DATA PreparsedData) 416 { 417 UNIMPLEMENTED; 418 ASSERT(FALSE); 419 return STATUS_NOT_IMPLEMENTED; 420 } 421 422 HIDAPI 423 NTSTATUS 424 NTAPI 425 HidP_GetData( 426 IN HIDP_REPORT_TYPE ReportType, 427 OUT PHIDP_DATA DataList, 428 IN OUT PULONG DataLength, 429 IN PHIDP_PREPARSED_DATA PreparsedData, 430 IN PCHAR Report, 431 IN ULONG ReportLength) 432 { 433 UNIMPLEMENTED; 434 ASSERT(FALSE); 435 return STATUS_NOT_IMPLEMENTED; 436 } 437 438 HIDAPI 439 NTSTATUS 440 NTAPI 441 HidP_GetExtendedAttributes( 442 IN HIDP_REPORT_TYPE ReportType, 443 IN USHORT DataIndex, 444 IN PHIDP_PREPARSED_DATA PreparsedData, 445 OUT PHIDP_EXTENDED_ATTRIBUTES Attributes, 446 IN OUT PULONG LengthAttributes) 447 { 448 UNIMPLEMENTED; 449 ASSERT(FALSE); 450 return STATUS_NOT_IMPLEMENTED; 451 } 452 453 HIDAPI 454 NTSTATUS 455 NTAPI 456 HidP_GetLinkCollectionNodes( 457 OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes, 458 IN OUT PULONG LinkCollectionNodesLength, 459 IN PHIDP_PREPARSED_DATA PreparsedData) 460 { 461 UNIMPLEMENTED; 462 ASSERT(FALSE); 463 return STATUS_NOT_IMPLEMENTED; 464 } 465 466 NTSTATUS 467 NTAPI 468 HidP_SysPowerEvent( 469 IN PCHAR HidPacket, 470 IN USHORT HidPacketLength, 471 IN PHIDP_PREPARSED_DATA Ppd, 472 OUT PULONG OutputBuffer) 473 { 474 UNIMPLEMENTED; 475 ASSERT(FALSE); 476 return STATUS_NOT_IMPLEMENTED; 477 } 478 479 NTSTATUS 480 NTAPI 481 HidP_SysPowerCaps( 482 IN PHIDP_PREPARSED_DATA Ppd, 483 OUT PULONG OutputBuffer) 484 { 485 UNIMPLEMENTED; 486 ASSERT(FALSE); 487 return STATUS_NOT_IMPLEMENTED; 488 } 489 490 HIDAPI 491 NTSTATUS 492 NTAPI 493 HidP_GetUsageValueArray( 494 IN HIDP_REPORT_TYPE ReportType, 495 IN USAGE UsagePage, 496 IN USHORT LinkCollection OPTIONAL, 497 IN USAGE Usage, 498 OUT PCHAR UsageValue, 499 IN USHORT UsageValueByteLength, 500 IN PHIDP_PREPARSED_DATA PreparsedData, 501 IN PCHAR Report, 502 IN ULONG ReportLength) 503 { 504 UNIMPLEMENTED; 505 ASSERT(FALSE); 506 return STATUS_NOT_IMPLEMENTED; 507 } 508 509 510 HIDAPI 511 NTSTATUS 512 NTAPI 513 HidP_UnsetUsages( 514 IN HIDP_REPORT_TYPE ReportType, 515 IN USAGE UsagePage, 516 IN USHORT LinkCollection, 517 IN PUSAGE UsageList, 518 IN OUT PULONG UsageLength, 519 IN PHIDP_PREPARSED_DATA PreparsedData, 520 IN OUT PCHAR Report, 521 IN ULONG ReportLength) 522 { 523 UNIMPLEMENTED; 524 ASSERT(FALSE); 525 return STATUS_NOT_IMPLEMENTED; 526 } 527 528 HIDAPI 529 NTSTATUS 530 NTAPI 531 HidP_TranslateUsagesToI8042ScanCodes( 532 IN PUSAGE ChangedUsageList, 533 IN ULONG UsageListLength, 534 IN HIDP_KEYBOARD_DIRECTION KeyAction, 535 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState, 536 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure, 537 IN PVOID InsertCodesContext) 538 { 539 UNIMPLEMENTED; 540 ASSERT(FALSE); 541 return STATUS_NOT_IMPLEMENTED; 542 } 543 544 HIDAPI 545 NTSTATUS 546 NTAPI 547 HidP_SetUsages( 548 IN HIDP_REPORT_TYPE ReportType, 549 IN USAGE UsagePage, 550 IN USHORT LinkCollection, 551 IN PUSAGE UsageList, 552 IN OUT PULONG UsageLength, 553 IN PHIDP_PREPARSED_DATA PreparsedData, 554 IN OUT PCHAR Report, 555 IN ULONG ReportLength) 556 { 557 UNIMPLEMENTED; 558 ASSERT(FALSE); 559 return STATUS_NOT_IMPLEMENTED; 560 } 561 562 HIDAPI 563 NTSTATUS 564 NTAPI 565 HidP_SetUsageValueArray( 566 IN HIDP_REPORT_TYPE ReportType, 567 IN USAGE UsagePage, 568 IN USHORT LinkCollection OPTIONAL, 569 IN USAGE Usage, 570 IN PCHAR UsageValue, 571 IN USHORT UsageValueByteLength, 572 IN PHIDP_PREPARSED_DATA PreparsedData, 573 OUT PCHAR Report, 574 IN ULONG ReportLength) 575 { 576 UNIMPLEMENTED; 577 ASSERT(FALSE); 578 return STATUS_NOT_IMPLEMENTED; 579 } 580 581 HIDAPI 582 NTSTATUS 583 NTAPI 584 HidP_SetUsageValue( 585 IN HIDP_REPORT_TYPE ReportType, 586 IN USAGE UsagePage, 587 IN USHORT LinkCollection, 588 IN USAGE Usage, 589 IN ULONG UsageValue, 590 IN PHIDP_PREPARSED_DATA PreparsedData, 591 IN OUT PCHAR Report, 592 IN ULONG ReportLength) 593 { 594 UNIMPLEMENTED; 595 ASSERT(FALSE); 596 return STATUS_NOT_IMPLEMENTED; 597 } 598 599 HIDAPI 600 NTSTATUS 601 NTAPI 602 HidP_SetScaledUsageValue( 603 IN HIDP_REPORT_TYPE ReportType, 604 IN USAGE UsagePage, 605 IN USHORT LinkCollection OPTIONAL, 606 IN USAGE Usage, 607 IN LONG UsageValue, 608 IN PHIDP_PREPARSED_DATA PreparsedData, 609 IN OUT PCHAR Report, 610 IN ULONG ReportLength) 611 { 612 UNIMPLEMENTED; 613 ASSERT(FALSE); 614 return STATUS_NOT_IMPLEMENTED; 615 } 616 617 HIDAPI 618 NTSTATUS 619 NTAPI 620 HidP_SetData( 621 IN HIDP_REPORT_TYPE ReportType, 622 IN PHIDP_DATA DataList, 623 IN OUT PULONG DataLength, 624 IN PHIDP_PREPARSED_DATA PreparsedData, 625 IN OUT PCHAR Report, 626 IN ULONG ReportLength) 627 { 628 UNIMPLEMENTED; 629 ASSERT(FALSE); 630 return STATUS_NOT_IMPLEMENTED; 631 } 632 633 HIDAPI 634 ULONG 635 NTAPI 636 HidP_MaxDataListLength( 637 IN HIDP_REPORT_TYPE ReportType, 638 IN PHIDP_PREPARSED_DATA PreparsedData) 639 { 640 UNIMPLEMENTED; 641 ASSERT(FALSE); 642 return STATUS_NOT_IMPLEMENTED; 643 } 644 645 HIDAPI 646 NTSTATUS 647 NTAPI 648 HidP_InitializeReportForID( 649 IN HIDP_REPORT_TYPE ReportType, 650 IN UCHAR ReportID, 651 IN PHIDP_PREPARSED_DATA PreparsedData, 652 IN OUT PCHAR Report, 653 IN ULONG ReportLength) 654 { 655 UNIMPLEMENTED; 656 ASSERT(FALSE); 657 return STATUS_NOT_IMPLEMENTED; 658 } 659 660 #undef HidP_GetValueCaps 661 662 HIDAPI 663 NTSTATUS 664 NTAPI 665 HidP_GetValueCaps( 666 HIDP_REPORT_TYPE ReportType, 667 PHIDP_VALUE_CAPS ValueCaps, 668 PUSHORT ValueCapsLength, 669 PHIDP_PREPARSED_DATA PreparsedData) 670 { 671 UNIMPLEMENTED; 672 ASSERT(FALSE); 673 return STATUS_NOT_IMPLEMENTED; 674 } 675 676 NTSTATUS 677 NTAPI 678 DriverEntry( 679 IN PDRIVER_OBJECT DriverObject, 680 IN PUNICODE_STRING RegPath) 681 { 682 DPRINT("********* HID PARSE *********\n"); 683 return STATUS_SUCCESS; 684 } 685