ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pdo.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Universal Serial Bus Hub Driver
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            drivers/usb/usbhub/fdo.c
00005  * PURPOSE:         Handle PDO
00006  * PROGRAMMERS:
00007  *                  Hervé Poussineau (hpoussin@reactos.org)
00008  *                  Michael Martin (michael.martin@reactos.org)
00009  *                  Johannes Anderwald (johannes.anderwald@reactos.org)
00010  */
00011 
00012 #include "usbhub.h"
00013 
00014 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
00015 
00016 NTSTATUS
00017 NTAPI
00018 UrbCompletion(
00019     PDEVICE_OBJECT DeviceObject,
00020     PIRP Irp,
00021     PVOID Context)
00022 {
00023     PIRP OriginalIrp;
00024     DPRINT("Entered Urb Completion\n");
00025 
00026     //
00027     // Get the original Irp
00028     //
00029     OriginalIrp = (PIRP)Context;
00030     
00031     //
00032     // Update it to match what was returned for the IRP that was passed to RootHub
00033     //
00034     OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
00035     OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
00036     DPRINT("Status %x, Information %x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
00037 
00038     //
00039     // Complete the original Irp
00040     //
00041     IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);
00042 
00043     //
00044     // Return this status so the IO Manager doesnt mess with the Irp
00045     //
00046     return STATUS_MORE_PROCESSING_REQUIRED;
00047 }
00048 
00049 NTSTATUS
00050 FowardUrbToRootHub(
00051     PDEVICE_OBJECT RootHubDeviceObject,
00052     IN ULONG IoControlCode,
00053     PIRP Irp,
00054     OUT PVOID OutParameter1,
00055     OUT PVOID OutParameter2)
00056 {
00057     NTSTATUS Status;
00058     PIRP ForwardIrp;
00059     IO_STATUS_BLOCK IoStatus;
00060     PIO_STACK_LOCATION ForwardStack, CurrentStack;
00061     PURB Urb;
00062 
00063     //
00064     // Get the current stack location for the Irp
00065     //
00066     CurrentStack = IoGetCurrentIrpStackLocation(Irp);
00067     ASSERT(CurrentStack);
00068 
00069     //
00070     // Pull the Urb from that stack, it will be reused in the Irp sent to RootHub
00071     //
00072     Urb = (PURB)CurrentStack->Parameters.Others.Argument1;
00073     ASSERT(Urb);
00074 
00075     //
00076     // Create the Irp to forward to RootHub
00077     //
00078     ForwardIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_SHUTDOWN,
00079                                                RootHubDeviceObject,
00080                                                NULL,
00081                                                0,
00082                                                0,
00083                                                &IoStatus);
00084     if (!ForwardIrp)
00085     {
00086         DPRINT1("Failed to allocate IRP\n");
00087         return STATUS_INSUFFICIENT_RESOURCES;
00088     }
00089 
00090     //
00091     // Get the new Irps next stack
00092     //
00093     ForwardStack = IoGetNextIrpStackLocation(ForwardIrp);
00094 
00095     //
00096     // Copy the stack for the current irp into the next stack of new irp
00097     //
00098     RtlCopyMemory(ForwardStack, CurrentStack, sizeof(IO_STACK_LOCATION));
00099 
00100     IoStatus.Status = STATUS_NOT_SUPPORTED;
00101     IoStatus.Information = 0;
00102 
00103     //
00104     // Mark the Irp from upper driver as pending
00105     //
00106     IoMarkIrpPending(Irp);
00107 
00108     //
00109     // Now set the completion routine for the new Irp.
00110     //
00111     IoSetCompletionRoutine(ForwardIrp,
00112                            UrbCompletion,
00113                            Irp,
00114                            TRUE,
00115                            TRUE,
00116                            TRUE);
00117 
00118     Status = IoCallDriver(RootHubDeviceObject, ForwardIrp);
00119 
00120     //
00121     // Always return pending as the completion routine will take care of it
00122     //
00123     return STATUS_PENDING;
00124 }
00125 
00126 BOOLEAN
00127 IsValidPDO(
00128     IN PDEVICE_OBJECT DeviceObject)
00129 {
00130     ULONG Index;
00131     PHUB_DEVICE_EXTENSION HubDeviceExtension;
00132     PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
00133 
00134 
00135     ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00136     ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
00137     HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
00138 
00139     for(Index = 0; Index < USB_MAXCHILDREN; Index++)
00140     {
00141         if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
00142         {
00143             /* PDO exists */
00144             return TRUE;
00145         }
00146     }
00147 
00148     /* invalid pdo */
00149     return FALSE;
00150 }
00151 
00152 
00153 NTSTATUS
00154 USBHUB_PdoHandleInternalDeviceControl(
00155     IN PDEVICE_OBJECT DeviceObject,
00156     IN PIRP Irp)
00157 {
00158     NTSTATUS Status;
00159     PIO_STACK_LOCATION Stack;
00160     ULONG_PTR Information = 0;
00161     PHUB_DEVICE_EXTENSION HubDeviceExtension;
00162     PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
00163     PDEVICE_OBJECT RootHubDeviceObject;
00164     PURB Urb;
00165 
00166     //DPRINT1("UsbhubInternalDeviceControlPdo(%x) called\n", DeviceObject);
00167 
00168     //
00169     // get current stack location
00170     //
00171     Stack = IoGetCurrentIrpStackLocation(Irp);
00172     ASSERT(Stack);
00173 
00174     //
00175     // Set default status
00176     //
00177     Status = Irp->IoStatus.Status;
00178 
00179     ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00180     ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
00181     HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
00182     RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
00183 
00184     if(!IsValidPDO(DeviceObject))
00185     {
00186         DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
00187         Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
00188         Irp->IoStatus.Information = 0;
00189         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00190         return STATUS_DEVICE_NOT_CONNECTED;
00191     }
00192 
00193     switch (Stack->Parameters.DeviceIoControl.IoControlCode)
00194     {
00195         case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
00196         {
00197             PHUB_DEVICE_EXTENSION DeviceExtension;
00198 
00199             DPRINT("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
00200             if (Irp->AssociatedIrp.SystemBuffer == NULL
00201                 || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
00202             {
00203                 Status = STATUS_INVALID_PARAMETER;
00204             }
00205             else
00206             {
00207                 PVOID* pHubPointer;
00208                 DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00209 
00210                 pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
00211                 // FIXME
00212                 *pHubPointer = NULL;
00213                 Information = sizeof(PVOID);
00214                 Status = STATUS_SUCCESS;
00215             }
00216             break;
00217         }
00218         case IOCTL_INTERNAL_USB_SUBMIT_URB:
00219         {
00220             //DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
00221 
00222             //
00223             // Get the Urb
00224             //
00225             Urb = (PURB)Stack->Parameters.Others.Argument1;
00226             ASSERT(Urb);
00227             
00228             //
00229             // Set the real device handle
00230             //
00231             //DPRINT("UsbdDeviceHandle %x, ChildDeviceHandle %x\n", Urb->UrbHeader.UsbdDeviceHandle, ChildDeviceExtension->UsbDeviceHandle);
00232 
00233             Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
00234 
00235             //
00236             // Submit to RootHub
00237             //
00238             switch (Urb->UrbHeader.Function)
00239             {
00240                 //
00241                 // Debugging only
00242                 //
00243                 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
00244                     DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
00245                     break;
00246                 case URB_FUNCTION_CLASS_DEVICE:
00247                     DPRINT1("URB_FUNCTION_CLASS_DEVICE\n");
00248                     break;
00249                 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
00250                     DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
00251                     break;
00252                 case URB_FUNCTION_SELECT_CONFIGURATION:
00253                     DPRINT1("URB_FUNCTION_SELECT_CONFIGURATION\n");
00254                     break;
00255                 case URB_FUNCTION_SELECT_INTERFACE:
00256                     DPRINT1("URB_FUNCTION_SELECT_INTERFACE\n");
00257                     break;
00258                 case URB_FUNCTION_CLASS_OTHER:
00259                     DPRINT1("URB_FUNCTION_CLASS_OTHER\n");
00260                     break;
00261                 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
00262                 {
00263                 /*
00264                     DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
00265                     DPRINT1("PipeHandle %x\n", Urb->UrbBulkOrInterruptTransfer.PipeHandle);
00266                     DPRINT1("TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
00267                     DPRINT1("Buffer %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
00268                     DPRINT1("BufferMDL %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
00269                     DPRINT1("Length %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
00270                     DPRINT1("UrbLink %x\n", Urb->UrbBulkOrInterruptTransfer.UrbLink);
00271                     DPRINT1("hca %x\n", Urb->UrbBulkOrInterruptTransfer.hca);
00272                     if (Urb->UrbBulkOrInterruptTransfer.TransferFlags == USBD_SHORT_TRANSFER_OK)
00273                     {
00274                     }
00275                 */
00276                     break;
00277                             
00278                 }
00279                 case URB_FUNCTION_CLASS_INTERFACE:
00280                     DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
00281                     break;
00282                 default:
00283                     DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
00284                     break;
00285             }
00286             Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
00287             //DPRINT1("Stack->CompletionRoutine %x\n", Stack->CompletionRoutine);
00288             //
00289             // Send the request to RootHub
00290             //
00291             Status = FowardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
00292             return Status;
00293             break;
00294         }
00295         //
00296         // FIXME: Can these be sent to RootHub?
00297         //
00298         case IOCTL_INTERNAL_USB_RESET_PORT:
00299             DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
00300             break;
00301         case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
00302         {
00303             PORT_STATUS_CHANGE PortStatus;
00304             LONG PortId;
00305             PUCHAR PortStatusBits;
00306 
00307             PortStatusBits = (PUCHAR)Stack->Parameters.Others.Argument1;
00308             //
00309             // USBD_PORT_ENABLED (bit 0) or USBD_PORT_CONNECTED (bit 1)
00310             //
00311             DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
00312             DPRINT("Arg1 %x\n", *PortStatusBits);
00313             *PortStatusBits = 0;
00314             if (Stack->Parameters.Others.Argument1)
00315             {
00316                 for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
00317                 {
00318                     Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
00319                     if (NT_SUCCESS(Status))
00320                     {
00321                         DPRINT("Connect %x\n", ((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2));
00322                         DPRINT("Enable %x\n", ((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
00323                         *PortStatusBits +=
00324                             (((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2)) +
00325                             (((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
00326                         
00327                     }
00328                 }
00329             }
00330             
00331             DPRINT1("Arg1 %x\n", *PortStatusBits);
00332             Status = STATUS_SUCCESS;
00333             break;
00334         }
00335         case IOCTL_INTERNAL_USB_ENABLE_PORT:
00336             DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
00337             break;
00338         case IOCTL_INTERNAL_USB_CYCLE_PORT:
00339             DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
00340             break;
00341         case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
00342         {
00343             DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
00344             if (Stack->Parameters.Others.Argument1)
00345             {
00346                 // store device handle
00347                 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)ChildDeviceExtension->UsbDeviceHandle;
00348                 Status = STATUS_SUCCESS;
00349             }
00350             else
00351             {
00352                 // invalid parameter
00353                 Status = STATUS_INVALID_PARAMETER;
00354             }
00355             break;
00356         }
00357         case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
00358         {
00359             if (Stack->Parameters.Others.Argument1)
00360             {
00361                 // inform caller that it is a real usb hub
00362                 *(PVOID *)Stack->Parameters.Others.Argument1 = NULL;
00363             }
00364 
00365             if (Stack->Parameters.Others.Argument2)
00366             {
00367                 // output device object
00368                 *(PVOID *)Stack->Parameters.Others.Argument2 = DeviceObject;
00369             }
00370 
00371             // done
00372             Status = STATUS_SUCCESS;
00373             break;
00374         }
00375         default:
00376         {
00377             DPRINT1("Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
00378             Information = Irp->IoStatus.Information;
00379             Status = Irp->IoStatus.Status;
00380         }
00381     }
00382 
00383     if (Status != STATUS_PENDING)
00384     {
00385         Irp->IoStatus.Information = Information;
00386         Irp->IoStatus.Status = Status;
00387         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00388     }
00389     return Status;
00390 }
00391 
00392 NTSTATUS
00393 USBHUB_PdoStartDevice(
00394     IN PDEVICE_OBJECT DeviceObject,
00395     IN PIRP Irp)
00396 {
00397     PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
00398     //NTSTATUS Status;
00399     DPRINT("USBHUB_PdoStartDevice %x\n", DeviceObject);
00400     ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00401 
00402     //
00403     // This should be a PDO
00404     //
00405     ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
00406 
00407     //
00408     // FIXME: Fow now assume success
00409     //
00410 
00411     UNIMPLEMENTED
00412     return STATUS_SUCCESS;
00413 }
00414 
00415 NTSTATUS
00416 USBHUB_PdoQueryId(
00417     IN PDEVICE_OBJECT DeviceObject,
00418     IN PIRP Irp,
00419     OUT ULONG_PTR* Information)
00420 {
00421     PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
00422     ULONG IdType;
00423     PUNICODE_STRING SourceString = NULL;
00424     PWCHAR ReturnString = NULL;
00425     NTSTATUS Status = STATUS_SUCCESS;
00426 
00427     IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
00428     ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00429 
00430     switch (IdType)
00431     {
00432         case BusQueryDeviceID:
00433         {
00434             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
00435             SourceString = &ChildDeviceExtension->usDeviceId;
00436             break;
00437         }
00438         case BusQueryHardwareIDs:
00439         {
00440             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
00441             SourceString = &ChildDeviceExtension->usHardwareIds;
00442             break;
00443         }
00444         case BusQueryCompatibleIDs:
00445         {
00446             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
00447             SourceString = &ChildDeviceExtension->usCompatibleIds;
00448             break;
00449         }
00450         case BusQueryInstanceID:
00451         {
00452             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
00453             SourceString = &ChildDeviceExtension->usInstanceId;
00454             break;
00455         }
00456         default:
00457             DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
00458             return STATUS_NOT_SUPPORTED;
00459     }
00460 
00461     if (SourceString)
00462     {
00463         //
00464         // allocate buffer
00465         //
00466         ReturnString = ExAllocatePool(PagedPool, SourceString->MaximumLength);
00467         if (!ReturnString)
00468         {
00469             //
00470             // no memory
00471             //
00472             return STATUS_INSUFFICIENT_RESOURCES;
00473         }
00474 
00475         //
00476         // copy buffer
00477         //
00478         RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->MaximumLength);
00479     }
00480 
00481     *Information = (ULONG_PTR)ReturnString;
00482 
00483     return Status;
00484 }
00485 
00486 NTSTATUS
00487 USBHUB_PdoQueryDeviceText(
00488     IN PDEVICE_OBJECT DeviceObject,
00489     IN PIRP Irp,
00490     OUT ULONG_PTR* Information)
00491 {
00492     PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
00493     DEVICE_TEXT_TYPE DeviceTextType;
00494     PUNICODE_STRING SourceString = NULL;
00495     PWCHAR ReturnString = NULL;
00496     NTSTATUS Status = STATUS_SUCCESS;
00497     LCID LocaleId;
00498 
00499     DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
00500     LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
00501     ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00502 
00503     //
00504     // FIXME: LocaleId
00505     //
00506 
00507     switch (DeviceTextType)
00508     {
00509         case DeviceTextDescription:
00510         case DeviceTextLocationInformation:
00511         {
00512             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
00513 
00514             //
00515             // does the device provide a text description
00516             //
00517             if (ChildDeviceExtension->usTextDescription.Buffer && ChildDeviceExtension->usTextDescription.Length)
00518             {
00519                 //
00520                 // use device text
00521                 //
00522                 SourceString = &ChildDeviceExtension->usTextDescription;
00523             }
00524             break;
00525         }
00526         default:
00527         {
00528             DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
00529             Status = STATUS_NOT_SUPPORTED;
00530             break;
00531         }
00532     }
00533 
00534     if (SourceString)
00535     {
00536         ReturnString = ExAllocatePool(PagedPool, SourceString->MaximumLength);
00537         RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->MaximumLength);
00538         DPRINT1("%S\n", ReturnString);
00539         *Information = (ULONG_PTR)ReturnString;
00540     }
00541 
00542     return Status;
00543 }
00544 
00545 NTSTATUS
00546 USBHUB_PdoHandlePnp(
00547     IN PDEVICE_OBJECT DeviceObject,
00548     IN PIRP Irp)
00549 {
00550     NTSTATUS Status;
00551     ULONG MinorFunction;
00552     PIO_STACK_LOCATION Stack;
00553     ULONG_PTR Information = 0;
00554     PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
00555     ULONG Index;
00556     ULONG bFound;
00557     PDEVICE_RELATIONS DeviceRelation;
00558 
00559     UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00560     Stack = IoGetCurrentIrpStackLocation(Irp);
00561     MinorFunction = Stack->MinorFunction;
00562 
00563     switch (MinorFunction)
00564     {
00565         case IRP_MN_START_DEVICE:
00566         {
00567             DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
00568             Status = USBHUB_PdoStartDevice(DeviceObject, Irp);
00569             break;
00570         }
00571         case IRP_MN_QUERY_CAPABILITIES:
00572         {
00573             PDEVICE_CAPABILITIES DeviceCapabilities;
00574             ULONG i;
00575             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
00576 
00577             DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
00578             // FIXME: capabilities can change with connected device
00579             DeviceCapabilities->LockSupported = FALSE;
00580             DeviceCapabilities->EjectSupported = FALSE;
00581             DeviceCapabilities->Removable = TRUE;
00582             DeviceCapabilities->DockDevice = FALSE;
00583             DeviceCapabilities->UniqueID = FALSE;
00584             DeviceCapabilities->SilentInstall = FALSE;
00585             DeviceCapabilities->RawDeviceOK = FALSE;
00586             DeviceCapabilities->SurpriseRemovalOK = FALSE;
00587             DeviceCapabilities->HardwareDisabled = FALSE;
00588             //DeviceCapabilities->NoDisplayInUI = FALSE;
00589             DeviceCapabilities->Address = UsbChildExtension->PortNumber;
00590             DeviceCapabilities->UINumber = 0;
00591             DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
00592             for (i = 1; i < PowerSystemMaximum; i++)
00593                 DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
00594             //DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
00595             DeviceCapabilities->D1Latency = 0;
00596             DeviceCapabilities->D2Latency = 0;
00597             DeviceCapabilities->D3Latency = 0;
00598             Status = STATUS_SUCCESS;
00599             break;
00600         }
00601         case IRP_MN_QUERY_RESOURCES:
00602         {
00603             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
00604 
00605             Information = Irp->IoStatus.Information;
00606             Status = Irp->IoStatus.Status;
00607             break;
00608         }
00609         case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
00610         {
00611             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
00612             
00613             Information = Irp->IoStatus.Information;
00614             Status = Irp->IoStatus.Status;
00615             break;
00616         }
00617         case IRP_MN_QUERY_DEVICE_TEXT:
00618         {
00619             Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
00620             break;
00621         }
00622         case IRP_MN_QUERY_ID:
00623         {
00624             Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
00625             break;
00626         }
00627         case IRP_MN_QUERY_BUS_INFORMATION:
00628         {
00629             PPNP_BUS_INFORMATION BusInfo;
00630             BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
00631             RtlCopyMemory(&BusInfo->BusTypeGuid,
00632                           &GUID_BUS_TYPE_USB,
00633                           sizeof(BusInfo->BusTypeGuid));
00634             BusInfo->LegacyBusType = PNPBus;
00635             // FIXME
00636             BusInfo->BusNumber = 0;
00637             Information = (ULONG_PTR)BusInfo;
00638             Status = STATUS_SUCCESS;
00639             break;
00640         }
00641         case IRP_MN_REMOVE_DEVICE:
00642         {
00643             PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
00644             PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
00645 
00646             DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
00647 
00648             /* remove us from pdo list */
00649             bFound = FALSE;
00650             for(Index = 0; Index < USB_MAXCHILDREN; Index++)
00651             {
00652                 if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
00653                 {
00654                      /* Remove the device */
00655                      Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
00656 
00657                      /* FIXME handle error */
00658                      ASSERT(Status == STATUS_SUCCESS);
00659 
00660                     /* remove us */
00661                     HubDeviceExtension->ChildDeviceObject[Index] = NULL;
00662                     bFound = TRUE;
00663                     break;
00664                 }
00665             }
00666 
00667             /* Complete the IRP */
00668             Irp->IoStatus.Status = STATUS_SUCCESS;
00669             IoCompleteRequest(Irp, IO_NO_INCREMENT);
00670 
00671             if (bFound)
00672             {
00673                 /* Delete the device object */
00674                 IoDeleteDevice(DeviceObject);
00675             }
00676 
00677             return STATUS_SUCCESS;
00678         }
00679         case IRP_MN_QUERY_DEVICE_RELATIONS:
00680         {
00681             /* only target relations are supported */
00682             if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
00683             {
00684                 /* not supported */
00685                 Status = Irp->IoStatus.Status;
00686                 break;
00687             }
00688 
00689             /* allocate device relations */
00690             DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS));
00691             if (!DeviceRelation)
00692             {
00693                 /* no memory */
00694                 Status = STATUS_INSUFFICIENT_RESOURCES;
00695                 break;
00696             }
00697 
00698             /* init device relation */
00699             DeviceRelation->Count = 1;
00700             DeviceRelation->Objects[0] = DeviceObject;
00701             ObReferenceObject(DeviceRelation->Objects[0]);
00702 
00703             /* store result */
00704             Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
00705             Status = STATUS_SUCCESS;
00706             break;
00707         }
00708         case IRP_MN_QUERY_STOP_DEVICE:
00709         case IRP_MN_QUERY_REMOVE_DEVICE:
00710         {
00711             /* Sure, no problem */
00712             Status = STATUS_SUCCESS;
00713             Information = 0;
00714             break;
00715         }
00716         case IRP_MN_QUERY_INTERFACE:
00717         {
00718             DPRINT1("IRP_MN_QUERY_INTERFACE\n");
00719             if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
00720             {
00721                 DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
00722                 RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
00723                 Status = STATUS_SUCCESS;
00724                 break;
00725             }
00726 
00727             // pass irp down
00728             IoSkipCurrentIrpStackLocation(Irp);
00729             return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
00730         }
00731         default:
00732         {
00733             DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
00734             Information = Irp->IoStatus.Information;
00735             Status = Irp->IoStatus.Status;
00736         }
00737     }
00738 
00739     Irp->IoStatus.Information = Information;
00740     Irp->IoStatus.Status = Status;
00741     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00742     return Status;
00743 }
00744 

Generated on Sat May 26 2012 04:26:02 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.