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

fdo.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Serial enumerator driver
00004  * FILE:            drivers/bus/serenum/fdo.c
00005  * PURPOSE:         IRP_MJ_PNP operations for FDOs
00006  *
00007  * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.org)
00008  */
00009 
00010 #include "serenum.h"
00011 
00012 NTSTATUS NTAPI
00013 SerenumAddDevice(
00014     IN PDRIVER_OBJECT DriverObject,
00015     IN PDEVICE_OBJECT Pdo)
00016 {
00017     PDEVICE_OBJECT Fdo;
00018     PFDO_DEVICE_EXTENSION DeviceExtension;
00019     NTSTATUS Status;
00020 
00021     TRACE_(SERENUM, "SerenumAddDevice called. Pdo = %p\n", Pdo);
00022 
00023     /* Create new device object */
00024     Status = IoCreateDevice(DriverObject,
00025                             sizeof(FDO_DEVICE_EXTENSION),
00026                             NULL,
00027                             FILE_DEVICE_BUS_EXTENDER,
00028                             FILE_DEVICE_SECURE_OPEN,
00029                             FALSE,
00030                             &Fdo);
00031     if (!NT_SUCCESS(Status))
00032     {
00033         WARN_(SERENUM, "IoCreateDevice() failed with status 0x%08lx\n", Status);
00034         return Status;
00035     }
00036     DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
00037     RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
00038 
00039     /* Register device interface */
00040     Status = IoRegisterDeviceInterface(
00041         Pdo,
00042         &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,
00043         NULL,
00044         &DeviceExtension->SerenumInterfaceName);
00045     if (!NT_SUCCESS(Status))
00046     {
00047         WARN_(SERENUM, "IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
00048         IoDeleteDevice(Fdo);
00049         return Status;
00050     }
00051 
00052     DeviceExtension->Common.IsFDO = TRUE;
00053     DeviceExtension->Common.PnpState = dsStopped;
00054     DeviceExtension->Pdo = Pdo;
00055     IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERENUM_TAG, 0, 0);
00056     Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
00057     if (!NT_SUCCESS(Status))
00058     {
00059         WARN_(SERENUM, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
00060         IoDeleteDevice(Fdo);
00061         return Status;
00062     }
00063     if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
00064         Fdo->Flags |= DO_POWER_PAGABLE;
00065     if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
00066         Fdo->Flags |= DO_BUFFERED_IO;
00067     if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
00068         Fdo->Flags |= DO_DIRECT_IO;
00069     Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
00070 
00071     return STATUS_SUCCESS;
00072 }
00073 
00074 static NTSTATUS NTAPI
00075 SerenumFdoStartDevice(
00076     IN PDEVICE_OBJECT DeviceObject,
00077     IN PIRP Irp)
00078 {
00079     PFDO_DEVICE_EXTENSION DeviceExtension;
00080     NTSTATUS Status;
00081 
00082     TRACE_(SERENUM, "SerenumFdoStartDevice() called\n");
00083     DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00084 
00085     ASSERT(DeviceExtension->Common.PnpState == dsStopped);
00086 
00087     Status = IoSetDeviceInterfaceState(&DeviceExtension->SerenumInterfaceName, TRUE);
00088     if (!NT_SUCCESS(Status))
00089     {
00090         WARN_(SERENUM, "IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
00091         return Status;
00092     }
00093 
00094     DeviceExtension->Common.PnpState = dsStarted;
00095 
00096     return STATUS_SUCCESS;
00097 }
00098 
00099 static NTSTATUS
00100 SerenumFdoQueryBusRelations(
00101     IN PDEVICE_OBJECT DeviceObject,
00102     OUT PDEVICE_RELATIONS* pDeviceRelations)
00103 {
00104     PFDO_DEVICE_EXTENSION DeviceExtension;
00105     PDEVICE_RELATIONS DeviceRelations;
00106     ULONG NumPDO;
00107     ULONG i;
00108     NTSTATUS Status = STATUS_SUCCESS;
00109 
00110     DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00111     ASSERT(DeviceExtension->Common.IsFDO);
00112 
00113     /* Do enumeration if needed */
00114     if (!(DeviceExtension->Flags & FLAG_ENUMERATION_DONE))
00115     {
00116         ASSERT(DeviceExtension->AttachedPdo == NULL);
00117         /* Detect plug-and-play devices */
00118         Status = SerenumDetectPnpDevice(DeviceObject, DeviceExtension->LowerDevice);
00119         if (Status == STATUS_DEVICE_NOT_CONNECTED)
00120         {
00121             /* Detect legacy devices */
00122             Status = SerenumDetectLegacyDevice(DeviceObject, DeviceExtension->LowerDevice);
00123             if (Status == STATUS_DEVICE_NOT_CONNECTED)
00124                 Status = STATUS_SUCCESS;
00125         }
00126         DeviceExtension->Flags |= FLAG_ENUMERATION_DONE;
00127     }
00128     NumPDO = (DeviceExtension->AttachedPdo != NULL ? 1 : 0);
00129 
00130     DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(
00131         PagedPool,
00132         sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (NumPDO - 1),
00133         SERENUM_TAG);
00134     if (!DeviceRelations)
00135         return STATUS_INSUFFICIENT_RESOURCES;
00136 
00137     /* Fill returned structure */
00138     DeviceRelations->Count = NumPDO;
00139     for (i = 0; i < NumPDO; i++)
00140     {
00141         ObReferenceObject(DeviceExtension->AttachedPdo);
00142         DeviceRelations->Objects[i] = DeviceExtension->AttachedPdo;
00143     }
00144 
00145     *pDeviceRelations = DeviceRelations;
00146     return Status;
00147 }
00148 
00149 NTSTATUS
00150 SerenumFdoPnp(
00151     IN PDEVICE_OBJECT DeviceObject,
00152     IN PIRP Irp)
00153 {
00154     ULONG MinorFunction;
00155     PIO_STACK_LOCATION Stack;
00156     ULONG_PTR Information = 0;
00157     NTSTATUS Status;
00158 
00159     Stack = IoGetCurrentIrpStackLocation(Irp);
00160     MinorFunction = Stack->MinorFunction;
00161 
00162     switch (MinorFunction)
00163     {
00164         /* FIXME: do all these minor functions
00165         IRP_MN_QUERY_REMOVE_DEVICE 0x1
00166         IRP_MN_REMOVE_DEVICE 0x2
00167         IRP_MN_CANCEL_REMOVE_DEVICE 0x3
00168         IRP_MN_STOP_DEVICE 0x4
00169         IRP_MN_QUERY_STOP_DEVICE 0x5
00170         IRP_MN_CANCEL_STOP_DEVICE 0x6
00171         IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
00172         IRP_MN_QUERY_INTERFACE (optional) 0x8
00173         IRP_MN_QUERY_CAPABILITIES (optional) 0x9
00174         IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
00175         IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
00176         IRP_MN_SURPRISE_REMOVAL 0x17
00177         */
00178         case IRP_MN_START_DEVICE: /* 0x0 */
00179         {
00180             TRACE_(SERENUM, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
00181             /* Call lower driver */
00182             Status = ForwardIrpAndWait(DeviceObject, Irp);
00183             if (NT_SUCCESS(Status))
00184                 Status = SerenumFdoStartDevice(DeviceObject, Irp);
00185             break;
00186         }
00187         case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x7 */
00188         {
00189             switch (Stack->Parameters.QueryDeviceRelations.Type)
00190             {
00191                 case BusRelations:
00192                 {
00193                     PDEVICE_RELATIONS DeviceRelations = NULL;
00194                     TRACE_(SERENUM, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
00195                     Status = SerenumFdoQueryBusRelations(DeviceObject, &DeviceRelations);
00196                     Information = (ULONG_PTR)DeviceRelations;
00197                     break;
00198                 }
00199                 default:
00200                     TRACE_(SERENUM, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
00201                         Stack->Parameters.QueryDeviceRelations.Type);
00202                     return ForwardIrpAndForget(DeviceObject, Irp);
00203             }
00204             break;
00205         }
00206         case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0xd */
00207         {
00208             TRACE_(SERENUM, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
00209             return ForwardIrpAndForget(DeviceObject, Irp);
00210         }
00211         default:
00212         {
00213             TRACE_(SERENUM, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
00214             return ForwardIrpAndForget(DeviceObject, Irp);
00215         }
00216     }
00217 
00218     Irp->IoStatus.Information = Information;
00219     Irp->IoStatus.Status = Status;
00220     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00221     return Status;
00222 }

Generated on Sun May 27 2012 04:27:26 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.