1 /* $Id: pnproot.c,v 1.4 2001/08/27 01:20:50 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/pnproot.c
6 * PURPOSE: PnP manager root device
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 16/04/2001 CSH Created
12 /* INCLUDES ******************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
18 #include <internal/debug.h>
20 /* GLOBALS *******************************************************************/
22 /* DATA **********************************************************************/
24 typedef struct _PNPROOT_DEVICE
{
27 } PNPROOT_DEVICE
, *PPNPROOT_DEVICE
;
29 PDEVICE_OBJECT PnpRootDeviceObject
;
30 LIST_ENTRY PnpRootDeviceListHead
;
31 ULONG PnpRootDeviceListCount
;
32 KSPIN_LOCK PnpRootDeviceListLock
;
34 /* FUNCTIONS *****************************************************************/
38 PDEVICE_OBJECT
*PhysicalDeviceObject
)
40 PPNPROOT_DEVICE Device
;
45 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
47 return STATUS_INSUFFICIENT_RESOURCES
;
49 Status
= IoCreateDevice(PnpRootDeviceObject
->DriverObject
, 0,
50 NULL
, FILE_DEVICE_CONTROLLER
, 0, FALSE
, &Device
->Pdo
);
51 if (!NT_SUCCESS(Status
))
53 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
58 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
60 ObReferenceObject(Device
->Pdo
);
62 ExInterlockedInsertTailList(&PnpRootDeviceListHead
,
64 &PnpRootDeviceListLock
);
66 *PhysicalDeviceObject
= Device
->Pdo
;
68 return STATUS_SUCCESS
;
73 PnpRootQueryBusRelations(
74 IN PDEVICE_OBJECT DeviceObject
,
76 IN PIO_STACK_LOCATION IrpSp
)
78 PDEVICE_RELATIONS Relations
;
79 PLIST_ENTRY CurrentEntry
;
80 PPNPROOT_DEVICE Device
;
87 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
88 (PnpRootDeviceListCount
- 1);
89 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
91 return STATUS_INSUFFICIENT_RESOURCES
;
93 Relations
->Count
= PnpRootDeviceListCount
;
96 CurrentEntry
= PnpRootDeviceListHead
.Flink
;
97 while (CurrentEntry
!= &PnpRootDeviceListHead
)
99 Device
= CONTAINING_RECORD(
100 CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
103 /* Create a physical device object for the
104 device as it does not already have one */
105 Status
= IoCreateDevice(DeviceObject
->DriverObject
, 0,
106 NULL
, FILE_DEVICE_CONTROLLER
, 0, FALSE
, &Device
->Pdo
);
107 if (!NT_SUCCESS(Status
)) {
108 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
109 ExFreePool(Relations
);
113 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
116 /* Reference the physical device object. The PnP manager
117 will dereference it again when it is no longer needed */
118 ObReferenceObject(Device
->Pdo
);
120 Relations
->Objects
[i
] = Device
->Pdo
;
124 CurrentEntry
= CurrentEntry
->Flink
;
127 Irp
->IoStatus
.Information
= (ULONG
)Relations
;
133 PnpRootQueryDeviceRelations(
134 IN PDEVICE_OBJECT DeviceObject
,
136 IN PIO_STACK_LOCATION IrpSp
)
142 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
)
145 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
149 Status
= STATUS_NOT_IMPLEMENTED
;
158 IN PDEVICE_OBJECT DeviceObject
,
161 PIO_STACK_LOCATION IrpSp
;
166 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
167 switch (IrpSp
->MinorFunction
)
169 case IRP_MN_QUERY_DEVICE_RELATIONS
:
170 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
173 case IRP_MN_START_DEVICE
:
174 PnpRootDeviceListCount
= 0;
175 Status
= STATUS_SUCCESS
;
178 case IRP_MN_STOP_DEVICE
:
179 /* Root device cannot be stopped */
180 Status
= STATUS_UNSUCCESSFUL
;
184 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
185 Status
= STATUS_NOT_IMPLEMENTED
;
189 if (Status
!= STATUS_PENDING
)
191 Irp
->IoStatus
.Status
= Status
;
192 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
195 DPRINT("Leaving. Status 0x%X\n", Status
);
203 IN PDEVICE_OBJECT DeviceObject
,
206 PIO_STACK_LOCATION IrpSp
;
211 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
212 switch (IrpSp
->MinorFunction
)
215 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
216 Status
= STATUS_NOT_IMPLEMENTED
;
220 if (Status
!= STATUS_PENDING
)
222 Irp
->IoStatus
.Status
= Status
;
223 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
226 DPRINT("Leaving. Status 0x%X\n", Status
);
234 IN PDRIVER_OBJECT DriverObject
,
235 IN PDEVICE_OBJECT PhysicalDeviceObject
)
242 Status
= IoCreateDevice(DriverObject
, 0, NULL
, FILE_DEVICE_BUS_EXTENDER
,
243 FILE_DEVICE_SECURE_OPEN
, TRUE
, &PnpRootDeviceObject
);
244 if (!NT_SUCCESS(Status
))
246 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
251 Ldo
= IoAttachDeviceToDeviceStack(PnpRootDeviceObject
, PhysicalDeviceObject
);
253 if (!PnpRootDeviceObject
)
255 DbgPrint("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
259 if (!PhysicalDeviceObject
)
261 DbgPrint("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
265 InitializeListHead(&PnpRootDeviceListHead
);
266 PnpRootDeviceListCount
= 0;
267 KeInitializeSpinLock(&PnpRootDeviceListLock
);
269 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
273 return STATUS_SUCCESS
;
279 IN PDRIVER_OBJECT DriverObject
,
280 IN PUNICODE_STRING RegistryPath
)
284 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PnpRootPnpControl
;
285 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PnpRootPowerControl
;
286 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
288 return STATUS_SUCCESS
;