1 /* 2 * PROJECT: ReactOS Universal Serial Bus Human Interface Device Driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/usb/hidusb/hidusb.c 5 * PURPOSE: HID USB Interface Driver 6 * PROGRAMMERS: 7 * Michael Martin (michael.martin@reactos.org) 8 * Johannes Anderwald (johannes.anderwald@reactos.org) 9 */ 10 11 #include "hidusb.h" 12 13 PUSBD_PIPE_INFORMATION 14 HidUsb_GetInputInterruptInterfaceHandle( 15 PUSBD_INTERFACE_INFORMATION InterfaceInformation) 16 { 17 ULONG Index; 18 19 // 20 // sanity check 21 // 22 ASSERT(InterfaceInformation->NumberOfPipes); 23 24 for (Index = 0; Index < InterfaceInformation->NumberOfPipes; Index++) 25 { 26 //DPRINT1("[HIDUSB] EndpointAddress %x PipeType %x PipeHandle %x\n", InterfaceInformation->Pipes[Index].EndpointAddress, InterfaceInformation->Pipes[Index].PipeType, InterfaceInformation->Pipes[Index].PipeHandle); 27 if (InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeInterrupt && (InterfaceInformation->Pipes[Index].EndpointAddress & USB_ENDPOINT_DIRECTION_MASK)) 28 { 29 // 30 // found handle 31 // 32 return &InterfaceInformation->Pipes[Index]; 33 } 34 } 35 36 // 37 // not found 38 // 39 return NULL; 40 } 41 42 NTSTATUS 43 HidUsb_GetPortStatus( 44 IN PDEVICE_OBJECT DeviceObject, 45 IN PULONG PortStatus) 46 { 47 PIRP Irp; 48 KEVENT Event; 49 IO_STATUS_BLOCK IoStatus; 50 PHID_DEVICE_EXTENSION DeviceExtension; 51 PIO_STACK_LOCATION IoStack; 52 NTSTATUS Status; 53 54 // 55 // get device extension 56 // 57 DeviceExtension = DeviceObject->DeviceExtension; 58 59 // 60 // init result 61 // 62 *PortStatus = 0; 63 64 // 65 // init event 66 // 67 KeInitializeEvent(&Event, NotificationEvent, FALSE); 68 69 // 70 // build irp 71 // 72 Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS, 73 DeviceExtension->NextDeviceObject, 74 NULL, 75 0, 76 NULL, 77 0, 78 TRUE, 79 &Event, 80 &IoStatus); 81 if (!Irp) 82 { 83 // 84 // no memory 85 // 86 return STATUS_INSUFFICIENT_RESOURCES; 87 } 88 89 // 90 // get stack location 91 // 92 IoStack = IoGetNextIrpStackLocation(Irp); 93 94 // 95 // store result buffer 96 // 97 IoStack->Parameters.Others.Argument1 = PortStatus; 98 99 // 100 // call driver 101 // 102 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 103 if (Status == STATUS_PENDING) 104 { 105 // 106 // wait for completion 107 // 108 KeWaitForSingleObject(&Event, Executive, KernelMode, 0, NULL); 109 return IoStatus.Status; 110 } 111 112 // 113 // done 114 // 115 return Status; 116 } 117 118 NTSTATUS 119 HidUsb_ResetInterruptPipe( 120 IN PDEVICE_OBJECT DeviceObject) 121 { 122 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 123 PHID_DEVICE_EXTENSION DeviceExtension; 124 PUSBD_PIPE_INFORMATION PipeInformation; 125 PURB Urb; 126 NTSTATUS Status; 127 128 // 129 // get device extension 130 // 131 DeviceExtension = DeviceObject->DeviceExtension; 132 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 133 134 // 135 // get interrupt pipe handle 136 // 137 ASSERT(HidDeviceExtension->InterfaceInfo); 138 PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo); 139 ASSERT(PipeInformation); 140 ASSERT(PipeInformation->PipeHandle); 141 142 // 143 // allocate urb 144 // 145 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST), HIDUSB_URB_TAG); 146 if (!Urb) 147 { 148 // 149 // no memory 150 // 151 return STATUS_INSUFFICIENT_RESOURCES; 152 } 153 154 // 155 // init urb 156 // 157 RtlZeroMemory(Urb, sizeof(struct _URB_PIPE_REQUEST)); 158 Urb->UrbHeader.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL; 159 Urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST); 160 Urb->UrbPipeRequest.PipeHandle = PipeInformation->PipeHandle; 161 162 // 163 // dispatch request 164 // 165 Status = Hid_DispatchUrb(DeviceObject, Urb); 166 167 // 168 // free urb 169 // 170 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 171 172 // 173 // done 174 // 175 return Status; 176 } 177 178 NTSTATUS 179 HidUsb_AbortPipe( 180 IN PDEVICE_OBJECT DeviceObject) 181 { 182 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 183 PHID_DEVICE_EXTENSION DeviceExtension; 184 PURB Urb; 185 NTSTATUS Status; 186 PUSBD_PIPE_INFORMATION PipeInformation; 187 188 // 189 // get device extension 190 // 191 DeviceExtension = DeviceObject->DeviceExtension; 192 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 193 194 // 195 // allocate urb 196 // 197 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST), HIDUSB_URB_TAG); 198 if (!Urb) 199 { 200 // 201 // no memory 202 // 203 return STATUS_INSUFFICIENT_RESOURCES; 204 } 205 206 // 207 // get pipe information 208 // 209 PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo); 210 ASSERT(PipeInformation); 211 ASSERT(PipeInformation->PipeHandle); 212 213 // 214 // init urb 215 // 216 RtlZeroMemory(Urb, sizeof(struct _URB_PIPE_REQUEST)); 217 Urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE; 218 Urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST); 219 Urb->UrbPipeRequest.PipeHandle = PipeInformation->PipeHandle; 220 221 // 222 // dispatch request 223 // 224 Status = Hid_DispatchUrb(DeviceObject, Urb); 225 226 // 227 // free urb 228 // 229 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 230 231 // 232 // done 233 // 234 return Status; 235 } 236 237 NTSTATUS 238 HidUsb_ResetPort( 239 IN PDEVICE_OBJECT DeviceObject) 240 { 241 KEVENT Event; 242 PIRP Irp; 243 PHID_DEVICE_EXTENSION DeviceExtension; 244 IO_STATUS_BLOCK IoStatusBlock; 245 NTSTATUS Status; 246 247 // 248 // get device extension 249 // 250 DeviceExtension = DeviceObject->DeviceExtension; 251 252 // 253 // init event 254 // 255 KeInitializeEvent(&Event, NotificationEvent, FALSE); 256 257 // 258 // build irp 259 // 260 Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT, 261 DeviceExtension->NextDeviceObject, 262 NULL, 263 0, 264 NULL, 265 0, 266 TRUE, 267 &Event, 268 &IoStatusBlock); 269 if (!Irp) 270 { 271 // 272 // no memory 273 // 274 return STATUS_INSUFFICIENT_RESOURCES; 275 } 276 277 // 278 // send the irp 279 // 280 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 281 if (Status == STATUS_PENDING) 282 { 283 // 284 // wait for request completion 285 // 286 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 287 Status = IoStatusBlock.Status; 288 } 289 290 // 291 // done 292 // 293 return IoStatusBlock.Status; 294 } 295 296 NTSTATUS 297 NTAPI 298 HidCreate( 299 IN PDEVICE_OBJECT DeviceObject, 300 IN PIRP Irp) 301 { 302 PIO_STACK_LOCATION IoStack; 303 304 // 305 // get current irp stack location 306 // 307 IoStack = IoGetCurrentIrpStackLocation(Irp); 308 309 // 310 // sanity check for hidclass driver 311 // 312 ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_CLOSE); 313 314 // 315 // informational debug print 316 // 317 DPRINT("HIDUSB Request: %x\n", IoStack->MajorFunction); 318 319 // 320 // complete request 321 // 322 Irp->IoStatus.Information = 0; 323 Irp->IoStatus.Status = STATUS_SUCCESS; 324 IoCompleteRequest(Irp, IO_NO_INCREMENT); 325 326 // 327 // done 328 // 329 return STATUS_SUCCESS; 330 } 331 332 VOID 333 NTAPI 334 HidUsb_ResetWorkerRoutine( 335 IN PDEVICE_OBJECT DeviceObject, 336 IN PVOID Ctx) 337 { 338 NTSTATUS Status; 339 ULONG PortStatus; 340 PHID_USB_RESET_CONTEXT ResetContext; 341 PHID_DEVICE_EXTENSION DeviceExtension; 342 343 DPRINT("[HIDUSB] ResetWorkerRoutine\n"); 344 345 // 346 // get context 347 // 348 ResetContext = Ctx; 349 350 // 351 // get device extension 352 // 353 DeviceExtension = ResetContext->DeviceObject->DeviceExtension; 354 355 // 356 // get port status 357 // 358 Status = HidUsb_GetPortStatus(ResetContext->DeviceObject, &PortStatus); 359 DPRINT("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status, PortStatus); 360 if (NT_SUCCESS(Status)) 361 { 362 if (!(PortStatus & USB_PORT_STATUS_ENABLE)) 363 { 364 // 365 // port is disabled 366 // 367 Status = HidUsb_ResetInterruptPipe(ResetContext->DeviceObject); 368 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status); 369 } 370 else 371 { 372 // 373 // abort pipe 374 // 375 Status = HidUsb_AbortPipe(ResetContext->DeviceObject); 376 DPRINT1("[HIDUSB] ResetWorkerRoutine AbortPipe %x\n", Status); 377 if (NT_SUCCESS(Status)) 378 { 379 // 380 // reset port 381 // 382 Status = HidUsb_ResetPort(ResetContext->DeviceObject); 383 DPRINT1("[HIDUSB] ResetPort %x\n", Status); 384 if (Status == STATUS_DEVICE_DATA_ERROR) 385 { 386 // 387 // invalidate device state 388 // 389 IoInvalidateDeviceState(DeviceExtension->PhysicalDeviceObject); 390 } 391 392 // 393 // reset interrupt pipe 394 // 395 if (NT_SUCCESS(Status)) 396 { 397 // 398 // reset pipe 399 // 400 Status = HidUsb_ResetInterruptPipe(ResetContext->DeviceObject); 401 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status); 402 } 403 } 404 } 405 } 406 407 // 408 // cleanup 409 // 410 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 411 IoFreeWorkItem(ResetContext->WorkItem); 412 IoCompleteRequest(ResetContext->Irp, IO_NO_INCREMENT); 413 ExFreePoolWithTag(ResetContext, HIDUSB_TAG); 414 } 415 416 417 NTSTATUS 418 NTAPI 419 HidUsb_ReadReportCompletion( 420 IN PDEVICE_OBJECT DeviceObject, 421 IN PIRP Irp, 422 IN PVOID Context) 423 { 424 PURB Urb; 425 PHID_USB_RESET_CONTEXT ResetContext; 426 427 // 428 // get urb 429 // 430 Urb = Context; 431 ASSERT(Urb); 432 433 DPRINT("[HIDUSB] HidUsb_ReadReportCompletion %p Status %x Urb Status %x\n", Irp, Irp->IoStatus, Urb->UrbHeader.Status); 434 435 if (Irp->PendingReturned) 436 { 437 // 438 // mark irp pending 439 // 440 IoMarkIrpPending(Irp); 441 } 442 443 // 444 // did the reading report succeed / cancelled 445 // 446 if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->IoStatus.Status == STATUS_CANCELLED || Irp->IoStatus.Status == STATUS_DEVICE_NOT_CONNECTED) 447 { 448 // 449 // store result length 450 // 451 Irp->IoStatus.Information = Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; 452 453 // 454 // FIXME handle error 455 // 456 ASSERT(Urb->UrbHeader.Status == USBD_STATUS_SUCCESS || Urb->UrbHeader.Status == USBD_STATUS_DEVICE_GONE); 457 458 // 459 // free the urb 460 // 461 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 462 463 // 464 // finish completion 465 // 466 return STATUS_CONTINUE_COMPLETION; 467 } 468 469 // 470 // allocate reset context 471 // 472 ResetContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(HID_USB_RESET_CONTEXT), HIDUSB_TAG); 473 if (ResetContext) 474 { 475 // 476 // allocate work item 477 // 478 ResetContext->WorkItem = IoAllocateWorkItem(DeviceObject); 479 if (ResetContext->WorkItem) 480 { 481 // 482 // init reset context 483 // 484 ResetContext->Irp = Irp; 485 ResetContext->DeviceObject = DeviceObject; 486 487 // 488 // queue the work item 489 // 490 IoQueueWorkItem(ResetContext->WorkItem, HidUsb_ResetWorkerRoutine, DelayedWorkQueue, ResetContext); 491 492 // 493 // free urb 494 // 495 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 496 497 // 498 // defer completion 499 // 500 return STATUS_MORE_PROCESSING_REQUIRED; 501 } 502 // 503 // free context 504 // 505 ExFreePoolWithTag(ResetContext, HIDUSB_TAG); 506 } 507 508 // 509 // free urb 510 // 511 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 512 513 // 514 // complete request 515 // 516 return STATUS_CONTINUE_COMPLETION; 517 } 518 519 520 NTSTATUS 521 NTAPI 522 HidUsb_ReadReport( 523 IN PDEVICE_OBJECT DeviceObject, 524 IN PIRP Irp) 525 { 526 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 527 PHID_DEVICE_EXTENSION DeviceExtension; 528 PIO_STACK_LOCATION IoStack; 529 PURB Urb; 530 PUSBD_PIPE_INFORMATION PipeInformation; 531 532 // 533 // get device extension 534 // 535 DeviceExtension = DeviceObject->DeviceExtension; 536 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 537 538 // 539 // get current stack location 540 // 541 IoStack = IoGetCurrentIrpStackLocation(Irp); 542 543 // 544 // sanity checks 545 // 546 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength); 547 ASSERT(Irp->UserBuffer); 548 ASSERT(HidDeviceExtension->InterfaceInfo); 549 550 // 551 // get interrupt input pipe 552 // 553 PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo); 554 ASSERT(PipeInformation); 555 556 // 557 // lets allocate urb 558 // 559 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), HIDUSB_URB_TAG); 560 if (!Urb) 561 { 562 // 563 // no memory 564 // 565 return STATUS_INSUFFICIENT_RESOURCES; 566 } 567 568 // 569 // init urb 570 // 571 RtlZeroMemory(Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); 572 573 // 574 // sanity check 575 // 576 ASSERT(Irp->UserBuffer); 577 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength); 578 ASSERT(PipeInformation->PipeHandle); 579 580 // 581 // build the urb 582 // 583 UsbBuildInterruptOrBulkTransferRequest(Urb, 584 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), 585 PipeInformation->PipeHandle, 586 Irp->UserBuffer, 587 NULL, 588 IoStack->Parameters.DeviceIoControl.OutputBufferLength, 589 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, 590 NULL); 591 592 // 593 // store configuration handle 594 // 595 Urb->UrbHeader.UsbdDeviceHandle = HidDeviceExtension->ConfigurationHandle; 596 597 // 598 // get next location to setup irp 599 // 600 IoStack = IoGetNextIrpStackLocation(Irp); 601 602 // 603 // init irp for lower driver 604 // 605 IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; 606 IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; 607 IoStack->Parameters.DeviceIoControl.InputBufferLength = 0; 608 IoStack->Parameters.DeviceIoControl.OutputBufferLength = 0; 609 IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL; 610 IoStack->Parameters.Others.Argument1 = Urb; 611 612 613 // 614 // set completion routine 615 // 616 IoSetCompletionRoutine(Irp, HidUsb_ReadReportCompletion, Urb, TRUE, TRUE, TRUE); 617 618 // 619 // call driver 620 // 621 return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 622 } 623 624 625 NTSTATUS 626 NTAPI 627 HidUsb_GetReportDescriptor( 628 IN PDEVICE_OBJECT DeviceObject, 629 IN PIRP Irp) 630 { 631 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 632 PHID_DEVICE_EXTENSION DeviceExtension; 633 PVOID Report = NULL; 634 ULONG BufferLength, Length; 635 PIO_STACK_LOCATION IoStack; 636 NTSTATUS Status; 637 638 // 639 // get device extension 640 // 641 DeviceExtension = DeviceObject->DeviceExtension; 642 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 643 644 // 645 // sanity checks 646 // 647 ASSERT(HidDeviceExtension); 648 ASSERT(HidDeviceExtension->HidDescriptor); 649 ASSERT(HidDeviceExtension->HidDescriptor->bNumDescriptors >= 1); 650 ASSERT(HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType == HID_REPORT_DESCRIPTOR_TYPE); 651 ASSERT(HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength > 0); 652 653 // 654 // FIXME: support old hid version 655 // 656 BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength; 657 Status = Hid_GetDescriptor(DeviceObject, 658 URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE, 659 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 660 &Report, 661 &BufferLength, 662 HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType, 663 0, 664 HidDeviceExtension->InterfaceInfo->InterfaceNumber); 665 if (!NT_SUCCESS(Status)) 666 { 667 // 668 // failed to get descriptor 669 // try with old hid version 670 // 671 BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength; 672 Status = Hid_GetDescriptor(DeviceObject, 673 URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT, 674 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 675 &Report, 676 &BufferLength, 677 HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType, 678 0, 679 0 /* FIXME*/); 680 if (!NT_SUCCESS(Status)) 681 { 682 DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status); 683 return Status; 684 } 685 } 686 687 // 688 // get current stack location 689 // 690 IoStack = IoGetCurrentIrpStackLocation(Irp); 691 DPRINT("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status, HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength); 692 693 // 694 // get length to copy 695 // 696 Length = min(IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength); 697 ASSERT(Length); 698 699 // 700 // copy result 701 // 702 RtlCopyMemory(Irp->UserBuffer, Report, Length); 703 704 // 705 // store result length 706 // 707 Irp->IoStatus.Information = Length; 708 709 // 710 // free the report buffer 711 // 712 ExFreePoolWithTag(Report, HIDUSB_TAG); 713 714 // 715 // done 716 // 717 return Status; 718 719 } 720 721 NTSTATUS 722 NTAPI 723 HidInternalDeviceControl( 724 IN PDEVICE_OBJECT DeviceObject, 725 IN PIRP Irp) 726 { 727 PIO_STACK_LOCATION IoStack; 728 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 729 PHID_DEVICE_EXTENSION DeviceExtension; 730 PHID_DEVICE_ATTRIBUTES Attributes; 731 ULONG Length; 732 NTSTATUS Status; 733 734 // 735 // get device extension 736 // 737 DeviceExtension = DeviceObject->DeviceExtension; 738 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 739 740 // 741 // get current stack location 742 // 743 IoStack = IoGetCurrentIrpStackLocation(Irp); 744 745 switch (IoStack->Parameters.DeviceIoControl.IoControlCode) 746 { 747 case IOCTL_HID_GET_DEVICE_ATTRIBUTES: 748 { 749 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_DEVICE_ATTRIBUTES)) 750 { 751 // 752 // invalid request 753 // 754 Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE; 755 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES invalid buffer\n"); 756 IoCompleteRequest(Irp, IO_NO_INCREMENT); 757 return STATUS_INVALID_BUFFER_SIZE; 758 } 759 // 760 // store result 761 // 762 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n"); 763 ASSERT(HidDeviceExtension->DeviceDescriptor); 764 Irp->IoStatus.Information = sizeof(HID_DESCRIPTOR); 765 Attributes = Irp->UserBuffer; 766 Attributes->Size = sizeof(HID_DEVICE_ATTRIBUTES); 767 Attributes->VendorID = HidDeviceExtension->DeviceDescriptor->idVendor; 768 Attributes->ProductID = HidDeviceExtension->DeviceDescriptor->idProduct; 769 Attributes->VersionNumber = HidDeviceExtension->DeviceDescriptor->bcdDevice; 770 771 // 772 // complete request 773 // 774 Irp->IoStatus.Status = STATUS_SUCCESS; 775 IoCompleteRequest(Irp, IO_NO_INCREMENT); 776 return STATUS_SUCCESS; 777 } 778 case IOCTL_HID_GET_DEVICE_DESCRIPTOR: 779 { 780 // 781 // sanity check 782 // 783 ASSERT(HidDeviceExtension->HidDescriptor); 784 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength); 785 786 // 787 // store length 788 // 789 Length = min(HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength); 790 791 // 792 // copy descriptor 793 // 794 RtlCopyMemory(Irp->UserBuffer, HidDeviceExtension->HidDescriptor, Length); 795 796 // 797 // store result length 798 // 799 Irp->IoStatus.Information = HidDeviceExtension->HidDescriptor->bLength; 800 Irp->IoStatus.Status = STATUS_SUCCESS; 801 802 /* complete request */ 803 IoCompleteRequest(Irp, IO_NO_INCREMENT); 804 return STATUS_SUCCESS; 805 } 806 case IOCTL_HID_GET_REPORT_DESCRIPTOR: 807 { 808 Status = HidUsb_GetReportDescriptor(DeviceObject, Irp); 809 DPRINT("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status); 810 Irp->IoStatus.Status = Status; 811 IoCompleteRequest(Irp, IO_NO_INCREMENT); 812 return Status; 813 } 814 case IOCTL_HID_READ_REPORT: 815 { 816 DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n"); 817 Status = HidUsb_ReadReport(DeviceObject, Irp); 818 return Status; 819 } 820 case IOCTL_HID_WRITE_REPORT: 821 { 822 DPRINT1("[HIDUSB] IOCTL_HID_WRITE_REPORT not implemented \n"); 823 ASSERT(FALSE); 824 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 825 IoCompleteRequest(Irp, IO_NO_INCREMENT); 826 return STATUS_NOT_IMPLEMENTED; 827 } 828 case IOCTL_GET_PHYSICAL_DESCRIPTOR: 829 { 830 DPRINT1("[HIDUSB] IOCTL_GET_PHYSICAL_DESCRIPTOR not implemented \n"); 831 ASSERT(FALSE); 832 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 833 IoCompleteRequest(Irp, IO_NO_INCREMENT); 834 return STATUS_NOT_IMPLEMENTED; 835 } 836 case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST: 837 { 838 DPRINT1("[HIDUSB] IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST not implemented \n"); 839 ASSERT(FALSE); 840 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 841 IoCompleteRequest(Irp, IO_NO_INCREMENT); 842 return STATUS_NOT_IMPLEMENTED; 843 } 844 case IOCTL_HID_GET_FEATURE: 845 { 846 DPRINT1("[HIDUSB] IOCTL_HID_GET_FEATURE not implemented \n"); 847 ASSERT(FALSE); 848 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 849 IoCompleteRequest(Irp, IO_NO_INCREMENT); 850 return STATUS_NOT_IMPLEMENTED; 851 } 852 case IOCTL_HID_SET_FEATURE: 853 { 854 DPRINT1("[HIDUSB] IOCTL_HID_SET_FEATURE not implemented \n"); 855 ASSERT(FALSE); 856 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 857 IoCompleteRequest(Irp, IO_NO_INCREMENT); 858 return STATUS_NOT_IMPLEMENTED; 859 } 860 case IOCTL_HID_SET_OUTPUT_REPORT: 861 { 862 DPRINT1("[HIDUSB] IOCTL_HID_SET_OUTPUT_REPORT not implemented \n"); 863 ASSERT(FALSE); 864 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 865 IoCompleteRequest(Irp, IO_NO_INCREMENT); 866 return STATUS_NOT_IMPLEMENTED; 867 } 868 case IOCTL_HID_GET_INPUT_REPORT: 869 { 870 DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n"); 871 ASSERT(FALSE); 872 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 873 IoCompleteRequest(Irp, IO_NO_INCREMENT); 874 return STATUS_NOT_IMPLEMENTED; 875 } 876 case IOCTL_HID_GET_INDEXED_STRING: 877 { 878 DPRINT1("[HIDUSB] IOCTL_HID_GET_INDEXED_STRING not implemented \n"); 879 ASSERT(FALSE); 880 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 881 IoCompleteRequest(Irp, IO_NO_INCREMENT); 882 return STATUS_NOT_IMPLEMENTED; 883 } 884 case IOCTL_HID_GET_MS_GENRE_DESCRIPTOR: 885 { 886 DPRINT1("[HIDUSB] IOCTL_HID_GET_MS_GENRE_DESCRIPTOR not implemented \n"); 887 ASSERT(FALSE); 888 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 889 IoCompleteRequest(Irp, IO_NO_INCREMENT); 890 return STATUS_NOT_IMPLEMENTED; 891 } 892 default: 893 { 894 UNIMPLEMENTED; 895 ASSERT(FALSE); 896 Status = Irp->IoStatus.Status; 897 IoCompleteRequest(Irp, IO_NO_INCREMENT); 898 return Status; 899 } 900 } 901 } 902 903 NTSTATUS 904 NTAPI 905 HidPower( 906 IN PDEVICE_OBJECT DeviceObject, 907 IN PIRP Irp) 908 { 909 PHID_DEVICE_EXTENSION DeviceExtension; 910 911 DeviceExtension = DeviceObject->DeviceExtension; 912 PoStartNextPowerIrp(Irp); 913 IoSkipCurrentIrpStackLocation(Irp); 914 return PoCallDriver(DeviceExtension->NextDeviceObject, Irp); 915 } 916 917 NTSTATUS 918 NTAPI 919 HidSystemControl( 920 IN PDEVICE_OBJECT DeviceObject, 921 IN PIRP Irp) 922 { 923 PHID_DEVICE_EXTENSION DeviceExtension; 924 925 // 926 // get hid device extension 927 // 928 DeviceExtension = DeviceObject->DeviceExtension; 929 930 // 931 // skip stack location 932 // 933 IoSkipCurrentIrpStackLocation(Irp); 934 935 // 936 // submit request 937 // 938 return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 939 } 940 941 NTSTATUS 942 NTAPI 943 Hid_PnpCompletion( 944 IN PDEVICE_OBJECT DeviceObject, 945 IN PIRP Irp, 946 IN PVOID Context) 947 { 948 // 949 // signal event 950 // 951 KeSetEvent(Context, 0, FALSE); 952 953 // 954 // done 955 // 956 return STATUS_MORE_PROCESSING_REQUIRED; 957 } 958 959 NTSTATUS 960 Hid_DispatchUrb( 961 IN PDEVICE_OBJECT DeviceObject, 962 IN PURB Urb) 963 { 964 PIRP Irp; 965 KEVENT Event; 966 PHID_DEVICE_EXTENSION DeviceExtension; 967 IO_STATUS_BLOCK IoStatus; 968 PIO_STACK_LOCATION IoStack; 969 NTSTATUS Status; 970 971 // 972 // init event 973 // 974 KeInitializeEvent(&Event, NotificationEvent, FALSE); 975 976 // 977 // get device extension 978 // 979 DeviceExtension = DeviceObject->DeviceExtension; 980 981 // 982 // build irp 983 // 984 Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, 985 DeviceExtension->NextDeviceObject, 986 NULL, 987 0, 988 NULL, 989 0, 990 TRUE, 991 &Event, 992 &IoStatus); 993 if (!Irp) 994 { 995 // 996 // no memory 997 // 998 return STATUS_INSUFFICIENT_RESOURCES; 999 } 1000 1001 // 1002 // get next stack location 1003 // 1004 IoStack = IoGetNextIrpStackLocation(Irp); 1005 1006 // 1007 // store urb 1008 // 1009 IoStack->Parameters.Others.Argument1 = Urb; 1010 1011 // 1012 // set completion routine 1013 // 1014 IoSetCompletionRoutine(Irp, Hid_PnpCompletion, &Event, TRUE, TRUE, TRUE); 1015 1016 // 1017 // call driver 1018 // 1019 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1020 1021 // 1022 // wait for the request to finish 1023 // 1024 if (Status == STATUS_PENDING) 1025 { 1026 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 1027 } 1028 1029 // 1030 // complete request 1031 // 1032 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1033 1034 if (Status == STATUS_PENDING) 1035 { 1036 // 1037 // get final status 1038 // 1039 Status = IoStatus.Status; 1040 } 1041 1042 DPRINT("[HIDUSB] DispatchUrb %x\n", Status); 1043 1044 1045 // 1046 // done 1047 // 1048 return Status; 1049 } 1050 1051 NTSTATUS 1052 Hid_GetDescriptor( 1053 IN PDEVICE_OBJECT DeviceObject, 1054 IN USHORT UrbFunction, 1055 IN USHORT UrbLength, 1056 IN OUT PVOID *UrbBuffer, 1057 IN OUT PULONG UrbBufferLength, 1058 IN UCHAR DescriptorType, 1059 IN UCHAR Index, 1060 IN USHORT LanguageIndex) 1061 { 1062 PURB Urb; 1063 NTSTATUS Status; 1064 UCHAR Allocated = FALSE; 1065 1066 // 1067 // allocate urb 1068 // 1069 Urb = ExAllocatePoolWithTag(NonPagedPool, UrbLength, HIDUSB_URB_TAG); 1070 if (!Urb) 1071 { 1072 // 1073 // no memory 1074 // 1075 return STATUS_INSUFFICIENT_RESOURCES; 1076 } 1077 1078 // 1079 // is there an urb buffer 1080 // 1081 if (!*UrbBuffer) 1082 { 1083 // 1084 // allocate buffer 1085 // 1086 *UrbBuffer = ExAllocatePoolWithTag(NonPagedPool, *UrbBufferLength, HIDUSB_TAG); 1087 if (!*UrbBuffer) 1088 { 1089 // 1090 // no memory 1091 // 1092 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1093 return STATUS_INSUFFICIENT_RESOURCES; 1094 } 1095 1096 // 1097 // zero buffer 1098 // 1099 RtlZeroMemory(*UrbBuffer, *UrbBufferLength); 1100 Allocated = TRUE; 1101 } 1102 1103 // 1104 // zero urb 1105 // 1106 RtlZeroMemory(Urb, UrbLength); 1107 1108 // 1109 // build descriptor request 1110 // 1111 UsbBuildGetDescriptorRequest(Urb, UrbLength, DescriptorType, Index, LanguageIndex, *UrbBuffer, NULL, *UrbBufferLength, NULL); 1112 1113 // 1114 // set urb function 1115 // 1116 Urb->UrbHeader.Function = UrbFunction; 1117 1118 // 1119 // dispatch urb 1120 // 1121 Status = Hid_DispatchUrb(DeviceObject, Urb); 1122 1123 // 1124 // did the request fail 1125 // 1126 if (!NT_SUCCESS(Status)) 1127 { 1128 if (Allocated) 1129 { 1130 // 1131 // free allocated buffer 1132 // 1133 ExFreePoolWithTag(*UrbBuffer, HIDUSB_TAG); 1134 *UrbBuffer = NULL; 1135 } 1136 1137 // 1138 // free urb 1139 // 1140 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1141 *UrbBufferLength = 0; 1142 return Status; 1143 } 1144 1145 // 1146 // did urb request fail 1147 // 1148 if (!NT_SUCCESS(Urb->UrbHeader.Status)) 1149 { 1150 if (Allocated) 1151 { 1152 // 1153 // free allocated buffer 1154 // 1155 ExFreePoolWithTag(*UrbBuffer, HIDUSB_TAG); 1156 *UrbBuffer = NULL; 1157 } 1158 1159 // 1160 // free urb 1161 // 1162 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1163 *UrbBufferLength = 0; 1164 return STATUS_UNSUCCESSFUL; 1165 } 1166 1167 // 1168 // store result length 1169 // 1170 *UrbBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; 1171 1172 // 1173 // free urb 1174 // 1175 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1176 1177 // 1178 // completed successfully 1179 // 1180 return STATUS_SUCCESS; 1181 } 1182 1183 NTSTATUS 1184 Hid_SelectConfiguration( 1185 IN PDEVICE_OBJECT DeviceObject) 1186 { 1187 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 1188 NTSTATUS Status; 1189 USBD_INTERFACE_LIST_ENTRY InterfaceList[2]; 1190 PURB Urb; 1191 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 1192 PHID_DEVICE_EXTENSION DeviceExtension; 1193 1194 // 1195 // get device extension 1196 // 1197 DeviceExtension = DeviceObject->DeviceExtension; 1198 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 1199 1200 // 1201 // now parse the descriptors 1202 // 1203 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor, 1204 HidDeviceExtension->ConfigurationDescriptor, 1205 -1, 1206 -1, 1207 USB_DEVICE_CLASS_HUMAN_INTERFACE, 1208 -1, 1209 -1); 1210 if (!InterfaceDescriptor) 1211 { 1212 // 1213 // bogus configuration descriptor 1214 // 1215 return STATUS_INVALID_PARAMETER; 1216 } 1217 1218 // 1219 // sanity check 1220 // 1221 ASSERT(InterfaceDescriptor); 1222 ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE); 1223 ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); 1224 ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); 1225 1226 // 1227 // setup interface list 1228 // 1229 RtlZeroMemory(InterfaceList, sizeof(InterfaceList)); 1230 InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor; 1231 1232 // 1233 // build urb 1234 // 1235 Urb = USBD_CreateConfigurationRequestEx(HidDeviceExtension->ConfigurationDescriptor, InterfaceList); 1236 if (!Urb) 1237 { 1238 // 1239 // no memory 1240 // 1241 return STATUS_INSUFFICIENT_RESOURCES; 1242 } 1243 1244 // 1245 // dispatch request 1246 // 1247 Status = Hid_DispatchUrb(DeviceObject, Urb); 1248 if (NT_SUCCESS(Status)) 1249 { 1250 // 1251 // store configuration handle 1252 // 1253 HidDeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle; 1254 1255 // 1256 // copy interface info 1257 // 1258 HidDeviceExtension->InterfaceInfo = ExAllocatePoolWithTag(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length, HIDUSB_TAG); 1259 if (HidDeviceExtension->InterfaceInfo) 1260 { 1261 // 1262 // copy interface info 1263 // 1264 RtlCopyMemory(HidDeviceExtension->InterfaceInfo, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length); 1265 } 1266 } 1267 1268 // 1269 // free urb request 1270 // 1271 ExFreePoolWithTag(Urb, 0); 1272 1273 // 1274 // done 1275 // 1276 return Status; 1277 } 1278 1279 NTSTATUS 1280 Hid_DisableConfiguration( 1281 IN PDEVICE_OBJECT DeviceObject) 1282 { 1283 PHID_DEVICE_EXTENSION DeviceExtension; 1284 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 1285 NTSTATUS Status; 1286 PURB Urb; 1287 1288 // 1289 // get device extension 1290 // 1291 DeviceExtension = DeviceObject->DeviceExtension; 1292 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 1293 1294 // 1295 // build urb 1296 // 1297 Urb = ExAllocatePoolWithTag(NonPagedPool, 1298 sizeof(struct _URB_SELECT_CONFIGURATION), 1299 HIDUSB_URB_TAG); 1300 if (!Urb) 1301 { 1302 // 1303 // no memory 1304 // 1305 return STATUS_INSUFFICIENT_RESOURCES; 1306 } 1307 1308 // 1309 // format urb 1310 // 1311 UsbBuildSelectConfigurationRequest(Urb, 1312 sizeof(struct _URB_SELECT_CONFIGURATION), 1313 NULL); 1314 1315 // 1316 // dispatch request 1317 // 1318 Status = Hid_DispatchUrb(DeviceObject, Urb); 1319 if (!NT_SUCCESS(Status)) 1320 { 1321 DPRINT1("[HIDUSB] Dispatching unconfigure URB failed with %lx\n", Status); 1322 } 1323 else if (!USBD_SUCCESS(Urb->UrbHeader.Status)) 1324 { 1325 DPRINT("[HIDUSB] Unconfigure URB failed with %lx\n", Status); 1326 } 1327 1328 // 1329 // free urb 1330 // 1331 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1332 1333 // 1334 // free resources 1335 // 1336 HidDeviceExtension->ConfigurationHandle = NULL; 1337 1338 if (HidDeviceExtension->InterfaceInfo) 1339 { 1340 ExFreePoolWithTag(HidDeviceExtension->InterfaceInfo, HIDUSB_TAG); 1341 HidDeviceExtension->InterfaceInfo = NULL; 1342 } 1343 1344 if (HidDeviceExtension->ConfigurationDescriptor) 1345 { 1346 ExFreePoolWithTag(HidDeviceExtension->ConfigurationDescriptor, HIDUSB_TAG); 1347 HidDeviceExtension->ConfigurationDescriptor = NULL; 1348 HidDeviceExtension->HidDescriptor = NULL; 1349 } 1350 1351 if (HidDeviceExtension->DeviceDescriptor) 1352 { 1353 ExFreePoolWithTag(HidDeviceExtension->DeviceDescriptor, HIDUSB_TAG); 1354 HidDeviceExtension->DeviceDescriptor = NULL; 1355 } 1356 1357 // 1358 // done 1359 // 1360 return Status; 1361 } 1362 1363 NTSTATUS 1364 Hid_SetIdle( 1365 IN PDEVICE_OBJECT DeviceObject) 1366 { 1367 PURB Urb; 1368 NTSTATUS Status; 1369 1370 // 1371 // allocate urb 1372 // 1373 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), HIDUSB_URB_TAG); 1374 if (!Urb) 1375 { 1376 // 1377 // no memory 1378 // 1379 return STATUS_INSUFFICIENT_RESOURCES; 1380 } 1381 1382 // 1383 // zero urb 1384 // 1385 RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); 1386 1387 // 1388 // format urb 1389 // 1390 UsbBuildVendorRequest(Urb, 1391 URB_FUNCTION_CLASS_INTERFACE, 1392 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), 1393 0, 1394 0, 1395 USB_SET_IDLE_REQUEST, // HID_SET_IDLE 1396 0, 1397 0, 1398 NULL, 1399 NULL, 1400 0, 1401 NULL); 1402 1403 // 1404 // dispatch urb 1405 // 1406 Status = Hid_DispatchUrb(DeviceObject, Urb); 1407 1408 // 1409 // free urb 1410 // 1411 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1412 1413 // 1414 // print status 1415 // 1416 DPRINT1("Status %x\n", Status); 1417 return Status; 1418 } 1419 1420 1421 VOID 1422 Hid_GetProtocol( 1423 IN PDEVICE_OBJECT DeviceObject) 1424 { 1425 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 1426 PHID_DEVICE_EXTENSION DeviceExtension; 1427 PURB Urb; 1428 UCHAR Protocol[1]; 1429 1430 // 1431 // get device extension 1432 // 1433 DeviceExtension = DeviceObject->DeviceExtension; 1434 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 1435 ASSERT(HidDeviceExtension->InterfaceInfo); 1436 1437 if (HidDeviceExtension->InterfaceInfo->SubClass != 0x1) 1438 { 1439 // 1440 // device does not support the boot protocol 1441 // 1442 return; 1443 } 1444 1445 // 1446 // allocate urb 1447 // 1448 Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), HIDUSB_URB_TAG); 1449 if (!Urb) 1450 { 1451 // 1452 // no memory 1453 // 1454 return; 1455 } 1456 1457 // 1458 // zero urb 1459 // 1460 RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); 1461 1462 // 1463 // format urb 1464 // 1465 UsbBuildVendorRequest(Urb, 1466 URB_FUNCTION_CLASS_INTERFACE, 1467 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), 1468 USBD_TRANSFER_DIRECTION_IN, 1469 0, 1470 USB_GET_PROTOCOL_REQUEST, 1471 0, 1472 0, 1473 Protocol, 1474 NULL, 1475 1, 1476 NULL); 1477 Protocol[0] = 0xFF; 1478 1479 // 1480 // dispatch urb 1481 // 1482 Hid_DispatchUrb(DeviceObject, Urb); 1483 1484 // 1485 // free urb 1486 // 1487 ExFreePoolWithTag(Urb, HIDUSB_URB_TAG); 1488 1489 // 1490 // boot protocol active 0x00 disabled 0x1 1491 // 1492 if (Protocol[0] != 0x1) 1493 { 1494 if (Protocol[0] == 0x00) 1495 { 1496 DPRINT1("[HIDUSB] Need to disable boot protocol!\n"); 1497 } 1498 else 1499 { 1500 DPRINT1("[HIDUSB] Unexpected protocol value %x\n", Protocol[0] & 0xFF); 1501 } 1502 } 1503 } 1504 1505 NTSTATUS 1506 Hid_PnpStart( 1507 IN PDEVICE_OBJECT DeviceObject) 1508 { 1509 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 1510 PHID_DEVICE_EXTENSION DeviceExtension; 1511 NTSTATUS Status; 1512 ULONG DescriptorLength; 1513 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 1514 PHID_DESCRIPTOR HidDescriptor; 1515 1516 // 1517 // get device extension 1518 // 1519 DeviceExtension = DeviceObject->DeviceExtension; 1520 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 1521 1522 // 1523 // get device descriptor 1524 // 1525 DescriptorLength = sizeof(USB_DEVICE_DESCRIPTOR); 1526 Status = Hid_GetDescriptor(DeviceObject, 1527 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, 1528 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 1529 (PVOID *)&HidDeviceExtension->DeviceDescriptor, 1530 &DescriptorLength, 1531 USB_DEVICE_DESCRIPTOR_TYPE, 1532 0, 1533 0); 1534 if (!NT_SUCCESS(Status)) 1535 { 1536 // 1537 // failed to obtain device descriptor 1538 // 1539 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status); 1540 return Status; 1541 } 1542 1543 // 1544 // now get the configuration descriptor 1545 // 1546 DescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); 1547 Status = Hid_GetDescriptor(DeviceObject, 1548 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, 1549 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 1550 (PVOID *)&HidDeviceExtension->ConfigurationDescriptor, 1551 &DescriptorLength, 1552 USB_CONFIGURATION_DESCRIPTOR_TYPE, 1553 0, 1554 0); 1555 if (!NT_SUCCESS(Status)) 1556 { 1557 // 1558 // failed to obtain device descriptor 1559 // 1560 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status); 1561 return Status; 1562 } 1563 1564 // 1565 // sanity check 1566 // 1567 ASSERT(DescriptorLength); 1568 ASSERT(HidDeviceExtension->ConfigurationDescriptor); 1569 ASSERT(HidDeviceExtension->ConfigurationDescriptor->bLength); 1570 1571 // 1572 // store full length 1573 // 1574 DescriptorLength = HidDeviceExtension->ConfigurationDescriptor->wTotalLength; 1575 1576 // 1577 // delete partial configuration descriptor 1578 // 1579 ExFreePoolWithTag(HidDeviceExtension->ConfigurationDescriptor, HIDUSB_TAG); 1580 HidDeviceExtension->ConfigurationDescriptor = NULL; 1581 1582 // 1583 // get full configuration descriptor 1584 // 1585 Status = Hid_GetDescriptor(DeviceObject, 1586 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, 1587 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 1588 (PVOID *)&HidDeviceExtension->ConfigurationDescriptor, 1589 &DescriptorLength, 1590 USB_CONFIGURATION_DESCRIPTOR_TYPE, 1591 0, 1592 0); 1593 if (!NT_SUCCESS(Status)) 1594 { 1595 // 1596 // failed to obtain device descriptor 1597 // 1598 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status); 1599 return Status; 1600 } 1601 1602 // 1603 // now parse the descriptors 1604 // 1605 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor, 1606 HidDeviceExtension->ConfigurationDescriptor, 1607 -1, 1608 -1, 1609 USB_DEVICE_CLASS_HUMAN_INTERFACE, 1610 -1, 1611 -1); 1612 if (!InterfaceDescriptor) 1613 { 1614 // 1615 // no interface class 1616 // 1617 DPRINT1("[HIDUSB] HID Interface descriptor not found\n"); 1618 return STATUS_UNSUCCESSFUL; 1619 } 1620 1621 // 1622 // sanity check 1623 // 1624 ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE); 1625 ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); 1626 ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); 1627 1628 // 1629 // move to next descriptor 1630 // 1631 HidDescriptor = (PHID_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); 1632 ASSERT(HidDescriptor->bLength >= 2); 1633 1634 // 1635 // check if this is the hid descriptor 1636 // 1637 if (HidDescriptor->bLength == sizeof(HID_DESCRIPTOR) && HidDescriptor->bDescriptorType == HID_HID_DESCRIPTOR_TYPE) 1638 { 1639 // 1640 // found 1641 // 1642 HidDeviceExtension->HidDescriptor = HidDescriptor; 1643 1644 // 1645 // select configuration 1646 // 1647 Status = Hid_SelectConfiguration(DeviceObject); 1648 1649 // 1650 // done 1651 // 1652 DPRINT("[HIDUSB] SelectConfiguration %x\n", Status); 1653 1654 if (NT_SUCCESS(Status)) 1655 { 1656 // 1657 // now set the device idle 1658 // 1659 Hid_SetIdle(DeviceObject); 1660 1661 // 1662 // get protocol 1663 // 1664 Hid_GetProtocol(DeviceObject); 1665 return Status; 1666 } 1667 } 1668 else 1669 { 1670 // 1671 // FIXME parse hid descriptor 1672 // select configuration 1673 // set idle 1674 // and get protocol 1675 // 1676 UNIMPLEMENTED; 1677 ASSERT(FALSE); 1678 } 1679 return Status; 1680 } 1681 1682 1683 NTSTATUS 1684 NTAPI 1685 HidPnp( 1686 IN PDEVICE_OBJECT DeviceObject, 1687 IN PIRP Irp) 1688 { 1689 NTSTATUS Status; 1690 PIO_STACK_LOCATION IoStack; 1691 PHID_DEVICE_EXTENSION DeviceExtension; 1692 KEVENT Event; 1693 1694 // 1695 // get device extension 1696 // 1697 DeviceExtension = DeviceObject->DeviceExtension; 1698 1699 // 1700 // get current stack location 1701 // 1702 IoStack = IoGetCurrentIrpStackLocation(Irp); 1703 DPRINT("[HIDUSB] Pnp %x\n", IoStack->MinorFunction); 1704 1705 // 1706 // handle requests based on request type 1707 // 1708 switch (IoStack->MinorFunction) 1709 { 1710 case IRP_MN_REMOVE_DEVICE: 1711 { 1712 // 1713 // unconfigure device 1714 // FIXME: Call this on IRP_MN_SURPRISE_REMOVAL, but don't send URBs 1715 // FIXME: Don't call this after we've already seen a surprise removal or stop 1716 // 1717 Hid_DisableConfiguration(DeviceObject); 1718 1719 // 1720 // pass request onto lower driver 1721 // 1722 IoSkipCurrentIrpStackLocation(Irp); 1723 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1724 1725 return Status; 1726 } 1727 case IRP_MN_QUERY_PNP_DEVICE_STATE: 1728 { 1729 // 1730 // device can not be disabled 1731 // 1732 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; 1733 1734 // 1735 // pass request to next request 1736 // 1737 IoSkipCurrentIrpStackLocation(Irp); 1738 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1739 1740 // 1741 // done 1742 // 1743 return Status; 1744 } 1745 case IRP_MN_QUERY_STOP_DEVICE: 1746 case IRP_MN_QUERY_REMOVE_DEVICE: 1747 { 1748 // 1749 // we're fine with it 1750 // 1751 Irp->IoStatus.Status = STATUS_SUCCESS; 1752 1753 // 1754 // pass request to next driver 1755 // 1756 IoSkipCurrentIrpStackLocation(Irp); 1757 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1758 1759 // 1760 // done 1761 // 1762 return Status; 1763 } 1764 case IRP_MN_STOP_DEVICE: 1765 { 1766 // 1767 // unconfigure device 1768 // 1769 Hid_DisableConfiguration(DeviceObject); 1770 1771 // 1772 // prepare irp 1773 // 1774 KeInitializeEvent(&Event, NotificationEvent, FALSE); 1775 IoCopyCurrentIrpStackLocationToNext(Irp); 1776 IoSetCompletionRoutine(Irp, Hid_PnpCompletion, &Event, TRUE, TRUE, TRUE); 1777 1778 // 1779 // send irp and wait for completion 1780 // 1781 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1782 if (Status == STATUS_PENDING) 1783 { 1784 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 1785 Status = Irp->IoStatus.Status; 1786 } 1787 1788 // 1789 // done 1790 // 1791 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1792 return Status; 1793 } 1794 case IRP_MN_QUERY_CAPABILITIES: 1795 { 1796 // 1797 // prepare irp 1798 // 1799 KeInitializeEvent(&Event, NotificationEvent, FALSE); 1800 IoCopyCurrentIrpStackLocationToNext(Irp); 1801 IoSetCompletionRoutine(Irp, Hid_PnpCompletion, &Event, TRUE, TRUE, TRUE); 1802 1803 // 1804 // send irp and wait for completion 1805 // 1806 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1807 if (Status == STATUS_PENDING) 1808 { 1809 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 1810 Status = Irp->IoStatus.Status; 1811 } 1812 1813 if (NT_SUCCESS(Status) && IoStack->Parameters.DeviceCapabilities.Capabilities != NULL) 1814 { 1815 // 1816 // don't need to safely remove 1817 // 1818 IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE; 1819 } 1820 1821 // 1822 // done 1823 // 1824 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1825 return Status; 1826 } 1827 case IRP_MN_START_DEVICE: 1828 { 1829 // 1830 // prepare irp 1831 // 1832 KeInitializeEvent(&Event, NotificationEvent, FALSE); 1833 IoCopyCurrentIrpStackLocationToNext(Irp); 1834 IoSetCompletionRoutine(Irp, Hid_PnpCompletion, &Event, TRUE, TRUE, TRUE); 1835 1836 // 1837 // send irp and wait for completion 1838 // 1839 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1840 if (Status == STATUS_PENDING) 1841 { 1842 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 1843 Status = Irp->IoStatus.Status; 1844 } 1845 1846 // 1847 // did the device successfully start 1848 // 1849 if (!NT_SUCCESS(Status)) 1850 { 1851 // 1852 // failed 1853 // 1854 DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", Status); 1855 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1856 return Status; 1857 } 1858 1859 // 1860 // start device 1861 // 1862 Status = Hid_PnpStart(DeviceObject); 1863 1864 // 1865 // complete request 1866 // 1867 Irp->IoStatus.Status = Status; 1868 DPRINT("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status); 1869 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1870 return Status; 1871 } 1872 default: 1873 { 1874 // 1875 // forward and forget request 1876 // 1877 IoSkipCurrentIrpStackLocation(Irp); 1878 return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); 1879 } 1880 } 1881 } 1882 1883 NTSTATUS 1884 NTAPI 1885 HidAddDevice( 1886 IN PDRIVER_OBJECT DriverObject, 1887 IN PDEVICE_OBJECT DeviceObject) 1888 { 1889 PHID_USB_DEVICE_EXTENSION HidDeviceExtension; 1890 PHID_DEVICE_EXTENSION DeviceExtension; 1891 1892 // 1893 // get device extension 1894 // 1895 DeviceExtension = DeviceObject->DeviceExtension; 1896 HidDeviceExtension = DeviceExtension->MiniDeviceExtension; 1897 1898 // 1899 // init event 1900 // 1901 KeInitializeEvent(&HidDeviceExtension->Event, NotificationEvent, FALSE); 1902 1903 // 1904 // done 1905 // 1906 return STATUS_SUCCESS; 1907 } 1908 1909 VOID 1910 NTAPI 1911 Hid_Unload( 1912 IN PDRIVER_OBJECT DriverObject) 1913 { 1914 UNIMPLEMENTED; 1915 } 1916 1917 1918 NTSTATUS 1919 NTAPI 1920 DriverEntry( 1921 IN PDRIVER_OBJECT DriverObject, 1922 IN PUNICODE_STRING RegPath) 1923 { 1924 HID_MINIDRIVER_REGISTRATION Registration; 1925 NTSTATUS Status; 1926 1927 // 1928 // initialize driver object 1929 // 1930 DriverObject->MajorFunction[IRP_MJ_CREATE] = HidCreate; 1931 DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidCreate; 1932 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidInternalDeviceControl; 1933 DriverObject->MajorFunction[IRP_MJ_POWER] = HidPower; 1934 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidSystemControl; 1935 DriverObject->MajorFunction[IRP_MJ_PNP] = HidPnp; 1936 DriverObject->DriverExtension->AddDevice = HidAddDevice; 1937 DriverObject->DriverUnload = Hid_Unload; 1938 1939 // 1940 // prepare registration info 1941 // 1942 RtlZeroMemory(&Registration, sizeof(HID_MINIDRIVER_REGISTRATION)); 1943 1944 // 1945 // fill in registration info 1946 // 1947 Registration.Revision = HID_REVISION; 1948 Registration.DriverObject = DriverObject; 1949 Registration.RegistryPath = RegPath; 1950 Registration.DeviceExtensionSize = sizeof(HID_USB_DEVICE_EXTENSION); 1951 Registration.DevicesArePolled = FALSE; 1952 1953 // 1954 // register driver 1955 // 1956 Status = HidRegisterMinidriver(&Registration); 1957 1958 // 1959 // informal debug 1960 // 1961 DPRINT("********* HIDUSB *********\n"); 1962 DPRINT("HIDUSB Registration Status %x\n", Status); 1963 1964 return Status; 1965 } 1966