1 // Copyright (c) 2004, Antony C. Roberts 2 3 // Use of this file is subject to the terms 4 // described in the LICENSE.TXT file that 5 // accompanies this file. 6 // 7 // Your use of this file indicates your 8 // acceptance of the terms described in 9 // LICENSE.TXT. 10 // 11 // http://www.freebt.net 12 13 #include "stdio.h" 14 #include "fbtusb.h" 15 #include "fbtpnp.h" 16 #include "fbtpwr.h" 17 #include "fbtdev.h" 18 #include "fbtrwr.h" 19 #include "fbtwmi.h" 20 21 #include "fbtusr.h" 22 23 // Handle PNP events 24 NTSTATUS NTAPI FreeBT_DispatchPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 25 { 26 PIO_STACK_LOCATION irpStack; 27 PDEVICE_EXTENSION deviceExtension; 28 //KEVENT startDeviceEvent; 29 NTSTATUS ntStatus; 30 31 irpStack = IoGetCurrentIrpStackLocation(Irp); 32 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 33 34 // since the device is removed, fail the Irp. 35 if (Removed == deviceExtension->DeviceState) 36 { 37 ntStatus = STATUS_DELETE_PENDING; 38 Irp->IoStatus.Status = ntStatus; 39 Irp->IoStatus.Information = 0; 40 IoCompleteRequest(Irp, IO_NO_INCREMENT); 41 return ntStatus; 42 43 } 44 45 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 46 FreeBT_IoIncrement(deviceExtension); 47 if (irpStack->MinorFunction == IRP_MN_START_DEVICE) 48 { 49 ASSERT(deviceExtension->IdleReqPend == 0); 50 51 } 52 53 else 54 { 55 if (deviceExtension->SSEnable) 56 { 57 CancelSelectSuspend(deviceExtension); 58 59 } 60 61 } 62 63 FreeBT_DbgPrint(3, ("FBTUSB: ///////////////////////////////////////////\n")); 64 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 65 FreeBT_DbgPrint(2, (PnPMinorFunctionString(irpStack->MinorFunction))); 66 switch (irpStack->MinorFunction) 67 { 68 case IRP_MN_START_DEVICE: 69 ntStatus = HandleStartDevice(DeviceObject, Irp); 70 break; 71 72 case IRP_MN_QUERY_STOP_DEVICE: 73 // if we cannot stop the device, we fail the query stop irp 74 ntStatus = CanStopDevice(DeviceObject, Irp); 75 if(NT_SUCCESS(ntStatus)) 76 { 77 ntStatus = HandleQueryStopDevice(DeviceObject, Irp); 78 return ntStatus; 79 80 } 81 82 break; 83 84 case IRP_MN_CANCEL_STOP_DEVICE: 85 ntStatus = HandleCancelStopDevice(DeviceObject, Irp); 86 break; 87 88 case IRP_MN_STOP_DEVICE: 89 ntStatus = HandleStopDevice(DeviceObject, Irp); 90 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::IRP_MN_STOP_DEVICE::")); 91 FreeBT_IoDecrement(deviceExtension); 92 93 return ntStatus; 94 95 case IRP_MN_QUERY_REMOVE_DEVICE: 96 // if we cannot remove the device, we fail the query remove irp 97 ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp); 98 99 return ntStatus; 100 101 case IRP_MN_CANCEL_REMOVE_DEVICE: 102 ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp); 103 break; 104 105 case IRP_MN_SURPRISE_REMOVAL: 106 ntStatus = HandleSurpriseRemoval(DeviceObject, Irp); 107 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::")); 108 FreeBT_IoDecrement(deviceExtension); 109 return ntStatus; 110 111 case IRP_MN_REMOVE_DEVICE: 112 ntStatus = HandleRemoveDevice(DeviceObject, Irp); 113 return ntStatus; 114 115 case IRP_MN_QUERY_CAPABILITIES: 116 ntStatus = HandleQueryCapabilities(DeviceObject, Irp); 117 break; 118 119 default: 120 IoSkipCurrentIrpStackLocation(Irp); 121 122 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 123 124 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::default::")); 125 FreeBT_IoDecrement(deviceExtension); 126 127 return ntStatus; 128 129 } 130 131 Irp->IoStatus.Status = ntStatus; 132 Irp->IoStatus.Information = 0; 133 IoCompleteRequest(Irp, IO_NO_INCREMENT); 134 135 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 136 FreeBT_IoDecrement(deviceExtension); 137 138 return ntStatus; 139 140 } 141 142 NTSTATUS NTAPI HandleStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 143 { 144 KIRQL oldIrql; 145 KEVENT startDeviceEvent; 146 NTSTATUS ntStatus; 147 PDEVICE_EXTENSION deviceExtension; 148 LARGE_INTEGER dueTime; 149 150 FreeBT_DbgPrint(3, ("FBTUSB: HandleStartDevice: Entered\n")); 151 152 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 153 deviceExtension->UsbConfigurationDescriptor = NULL; 154 deviceExtension->UsbInterface = NULL; 155 deviceExtension->PipeContext = NULL; 156 157 // We cannot touch the device (send it any non pnp irps) until a 158 // start device has been passed down to the lower drivers. 159 // first pass the Irp down 160 KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE); 161 IoCopyCurrentIrpStackLocationToNext(Irp); 162 IoSetCompletionRoutine(Irp, 163 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 164 (PVOID)&startDeviceEvent, 165 TRUE, 166 TRUE, 167 TRUE); 168 169 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 170 if (ntStatus == STATUS_PENDING) 171 { 172 KeWaitForSingleObject(&startDeviceEvent, Executive, KernelMode, FALSE, NULL); 173 ntStatus = Irp->IoStatus.Status; 174 175 } 176 177 if (!NT_SUCCESS(ntStatus)) 178 { 179 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: Lower drivers failed this Irp (0x%08x)\n", ntStatus)); 180 return ntStatus; 181 182 } 183 184 // Read the device descriptor, configuration descriptor 185 // and select the interface descriptors 186 ntStatus = ReadandSelectDescriptors(DeviceObject); 187 if (!NT_SUCCESS(ntStatus)) 188 { 189 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: ReadandSelectDescriptors failed (0x%08x)\n", ntStatus)); 190 return ntStatus; 191 192 } 193 194 // enable the symbolic links for system components to open 195 // handles to the device 196 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, TRUE); 197 if (!NT_SUCCESS(ntStatus)) 198 { 199 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: IoSetDeviceInterfaceState failed (0x%08x)\n", ntStatus)); 200 return ntStatus; 201 202 } 203 204 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 205 206 SET_NEW_PNP_STATE(deviceExtension, Working); 207 deviceExtension->QueueState = AllowRequests; 208 209 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 210 211 deviceExtension->FlagWWOutstanding = 0; 212 deviceExtension->FlagWWCancel = 0; 213 deviceExtension->WaitWakeIrp = NULL; 214 215 if (deviceExtension->WaitWakeEnable) 216 { 217 IssueWaitWake(deviceExtension); 218 219 } 220 221 ProcessQueuedRequests(deviceExtension); 222 if (WinXpOrBetter == deviceExtension->WdmVersion) 223 { 224 deviceExtension->SSEnable = deviceExtension->SSRegistryEnable; 225 226 // set timer.for selective suspend requests 227 if (deviceExtension->SSEnable) 228 { 229 dueTime.QuadPart = -10000 * IDLE_INTERVAL; // 5000 ms 230 KeSetTimerEx(&deviceExtension->Timer, dueTime, IDLE_INTERVAL, &deviceExtension->DeferredProcCall); 231 deviceExtension->FreeIdleIrpCount = 0; 232 233 } 234 235 } 236 237 FreeBT_DbgPrint(3, ("FBTUSB: HandleStartDevice: Leaving\n")); 238 239 return ntStatus; 240 241 } 242 243 244 NTSTATUS NTAPI ReadandSelectDescriptors(IN PDEVICE_OBJECT DeviceObject) 245 { 246 PURB urb; 247 ULONG siz; 248 NTSTATUS ntStatus; 249 PUSB_DEVICE_DESCRIPTOR deviceDescriptor; 250 251 urb = NULL; 252 deviceDescriptor = NULL; 253 254 // 1. Read the device descriptor 255 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 256 if(urb) 257 { 258 siz = sizeof(USB_DEVICE_DESCRIPTOR); 259 deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 260 if (deviceDescriptor) 261 { 262 UsbBuildGetDescriptorRequest( 263 urb, 264 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 265 USB_DEVICE_DESCRIPTOR_TYPE, 266 0, 267 0, 268 deviceDescriptor, 269 NULL, 270 siz, 271 NULL); 272 273 ntStatus = CallUSBD(DeviceObject, urb); 274 if (NT_SUCCESS(ntStatus)) 275 { 276 ASSERT(deviceDescriptor->bNumConfigurations); 277 ntStatus = ConfigureDevice(DeviceObject); 278 279 } 280 281 ExFreePool(urb); 282 ExFreePool(deviceDescriptor); 283 284 } 285 286 else 287 { 288 FreeBT_DbgPrint(1, ("FBTUSB: ReadandSelectDescriptors: Failed to allocate memory for deviceDescriptor")); 289 ExFreePool(urb); 290 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 291 292 } 293 294 } 295 296 else 297 { 298 FreeBT_DbgPrint(1, ("FBTUSB: ReadandSelectDescriptors: Failed to allocate memory for urb")); 299 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 300 301 } 302 303 304 return ntStatus; 305 306 } 307 308 NTSTATUS NTAPI ConfigureDevice(IN PDEVICE_OBJECT DeviceObject) 309 { 310 PURB urb; 311 ULONG siz; 312 NTSTATUS ntStatus; 313 PDEVICE_EXTENSION deviceExtension; 314 PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor; 315 316 urb = NULL; 317 configurationDescriptor = NULL; 318 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 319 320 // Read the first configuration descriptor 321 // This requires two steps: 322 // 1. Read the fixed sized configuration desciptor (CD) 323 // 2. Read the CD with all embedded interface and endpoint descriptors 324 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 325 if (urb) 326 { 327 siz = sizeof(USB_CONFIGURATION_DESCRIPTOR); 328 configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 329 330 if(configurationDescriptor) 331 { 332 UsbBuildGetDescriptorRequest( 333 urb, 334 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 335 USB_CONFIGURATION_DESCRIPTOR_TYPE, 336 0, 337 0, 338 configurationDescriptor, 339 NULL, 340 sizeof(USB_CONFIGURATION_DESCRIPTOR), 341 NULL); 342 343 ntStatus = CallUSBD(DeviceObject, urb); 344 if(!NT_SUCCESS(ntStatus)) 345 { 346 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: UsbBuildGetDescriptorRequest failed\n")); 347 goto ConfigureDevice_Exit; 348 349 } 350 351 } 352 353 else 354 { 355 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to allocate mem for config Descriptor\n")); 356 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 357 goto ConfigureDevice_Exit; 358 359 } 360 361 siz = configurationDescriptor->wTotalLength; 362 ExFreePool(configurationDescriptor); 363 364 configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 365 if (configurationDescriptor) 366 { 367 UsbBuildGetDescriptorRequest( 368 urb, 369 (USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 370 USB_CONFIGURATION_DESCRIPTOR_TYPE, 371 0, 372 0, 373 configurationDescriptor, 374 NULL, 375 siz, 376 NULL); 377 378 ntStatus = CallUSBD(DeviceObject, urb); 379 if (!NT_SUCCESS(ntStatus)) 380 { 381 FreeBT_DbgPrint(1,("FBTUSB: ConfigureDevice: Failed to read configuration descriptor")); 382 goto ConfigureDevice_Exit; 383 384 } 385 386 } 387 388 else 389 { 390 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to alloc mem for config Descriptor\n")); 391 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 392 goto ConfigureDevice_Exit; 393 394 } 395 396 } 397 398 else 399 { 400 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to allocate memory for urb\n")); 401 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 402 goto ConfigureDevice_Exit; 403 404 } 405 406 if (configurationDescriptor) 407 { 408 // save a copy of configurationDescriptor in deviceExtension 409 // remember to free it later. 410 deviceExtension->UsbConfigurationDescriptor = configurationDescriptor; 411 412 if (configurationDescriptor->bmAttributes & REMOTE_WAKEUP_MASK) 413 { 414 // this configuration supports remote wakeup 415 deviceExtension->WaitWakeEnable = 1; 416 417 } 418 419 else 420 { 421 deviceExtension->WaitWakeEnable = 0; 422 423 } 424 425 ntStatus = SelectInterfaces(DeviceObject, configurationDescriptor); 426 427 } 428 429 else 430 { 431 deviceExtension->UsbConfigurationDescriptor = NULL; 432 433 } 434 435 ConfigureDevice_Exit: 436 if (urb) 437 { 438 ExFreePool(urb); 439 440 } 441 442 return ntStatus; 443 444 } 445 446 NTSTATUS NTAPI SelectInterfaces(IN PDEVICE_OBJECT DeviceObject, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) 447 { 448 LONG numberOfInterfaces, interfaceNumber, interfaceindex; 449 ULONG i; 450 PURB urb; 451 //PUCHAR pInf; 452 NTSTATUS ntStatus; 453 PDEVICE_EXTENSION deviceExtension; 454 PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor; 455 PUSBD_INTERFACE_LIST_ENTRY interfaceList, 456 tmp; 457 PUSBD_INTERFACE_INFORMATION Interface; 458 459 urb = NULL; 460 Interface = NULL; 461 interfaceDescriptor = NULL; 462 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 463 numberOfInterfaces = ConfigurationDescriptor->bNumInterfaces; 464 interfaceindex = interfaceNumber = 0; 465 466 // Parse the configuration descriptor for the interface; 467 tmp = interfaceList = (PUSBD_INTERFACE_LIST_ENTRY) 468 ExAllocatePool(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (numberOfInterfaces + 1)); 469 470 if (!tmp) 471 { 472 473 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Failed to allocate mem for interfaceList\n")); 474 return STATUS_INSUFFICIENT_RESOURCES; 475 476 } 477 478 479 FreeBT_DbgPrint(3, ("FBTUSB: -------------\n")); 480 FreeBT_DbgPrint(3, ("FBTUSB: Number of interfaces %d\n", numberOfInterfaces)); 481 482 while (interfaceNumber < numberOfInterfaces) 483 { 484 interfaceDescriptor = USBD_ParseConfigurationDescriptorEx( 485 ConfigurationDescriptor, 486 ConfigurationDescriptor, 487 interfaceindex, 488 0, -1, -1, -1); 489 490 if (interfaceDescriptor) 491 { 492 interfaceList->InterfaceDescriptor = interfaceDescriptor; 493 interfaceList->Interface = NULL; 494 interfaceList++; 495 interfaceNumber++; 496 497 } 498 499 interfaceindex++; 500 501 } 502 503 interfaceList->InterfaceDescriptor = NULL; 504 interfaceList->Interface = NULL; 505 urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, tmp); 506 507 if (urb) 508 { 509 Interface = &urb->UrbSelectConfiguration.Interface; 510 for (i=0; i<Interface->NumberOfPipes; i++) 511 { 512 // perform pipe initialization here 513 // set the transfer size and any pipe flags we use 514 // USBD sets the rest of the Interface struct members 515 Interface->Pipes[i].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; 516 517 } 518 519 ntStatus = CallUSBD(DeviceObject, urb); 520 if (NT_SUCCESS(ntStatus)) 521 { 522 // save a copy of interface information in the device extension. 523 deviceExtension->UsbInterface = (PUSBD_INTERFACE_INFORMATION) ExAllocatePool(NonPagedPool, Interface->Length); 524 if (deviceExtension->UsbInterface) 525 { 526 RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length); 527 528 } 529 530 else 531 { 532 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 533 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Memory alloc for UsbInterface failed\n")); 534 535 } 536 537 // Dump the interface to the debugger 538 Interface = &urb->UrbSelectConfiguration.Interface; 539 540 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 541 FreeBT_DbgPrint(3, ("FBTUSB: NumberOfPipes 0x%x\n", Interface->NumberOfPipes)); 542 FreeBT_DbgPrint(3, ("FBTUSB: Length 0x%x\n", Interface->Length)); 543 FreeBT_DbgPrint(3, ("FBTUSB: Alt Setting 0x%x\n", Interface->AlternateSetting)); 544 FreeBT_DbgPrint(3, ("FBTUSB: Interface Number 0x%x\n", Interface->InterfaceNumber)); 545 FreeBT_DbgPrint(3, ("FBTUSB: Class, subclass, protocol 0x%x 0x%x 0x%x\n", 546 Interface->Class, 547 Interface->SubClass, 548 Interface->Protocol)); 549 550 if (Interface->Class==FREEBT_USB_STDCLASS && Interface->SubClass==FREEBT_USB_STDSUBCLASS && 551 Interface->Protocol==FREEBT_USB_STDPROTOCOL) 552 { 553 FreeBT_DbgPrint(3, ("FBTUSB: This is a standard USB Bluetooth device\n")); 554 555 } 556 557 else 558 { 559 FreeBT_DbgPrint(3, ("FBTUSB: WARNING: This device does not report itself as a standard USB Bluetooth device\n")); 560 561 } 562 563 // Initialize the PipeContext 564 // Dump the pipe info 565 deviceExtension->PipeContext = (PFREEBT_PIPE_CONTEXT) ExAllocatePool( 566 NonPagedPool, 567 Interface->NumberOfPipes * 568 sizeof(FREEBT_PIPE_CONTEXT)); 569 570 if (!deviceExtension->PipeContext) 571 { 572 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 573 FreeBT_DbgPrint(1, ("FBTUSB: Memory alloc for UsbInterface failed\n")); 574 575 } 576 577 else 578 { 579 FreeBT_DbgPrint(3, ("FBTUSB: SelectInterfaces: Allocated PipeContext %p\n", deviceExtension->PipeContext)); 580 for (i=0; i<Interface->NumberOfPipes; i++) 581 { 582 deviceExtension->PipeContext[i].PipeOpen = FALSE; 583 584 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 585 FreeBT_DbgPrint(3, ("FBTUSB: PipeType 0x%x\n", Interface->Pipes[i].PipeType)); 586 FreeBT_DbgPrint(3, ("FBTUSB: EndpointAddress 0x%x\n", Interface->Pipes[i].EndpointAddress)); 587 FreeBT_DbgPrint(3, ("FBTUSB: MaxPacketSize 0x%x\n", Interface->Pipes[i].MaximumPacketSize)); 588 FreeBT_DbgPrint(3, ("FBTUSB: Interval 0x%x\n", Interface->Pipes[i].Interval)); 589 FreeBT_DbgPrint(3, ("FBTUSB: Handle 0x%x\n", Interface->Pipes[i].PipeHandle)); 590 FreeBT_DbgPrint(3, ("FBTUSB: MaximumTransferSize 0x%x\n", Interface->Pipes[i].MaximumTransferSize)); 591 592 // Log the pipes 593 // Note the HCI Command endpoint won't appear here, because the Default Control Pipe 594 // is used for this. The Default Control Pipe is always present at EndPointAddress 0x0 595 switch (Interface->Pipes[i].EndpointAddress) 596 { 597 case FREEBT_STDENDPOINT_HCIEVENT: 598 deviceExtension->PipeContext[i].PipeType=HciEventPipe; 599 deviceExtension->EventPipe=Interface->Pipes[i]; 600 FreeBT_DbgPrint(3, ("FBTUSB: HCI Event Endpoint\n")); 601 break; 602 603 case FREEBT_STDENDPOINT_ACLIN: 604 deviceExtension->PipeContext[i].PipeType=AclDataIn; 605 deviceExtension->DataInPipe=Interface->Pipes[i]; 606 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data In Endpoint\n")); 607 break; 608 609 case FREEBT_STDENDPOINT_ACLOUT: 610 deviceExtension->PipeContext[i].PipeType=AclDataOut; 611 deviceExtension->DataOutPipe=Interface->Pipes[i]; 612 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 613 break; 614 615 case FREEBT_STDENDPOINT_AUDIOIN: 616 deviceExtension->PipeContext[i].PipeType=SCODataIn; 617 deviceExtension->AudioInPipe=Interface->Pipes[i]; 618 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 619 break; 620 621 case FREEBT_STDENDPOINT_AUDIOOUT: 622 deviceExtension->PipeContext[i].PipeType=SCODataOut; 623 deviceExtension->AudioOutPipe=Interface->Pipes[i]; 624 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 625 break; 626 627 } 628 629 } 630 631 } 632 633 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 634 635 } 636 637 else 638 { 639 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Failed to select an interface\n")); 640 641 } 642 643 } 644 645 else 646 { 647 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: USBD_CreateConfigurationRequestEx failed\n")); 648 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 649 650 } 651 652 if (tmp) 653 { 654 ExFreePool(tmp); 655 656 } 657 658 if (urb) 659 { 660 ExFreePool(urb); 661 662 } 663 664 return ntStatus; 665 } 666 667 668 NTSTATUS NTAPI DeconfigureDevice(IN PDEVICE_OBJECT DeviceObject) 669 { 670 PURB urb; 671 ULONG siz; 672 NTSTATUS ntStatus; 673 674 siz = sizeof(struct _URB_SELECT_CONFIGURATION); 675 urb = (PURB) ExAllocatePool(NonPagedPool, siz); 676 if (urb) 677 { 678 UsbBuildSelectConfigurationRequest(urb, (USHORT)siz, NULL); 679 ntStatus = CallUSBD(DeviceObject, urb); 680 if(!NT_SUCCESS(ntStatus)) 681 { 682 FreeBT_DbgPrint(3, ("FBTUSB: DeconfigureDevice: Failed to deconfigure device\n")); 683 684 } 685 686 ExFreePool(urb); 687 688 } 689 690 else 691 { 692 FreeBT_DbgPrint(1, ("FBTUSB: DeconfigureDevice: Failed to allocate urb\n")); 693 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 694 695 } 696 697 return ntStatus; 698 699 } 700 701 NTSTATUS NTAPI CallUSBD(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb) 702 { 703 PIRP irp; 704 KEVENT event; 705 NTSTATUS ntStatus; 706 IO_STATUS_BLOCK ioStatus; 707 PIO_STACK_LOCATION nextStack; 708 PDEVICE_EXTENSION deviceExtension; 709 710 irp = NULL; 711 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 712 713 KeInitializeEvent(&event, NotificationEvent, FALSE); 714 irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, 715 deviceExtension->TopOfStackDeviceObject, 716 NULL, 717 0, 718 NULL, 719 0, 720 TRUE, 721 &event, 722 &ioStatus); 723 724 if (!irp) 725 { 726 FreeBT_DbgPrint(1, ("FBTUSB: CallUSBD: IoBuildDeviceIoControlRequest failed\n")); 727 return STATUS_INSUFFICIENT_RESOURCES; 728 729 } 730 731 nextStack = IoGetNextIrpStackLocation(irp); 732 ASSERT(nextStack != NULL); 733 nextStack->Parameters.Others.Argument1 = Urb; 734 735 FreeBT_DbgPrint(3, ("FBTUSB: CallUSBD::")); 736 FreeBT_IoIncrement(deviceExtension); 737 738 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp); 739 if (ntStatus == STATUS_PENDING) 740 { 741 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 742 ntStatus = ioStatus.Status; 743 744 } 745 746 FreeBT_DbgPrint(3, ("FBTUSB: CallUSBD::")); 747 FreeBT_IoDecrement(deviceExtension); 748 return ntStatus; 749 750 } 751 752 NTSTATUS NTAPI HandleQueryStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 753 { 754 KIRQL oldIrql; 755 NTSTATUS ntStatus; 756 PDEVICE_EXTENSION deviceExtension; 757 758 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice: Entered\n")); 759 760 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 761 762 // If we can stop the device, we need to set the QueueState to 763 // HoldRequests so further requests will be queued. 764 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 765 766 SET_NEW_PNP_STATE(deviceExtension, PendingStop); 767 deviceExtension->QueueState = HoldRequests; 768 769 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 770 771 // wait for the existing ones to be finished. 772 // first, decrement this operation 773 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice::")); 774 FreeBT_IoDecrement(deviceExtension); 775 776 KeWaitForSingleObject(&deviceExtension->StopEvent, Executive, KernelMode, FALSE, NULL); 777 778 Irp->IoStatus.Status = STATUS_SUCCESS; 779 Irp->IoStatus.Information = 0; 780 781 IoSkipCurrentIrpStackLocation(Irp); 782 783 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 784 785 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice: Leaving\n")); 786 787 return ntStatus; 788 789 } 790 791 NTSTATUS NTAPI HandleCancelStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 792 { 793 KIRQL oldIrql; 794 KEVENT event; 795 NTSTATUS ntStatus; 796 PDEVICE_EXTENSION deviceExtension; 797 798 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelStopDevice: Entered\n")); 799 800 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 801 802 // Send this IRP down and wait for it to come back. 803 // Set the QueueState flag to AllowRequests, 804 // and process all the previously queued up IRPs. 805 806 // First check to see whether you have received cancel-stop 807 // without first receiving a query-stop. This could happen if someone 808 // above us fails a query-stop and passes down the subsequent 809 // cancel-stop. 810 if(PendingStop == deviceExtension->DeviceState) 811 { 812 KeInitializeEvent(&event, NotificationEvent, FALSE); 813 814 IoCopyCurrentIrpStackLocationToNext(Irp); 815 IoSetCompletionRoutine(Irp, 816 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 817 (PVOID)&event, 818 TRUE, 819 TRUE, 820 TRUE); 821 822 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 823 if(ntStatus == STATUS_PENDING) 824 { 825 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 826 ntStatus = Irp->IoStatus.Status; 827 828 } 829 830 if(NT_SUCCESS(ntStatus)) 831 { 832 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 833 834 RESTORE_PREVIOUS_PNP_STATE(deviceExtension); 835 deviceExtension->QueueState = AllowRequests; 836 ASSERT(deviceExtension->DeviceState == Working); 837 838 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 839 840 ProcessQueuedRequests(deviceExtension); 841 842 } 843 844 } 845 846 else 847 { 848 // spurious Irp 849 ntStatus = STATUS_SUCCESS; 850 851 } 852 853 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelStopDevice: Leaving\n")); 854 855 return ntStatus; 856 857 } 858 859 NTSTATUS NTAPI HandleStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 860 { 861 KIRQL oldIrql; 862 NTSTATUS ntStatus; 863 PDEVICE_EXTENSION deviceExtension; 864 865 FreeBT_DbgPrint(3, ("FBTUSB: HandleStopDevice: Entered\n")); 866 867 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 868 if(WinXpOrBetter == deviceExtension->WdmVersion) 869 { 870 if(deviceExtension->SSEnable) 871 { 872 // Cancel the timer so that the DPCs are no longer fired. 873 // Thus, we are making judicious usage of our resources. 874 // we do not need DPCs because the device is stopping. 875 // The timers are re-initialized while handling the start 876 // device irp. 877 KeCancelTimer(&deviceExtension->Timer); 878 879 // after the device is stopped, it can be surprise removed. 880 // we set this to 0, so that we do not attempt to cancel 881 // the timer while handling surprise remove or remove irps. 882 // when we get the start device request, this flag will be 883 // reinitialized. 884 deviceExtension->SSEnable = 0; 885 886 // make sure that if a DPC was fired before we called cancel timer, 887 // then the DPC and work-time have run to their completion 888 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 889 890 // make sure that the selective suspend request has been completed. 891 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 892 893 } 894 895 } 896 897 // after the stop Irp is sent to the lower driver object, 898 // the driver must not send any more Irps down that touch 899 // the device until another Start has occurred. 900 if (deviceExtension->WaitWakeEnable) 901 { 902 CancelWaitWake(deviceExtension); 903 904 } 905 906 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 907 908 SET_NEW_PNP_STATE(deviceExtension, Stopped); 909 910 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 911 912 // This is the right place to actually give up all the resources used 913 // This might include calls to IoDisconnectInterrupt, MmUnmapIoSpace, 914 // etc. 915 ReleaseMemory(DeviceObject); 916 917 ntStatus = DeconfigureDevice(DeviceObject); 918 919 Irp->IoStatus.Status = ntStatus; 920 Irp->IoStatus.Information = 0; 921 922 IoSkipCurrentIrpStackLocation(Irp); 923 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 924 925 FreeBT_DbgPrint(3, ("FBTUSB: HandleStopDevice: Leaving\n")); 926 927 return ntStatus; 928 929 } 930 931 NTSTATUS NTAPI HandleQueryRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 932 { 933 KIRQL oldIrql; 934 NTSTATUS ntStatus; 935 PDEVICE_EXTENSION deviceExtension; 936 937 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice: Entered\n")); 938 939 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 940 941 // If we can allow removal of the device, we should set the QueueState 942 // to HoldRequests so further requests will be queued. This is required 943 // so that we can process queued up requests in cancel-remove just in 944 // case somebody else in the stack fails the query-remove. 945 ntStatus = CanRemoveDevice(DeviceObject, Irp); 946 947 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 948 949 deviceExtension->QueueState = HoldRequests; 950 SET_NEW_PNP_STATE(deviceExtension, PendingRemove); 951 952 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 953 954 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice::")); 955 FreeBT_IoDecrement(deviceExtension); 956 957 // Wait for all the requests to be completed 958 KeWaitForSingleObject(&deviceExtension->StopEvent, Executive, KernelMode, FALSE, NULL); 959 960 Irp->IoStatus.Status = STATUS_SUCCESS; 961 Irp->IoStatus.Information = 0; 962 963 IoSkipCurrentIrpStackLocation(Irp); 964 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 965 966 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice: Leaving\n")); 967 968 return ntStatus; 969 970 } 971 972 NTSTATUS NTAPI HandleCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 973 { 974 KIRQL oldIrql; 975 KEVENT event; 976 NTSTATUS ntStatus; 977 PDEVICE_EXTENSION deviceExtension; 978 979 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelRemoveDevice: Entered\n")); 980 981 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 982 983 // We need to reset the QueueState flag to ProcessRequest, 984 // since the device resume its normal activities. 985 986 // First check to see whether you have received cancel-remove 987 // without first receiving a query-remove. This could happen if 988 // someone above us fails a query-remove and passes down the 989 // subsequent cancel-remove. 990 if(PendingRemove == deviceExtension->DeviceState) 991 { 992 993 KeInitializeEvent(&event, NotificationEvent, FALSE); 994 995 IoCopyCurrentIrpStackLocationToNext(Irp); 996 IoSetCompletionRoutine(Irp, 997 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 998 (PVOID)&event, 999 TRUE, 1000 TRUE, 1001 TRUE); 1002 1003 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 1004 if(ntStatus == STATUS_PENDING) 1005 { 1006 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 1007 ntStatus = Irp->IoStatus.Status; 1008 1009 } 1010 1011 if (NT_SUCCESS(ntStatus)) 1012 { 1013 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 1014 1015 deviceExtension->QueueState = AllowRequests; 1016 RESTORE_PREVIOUS_PNP_STATE(deviceExtension); 1017 1018 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 1019 1020 // process the queued requests that arrive between 1021 // QUERY_REMOVE and CANCEL_REMOVE 1022 ProcessQueuedRequests(deviceExtension); 1023 1024 } 1025 1026 } 1027 1028 else 1029 { 1030 // spurious cancel-remove 1031 ntStatus = STATUS_SUCCESS; 1032 1033 } 1034 1035 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelRemoveDevice: Leaving\n")); 1036 1037 return ntStatus; 1038 1039 } 1040 1041 NTSTATUS NTAPI HandleSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1042 { 1043 KIRQL oldIrql; 1044 NTSTATUS ntStatus; 1045 PDEVICE_EXTENSION deviceExtension; 1046 1047 FreeBT_DbgPrint(3, ("FBTUSB: HandleSurpriseRemoval: Entered\n")); 1048 1049 // initialize variables 1050 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1051 1052 // 1. fail pending requests 1053 // 2. return device and memory resources 1054 // 3. disable interfaces 1055 if(deviceExtension->WaitWakeEnable) 1056 { 1057 CancelWaitWake(deviceExtension); 1058 1059 } 1060 1061 1062 if (WinXpOrBetter == deviceExtension->WdmVersion) 1063 { 1064 if (deviceExtension->SSEnable) 1065 { 1066 // Cancel the timer so that the DPCs are no longer fired. 1067 // we do not need DPCs because the device has been surprise 1068 // removed 1069 KeCancelTimer(&deviceExtension->Timer); 1070 1071 deviceExtension->SSEnable = 0; 1072 1073 // make sure that if a DPC was fired before we called cancel timer, 1074 // then the DPC and work-time have run to their completion 1075 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 1076 1077 // make sure that the selective suspend request has been completed. 1078 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 1079 1080 } 1081 1082 } 1083 1084 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 1085 deviceExtension->QueueState = FailRequests; 1086 SET_NEW_PNP_STATE(deviceExtension, SurpriseRemoved); 1087 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 1088 1089 ProcessQueuedRequests(deviceExtension); 1090 1091 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE); 1092 if(!NT_SUCCESS(ntStatus)) 1093 { 1094 FreeBT_DbgPrint(1, ("FBTUSB: HandleSurpriseRemoval: IoSetDeviceInterfaceState::disable:failed\n")); 1095 1096 } 1097 1098 FreeBT_AbortPipes(DeviceObject); 1099 1100 Irp->IoStatus.Status = STATUS_SUCCESS; 1101 Irp->IoStatus.Information = 0; 1102 1103 IoSkipCurrentIrpStackLocation(Irp); 1104 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 1105 1106 FreeBT_DbgPrint(3, ("FBTUSB: HandleSurpriseRemoval: Leaving\n")); 1107 1108 return ntStatus; 1109 1110 } 1111 1112 NTSTATUS NTAPI HandleRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1113 { 1114 KIRQL oldIrql; 1115 //KEVENT event; 1116 ULONG requestCount; 1117 NTSTATUS ntStatus; 1118 PDEVICE_EXTENSION deviceExtension; 1119 1120 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice: Entered\n")); 1121 1122 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1123 1124 // The Plug & Play system has dictated the removal of this device. We 1125 // have no choice but to detach and delete the device object. 1126 // (If we wanted to express an interest in preventing this removal, 1127 // we should have failed the query remove IRP). 1128 if(SurpriseRemoved != deviceExtension->DeviceState) 1129 { 1130 1131 // we are here after QUERY_REMOVE 1132 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 1133 deviceExtension->QueueState = FailRequests; 1134 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 1135 1136 if(deviceExtension->WaitWakeEnable) 1137 { 1138 CancelWaitWake(deviceExtension); 1139 1140 } 1141 1142 if(WinXpOrBetter == deviceExtension->WdmVersion) 1143 { 1144 if (deviceExtension->SSEnable) 1145 { 1146 // Cancel the timer so that the DPCs are no longer fired. 1147 // we do not need DPCs because the device has been removed 1148 KeCancelTimer(&deviceExtension->Timer); 1149 1150 deviceExtension->SSEnable = 0; 1151 1152 // make sure that if a DPC was fired before we called cancel timer, 1153 // then the DPC and work-time have run to their completion 1154 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 1155 1156 // make sure that the selective suspend request has been completed. 1157 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 1158 1159 } 1160 1161 } 1162 1163 ProcessQueuedRequests(deviceExtension); 1164 1165 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE); 1166 if(!NT_SUCCESS(ntStatus)) 1167 { 1168 FreeBT_DbgPrint(1, ("FBTUSB: HandleRemoveDevice: IoSetDeviceInterfaceState::disable:failed\n")); 1169 1170 } 1171 1172 FreeBT_AbortPipes(DeviceObject); 1173 1174 } 1175 1176 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 1177 SET_NEW_PNP_STATE(deviceExtension, Removed); 1178 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 1179 #ifdef ENABLE_WMI 1180 FreeBT_WmiDeRegistration(deviceExtension); 1181 #endif 1182 1183 // Need 2 decrements 1184 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice::")); 1185 requestCount = FreeBT_IoDecrement(deviceExtension); 1186 1187 ASSERT(requestCount > 0); 1188 1189 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice::")); 1190 requestCount = FreeBT_IoDecrement(deviceExtension); 1191 1192 KeWaitForSingleObject(&deviceExtension->RemoveEvent, 1193 Executive, 1194 KernelMode, 1195 FALSE, 1196 NULL); 1197 1198 ReleaseMemory(DeviceObject); 1199 1200 // We need to send the remove down the stack before we detach, 1201 // but we don't need to wait for the completion of this operation 1202 // (and to register a completion routine). 1203 Irp->IoStatus.Status = STATUS_SUCCESS; 1204 Irp->IoStatus.Information = 0; 1205 1206 IoSkipCurrentIrpStackLocation(Irp); 1207 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 1208 1209 IoDetachDevice(deviceExtension->TopOfStackDeviceObject); 1210 IoDeleteDevice(DeviceObject); 1211 1212 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice: Leaving\n")); 1213 1214 return ntStatus; 1215 1216 } 1217 1218 NTSTATUS NTAPI HandleQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1219 { 1220 ULONG i; 1221 KEVENT event; 1222 NTSTATUS ntStatus; 1223 PDEVICE_EXTENSION deviceExtension; 1224 PDEVICE_CAPABILITIES pdc; 1225 PIO_STACK_LOCATION irpStack; 1226 1227 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryCapabilities: Entered\n")); 1228 1229 irpStack = IoGetCurrentIrpStackLocation(Irp); 1230 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1231 pdc = irpStack->Parameters.DeviceCapabilities.Capabilities; 1232 1233 if(pdc->Version < 1 || pdc->Size < sizeof(DEVICE_CAPABILITIES)) 1234 { 1235 1236 FreeBT_DbgPrint(1, ("FBTUSB: HandleQueryCapabilities::request failed\n")); 1237 ntStatus = STATUS_UNSUCCESSFUL; 1238 return ntStatus; 1239 1240 } 1241 1242 // Add in the SurpriseRemovalOK bit before passing it down. 1243 pdc->SurpriseRemovalOK = TRUE; 1244 Irp->IoStatus.Status = STATUS_SUCCESS; 1245 1246 KeInitializeEvent(&event, NotificationEvent, FALSE); 1247 1248 IoCopyCurrentIrpStackLocationToNext(Irp); 1249 IoSetCompletionRoutine(Irp, 1250 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 1251 (PVOID)&event, 1252 TRUE, 1253 TRUE, 1254 TRUE); 1255 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 1256 if(ntStatus == STATUS_PENDING) 1257 { 1258 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 1259 ntStatus = Irp->IoStatus.Status; 1260 1261 } 1262 1263 // initialize PowerDownLevel to disabled 1264 deviceExtension->PowerDownLevel = PowerDeviceUnspecified; 1265 if(NT_SUCCESS(ntStatus)) 1266 { 1267 deviceExtension->DeviceCapabilities = *pdc; 1268 for(i = PowerSystemSleeping1; i <= PowerSystemSleeping3; i++) 1269 { 1270 if(deviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3) 1271 { 1272 deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceState[i]; 1273 1274 } 1275 1276 } 1277 1278 // since its safe to surprise-remove this device, we shall 1279 // set the SurpriseRemoveOK flag to supress any dialog to 1280 // user. 1281 pdc->SurpriseRemovalOK = 1; 1282 1283 } 1284 1285 if(deviceExtension->PowerDownLevel == PowerDeviceUnspecified || 1286 deviceExtension->PowerDownLevel <= PowerDeviceD0) 1287 { 1288 deviceExtension->PowerDownLevel = PowerDeviceD2; 1289 1290 } 1291 1292 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryCapabilities: Leaving\n")); 1293 1294 return ntStatus; 1295 } 1296 1297 1298 VOID NTAPI DpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) 1299 /*++ 1300 1301 DPC routine triggered by the timer to check the idle state 1302 of the device and submit an idle request for the device. 1303 1304 --*/ 1305 { 1306 NTSTATUS ntStatus; 1307 PDEVICE_OBJECT deviceObject; 1308 PDEVICE_EXTENSION deviceExtension; 1309 PIO_WORKITEM item; 1310 1311 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Entered\n")); 1312 1313 deviceObject = (PDEVICE_OBJECT)DeferredContext; 1314 deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; 1315 1316 // Clear this event since a DPC has been fired! 1317 KeClearEvent(&deviceExtension->NoDpcWorkItemPendingEvent); 1318 1319 if(CanDeviceSuspend(deviceExtension)) 1320 { 1321 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Device is Idle\n")); 1322 item = IoAllocateWorkItem(deviceObject); 1323 1324 if (item) 1325 { 1326 IoQueueWorkItem(item, IdleRequestWorkerRoutine, DelayedWorkQueue, item); 1327 ntStatus = STATUS_PENDING; 1328 1329 } 1330 1331 else 1332 { 1333 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Cannot alloc memory for work item\n")); 1334 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 1335 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 1336 1337 } 1338 1339 } 1340 1341 else 1342 { 1343 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Idle event not signaled\n")); 1344 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 1345 1346 } 1347 1348 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Leaving\n")); 1349 } 1350 1351 1352 VOID NTAPI IdleRequestWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) 1353 { 1354 //PIRP irp; 1355 NTSTATUS ntStatus; 1356 PDEVICE_EXTENSION deviceExtension; 1357 PIO_WORKITEM workItem; 1358 1359 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Entered\n")); 1360 1361 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1362 workItem = (PIO_WORKITEM) Context; 1363 1364 if(CanDeviceSuspend(deviceExtension)) 1365 { 1366 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Device is idle\n")); 1367 ntStatus = SubmitIdleRequestIrp(deviceExtension); 1368 if(!NT_SUCCESS(ntStatus)) 1369 { 1370 FreeBT_DbgPrint(1, ("FBTUSB: IdleRequestWorkerRoutine: SubmitIdleRequestIrp failed\n")); 1371 1372 } 1373 1374 } 1375 1376 else 1377 { 1378 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Device is not idle\n")); 1379 1380 } 1381 1382 IoFreeWorkItem(workItem); 1383 1384 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 1385 1386 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestsWorkerRoutine: Leaving\n")); 1387 1388 } 1389 1390 1391 VOID NTAPI ProcessQueuedRequests(IN OUT PDEVICE_EXTENSION DeviceExtension) 1392 /*++ 1393 1394 Routine Description: 1395 1396 Remove and process the entries in the queue. If this routine is called 1397 when processing IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE 1398 or IRP_MN_START_DEVICE, the requests are passed to the next lower driver. 1399 If the routine is called when IRP_MN_REMOVE_DEVICE is received, the IRPs 1400 are complete with STATUS_DELETE_PENDING 1401 1402 Arguments: 1403 1404 DeviceExtension - pointer to device extension 1405 1406 Return Value: 1407 1408 None 1409 1410 --*/ 1411 { 1412 KIRQL oldIrql; 1413 PIRP nextIrp, 1414 cancelledIrp; 1415 PVOID cancelRoutine; 1416 LIST_ENTRY cancelledIrpList; 1417 PLIST_ENTRY listEntry; 1418 1419 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests: Entered\n")); 1420 1421 cancelRoutine = NULL; 1422 InitializeListHead(&cancelledIrpList); 1423 1424 // 1. dequeue the entries in the queue 1425 // 2. reset the cancel routine 1426 // 3. process them 1427 // 3a. if the device is active, send them down 1428 // 3b. else complete with STATUS_DELETE_PENDING 1429 while(1) 1430 { 1431 KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql); 1432 if(IsListEmpty(&DeviceExtension->NewRequestsQueue)) 1433 { 1434 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 1435 break; 1436 1437 } 1438 1439 listEntry = RemoveHeadList(&DeviceExtension->NewRequestsQueue); 1440 nextIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry); 1441 1442 cancelRoutine = IoSetCancelRoutine(nextIrp, NULL); 1443 1444 // check if its already cancelled 1445 if (nextIrp->Cancel) 1446 { 1447 if(cancelRoutine) 1448 { 1449 // the cancel routine for this IRP hasnt been called yet 1450 // so queue the IRP in the cancelledIrp list and complete 1451 // after releasing the lock 1452 InsertTailList(&cancelledIrpList, listEntry); 1453 1454 } 1455 1456 else 1457 { 1458 // the cancel routine has run 1459 // it must be waiting to hold the queue lock 1460 // so initialize the IRPs listEntry 1461 InitializeListHead(listEntry); 1462 1463 } 1464 1465 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 1466 1467 } 1468 1469 else 1470 { 1471 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 1472 if(FailRequests == DeviceExtension->QueueState) 1473 { 1474 nextIrp->IoStatus.Information = 0; 1475 nextIrp->IoStatus.Status = STATUS_DELETE_PENDING; 1476 IoCompleteRequest(nextIrp, IO_NO_INCREMENT); 1477 1478 } 1479 1480 else 1481 { 1482 //PIO_STACK_LOCATION irpStack; 1483 1484 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests::")); 1485 FreeBT_IoIncrement(DeviceExtension); 1486 1487 IoSkipCurrentIrpStackLocation(nextIrp); 1488 IoCallDriver(DeviceExtension->TopOfStackDeviceObject, nextIrp); 1489 1490 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests::")); 1491 FreeBT_IoDecrement(DeviceExtension); 1492 1493 } 1494 1495 } 1496 1497 } 1498 1499 while(!IsListEmpty(&cancelledIrpList)) 1500 { 1501 PLIST_ENTRY cancelEntry = RemoveHeadList(&cancelledIrpList); 1502 1503 cancelledIrp = CONTAINING_RECORD(cancelEntry, IRP, Tail.Overlay.ListEntry); 1504 cancelledIrp->IoStatus.Status = STATUS_CANCELLED; 1505 cancelledIrp->IoStatus.Information = 0; 1506 1507 IoCompleteRequest(cancelledIrp, IO_NO_INCREMENT); 1508 1509 } 1510 1511 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests: Leaving\n")); 1512 1513 return; 1514 1515 } 1516 1517 NTSTATUS NTAPI FreeBT_GetRegistryDword(IN PWCHAR RegPath, IN PWCHAR ValueName, IN OUT PULONG Value) 1518 { 1519 ULONG defaultData; 1520 WCHAR buffer[MAXIMUM_FILENAME_LENGTH]; 1521 NTSTATUS ntStatus; 1522 UNICODE_STRING regPath; 1523 RTL_QUERY_REGISTRY_TABLE paramTable[2]; 1524 1525 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Entered\n")); 1526 1527 regPath.Length = 0; 1528 regPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); 1529 regPath.Buffer = buffer; 1530 1531 RtlZeroMemory(regPath.Buffer, regPath.MaximumLength); 1532 RtlMoveMemory(regPath.Buffer, RegPath, wcslen(RegPath) * sizeof(WCHAR)); 1533 RtlZeroMemory(paramTable, sizeof(paramTable)); 1534 1535 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 1536 paramTable[0].Name = ValueName; 1537 paramTable[0].EntryContext = Value; 1538 paramTable[0].DefaultType = REG_DWORD; 1539 paramTable[0].DefaultData = &defaultData; 1540 paramTable[0].DefaultLength = sizeof(ULONG); 1541 1542 ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | 1543 RTL_REGISTRY_OPTIONAL, 1544 regPath.Buffer, 1545 paramTable, 1546 NULL, 1547 NULL); 1548 1549 if (NT_SUCCESS(ntStatus)) 1550 { 1551 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Success, Value = %X\n", *Value)); 1552 return STATUS_SUCCESS; 1553 } 1554 1555 else 1556 { 1557 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Failed\n")); 1558 *Value = 0; 1559 return STATUS_UNSUCCESSFUL; 1560 1561 } 1562 } 1563 1564 1565 NTSTATUS NTAPI FreeBT_DispatchClean(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1566 { 1567 PDEVICE_EXTENSION deviceExtension; 1568 KIRQL oldIrql; 1569 LIST_ENTRY cleanupList; 1570 PLIST_ENTRY thisEntry, 1571 nextEntry, 1572 listHead; 1573 PIRP pendingIrp; 1574 PIO_STACK_LOCATION pendingIrpStack, 1575 irpStack; 1576 //NTSTATUS ntStatus; 1577 1578 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1579 irpStack = IoGetCurrentIrpStackLocation(Irp); 1580 InitializeListHead(&cleanupList); 1581 1582 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchClean::")); 1583 FreeBT_IoIncrement(deviceExtension); 1584 1585 KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql); 1586 1587 listHead = &deviceExtension->NewRequestsQueue; 1588 for(thisEntry = listHead->Flink, nextEntry = thisEntry->Flink; 1589 thisEntry != listHead; 1590 thisEntry = nextEntry, nextEntry = thisEntry->Flink) 1591 { 1592 pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry); 1593 pendingIrpStack = IoGetCurrentIrpStackLocation(pendingIrp); 1594 if (irpStack->FileObject == pendingIrpStack->FileObject) 1595 { 1596 RemoveEntryList(thisEntry); 1597 1598 if (NULL == IoSetCancelRoutine(pendingIrp, NULL)) 1599 { 1600 InitializeListHead(thisEntry); 1601 1602 } 1603 1604 else 1605 { 1606 InsertTailList(&cleanupList, thisEntry); 1607 1608 } 1609 1610 } 1611 1612 } 1613 1614 KeReleaseSpinLock(&deviceExtension->QueueLock, oldIrql); 1615 1616 while(!IsListEmpty(&cleanupList)) 1617 { 1618 thisEntry = RemoveHeadList(&cleanupList); 1619 pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry); 1620 1621 pendingIrp->IoStatus.Information = 0; 1622 pendingIrp->IoStatus.Status = STATUS_CANCELLED; 1623 IoCompleteRequest(pendingIrp, IO_NO_INCREMENT); 1624 1625 } 1626 1627 Irp->IoStatus.Information = 0; 1628 Irp->IoStatus.Status = STATUS_SUCCESS; 1629 1630 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1631 1632 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchClean::")); 1633 FreeBT_IoDecrement(deviceExtension); 1634 1635 return STATUS_SUCCESS; 1636 1637 } 1638 1639 1640 BOOLEAN NTAPI CanDeviceSuspend(IN PDEVICE_EXTENSION DeviceExtension) 1641 { 1642 FreeBT_DbgPrint(3, ("FBTUSB: CanDeviceSuspend: Entered\n")); 1643 1644 if ((DeviceExtension->OpenHandleCount == 0) && (DeviceExtension->OutStandingIO == 1)) 1645 return TRUE; 1646 1647 return FALSE; 1648 1649 } 1650 1651 NTSTATUS NTAPI FreeBT_AbortPipes(IN PDEVICE_OBJECT DeviceObject) 1652 { 1653 PURB urb; 1654 ULONG i; 1655 NTSTATUS ntStatus; 1656 PDEVICE_EXTENSION deviceExtension; 1657 PFREEBT_PIPE_CONTEXT pipeContext; 1658 //PUSBD_PIPE_INFORMATION pipeInformation; 1659 PUSBD_INTERFACE_INFORMATION interfaceInfo; 1660 1661 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1662 pipeContext = deviceExtension->PipeContext; 1663 interfaceInfo = deviceExtension->UsbInterface; 1664 1665 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Entered\n")); 1666 1667 if(interfaceInfo == NULL || pipeContext == NULL) 1668 return STATUS_SUCCESS; 1669 1670 for(i=0; i<interfaceInfo->NumberOfPipes; i++) 1671 { 1672 if(pipeContext[i].PipeOpen) 1673 { 1674 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Aborting open pipe %d\n", i)); 1675 1676 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); 1677 if (urb) 1678 { 1679 urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST); 1680 urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE; 1681 urb->UrbPipeRequest.PipeHandle = interfaceInfo->Pipes[i].PipeHandle; 1682 1683 ntStatus = CallUSBD(DeviceObject, urb); 1684 1685 ExFreePool(urb); 1686 1687 } 1688 1689 else 1690 { 1691 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_AbortPipes: Failed to alloc memory for urb\n")); 1692 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 1693 return ntStatus; 1694 1695 } 1696 1697 if(NT_SUCCESS(ntStatus)) 1698 pipeContext[i].PipeOpen = FALSE; 1699 1700 1701 } 1702 1703 } 1704 1705 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Leaving\n")); 1706 1707 return STATUS_SUCCESS; 1708 1709 } 1710 1711 // Completion routine for PNP IRPs 1712 NTSTATUS NTAPI IrpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) 1713 { 1714 PKEVENT event = (PKEVENT) Context; 1715 KeSetEvent(event, 0, FALSE); 1716 1717 return STATUS_MORE_PROCESSING_REQUIRED; 1718 1719 } 1720 1721 1722 LONG NTAPI FreeBT_IoIncrement(IN OUT PDEVICE_EXTENSION DeviceExtension) 1723 { 1724 LONG result = 0; 1725 KIRQL oldIrql; 1726 1727 KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql); 1728 result = InterlockedIncrement((PLONG)(&DeviceExtension->OutStandingIO)); 1729 1730 // When OutStandingIO bumps from 1 to 2, clear the StopEvent 1731 if (result == 2) 1732 KeClearEvent(&DeviceExtension->StopEvent); 1733 1734 KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql); 1735 1736 FreeBT_DbgPrint(3, ("FreeBT_IoIncrement::%d\n", result)); 1737 1738 return result; 1739 1740 } 1741 1742 LONG NTAPI FreeBT_IoDecrement(IN OUT PDEVICE_EXTENSION DeviceExtension) 1743 { 1744 LONG result = 0; 1745 KIRQL oldIrql; 1746 1747 KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql); 1748 1749 result = InterlockedDecrement((PLONG)(&DeviceExtension->OutStandingIO)); 1750 1751 if (result == 1) 1752 KeSetEvent(&DeviceExtension->StopEvent, IO_NO_INCREMENT, FALSE); 1753 1754 if(result == 0) 1755 { 1756 ASSERT(Removed == DeviceExtension->DeviceState); 1757 KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE); 1758 1759 } 1760 1761 KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql); 1762 1763 FreeBT_DbgPrint(3, ("FreeBT_IoDecrement::%d\n", result)); 1764 1765 return result; 1766 1767 } 1768 1769 NTSTATUS NTAPI CanStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1770 { 1771 // For the time being, just allow it to be stopped 1772 UNREFERENCED_PARAMETER(DeviceObject); 1773 UNREFERENCED_PARAMETER(Irp); 1774 1775 return STATUS_SUCCESS; 1776 1777 } 1778 1779 NTSTATUS NTAPI CanRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 1780 1781 { 1782 // For the time being, just allow it to be removed 1783 UNREFERENCED_PARAMETER(DeviceObject); 1784 UNREFERENCED_PARAMETER(Irp); 1785 1786 return STATUS_SUCCESS; 1787 1788 } 1789 1790 NTSTATUS NTAPI ReleaseMemory(IN PDEVICE_OBJECT DeviceObject) 1791 { 1792 // Disconnect from the interrupt and unmap any I/O ports 1793 PDEVICE_EXTENSION deviceExtension; 1794 UNICODE_STRING uniDeviceName; 1795 NTSTATUS ntStatus; 1796 1797 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 1798 if (deviceExtension->UsbConfigurationDescriptor) 1799 { 1800 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing UsbConfigurationDescriptor\n")); 1801 ExFreePool(deviceExtension->UsbConfigurationDescriptor); 1802 deviceExtension->UsbConfigurationDescriptor = NULL; 1803 1804 } 1805 1806 if(deviceExtension->UsbInterface) 1807 { 1808 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing UsbInterface\n")); 1809 ExFreePool(deviceExtension->UsbInterface); 1810 deviceExtension->UsbInterface = NULL; 1811 1812 } 1813 1814 if(deviceExtension->PipeContext) 1815 { 1816 RtlInitUnicodeString(&uniDeviceName, deviceExtension->wszDosDeviceName); 1817 ntStatus = IoDeleteSymbolicLink(&uniDeviceName); 1818 if (!NT_SUCCESS(ntStatus)) 1819 FreeBT_DbgPrint(3, ("FBTUSB: Failed to delete symbolic link %ws\n", deviceExtension->wszDosDeviceName)); 1820 1821 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing PipeContext %p\n", deviceExtension->PipeContext)); 1822 ExFreePool(deviceExtension->PipeContext); 1823 deviceExtension->PipeContext = NULL; 1824 1825 } 1826 1827 return STATUS_SUCCESS; 1828 1829 } 1830 1831 PCHAR NTAPI PnPMinorFunctionString (UCHAR MinorFunction) 1832 { 1833 switch (MinorFunction) 1834 { 1835 case IRP_MN_START_DEVICE: 1836 return "IRP_MN_START_DEVICE\n"; 1837 1838 case IRP_MN_QUERY_REMOVE_DEVICE: 1839 return "IRP_MN_QUERY_REMOVE_DEVICE\n"; 1840 1841 case IRP_MN_REMOVE_DEVICE: 1842 return "IRP_MN_REMOVE_DEVICE\n"; 1843 1844 case IRP_MN_CANCEL_REMOVE_DEVICE: 1845 return "IRP_MN_CANCEL_REMOVE_DEVICE\n"; 1846 1847 case IRP_MN_STOP_DEVICE: 1848 return "IRP_MN_STOP_DEVICE\n"; 1849 1850 case IRP_MN_QUERY_STOP_DEVICE: 1851 return "IRP_MN_QUERY_STOP_DEVICE\n"; 1852 1853 case IRP_MN_CANCEL_STOP_DEVICE: 1854 return "IRP_MN_CANCEL_STOP_DEVICE\n"; 1855 1856 case IRP_MN_QUERY_DEVICE_RELATIONS: 1857 return "IRP_MN_QUERY_DEVICE_RELATIONS\n"; 1858 1859 case IRP_MN_QUERY_INTERFACE: 1860 return "IRP_MN_QUERY_INTERFACE\n"; 1861 1862 case IRP_MN_QUERY_CAPABILITIES: 1863 return "IRP_MN_QUERY_CAPABILITIES\n"; 1864 1865 case IRP_MN_QUERY_RESOURCES: 1866 return "IRP_MN_QUERY_RESOURCES\n"; 1867 1868 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 1869 return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"; 1870 1871 case IRP_MN_QUERY_DEVICE_TEXT: 1872 return "IRP_MN_QUERY_DEVICE_TEXT\n"; 1873 1874 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 1875 return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"; 1876 1877 case IRP_MN_READ_CONFIG: 1878 return "IRP_MN_READ_CONFIG\n"; 1879 1880 case IRP_MN_WRITE_CONFIG: 1881 return "IRP_MN_WRITE_CONFIG\n"; 1882 1883 case IRP_MN_EJECT: 1884 return "IRP_MN_EJECT\n"; 1885 1886 case IRP_MN_SET_LOCK: 1887 return "IRP_MN_SET_LOCK\n"; 1888 1889 case IRP_MN_QUERY_ID: 1890 return "IRP_MN_QUERY_ID\n"; 1891 1892 case IRP_MN_QUERY_PNP_DEVICE_STATE: 1893 return "IRP_MN_QUERY_PNP_DEVICE_STATE\n"; 1894 1895 case IRP_MN_QUERY_BUS_INFORMATION: 1896 return "IRP_MN_QUERY_BUS_INFORMATION\n"; 1897 1898 case IRP_MN_DEVICE_USAGE_NOTIFICATION: 1899 return "IRP_MN_DEVICE_USAGE_NOTIFICATION\n"; 1900 1901 case IRP_MN_SURPRISE_REMOVAL: 1902 return "IRP_MN_SURPRISE_REMOVAL\n"; 1903 1904 default: 1905 return "IRP_MN_?????\n"; 1906 1907 } 1908 1909 } 1910 1911