Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfbtpnp.c
Go to the documentation of this file.
00001 // Copyright (c) 2004, Antony C. Roberts 00002 00003 // Use of this file is subject to the terms 00004 // described in the LICENSE.TXT file that 00005 // accompanies this file. 00006 // 00007 // Your use of this file indicates your 00008 // acceptance of the terms described in 00009 // LICENSE.TXT. 00010 // 00011 // http://www.freebt.net 00012 00013 #include "stdio.h" 00014 #include "fbtusb.h" 00015 #include "fbtpnp.h" 00016 #include "fbtpwr.h" 00017 #include "fbtdev.h" 00018 #include "fbtrwr.h" 00019 #include "fbtwmi.h" 00020 00021 #include "fbtusr.h" 00022 00023 // Handle PNP events 00024 NTSTATUS FreeBT_DispatchPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00025 { 00026 PIO_STACK_LOCATION irpStack; 00027 PDEVICE_EXTENSION deviceExtension; 00028 //KEVENT startDeviceEvent; 00029 NTSTATUS ntStatus; 00030 00031 irpStack = IoGetCurrentIrpStackLocation(Irp); 00032 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00033 00034 // since the device is removed, fail the Irp. 00035 if (Removed == deviceExtension->DeviceState) 00036 { 00037 ntStatus = STATUS_DELETE_PENDING; 00038 Irp->IoStatus.Status = ntStatus; 00039 Irp->IoStatus.Information = 0; 00040 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00041 return ntStatus; 00042 00043 } 00044 00045 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 00046 FreeBT_IoIncrement(deviceExtension); 00047 if (irpStack->MinorFunction == IRP_MN_START_DEVICE) 00048 { 00049 ASSERT(deviceExtension->IdleReqPend == 0); 00050 00051 } 00052 00053 else 00054 { 00055 if (deviceExtension->SSEnable) 00056 { 00057 CancelSelectSuspend(deviceExtension); 00058 00059 } 00060 00061 } 00062 00063 FreeBT_DbgPrint(3, ("FBTUSB: ///////////////////////////////////////////\n")); 00064 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 00065 FreeBT_DbgPrint(2, (PnPMinorFunctionString(irpStack->MinorFunction))); 00066 switch (irpStack->MinorFunction) 00067 { 00068 case IRP_MN_START_DEVICE: 00069 ntStatus = HandleStartDevice(DeviceObject, Irp); 00070 break; 00071 00072 case IRP_MN_QUERY_STOP_DEVICE: 00073 // if we cannot stop the device, we fail the query stop irp 00074 ntStatus = CanStopDevice(DeviceObject, Irp); 00075 if(NT_SUCCESS(ntStatus)) 00076 { 00077 ntStatus = HandleQueryStopDevice(DeviceObject, Irp); 00078 return ntStatus; 00079 00080 } 00081 00082 break; 00083 00084 case IRP_MN_CANCEL_STOP_DEVICE: 00085 ntStatus = HandleCancelStopDevice(DeviceObject, Irp); 00086 break; 00087 00088 case IRP_MN_STOP_DEVICE: 00089 ntStatus = HandleStopDevice(DeviceObject, Irp); 00090 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::IRP_MN_STOP_DEVICE::")); 00091 FreeBT_IoDecrement(deviceExtension); 00092 00093 return ntStatus; 00094 00095 case IRP_MN_QUERY_REMOVE_DEVICE: 00096 // if we cannot remove the device, we fail the query remove irp 00097 ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp); 00098 00099 return ntStatus; 00100 00101 case IRP_MN_CANCEL_REMOVE_DEVICE: 00102 ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp); 00103 break; 00104 00105 case IRP_MN_SURPRISE_REMOVAL: 00106 ntStatus = HandleSurpriseRemoval(DeviceObject, Irp); 00107 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::")); 00108 FreeBT_IoDecrement(deviceExtension); 00109 return ntStatus; 00110 00111 case IRP_MN_REMOVE_DEVICE: 00112 ntStatus = HandleRemoveDevice(DeviceObject, Irp); 00113 return ntStatus; 00114 00115 case IRP_MN_QUERY_CAPABILITIES: 00116 ntStatus = HandleQueryCapabilities(DeviceObject, Irp); 00117 break; 00118 00119 default: 00120 IoSkipCurrentIrpStackLocation(Irp); 00121 00122 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00123 00124 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::default::")); 00125 FreeBT_IoDecrement(deviceExtension); 00126 00127 return ntStatus; 00128 00129 } 00130 00131 Irp->IoStatus.Status = ntStatus; 00132 Irp->IoStatus.Information = 0; 00133 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00134 00135 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPnP::")); 00136 FreeBT_IoDecrement(deviceExtension); 00137 00138 return ntStatus; 00139 00140 } 00141 00142 NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00143 { 00144 KIRQL oldIrql; 00145 KEVENT startDeviceEvent; 00146 NTSTATUS ntStatus; 00147 PDEVICE_EXTENSION deviceExtension; 00148 LARGE_INTEGER dueTime; 00149 00150 FreeBT_DbgPrint(3, ("FBTUSB: HandleStartDevice: Entered\n")); 00151 00152 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00153 deviceExtension->UsbConfigurationDescriptor = NULL; 00154 deviceExtension->UsbInterface = NULL; 00155 deviceExtension->PipeContext = NULL; 00156 00157 // We cannot touch the device (send it any non pnp irps) until a 00158 // start device has been passed down to the lower drivers. 00159 // first pass the Irp down 00160 KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE); 00161 IoCopyCurrentIrpStackLocationToNext(Irp); 00162 IoSetCompletionRoutine(Irp, 00163 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 00164 (PVOID)&startDeviceEvent, 00165 TRUE, 00166 TRUE, 00167 TRUE); 00168 00169 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00170 if (ntStatus == STATUS_PENDING) 00171 { 00172 KeWaitForSingleObject(&startDeviceEvent, Executive, KernelMode, FALSE, NULL); 00173 ntStatus = Irp->IoStatus.Status; 00174 00175 } 00176 00177 if (!NT_SUCCESS(ntStatus)) 00178 { 00179 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: Lower drivers failed this Irp (0x%08x)\n", ntStatus)); 00180 return ntStatus; 00181 00182 } 00183 00184 // Read the device descriptor, configuration descriptor 00185 // and select the interface descriptors 00186 ntStatus = ReadandSelectDescriptors(DeviceObject); 00187 if (!NT_SUCCESS(ntStatus)) 00188 { 00189 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: ReadandSelectDescriptors failed (0x%08x)\n", ntStatus)); 00190 return ntStatus; 00191 00192 } 00193 00194 // enable the symbolic links for system components to open 00195 // handles to the device 00196 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, TRUE); 00197 if (!NT_SUCCESS(ntStatus)) 00198 { 00199 FreeBT_DbgPrint(1, ("FBTUSB: HandleStartDevice: IoSetDeviceInterfaceState failed (0x%08x)\n", ntStatus)); 00200 return ntStatus; 00201 00202 } 00203 00204 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 00205 00206 SET_NEW_PNP_STATE(deviceExtension, Working); 00207 deviceExtension->QueueState = AllowRequests; 00208 00209 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 00210 00211 deviceExtension->FlagWWOutstanding = 0; 00212 deviceExtension->FlagWWCancel = 0; 00213 deviceExtension->WaitWakeIrp = NULL; 00214 00215 if (deviceExtension->WaitWakeEnable) 00216 { 00217 IssueWaitWake(deviceExtension); 00218 00219 } 00220 00221 ProcessQueuedRequests(deviceExtension); 00222 if (WinXpOrBetter == deviceExtension->WdmVersion) 00223 { 00224 deviceExtension->SSEnable = deviceExtension->SSRegistryEnable; 00225 00226 // set timer.for selective suspend requests 00227 if (deviceExtension->SSEnable) 00228 { 00229 dueTime.QuadPart = -10000 * IDLE_INTERVAL; // 5000 ms 00230 KeSetTimerEx(&deviceExtension->Timer, dueTime, IDLE_INTERVAL, &deviceExtension->DeferredProcCall); 00231 deviceExtension->FreeIdleIrpCount = 0; 00232 00233 } 00234 00235 } 00236 00237 FreeBT_DbgPrint(3, ("FBTUSB: HandleStartDevice: Leaving\n")); 00238 00239 return ntStatus; 00240 00241 } 00242 00243 00244 NTSTATUS ReadandSelectDescriptors(IN PDEVICE_OBJECT DeviceObject) 00245 { 00246 PURB urb; 00247 ULONG siz; 00248 NTSTATUS ntStatus; 00249 PUSB_DEVICE_DESCRIPTOR deviceDescriptor; 00250 00251 urb = NULL; 00252 deviceDescriptor = NULL; 00253 00254 // 1. Read the device descriptor 00255 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 00256 if(urb) 00257 { 00258 siz = sizeof(USB_DEVICE_DESCRIPTOR); 00259 deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 00260 if (deviceDescriptor) 00261 { 00262 UsbBuildGetDescriptorRequest( 00263 urb, 00264 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 00265 USB_DEVICE_DESCRIPTOR_TYPE, 00266 0, 00267 0, 00268 deviceDescriptor, 00269 NULL, 00270 siz, 00271 NULL); 00272 00273 ntStatus = CallUSBD(DeviceObject, urb); 00274 if (NT_SUCCESS(ntStatus)) 00275 { 00276 ASSERT(deviceDescriptor->bNumConfigurations); 00277 ntStatus = ConfigureDevice(DeviceObject); 00278 00279 } 00280 00281 ExFreePool(urb); 00282 ExFreePool(deviceDescriptor); 00283 00284 } 00285 00286 else 00287 { 00288 FreeBT_DbgPrint(1, ("FBTUSB: ReadandSelectDescriptors: Failed to allocate memory for deviceDescriptor")); 00289 ExFreePool(urb); 00290 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00291 00292 } 00293 00294 } 00295 00296 else 00297 { 00298 FreeBT_DbgPrint(1, ("FBTUSB: ReadandSelectDescriptors: Failed to allocate memory for urb")); 00299 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00300 00301 } 00302 00303 00304 return ntStatus; 00305 00306 } 00307 00308 NTSTATUS ConfigureDevice(IN PDEVICE_OBJECT DeviceObject) 00309 { 00310 PURB urb; 00311 ULONG siz; 00312 NTSTATUS ntStatus; 00313 PDEVICE_EXTENSION deviceExtension; 00314 PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor; 00315 00316 urb = NULL; 00317 configurationDescriptor = NULL; 00318 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00319 00320 // Read the first configuration descriptor 00321 // This requires two steps: 00322 // 1. Read the fixed sized configuration desciptor (CD) 00323 // 2. Read the CD with all embedded interface and endpoint descriptors 00324 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 00325 if (urb) 00326 { 00327 siz = sizeof(USB_CONFIGURATION_DESCRIPTOR); 00328 configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 00329 00330 if(configurationDescriptor) 00331 { 00332 UsbBuildGetDescriptorRequest( 00333 urb, 00334 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 00335 USB_CONFIGURATION_DESCRIPTOR_TYPE, 00336 0, 00337 0, 00338 configurationDescriptor, 00339 NULL, 00340 sizeof(USB_CONFIGURATION_DESCRIPTOR), 00341 NULL); 00342 00343 ntStatus = CallUSBD(DeviceObject, urb); 00344 if(!NT_SUCCESS(ntStatus)) 00345 { 00346 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: UsbBuildGetDescriptorRequest failed\n")); 00347 goto ConfigureDevice_Exit; 00348 00349 } 00350 00351 } 00352 00353 else 00354 { 00355 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to allocate mem for config Descriptor\n")); 00356 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00357 goto ConfigureDevice_Exit; 00358 00359 } 00360 00361 siz = configurationDescriptor->wTotalLength; 00362 ExFreePool(configurationDescriptor); 00363 00364 configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePool(NonPagedPool, siz); 00365 if (configurationDescriptor) 00366 { 00367 UsbBuildGetDescriptorRequest( 00368 urb, 00369 (USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), 00370 USB_CONFIGURATION_DESCRIPTOR_TYPE, 00371 0, 00372 0, 00373 configurationDescriptor, 00374 NULL, 00375 siz, 00376 NULL); 00377 00378 ntStatus = CallUSBD(DeviceObject, urb); 00379 if (!NT_SUCCESS(ntStatus)) 00380 { 00381 FreeBT_DbgPrint(1,("FBTUSB: ConfigureDevice: Failed to read configuration descriptor")); 00382 goto ConfigureDevice_Exit; 00383 00384 } 00385 00386 } 00387 00388 else 00389 { 00390 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to alloc mem for config Descriptor\n")); 00391 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00392 goto ConfigureDevice_Exit; 00393 00394 } 00395 00396 } 00397 00398 else 00399 { 00400 FreeBT_DbgPrint(1, ("FBTUSB: ConfigureDevice: Failed to allocate memory for urb\n")); 00401 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00402 goto ConfigureDevice_Exit; 00403 00404 } 00405 00406 if (configurationDescriptor) 00407 { 00408 // save a copy of configurationDescriptor in deviceExtension 00409 // remember to free it later. 00410 deviceExtension->UsbConfigurationDescriptor = configurationDescriptor; 00411 00412 if (configurationDescriptor->bmAttributes & REMOTE_WAKEUP_MASK) 00413 { 00414 // this configuration supports remote wakeup 00415 deviceExtension->WaitWakeEnable = 1; 00416 00417 } 00418 00419 else 00420 { 00421 deviceExtension->WaitWakeEnable = 0; 00422 00423 } 00424 00425 ntStatus = SelectInterfaces(DeviceObject, configurationDescriptor); 00426 00427 } 00428 00429 else 00430 { 00431 deviceExtension->UsbConfigurationDescriptor = NULL; 00432 00433 } 00434 00435 ConfigureDevice_Exit: 00436 if (urb) 00437 { 00438 ExFreePool(urb); 00439 00440 } 00441 00442 return ntStatus; 00443 00444 } 00445 00446 NTSTATUS SelectInterfaces(IN PDEVICE_OBJECT DeviceObject, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) 00447 { 00448 LONG numberOfInterfaces, interfaceNumber, interfaceindex; 00449 ULONG i; 00450 PURB urb; 00451 //PUCHAR pInf; 00452 NTSTATUS ntStatus; 00453 PDEVICE_EXTENSION deviceExtension; 00454 PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor; 00455 PUSBD_INTERFACE_LIST_ENTRY interfaceList, 00456 tmp; 00457 PUSBD_INTERFACE_INFORMATION Interface; 00458 00459 urb = NULL; 00460 Interface = NULL; 00461 interfaceDescriptor = NULL; 00462 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00463 numberOfInterfaces = ConfigurationDescriptor->bNumInterfaces; 00464 interfaceindex = interfaceNumber = 0; 00465 00466 // Parse the configuration descriptor for the interface; 00467 tmp = interfaceList = (PUSBD_INTERFACE_LIST_ENTRY) 00468 ExAllocatePool(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (numberOfInterfaces + 1)); 00469 00470 if (!tmp) 00471 { 00472 00473 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Failed to allocate mem for interfaceList\n")); 00474 return STATUS_INSUFFICIENT_RESOURCES; 00475 00476 } 00477 00478 00479 FreeBT_DbgPrint(3, ("FBTUSB: -------------\n")); 00480 FreeBT_DbgPrint(3, ("FBTUSB: Number of interfaces %d\n", numberOfInterfaces)); 00481 00482 while (interfaceNumber < numberOfInterfaces) 00483 { 00484 interfaceDescriptor = USBD_ParseConfigurationDescriptorEx( 00485 ConfigurationDescriptor, 00486 ConfigurationDescriptor, 00487 interfaceindex, 00488 0, -1, -1, -1); 00489 00490 if (interfaceDescriptor) 00491 { 00492 interfaceList->InterfaceDescriptor = interfaceDescriptor; 00493 interfaceList->Interface = NULL; 00494 interfaceList++; 00495 interfaceNumber++; 00496 00497 } 00498 00499 interfaceindex++; 00500 00501 } 00502 00503 interfaceList->InterfaceDescriptor = NULL; 00504 interfaceList->Interface = NULL; 00505 urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, tmp); 00506 00507 if (urb) 00508 { 00509 Interface = &urb->UrbSelectConfiguration.Interface; 00510 for (i=0; i<Interface->NumberOfPipes; i++) 00511 { 00512 // perform pipe initialization here 00513 // set the transfer size and any pipe flags we use 00514 // USBD sets the rest of the Interface struct members 00515 Interface->Pipes[i].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; 00516 00517 } 00518 00519 ntStatus = CallUSBD(DeviceObject, urb); 00520 if (NT_SUCCESS(ntStatus)) 00521 { 00522 // save a copy of interface information in the device extension. 00523 deviceExtension->UsbInterface = (PUSBD_INTERFACE_INFORMATION) ExAllocatePool(NonPagedPool, Interface->Length); 00524 if (deviceExtension->UsbInterface) 00525 { 00526 RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length); 00527 00528 } 00529 00530 else 00531 { 00532 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00533 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Memory alloc for UsbInterface failed\n")); 00534 00535 } 00536 00537 // Dump the interface to the debugger 00538 Interface = &urb->UrbSelectConfiguration.Interface; 00539 00540 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 00541 FreeBT_DbgPrint(3, ("FBTUSB: NumberOfPipes 0x%x\n", Interface->NumberOfPipes)); 00542 FreeBT_DbgPrint(3, ("FBTUSB: Length 0x%x\n", Interface->Length)); 00543 FreeBT_DbgPrint(3, ("FBTUSB: Alt Setting 0x%x\n", Interface->AlternateSetting)); 00544 FreeBT_DbgPrint(3, ("FBTUSB: Interface Number 0x%x\n", Interface->InterfaceNumber)); 00545 FreeBT_DbgPrint(3, ("FBTUSB: Class, subclass, protocol 0x%x 0x%x 0x%x\n", 00546 Interface->Class, 00547 Interface->SubClass, 00548 Interface->Protocol)); 00549 00550 if (Interface->Class==FREEBT_USB_STDCLASS && Interface->SubClass==FREEBT_USB_STDSUBCLASS && 00551 Interface->Protocol==FREEBT_USB_STDPROTOCOL) 00552 { 00553 FreeBT_DbgPrint(3, ("FBTUSB: This is a standard USB Bluetooth device\n")); 00554 00555 } 00556 00557 else 00558 { 00559 FreeBT_DbgPrint(3, ("FBTUSB: WARNING: This device does not report itself as a standard USB Bluetooth device\n")); 00560 00561 } 00562 00563 // Initialize the PipeContext 00564 // Dump the pipe info 00565 deviceExtension->PipeContext = (PFREEBT_PIPE_CONTEXT) ExAllocatePool( 00566 NonPagedPool, 00567 Interface->NumberOfPipes * 00568 sizeof(FREEBT_PIPE_CONTEXT)); 00569 00570 if (!deviceExtension->PipeContext) 00571 { 00572 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00573 FreeBT_DbgPrint(1, ("FBTUSB: Memory alloc for UsbInterface failed\n")); 00574 00575 } 00576 00577 else 00578 { 00579 FreeBT_DbgPrint(3, ("FBTUSB: SelectInterfaces: Allocated PipeContext %p\n", deviceExtension->PipeContext)); 00580 for (i=0; i<Interface->NumberOfPipes; i++) 00581 { 00582 deviceExtension->PipeContext[i].PipeOpen = FALSE; 00583 00584 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 00585 FreeBT_DbgPrint(3, ("FBTUSB: PipeType 0x%x\n", Interface->Pipes[i].PipeType)); 00586 FreeBT_DbgPrint(3, ("FBTUSB: EndpointAddress 0x%x\n", Interface->Pipes[i].EndpointAddress)); 00587 FreeBT_DbgPrint(3, ("FBTUSB: MaxPacketSize 0x%x\n", Interface->Pipes[i].MaximumPacketSize)); 00588 FreeBT_DbgPrint(3, ("FBTUSB: Interval 0x%x\n", Interface->Pipes[i].Interval)); 00589 FreeBT_DbgPrint(3, ("FBTUSB: Handle 0x%x\n", Interface->Pipes[i].PipeHandle)); 00590 FreeBT_DbgPrint(3, ("FBTUSB: MaximumTransferSize 0x%x\n", Interface->Pipes[i].MaximumTransferSize)); 00591 00592 // Log the pipes 00593 // Note the HCI Command endpoint won't appear here, because the Default Control Pipe 00594 // is used for this. The Default Control Pipe is always present at EndPointAddress 0x0 00595 switch (Interface->Pipes[i].EndpointAddress) 00596 { 00597 case FREEBT_STDENDPOINT_HCIEVENT: 00598 deviceExtension->PipeContext[i].PipeType=HciEventPipe; 00599 deviceExtension->EventPipe=Interface->Pipes[i]; 00600 FreeBT_DbgPrint(3, ("FBTUSB: HCI Event Endpoint\n")); 00601 break; 00602 00603 case FREEBT_STDENDPOINT_ACLIN: 00604 deviceExtension->PipeContext[i].PipeType=AclDataIn; 00605 deviceExtension->DataInPipe=Interface->Pipes[i]; 00606 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data In Endpoint\n")); 00607 break; 00608 00609 case FREEBT_STDENDPOINT_ACLOUT: 00610 deviceExtension->PipeContext[i].PipeType=AclDataOut; 00611 deviceExtension->DataOutPipe=Interface->Pipes[i]; 00612 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 00613 break; 00614 00615 case FREEBT_STDENDPOINT_AUDIOIN: 00616 deviceExtension->PipeContext[i].PipeType=SCODataIn; 00617 deviceExtension->AudioInPipe=Interface->Pipes[i]; 00618 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 00619 break; 00620 00621 case FREEBT_STDENDPOINT_AUDIOOUT: 00622 deviceExtension->PipeContext[i].PipeType=SCODataOut; 00623 deviceExtension->AudioOutPipe=Interface->Pipes[i]; 00624 FreeBT_DbgPrint(3, ("FBTUSB: ACL Data Out Endpoint\n")); 00625 break; 00626 00627 } 00628 00629 } 00630 00631 } 00632 00633 FreeBT_DbgPrint(3, ("FBTUSB: ---------\n")); 00634 00635 } 00636 00637 else 00638 { 00639 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: Failed to select an interface\n")); 00640 00641 } 00642 00643 } 00644 00645 else 00646 { 00647 FreeBT_DbgPrint(1, ("FBTUSB: SelectInterfaces: USBD_CreateConfigurationRequestEx failed\n")); 00648 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00649 00650 } 00651 00652 if (tmp) 00653 { 00654 ExFreePool(tmp); 00655 00656 } 00657 00658 if (urb) 00659 { 00660 ExFreePool(urb); 00661 00662 } 00663 00664 return ntStatus; 00665 } 00666 00667 00668 NTSTATUS DeconfigureDevice(IN PDEVICE_OBJECT DeviceObject) 00669 { 00670 PURB urb; 00671 ULONG siz; 00672 NTSTATUS ntStatus; 00673 00674 siz = sizeof(struct _URB_SELECT_CONFIGURATION); 00675 urb = (PURB) ExAllocatePool(NonPagedPool, siz); 00676 if (urb) 00677 { 00678 UsbBuildSelectConfigurationRequest(urb, (USHORT)siz, NULL); 00679 ntStatus = CallUSBD(DeviceObject, urb); 00680 if(!NT_SUCCESS(ntStatus)) 00681 { 00682 FreeBT_DbgPrint(3, ("FBTUSB: DeconfigureDevice: Failed to deconfigure device\n")); 00683 00684 } 00685 00686 ExFreePool(urb); 00687 00688 } 00689 00690 else 00691 { 00692 FreeBT_DbgPrint(1, ("FBTUSB: DeconfigureDevice: Failed to allocate urb\n")); 00693 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00694 00695 } 00696 00697 return ntStatus; 00698 00699 } 00700 00701 NTSTATUS CallUSBD(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb) 00702 { 00703 PIRP irp; 00704 KEVENT event; 00705 NTSTATUS ntStatus; 00706 IO_STATUS_BLOCK ioStatus; 00707 PIO_STACK_LOCATION nextStack; 00708 PDEVICE_EXTENSION deviceExtension; 00709 00710 irp = NULL; 00711 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00712 00713 KeInitializeEvent(&event, NotificationEvent, FALSE); 00714 irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, 00715 deviceExtension->TopOfStackDeviceObject, 00716 NULL, 00717 0, 00718 NULL, 00719 0, 00720 TRUE, 00721 &event, 00722 &ioStatus); 00723 00724 if (!irp) 00725 { 00726 FreeBT_DbgPrint(1, ("FBTUSB: CallUSBD: IoBuildDeviceIoControlRequest failed\n")); 00727 return STATUS_INSUFFICIENT_RESOURCES; 00728 00729 } 00730 00731 nextStack = IoGetNextIrpStackLocation(irp); 00732 ASSERT(nextStack != NULL); 00733 nextStack->Parameters.Others.Argument1 = Urb; 00734 00735 FreeBT_DbgPrint(3, ("FBTUSB: CallUSBD::")); 00736 FreeBT_IoIncrement(deviceExtension); 00737 00738 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp); 00739 if (ntStatus == STATUS_PENDING) 00740 { 00741 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 00742 ntStatus = ioStatus.Status; 00743 00744 } 00745 00746 FreeBT_DbgPrint(3, ("FBTUSB: CallUSBD::")); 00747 FreeBT_IoDecrement(deviceExtension); 00748 return ntStatus; 00749 00750 } 00751 00752 NTSTATUS HandleQueryStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00753 { 00754 KIRQL oldIrql; 00755 NTSTATUS ntStatus; 00756 PDEVICE_EXTENSION deviceExtension; 00757 00758 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice: Entered\n")); 00759 00760 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00761 00762 // If we can stop the device, we need to set the QueueState to 00763 // HoldRequests so further requests will be queued. 00764 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 00765 00766 SET_NEW_PNP_STATE(deviceExtension, PendingStop); 00767 deviceExtension->QueueState = HoldRequests; 00768 00769 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 00770 00771 // wait for the existing ones to be finished. 00772 // first, decrement this operation 00773 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice::")); 00774 FreeBT_IoDecrement(deviceExtension); 00775 00776 KeWaitForSingleObject(&deviceExtension->StopEvent, Executive, KernelMode, FALSE, NULL); 00777 00778 Irp->IoStatus.Status = STATUS_SUCCESS; 00779 Irp->IoStatus.Information = 0; 00780 00781 IoSkipCurrentIrpStackLocation(Irp); 00782 00783 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00784 00785 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryStopDevice: Leaving\n")); 00786 00787 return ntStatus; 00788 00789 } 00790 00791 NTSTATUS HandleCancelStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00792 { 00793 KIRQL oldIrql; 00794 KEVENT event; 00795 NTSTATUS ntStatus; 00796 PDEVICE_EXTENSION deviceExtension; 00797 00798 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelStopDevice: Entered\n")); 00799 00800 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00801 00802 // Send this IRP down and wait for it to come back. 00803 // Set the QueueState flag to AllowRequests, 00804 // and process all the previously queued up IRPs. 00805 00806 // First check to see whether you have received cancel-stop 00807 // without first receiving a query-stop. This could happen if someone 00808 // above us fails a query-stop and passes down the subsequent 00809 // cancel-stop. 00810 if(PendingStop == deviceExtension->DeviceState) 00811 { 00812 KeInitializeEvent(&event, NotificationEvent, FALSE); 00813 00814 IoCopyCurrentIrpStackLocationToNext(Irp); 00815 IoSetCompletionRoutine(Irp, 00816 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 00817 (PVOID)&event, 00818 TRUE, 00819 TRUE, 00820 TRUE); 00821 00822 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00823 if(ntStatus == STATUS_PENDING) 00824 { 00825 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 00826 ntStatus = Irp->IoStatus.Status; 00827 00828 } 00829 00830 if(NT_SUCCESS(ntStatus)) 00831 { 00832 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 00833 00834 RESTORE_PREVIOUS_PNP_STATE(deviceExtension); 00835 deviceExtension->QueueState = AllowRequests; 00836 ASSERT(deviceExtension->DeviceState == Working); 00837 00838 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 00839 00840 ProcessQueuedRequests(deviceExtension); 00841 00842 } 00843 00844 } 00845 00846 else 00847 { 00848 // spurious Irp 00849 ntStatus = STATUS_SUCCESS; 00850 00851 } 00852 00853 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelStopDevice: Leaving\n")); 00854 00855 return ntStatus; 00856 00857 } 00858 00859 NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00860 { 00861 KIRQL oldIrql; 00862 NTSTATUS ntStatus; 00863 PDEVICE_EXTENSION deviceExtension; 00864 00865 FreeBT_DbgPrint(3, ("FBTUSB: HandleStopDevice: Entered\n")); 00866 00867 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00868 if(WinXpOrBetter == deviceExtension->WdmVersion) 00869 { 00870 if(deviceExtension->SSEnable) 00871 { 00872 // Cancel the timer so that the DPCs are no longer fired. 00873 // Thus, we are making judicious usage of our resources. 00874 // we do not need DPCs because the device is stopping. 00875 // The timers are re-initialized while handling the start 00876 // device irp. 00877 KeCancelTimer(&deviceExtension->Timer); 00878 00879 // after the device is stopped, it can be surprise removed. 00880 // we set this to 0, so that we do not attempt to cancel 00881 // the timer while handling surprise remove or remove irps. 00882 // when we get the start device request, this flag will be 00883 // reinitialized. 00884 deviceExtension->SSEnable = 0; 00885 00886 // make sure that if a DPC was fired before we called cancel timer, 00887 // then the DPC and work-time have run to their completion 00888 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 00889 00890 // make sure that the selective suspend request has been completed. 00891 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 00892 00893 } 00894 00895 } 00896 00897 // after the stop Irp is sent to the lower driver object, 00898 // the driver must not send any more Irps down that touch 00899 // the device until another Start has occurred. 00900 if (deviceExtension->WaitWakeEnable) 00901 { 00902 CancelWaitWake(deviceExtension); 00903 00904 } 00905 00906 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 00907 00908 SET_NEW_PNP_STATE(deviceExtension, Stopped); 00909 00910 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 00911 00912 // This is the right place to actually give up all the resources used 00913 // This might include calls to IoDisconnectInterrupt, MmUnmapIoSpace, 00914 // etc. 00915 ReleaseMemory(DeviceObject); 00916 00917 ntStatus = DeconfigureDevice(DeviceObject); 00918 00919 Irp->IoStatus.Status = ntStatus; 00920 Irp->IoStatus.Information = 0; 00921 00922 IoSkipCurrentIrpStackLocation(Irp); 00923 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00924 00925 FreeBT_DbgPrint(3, ("FBTUSB: HandleStopDevice: Leaving\n")); 00926 00927 return ntStatus; 00928 00929 } 00930 00931 NTSTATUS HandleQueryRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00932 { 00933 KIRQL oldIrql; 00934 NTSTATUS ntStatus; 00935 PDEVICE_EXTENSION deviceExtension; 00936 00937 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice: Entered\n")); 00938 00939 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00940 00941 // If we can allow removal of the device, we should set the QueueState 00942 // to HoldRequests so further requests will be queued. This is required 00943 // so that we can process queued up requests in cancel-remove just in 00944 // case somebody else in the stack fails the query-remove. 00945 ntStatus = CanRemoveDevice(DeviceObject, Irp); 00946 00947 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 00948 00949 deviceExtension->QueueState = HoldRequests; 00950 SET_NEW_PNP_STATE(deviceExtension, PendingRemove); 00951 00952 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 00953 00954 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice::")); 00955 FreeBT_IoDecrement(deviceExtension); 00956 00957 // Wait for all the requests to be completed 00958 KeWaitForSingleObject(&deviceExtension->StopEvent, Executive, KernelMode, FALSE, NULL); 00959 00960 Irp->IoStatus.Status = STATUS_SUCCESS; 00961 Irp->IoStatus.Information = 0; 00962 00963 IoSkipCurrentIrpStackLocation(Irp); 00964 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00965 00966 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryRemoveDevice: Leaving\n")); 00967 00968 return ntStatus; 00969 00970 } 00971 00972 NTSTATUS HandleCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00973 { 00974 KIRQL oldIrql; 00975 KEVENT event; 00976 NTSTATUS ntStatus; 00977 PDEVICE_EXTENSION deviceExtension; 00978 00979 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelRemoveDevice: Entered\n")); 00980 00981 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00982 00983 // We need to reset the QueueState flag to ProcessRequest, 00984 // since the device resume its normal activities. 00985 00986 // First check to see whether you have received cancel-remove 00987 // without first receiving a query-remove. This could happen if 00988 // someone above us fails a query-remove and passes down the 00989 // subsequent cancel-remove. 00990 if(PendingRemove == deviceExtension->DeviceState) 00991 { 00992 00993 KeInitializeEvent(&event, NotificationEvent, FALSE); 00994 00995 IoCopyCurrentIrpStackLocationToNext(Irp); 00996 IoSetCompletionRoutine(Irp, 00997 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 00998 (PVOID)&event, 00999 TRUE, 01000 TRUE, 01001 TRUE); 01002 01003 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 01004 if(ntStatus == STATUS_PENDING) 01005 { 01006 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 01007 ntStatus = Irp->IoStatus.Status; 01008 01009 } 01010 01011 if (NT_SUCCESS(ntStatus)) 01012 { 01013 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 01014 01015 deviceExtension->QueueState = AllowRequests; 01016 RESTORE_PREVIOUS_PNP_STATE(deviceExtension); 01017 01018 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 01019 01020 // process the queued requests that arrive between 01021 // QUERY_REMOVE and CANCEL_REMOVE 01022 ProcessQueuedRequests(deviceExtension); 01023 01024 } 01025 01026 } 01027 01028 else 01029 { 01030 // spurious cancel-remove 01031 ntStatus = STATUS_SUCCESS; 01032 01033 } 01034 01035 FreeBT_DbgPrint(3, ("FBTUSB: HandleCancelRemoveDevice: Leaving\n")); 01036 01037 return ntStatus; 01038 01039 } 01040 01041 NTSTATUS HandleSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01042 { 01043 KIRQL oldIrql; 01044 NTSTATUS ntStatus; 01045 PDEVICE_EXTENSION deviceExtension; 01046 01047 FreeBT_DbgPrint(3, ("FBTUSB: HandleSurpriseRemoval: Entered\n")); 01048 01049 // initialize variables 01050 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01051 01052 // 1. fail pending requests 01053 // 2. return device and memory resources 01054 // 3. disable interfaces 01055 if(deviceExtension->WaitWakeEnable) 01056 { 01057 CancelWaitWake(deviceExtension); 01058 01059 } 01060 01061 01062 if (WinXpOrBetter == deviceExtension->WdmVersion) 01063 { 01064 if (deviceExtension->SSEnable) 01065 { 01066 // Cancel the timer so that the DPCs are no longer fired. 01067 // we do not need DPCs because the device has been surprise 01068 // removed 01069 KeCancelTimer(&deviceExtension->Timer); 01070 01071 deviceExtension->SSEnable = 0; 01072 01073 // make sure that if a DPC was fired before we called cancel timer, 01074 // then the DPC and work-time have run to their completion 01075 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 01076 01077 // make sure that the selective suspend request has been completed. 01078 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 01079 01080 } 01081 01082 } 01083 01084 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 01085 deviceExtension->QueueState = FailRequests; 01086 SET_NEW_PNP_STATE(deviceExtension, SurpriseRemoved); 01087 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 01088 01089 ProcessQueuedRequests(deviceExtension); 01090 01091 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE); 01092 if(!NT_SUCCESS(ntStatus)) 01093 { 01094 FreeBT_DbgPrint(1, ("FBTUSB: HandleSurpriseRemoval: IoSetDeviceInterfaceState::disable:failed\n")); 01095 01096 } 01097 01098 FreeBT_AbortPipes(DeviceObject); 01099 01100 Irp->IoStatus.Status = STATUS_SUCCESS; 01101 Irp->IoStatus.Information = 0; 01102 01103 IoSkipCurrentIrpStackLocation(Irp); 01104 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 01105 01106 FreeBT_DbgPrint(3, ("FBTUSB: HandleSurpriseRemoval: Leaving\n")); 01107 01108 return ntStatus; 01109 01110 } 01111 01112 NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01113 { 01114 KIRQL oldIrql; 01115 //KEVENT event; 01116 ULONG requestCount; 01117 NTSTATUS ntStatus; 01118 PDEVICE_EXTENSION deviceExtension; 01119 01120 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice: Entered\n")); 01121 01122 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01123 01124 // The Plug & Play system has dictated the removal of this device. We 01125 // have no choice but to detach and delete the device object. 01126 // (If we wanted to express an interest in preventing this removal, 01127 // we should have failed the query remove IRP). 01128 if(SurpriseRemoved != deviceExtension->DeviceState) 01129 { 01130 01131 // we are here after QUERY_REMOVE 01132 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 01133 deviceExtension->QueueState = FailRequests; 01134 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 01135 01136 if(deviceExtension->WaitWakeEnable) 01137 { 01138 CancelWaitWake(deviceExtension); 01139 01140 } 01141 01142 if(WinXpOrBetter == deviceExtension->WdmVersion) 01143 { 01144 if (deviceExtension->SSEnable) 01145 { 01146 // Cancel the timer so that the DPCs are no longer fired. 01147 // we do not need DPCs because the device has been removed 01148 KeCancelTimer(&deviceExtension->Timer); 01149 01150 deviceExtension->SSEnable = 0; 01151 01152 // make sure that if a DPC was fired before we called cancel timer, 01153 // then the DPC and work-time have run to their completion 01154 KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent, Executive, KernelMode, FALSE, NULL); 01155 01156 // make sure that the selective suspend request has been completed. 01157 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); 01158 01159 } 01160 01161 } 01162 01163 ProcessQueuedRequests(deviceExtension); 01164 01165 ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE); 01166 if(!NT_SUCCESS(ntStatus)) 01167 { 01168 FreeBT_DbgPrint(1, ("FBTUSB: HandleRemoveDevice: IoSetDeviceInterfaceState::disable:failed\n")); 01169 01170 } 01171 01172 FreeBT_AbortPipes(DeviceObject); 01173 01174 } 01175 01176 KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); 01177 SET_NEW_PNP_STATE(deviceExtension, Removed); 01178 KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); 01179 #ifdef ENABLE_WMI 01180 FreeBT_WmiDeRegistration(deviceExtension); 01181 #endif 01182 01183 // Need 2 decrements 01184 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice::")); 01185 requestCount = FreeBT_IoDecrement(deviceExtension); 01186 01187 ASSERT(requestCount > 0); 01188 01189 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice::")); 01190 requestCount = FreeBT_IoDecrement(deviceExtension); 01191 01192 KeWaitForSingleObject(&deviceExtension->RemoveEvent, 01193 Executive, 01194 KernelMode, 01195 FALSE, 01196 NULL); 01197 01198 ReleaseMemory(DeviceObject); 01199 01200 // We need to send the remove down the stack before we detach, 01201 // but we don't need to wait for the completion of this operation 01202 // (and to register a completion routine). 01203 Irp->IoStatus.Status = STATUS_SUCCESS; 01204 Irp->IoStatus.Information = 0; 01205 01206 IoSkipCurrentIrpStackLocation(Irp); 01207 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 01208 01209 IoDetachDevice(deviceExtension->TopOfStackDeviceObject); 01210 IoDeleteDevice(DeviceObject); 01211 01212 FreeBT_DbgPrint(3, ("FBTUSB: HandleRemoveDevice: Leaving\n")); 01213 01214 return ntStatus; 01215 01216 } 01217 01218 NTSTATUS HandleQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01219 { 01220 ULONG i; 01221 KEVENT event; 01222 NTSTATUS ntStatus; 01223 PDEVICE_EXTENSION deviceExtension; 01224 PDEVICE_CAPABILITIES pdc; 01225 PIO_STACK_LOCATION irpStack; 01226 01227 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryCapabilities: Entered\n")); 01228 01229 irpStack = IoGetCurrentIrpStackLocation(Irp); 01230 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01231 pdc = irpStack->Parameters.DeviceCapabilities.Capabilities; 01232 01233 if(pdc->Version < 1 || pdc->Size < sizeof(DEVICE_CAPABILITIES)) 01234 { 01235 01236 FreeBT_DbgPrint(1, ("FBTUSB: HandleQueryCapabilities::request failed\n")); 01237 ntStatus = STATUS_UNSUCCESSFUL; 01238 return ntStatus; 01239 01240 } 01241 01242 // Add in the SurpriseRemovalOK bit before passing it down. 01243 pdc->SurpriseRemovalOK = TRUE; 01244 Irp->IoStatus.Status = STATUS_SUCCESS; 01245 01246 KeInitializeEvent(&event, NotificationEvent, FALSE); 01247 01248 IoCopyCurrentIrpStackLocationToNext(Irp); 01249 IoSetCompletionRoutine(Irp, 01250 (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, 01251 (PVOID)&event, 01252 TRUE, 01253 TRUE, 01254 TRUE); 01255 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 01256 if(ntStatus == STATUS_PENDING) 01257 { 01258 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 01259 ntStatus = Irp->IoStatus.Status; 01260 01261 } 01262 01263 // initialize PowerDownLevel to disabled 01264 deviceExtension->PowerDownLevel = PowerDeviceUnspecified; 01265 if(NT_SUCCESS(ntStatus)) 01266 { 01267 deviceExtension->DeviceCapabilities = *pdc; 01268 for(i = PowerSystemSleeping1; i <= PowerSystemSleeping3; i++) 01269 { 01270 if(deviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3) 01271 { 01272 deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceState[i]; 01273 01274 } 01275 01276 } 01277 01278 // since its safe to surprise-remove this device, we shall 01279 // set the SurpriseRemoveOK flag to supress any dialog to 01280 // user. 01281 pdc->SurpriseRemovalOK = 1; 01282 01283 } 01284 01285 if(deviceExtension->PowerDownLevel == PowerDeviceUnspecified || 01286 deviceExtension->PowerDownLevel <= PowerDeviceD0) 01287 { 01288 deviceExtension->PowerDownLevel = PowerDeviceD2; 01289 01290 } 01291 01292 FreeBT_DbgPrint(3, ("FBTUSB: HandleQueryCapabilities: Leaving\n")); 01293 01294 return ntStatus; 01295 } 01296 01297 01298 VOID DpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) 01299 /*++ 01300 01301 DPC routine triggered by the timer to check the idle state 01302 of the device and submit an idle request for the device. 01303 01304 --*/ 01305 { 01306 NTSTATUS ntStatus; 01307 PDEVICE_OBJECT deviceObject; 01308 PDEVICE_EXTENSION deviceExtension; 01309 PIO_WORKITEM item; 01310 01311 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Entered\n")); 01312 01313 deviceObject = (PDEVICE_OBJECT)DeferredContext; 01314 deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; 01315 01316 // Clear this event since a DPC has been fired! 01317 KeClearEvent(&deviceExtension->NoDpcWorkItemPendingEvent); 01318 01319 if(CanDeviceSuspend(deviceExtension)) 01320 { 01321 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Device is Idle\n")); 01322 item = IoAllocateWorkItem(deviceObject); 01323 01324 if (item) 01325 { 01326 IoQueueWorkItem(item, IdleRequestWorkerRoutine, DelayedWorkQueue, item); 01327 ntStatus = STATUS_PENDING; 01328 01329 } 01330 01331 else 01332 { 01333 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Cannot alloc memory for work item\n")); 01334 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 01335 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 01336 01337 } 01338 01339 } 01340 01341 else 01342 { 01343 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Idle event not signaled\n")); 01344 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 01345 01346 } 01347 01348 FreeBT_DbgPrint(3, ("FBTUSB: DpcRoutine: Leaving\n")); 01349 } 01350 01351 01352 VOID IdleRequestWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) 01353 { 01354 //PIRP irp; 01355 NTSTATUS ntStatus; 01356 PDEVICE_EXTENSION deviceExtension; 01357 PIO_WORKITEM workItem; 01358 01359 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Entered\n")); 01360 01361 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01362 workItem = (PIO_WORKITEM) Context; 01363 01364 if(CanDeviceSuspend(deviceExtension)) 01365 { 01366 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Device is idle\n")); 01367 ntStatus = SubmitIdleRequestIrp(deviceExtension); 01368 if(!NT_SUCCESS(ntStatus)) 01369 { 01370 FreeBT_DbgPrint(1, ("FBTUSB: IdleRequestWorkerRoutine: SubmitIdleRequestIrp failed\n")); 01371 01372 } 01373 01374 } 01375 01376 else 01377 { 01378 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestWorkerRoutine: Device is not idle\n")); 01379 01380 } 01381 01382 IoFreeWorkItem(workItem); 01383 01384 KeSetEvent(&deviceExtension->NoDpcWorkItemPendingEvent, IO_NO_INCREMENT, FALSE); 01385 01386 FreeBT_DbgPrint(3, ("FBTUSB: IdleRequestsWorkerRoutine: Leaving\n")); 01387 01388 } 01389 01390 01391 VOID ProcessQueuedRequests(IN OUT PDEVICE_EXTENSION DeviceExtension) 01392 /*++ 01393 01394 Routine Description: 01395 01396 Remove and process the entries in the queue. If this routine is called 01397 when processing IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE 01398 or IRP_MN_START_DEVICE, the requests are passed to the next lower driver. 01399 If the routine is called when IRP_MN_REMOVE_DEVICE is received, the IRPs 01400 are complete with STATUS_DELETE_PENDING 01401 01402 Arguments: 01403 01404 DeviceExtension - pointer to device extension 01405 01406 Return Value: 01407 01408 None 01409 01410 --*/ 01411 { 01412 KIRQL oldIrql; 01413 PIRP nextIrp, 01414 cancelledIrp; 01415 PVOID cancelRoutine; 01416 LIST_ENTRY cancelledIrpList; 01417 PLIST_ENTRY listEntry; 01418 01419 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests: Entered\n")); 01420 01421 cancelRoutine = NULL; 01422 InitializeListHead(&cancelledIrpList); 01423 01424 // 1. dequeue the entries in the queue 01425 // 2. reset the cancel routine 01426 // 3. process them 01427 // 3a. if the device is active, send them down 01428 // 3b. else complete with STATUS_DELETE_PENDING 01429 while(1) 01430 { 01431 KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql); 01432 if(IsListEmpty(&DeviceExtension->NewRequestsQueue)) 01433 { 01434 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 01435 break; 01436 01437 } 01438 01439 listEntry = RemoveHeadList(&DeviceExtension->NewRequestsQueue); 01440 nextIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry); 01441 01442 cancelRoutine = IoSetCancelRoutine(nextIrp, NULL); 01443 01444 // check if its already cancelled 01445 if (nextIrp->Cancel) 01446 { 01447 if(cancelRoutine) 01448 { 01449 // the cancel routine for this IRP hasnt been called yet 01450 // so queue the IRP in the cancelledIrp list and complete 01451 // after releasing the lock 01452 InsertTailList(&cancelledIrpList, listEntry); 01453 01454 } 01455 01456 else 01457 { 01458 // the cancel routine has run 01459 // it must be waiting to hold the queue lock 01460 // so initialize the IRPs listEntry 01461 InitializeListHead(listEntry); 01462 01463 } 01464 01465 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 01466 01467 } 01468 01469 else 01470 { 01471 KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql); 01472 if(FailRequests == DeviceExtension->QueueState) 01473 { 01474 nextIrp->IoStatus.Information = 0; 01475 nextIrp->IoStatus.Status = STATUS_DELETE_PENDING; 01476 IoCompleteRequest(nextIrp, IO_NO_INCREMENT); 01477 01478 } 01479 01480 else 01481 { 01482 //PIO_STACK_LOCATION irpStack; 01483 01484 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests::")); 01485 FreeBT_IoIncrement(DeviceExtension); 01486 01487 IoSkipCurrentIrpStackLocation(nextIrp); 01488 IoCallDriver(DeviceExtension->TopOfStackDeviceObject, nextIrp); 01489 01490 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests::")); 01491 FreeBT_IoDecrement(DeviceExtension); 01492 01493 } 01494 01495 } 01496 01497 } 01498 01499 while(!IsListEmpty(&cancelledIrpList)) 01500 { 01501 PLIST_ENTRY cancelEntry = RemoveHeadList(&cancelledIrpList); 01502 01503 cancelledIrp = CONTAINING_RECORD(cancelEntry, IRP, Tail.Overlay.ListEntry); 01504 cancelledIrp->IoStatus.Status = STATUS_CANCELLED; 01505 cancelledIrp->IoStatus.Information = 0; 01506 01507 IoCompleteRequest(cancelledIrp, IO_NO_INCREMENT); 01508 01509 } 01510 01511 FreeBT_DbgPrint(3, ("FBTUSB: ProcessQueuedRequests: Leaving\n")); 01512 01513 return; 01514 01515 } 01516 01517 NTSTATUS FreeBT_GetRegistryDword(IN PWCHAR RegPath, IN PWCHAR ValueName, IN OUT PULONG Value) 01518 { 01519 ULONG defaultData; 01520 WCHAR buffer[MAXIMUM_FILENAME_LENGTH]; 01521 NTSTATUS ntStatus; 01522 UNICODE_STRING regPath; 01523 RTL_QUERY_REGISTRY_TABLE paramTable[2]; 01524 01525 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Entered\n")); 01526 01527 regPath.Length = 0; 01528 regPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); 01529 regPath.Buffer = buffer; 01530 01531 RtlZeroMemory(regPath.Buffer, regPath.MaximumLength); 01532 RtlMoveMemory(regPath.Buffer, RegPath, wcslen(RegPath) * sizeof(WCHAR)); 01533 RtlZeroMemory(paramTable, sizeof(paramTable)); 01534 01535 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 01536 paramTable[0].Name = ValueName; 01537 paramTable[0].EntryContext = Value; 01538 paramTable[0].DefaultType = REG_DWORD; 01539 paramTable[0].DefaultData = &defaultData; 01540 paramTable[0].DefaultLength = sizeof(ULONG); 01541 01542 ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | 01543 RTL_REGISTRY_OPTIONAL, 01544 regPath.Buffer, 01545 paramTable, 01546 NULL, 01547 NULL); 01548 01549 if (NT_SUCCESS(ntStatus)) 01550 { 01551 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Success, Value = %X\n", *Value)); 01552 return STATUS_SUCCESS; 01553 } 01554 01555 else 01556 { 01557 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_GetRegistryDword: Failed\n")); 01558 *Value = 0; 01559 return STATUS_UNSUCCESSFUL; 01560 01561 } 01562 } 01563 01564 01565 NTSTATUS FreeBT_DispatchClean(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01566 { 01567 PDEVICE_EXTENSION deviceExtension; 01568 KIRQL oldIrql; 01569 LIST_ENTRY cleanupList; 01570 PLIST_ENTRY thisEntry, 01571 nextEntry, 01572 listHead; 01573 PIRP pendingIrp; 01574 PIO_STACK_LOCATION pendingIrpStack, 01575 irpStack; 01576 //NTSTATUS ntStatus; 01577 01578 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01579 irpStack = IoGetCurrentIrpStackLocation(Irp); 01580 InitializeListHead(&cleanupList); 01581 01582 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchClean::")); 01583 FreeBT_IoIncrement(deviceExtension); 01584 01585 KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql); 01586 01587 listHead = &deviceExtension->NewRequestsQueue; 01588 for(thisEntry = listHead->Flink, nextEntry = thisEntry->Flink; 01589 thisEntry != listHead; 01590 thisEntry = nextEntry, nextEntry = thisEntry->Flink) 01591 { 01592 pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry); 01593 pendingIrpStack = IoGetCurrentIrpStackLocation(pendingIrp); 01594 if (irpStack->FileObject == pendingIrpStack->FileObject) 01595 { 01596 RemoveEntryList(thisEntry); 01597 01598 if (NULL == IoSetCancelRoutine(pendingIrp, NULL)) 01599 { 01600 InitializeListHead(thisEntry); 01601 01602 } 01603 01604 else 01605 { 01606 InsertTailList(&cleanupList, thisEntry); 01607 01608 } 01609 01610 } 01611 01612 } 01613 01614 KeReleaseSpinLock(&deviceExtension->QueueLock, oldIrql); 01615 01616 while(!IsListEmpty(&cleanupList)) 01617 { 01618 thisEntry = RemoveHeadList(&cleanupList); 01619 pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry); 01620 01621 pendingIrp->IoStatus.Information = 0; 01622 pendingIrp->IoStatus.Status = STATUS_CANCELLED; 01623 IoCompleteRequest(pendingIrp, IO_NO_INCREMENT); 01624 01625 } 01626 01627 Irp->IoStatus.Information = 0; 01628 Irp->IoStatus.Status = STATUS_SUCCESS; 01629 01630 IoCompleteRequest(Irp, IO_NO_INCREMENT); 01631 01632 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchClean::")); 01633 FreeBT_IoDecrement(deviceExtension); 01634 01635 return STATUS_SUCCESS; 01636 01637 } 01638 01639 01640 BOOLEAN CanDeviceSuspend(IN PDEVICE_EXTENSION DeviceExtension) 01641 { 01642 FreeBT_DbgPrint(3, ("FBTUSB: CanDeviceSuspend: Entered\n")); 01643 01644 if ((DeviceExtension->OpenHandleCount == 0) && (DeviceExtension->OutStandingIO == 1)) 01645 return TRUE; 01646 01647 return FALSE; 01648 01649 } 01650 01651 NTSTATUS FreeBT_AbortPipes(IN PDEVICE_OBJECT DeviceObject) 01652 { 01653 PURB urb; 01654 ULONG i; 01655 NTSTATUS ntStatus; 01656 PDEVICE_EXTENSION deviceExtension; 01657 PFREEBT_PIPE_CONTEXT pipeContext; 01658 //PUSBD_PIPE_INFORMATION pipeInformation; 01659 PUSBD_INTERFACE_INFORMATION interfaceInfo; 01660 01661 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01662 pipeContext = deviceExtension->PipeContext; 01663 interfaceInfo = deviceExtension->UsbInterface; 01664 01665 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Entered\n")); 01666 01667 if(interfaceInfo == NULL || pipeContext == NULL) 01668 return STATUS_SUCCESS; 01669 01670 for(i=0; i<interfaceInfo->NumberOfPipes; i++) 01671 { 01672 if(pipeContext[i].PipeOpen) 01673 { 01674 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Aborting open pipe %d\n", i)); 01675 01676 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); 01677 if (urb) 01678 { 01679 urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST); 01680 urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE; 01681 urb->UrbPipeRequest.PipeHandle = interfaceInfo->Pipes[i].PipeHandle; 01682 01683 ntStatus = CallUSBD(DeviceObject, urb); 01684 01685 ExFreePool(urb); 01686 01687 } 01688 01689 else 01690 { 01691 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_AbortPipes: Failed to alloc memory for urb\n")); 01692 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 01693 return ntStatus; 01694 01695 } 01696 01697 if(NT_SUCCESS(ntStatus)) 01698 pipeContext[i].PipeOpen = FALSE; 01699 01700 01701 } 01702 01703 } 01704 01705 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AbortPipes: Leaving\n")); 01706 01707 return STATUS_SUCCESS; 01708 01709 } 01710 01711 // Completion routine for PNP IRPs 01712 NTSTATUS IrpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) 01713 { 01714 PKEVENT event = (PKEVENT) Context; 01715 KeSetEvent(event, 0, FALSE); 01716 01717 return STATUS_MORE_PROCESSING_REQUIRED; 01718 01719 } 01720 01721 01722 LONG FreeBT_IoIncrement(IN OUT PDEVICE_EXTENSION DeviceExtension) 01723 { 01724 LONG result = 0; 01725 KIRQL oldIrql; 01726 01727 KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql); 01728 result = InterlockedIncrement((PLONG)(&DeviceExtension->OutStandingIO)); 01729 01730 // When OutStandingIO bumps from 1 to 2, clear the StopEvent 01731 if (result == 2) 01732 KeClearEvent(&DeviceExtension->StopEvent); 01733 01734 KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql); 01735 01736 FreeBT_DbgPrint(3, ("FreeBT_IoIncrement::%d\n", result)); 01737 01738 return result; 01739 01740 } 01741 01742 LONG FreeBT_IoDecrement(IN OUT PDEVICE_EXTENSION DeviceExtension) 01743 { 01744 LONG result = 0; 01745 KIRQL oldIrql; 01746 01747 KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql); 01748 01749 result = InterlockedDecrement((PLONG)(&DeviceExtension->OutStandingIO)); 01750 01751 if (result == 1) 01752 KeSetEvent(&DeviceExtension->StopEvent, IO_NO_INCREMENT, FALSE); 01753 01754 if(result == 0) 01755 { 01756 ASSERT(Removed == DeviceExtension->DeviceState); 01757 KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE); 01758 01759 } 01760 01761 KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql); 01762 01763 FreeBT_DbgPrint(3, ("FreeBT_IoDecrement::%d\n", result)); 01764 01765 return result; 01766 01767 } 01768 01769 NTSTATUS CanStopDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01770 { 01771 // For the time being, just allow it to be stopped 01772 UNREFERENCED_PARAMETER(DeviceObject); 01773 UNREFERENCED_PARAMETER(Irp); 01774 01775 return STATUS_SUCCESS; 01776 01777 } 01778 01779 NTSTATUS CanRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 01780 01781 { 01782 // For the time being, just allow it to be removed 01783 UNREFERENCED_PARAMETER(DeviceObject); 01784 UNREFERENCED_PARAMETER(Irp); 01785 01786 return STATUS_SUCCESS; 01787 01788 } 01789 01790 NTSTATUS ReleaseMemory(IN PDEVICE_OBJECT DeviceObject) 01791 { 01792 // Disconnect from the interrupt and unmap any I/O ports 01793 PDEVICE_EXTENSION deviceExtension; 01794 UNICODE_STRING uniDeviceName; 01795 NTSTATUS ntStatus; 01796 01797 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 01798 if (deviceExtension->UsbConfigurationDescriptor) 01799 { 01800 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing UsbConfigurationDescriptor\n")); 01801 ExFreePool(deviceExtension->UsbConfigurationDescriptor); 01802 deviceExtension->UsbConfigurationDescriptor = NULL; 01803 01804 } 01805 01806 if(deviceExtension->UsbInterface) 01807 { 01808 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing UsbInterface\n")); 01809 ExFreePool(deviceExtension->UsbInterface); 01810 deviceExtension->UsbInterface = NULL; 01811 01812 } 01813 01814 if(deviceExtension->PipeContext) 01815 { 01816 RtlInitUnicodeString(&uniDeviceName, deviceExtension->wszDosDeviceName); 01817 ntStatus = IoDeleteSymbolicLink(&uniDeviceName); 01818 if (!NT_SUCCESS(ntStatus)) 01819 FreeBT_DbgPrint(3, ("FBTUSB: Failed to delete symbolic link %ws\n", deviceExtension->wszDosDeviceName)); 01820 01821 FreeBT_DbgPrint(3, ("FBTUSB: ReleaseMemory: Freeing PipeContext %p\n", deviceExtension->PipeContext)); 01822 ExFreePool(deviceExtension->PipeContext); 01823 deviceExtension->PipeContext = NULL; 01824 01825 } 01826 01827 return STATUS_SUCCESS; 01828 01829 } 01830 01831 PCHAR PnPMinorFunctionString (UCHAR MinorFunction) 01832 { 01833 switch (MinorFunction) 01834 { 01835 case IRP_MN_START_DEVICE: 01836 return "IRP_MN_START_DEVICE\n"; 01837 01838 case IRP_MN_QUERY_REMOVE_DEVICE: 01839 return "IRP_MN_QUERY_REMOVE_DEVICE\n"; 01840 01841 case IRP_MN_REMOVE_DEVICE: 01842 return "IRP_MN_REMOVE_DEVICE\n"; 01843 01844 case IRP_MN_CANCEL_REMOVE_DEVICE: 01845 return "IRP_MN_CANCEL_REMOVE_DEVICE\n"; 01846 01847 case IRP_MN_STOP_DEVICE: 01848 return "IRP_MN_STOP_DEVICE\n"; 01849 01850 case IRP_MN_QUERY_STOP_DEVICE: 01851 return "IRP_MN_QUERY_STOP_DEVICE\n"; 01852 01853 case IRP_MN_CANCEL_STOP_DEVICE: 01854 return "IRP_MN_CANCEL_STOP_DEVICE\n"; 01855 01856 case IRP_MN_QUERY_DEVICE_RELATIONS: 01857 return "IRP_MN_QUERY_DEVICE_RELATIONS\n"; 01858 01859 case IRP_MN_QUERY_INTERFACE: 01860 return "IRP_MN_QUERY_INTERFACE\n"; 01861 01862 case IRP_MN_QUERY_CAPABILITIES: 01863 return "IRP_MN_QUERY_CAPABILITIES\n"; 01864 01865 case IRP_MN_QUERY_RESOURCES: 01866 return "IRP_MN_QUERY_RESOURCES\n"; 01867 01868 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 01869 return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"; 01870 01871 case IRP_MN_QUERY_DEVICE_TEXT: 01872 return "IRP_MN_QUERY_DEVICE_TEXT\n"; 01873 01874 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 01875 return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"; 01876 01877 case IRP_MN_READ_CONFIG: 01878 return "IRP_MN_READ_CONFIG\n"; 01879 01880 case IRP_MN_WRITE_CONFIG: 01881 return "IRP_MN_WRITE_CONFIG\n"; 01882 01883 case IRP_MN_EJECT: 01884 return "IRP_MN_EJECT\n"; 01885 01886 case IRP_MN_SET_LOCK: 01887 return "IRP_MN_SET_LOCK\n"; 01888 01889 case IRP_MN_QUERY_ID: 01890 return "IRP_MN_QUERY_ID\n"; 01891 01892 case IRP_MN_QUERY_PNP_DEVICE_STATE: 01893 return "IRP_MN_QUERY_PNP_DEVICE_STATE\n"; 01894 01895 case IRP_MN_QUERY_BUS_INFORMATION: 01896 return "IRP_MN_QUERY_BUS_INFORMATION\n"; 01897 01898 case IRP_MN_DEVICE_USAGE_NOTIFICATION: 01899 return "IRP_MN_DEVICE_USAGE_NOTIFICATION\n"; 01900 01901 case IRP_MN_SURPRISE_REMOVAL: 01902 return "IRP_MN_SURPRISE_REMOVAL\n"; 01903 01904 default: 01905 return "IRP_MN_?????\n"; 01906 01907 } 01908 01909 } 01910 Generated on Sat May 26 2012 04:25:43 for ReactOS by
1.7.6.1
|