Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfdo.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
1.7.6.1
|