1 /* $Id: pnproot.c,v 1.24 2004/10/24 09:13:18 navaraf Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/pnpmgr/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 ******************************************************************/
16 #include <internal/debug.h>
18 /* GLOBALS *******************************************************************/
20 #define ENUM_NAME_ROOT L"Root"
22 /* DATA **********************************************************************/
24 typedef struct _PNPROOT_DEVICE
{
25 // Entry on device list
27 // Physical Device Object of device
30 UNICODE_STRING ServiceName
;
32 UNICODE_STRING DeviceID
;
34 UNICODE_STRING InstanceID
;
36 UNICODE_STRING DeviceDescription
;
37 } PNPROOT_DEVICE
, *PPNPROOT_DEVICE
;
45 } PNPROOT_DEVICE_STATE
;
50 typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
52 // Pointer to device object, this device extension is associated with
53 PDEVICE_OBJECT DeviceObject
;
54 // Wether this device extension is for an FDO or PDO
56 // Wether the device is removed
58 // Current device power state for the device
59 DEVICE_POWER_STATE DevicePowerState
;
60 } PNPROOT_COMMON_DEVICE_EXTENSION
, *PPNPROOT_COMMON_DEVICE_EXTENSION
;
63 /* Physical Device Object device extension for a child device */
64 typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
67 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
69 UNICODE_STRING DeviceID
;
71 UNICODE_STRING InstanceID
;
72 } PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
75 /* Functional Device Object device extension for the PCI driver device object */
76 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
79 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
80 // Physical Device Object
82 // Lower device object
84 // Current state of the driver
85 PNPROOT_DEVICE_STATE State
;
86 // Namespace device list
87 LIST_ENTRY DeviceListHead
;
88 // Number of (not removed) devices in device list
89 ULONG DeviceListCount
;
90 // Lock for namespace device list
91 // FIXME: Use fast mutex instead?
92 KSPIN_LOCK DeviceListLock
;
93 } PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
99 PDEVICE_OBJECT PnpRootDeviceObject
;
102 /* FUNCTIONS *****************************************************************/
104 /* Physical Device Object routines */
108 PDEVICE_OBJECT
*PhysicalDeviceObject
)
110 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
111 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
112 PPNPROOT_DEVICE Device
;
115 /* This function should be obsoleted soon */
119 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
121 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
123 return STATUS_INSUFFICIENT_RESOURCES
;
125 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
127 Status
= IoCreateDevice(
128 PnpRootDeviceObject
->DriverObject
,
129 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
131 FILE_DEVICE_CONTROLLER
,
135 if (!NT_SUCCESS(Status
)) {
136 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
141 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
143 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
145 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
147 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
149 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
151 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
153 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
155 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
157 if (!IopCreateUnicodeString(
158 &PdoDeviceExtension
->DeviceID
,
164 DPRINT("IopCreateUnicodeString() failed\n");
167 if (!IopCreateUnicodeString(
168 &PdoDeviceExtension
->InstanceID
,
173 DPRINT("IopCreateUnicodeString() failed\n");
176 ExInterlockedInsertTailList(
177 &DeviceExtension
->DeviceListHead
,
179 &DeviceExtension
->DeviceListLock
);
181 DeviceExtension
->DeviceListCount
++;
183 *PhysicalDeviceObject
= Device
->Pdo
;
185 return STATUS_SUCCESS
;
191 IN PDEVICE_OBJECT DeviceObject
,
193 PIO_STACK_LOCATION IrpSp
)
195 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
196 UNICODE_STRING String
;
201 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
203 // Irp->IoStatus.Information = 0;
205 Status
= STATUS_SUCCESS
;
207 RtlInitUnicodeString(&String
, NULL
);
209 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
210 case BusQueryDeviceID
:
211 Status
= IopCreateUnicodeString(
213 DeviceExtension
->DeviceID
.Buffer
,
216 DPRINT("DeviceID: %S\n", String
.Buffer
);
218 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
221 case BusQueryHardwareIDs
:
222 case BusQueryCompatibleIDs
:
223 Status
= STATUS_NOT_IMPLEMENTED
;
226 case BusQueryInstanceID
:
227 Status
= IopCreateUnicodeString(
229 DeviceExtension
->InstanceID
.Buffer
,
232 DPRINT("InstanceID: %S\n", String
.Buffer
);
234 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
237 case BusQueryDeviceSerialNumber
:
239 Status
= STATUS_NOT_IMPLEMENTED
;
248 IN PDEVICE_OBJECT DeviceObject
,
250 PIO_STACK_LOCATION IrpSp
)
252 PCM_RESOURCE_LIST ResourceList
;
253 ULONG ResourceListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
);
255 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
256 if (ResourceList
== NULL
)
257 return STATUS_INSUFFICIENT_RESOURCES
;
259 ResourceList
->Count
= 0;
261 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
263 return STATUS_SUCCESS
;
268 PdoQueryResourceRequirements(
269 IN PDEVICE_OBJECT DeviceObject
,
271 PIO_STACK_LOCATION IrpSp
)
273 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
274 ULONG ResourceListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
);
276 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
277 if (ResourceList
== NULL
)
278 return STATUS_INSUFFICIENT_RESOURCES
;
280 RtlZeroMemory(ResourceList
, ResourceListSize
);
281 ResourceList
->ListSize
= ResourceListSize
;
283 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
285 return STATUS_SUCCESS
;
290 PnpRootPdoPnpControl(
291 PDEVICE_OBJECT DeviceObject
,
294 * FUNCTION: Handle Plug and Play IRPs for the child device
296 * DeviceObject = Pointer to physical device object of the child device
297 * Irp = Pointer to IRP that should be handled
302 PIO_STACK_LOCATION IrpSp
;
307 Status
= Irp
->IoStatus
.Status
;
309 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
311 switch (IrpSp
->MinorFunction
) {
313 case IRP_MN_QUERY_BUS_INFORMATION
:
316 case IRP_MN_QUERY_DEVICE_RELATIONS
:
317 /* FIXME: Handle for TargetDeviceRelation */
321 case IRP_MN_QUERY_ID
:
322 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
325 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
326 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
329 case IRP_MN_QUERY_RESOURCES
:
330 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
333 case IRP_MN_START_DEVICE
:
334 case IRP_MN_QUERY_STOP_DEVICE
:
335 case IRP_MN_CANCEL_STOP_DEVICE
:
336 case IRP_MN_STOP_DEVICE
:
337 case IRP_MN_QUERY_REMOVE_DEVICE
:
338 case IRP_MN_CANCEL_REMOVE_DEVICE
:
339 case IRP_MN_REMOVE_DEVICE
:
340 case IRP_MN_SURPRISE_REMOVAL
:
341 Status
= STATUS_SUCCESS
;
345 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
349 Irp
->IoStatus
.Status
= Status
;
350 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
352 DPRINT("Leaving. Status 0x%X\n", Status
);
358 PnpRootPdoPowerControl(
359 PDEVICE_OBJECT DeviceObject
,
362 * FUNCTION: Handle power management IRPs for the child device
364 * DeviceObject = Pointer to physical device object of the child device
365 * Irp = Pointer to IRP that should be handled
370 PIO_STACK_LOCATION IrpSp
;
375 Status
= Irp
->IoStatus
.Status
;
377 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
379 switch (IrpSp
->MinorFunction
) {
381 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
382 Status
= STATUS_NOT_IMPLEMENTED
;
386 Irp
->IoStatus
.Status
= Status
;
387 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
389 DPRINT("Leaving. Status 0x%X\n", Status
);
395 /* Functional Device Object routines */
398 PnpRootFdoReadDeviceInfo(
399 PPNPROOT_DEVICE Device
)
401 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
402 PUNICODE_STRING DeviceDesc
;
403 WCHAR KeyName
[MAX_PATH
];
408 /* Retrieve configuration from Enum key */
410 DeviceDesc
= &Device
->DeviceDescription
;
412 wcscpy(KeyName
, ENUM_NAME_ROOT
);
413 wcscat(KeyName
, L
"\\");
414 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
415 wcscat(KeyName
, L
"\\");
416 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
418 DPRINT("KeyName %S\n", KeyName
);
420 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
422 RtlInitUnicodeString(DeviceDesc
, NULL
);
424 QueryTable
[0].Name
= L
"DeviceDesc";
425 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
426 QueryTable
[0].EntryContext
= DeviceDesc
;
428 Status
= RtlQueryRegistryValues(
435 DPRINT("RtlQueryRegistryValues() returned status %x\n", Status
);
437 if (!NT_SUCCESS(Status
))
442 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
444 return STATUS_SUCCESS
;
449 PnpRootFdoEnumerateDevices(
450 PDEVICE_OBJECT DeviceObject
)
452 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
453 OBJECT_ATTRIBUTES ObjectAttributes
;
454 PKEY_BASIC_INFORMATION KeyInfo
;
455 UNICODE_STRING KeyName
;
456 PPNPROOT_DEVICE Device
;
457 WCHAR Buffer
[MAX_PATH
];
466 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
468 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
469 KeyInfo
= ExAllocatePool(PagedPool
, BufferSize
);
472 return STATUS_INSUFFICIENT_RESOURCES
;
475 RtlRosInitUnicodeStringFromLiteral(
477 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
480 InitializeObjectAttributes(
483 OBJ_CASE_INSENSITIVE
,
487 Status
= NtOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
488 if (!NT_SUCCESS(Status
))
490 DPRINT("NtOpenKey() failed (Status %x)\n", Status
);
495 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
496 there are more entries in the list than found in the registry as some
497 drivers are passed on the command line */
498 // DeviceExtension->DeviceListCount = 0;
502 Status
= ZwEnumerateKey(
509 if (!NT_SUCCESS(Status
))
511 DPRINT("ZwEnumerateKey() (Status %x)\n", Status
);
515 /* Terminate the string */
516 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
518 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
525 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
527 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
530 DPRINT("IopCreateUnicodeString() failed\n");
533 wcscpy(Buffer
, ENUM_NAME_ROOT
);
534 wcscat(Buffer
, L
"\\");
535 wcscat(Buffer
, KeyInfo
->Name
);
537 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
540 DPRINT("IopCreateUnicodeString() failed\n");
543 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
545 if (!IopCreateUnicodeString(
551 DPRINT("IopCreateUnicodeString() failed\n");
554 Status
= PnpRootFdoReadDeviceInfo(Device
);
555 if (!NT_SUCCESS(Status
))
557 DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status
);
561 ExInterlockedInsertTailList(
562 &DeviceExtension
->DeviceListHead
,
564 &DeviceExtension
->DeviceListLock
);
566 DeviceExtension
->DeviceListCount
++;
571 DPRINT("Entries found: %d\n", Index
);
577 return STATUS_SUCCESS
;
582 PnpRootQueryBusRelations(
583 IN PDEVICE_OBJECT DeviceObject
,
585 IN PIO_STACK_LOCATION IrpSp
)
587 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
588 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
589 PDEVICE_RELATIONS Relations
;
590 PLIST_ENTRY CurrentEntry
;
591 PPNPROOT_DEVICE Device
;
598 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
599 if (!NT_SUCCESS(Status
))
602 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
604 if (Irp
->IoStatus
.Information
)
606 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
607 structure so we must merge this structure with our own */
610 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
611 (DeviceExtension
->DeviceListCount
- 1);
613 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
615 return STATUS_INSUFFICIENT_RESOURCES
;
617 Relations
->Count
= DeviceExtension
->DeviceListCount
;
620 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
621 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
623 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
627 /* Create a physical device object for the
628 device as it does not already have one */
629 Status
= IoCreateDevice(
630 DeviceObject
->DriverObject
,
631 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
633 FILE_DEVICE_CONTROLLER
,
637 if (!NT_SUCCESS(Status
))
639 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
640 ExFreePool(Relations
);
644 DPRINT("Created PDO %x\n", Device
->Pdo
);
646 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
648 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
650 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
652 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
654 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
656 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
658 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
660 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
662 if (!IopCreateUnicodeString(
663 &PdoDeviceExtension
->DeviceID
,
664 Device
->DeviceID
.Buffer
,
667 DPRINT("Insufficient resources\n");
671 DPRINT("DeviceID: %S PDO %x\n",
672 PdoDeviceExtension
->DeviceID
.Buffer
,
675 if (!IopCreateUnicodeString(
676 &PdoDeviceExtension
->InstanceID
,
677 Device
->InstanceID
.Buffer
,
680 DPRINT("Insufficient resources\n");
686 /* Reference the physical device object. The PnP manager
687 will dereference it again when it is no longer needed */
688 ObReferenceObject(Device
->Pdo
);
690 Relations
->Objects
[i
] = Device
->Pdo
;
694 CurrentEntry
= CurrentEntry
->Flink
;
697 if (NT_SUCCESS(Status
))
699 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
703 Irp
->IoStatus
.Information
= 0;
711 PnpRootQueryDeviceRelations(
712 IN PDEVICE_OBJECT DeviceObject
,
714 IN PIO_STACK_LOCATION IrpSp
)
720 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
722 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
726 Status
= STATUS_NOT_IMPLEMENTED
;
735 PnpRootFdoPnpControl(
736 IN PDEVICE_OBJECT DeviceObject
,
739 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
741 * DeviceObject = Pointer to functional device object of the root bus driver
742 * Irp = Pointer to IRP that should be handled
747 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
748 PIO_STACK_LOCATION IrpSp
;
753 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
755 Status
= Irp
->IoStatus
.Status
;
757 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
759 switch (IrpSp
->MinorFunction
) {
760 case IRP_MN_QUERY_DEVICE_RELATIONS
:
761 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
764 case IRP_MN_START_DEVICE
:
765 DeviceExtension
->State
= dsStarted
;
766 Status
= STATUS_SUCCESS
;
769 case IRP_MN_STOP_DEVICE
:
770 /* Root device cannot be stopped */
771 Status
= STATUS_UNSUCCESSFUL
;
775 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
776 Status
= STATUS_NOT_IMPLEMENTED
;
780 if (Status
!= STATUS_PENDING
) {
781 Irp
->IoStatus
.Status
= Status
;
782 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
785 DPRINT("Leaving. Status 0x%X\n", Status
);
793 PnpRootFdoPowerControl(
794 IN PDEVICE_OBJECT DeviceObject
,
797 * FUNCTION: Handle power management IRPs for the root bus device object
799 * DeviceObject = Pointer to functional device object of the root bus driver
800 * Irp = Pointer to IRP that should be handled
805 PIO_STACK_LOCATION IrpSp
;
810 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
812 switch (IrpSp
->MinorFunction
) {
814 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
815 Status
= STATUS_NOT_IMPLEMENTED
;
819 if (Status
!= STATUS_PENDING
) {
820 Irp
->IoStatus
.Status
= Status
;
821 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
824 DPRINT("Leaving. Status 0x%X\n", Status
);
833 IN PDEVICE_OBJECT DeviceObject
,
836 * FUNCTION: Handle Plug and Play IRPs
838 * DeviceObject = Pointer to PDO or FDO
839 * Irp = Pointer to IRP that should be handled
844 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
847 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
849 DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
852 DeviceExtension
->IsFDO
);
854 if (DeviceExtension
->IsFDO
) {
855 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
857 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
867 IN PDEVICE_OBJECT DeviceObject
,
870 * FUNCTION: Handle power management IRPs
872 * DeviceObject = Pointer to PDO or FDO
873 * Irp = Pointer to IRP that should be handled
878 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
881 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
883 if (DeviceExtension
->IsFDO
) {
884 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
886 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
896 IN PDRIVER_OBJECT DriverObject
,
897 IN PDEVICE_OBJECT PhysicalDeviceObject
)
899 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
904 Status
= IoCreateDevice(
906 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
908 FILE_DEVICE_BUS_EXTENDER
,
909 FILE_DEVICE_SECURE_OPEN
,
911 &PnpRootDeviceObject
);
912 if (!NT_SUCCESS(Status
)) {
913 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
916 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
918 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
920 DeviceExtension
->Common
.IsFDO
= TRUE
;
922 DeviceExtension
->State
= dsStopped
;
924 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
926 PhysicalDeviceObject
);
928 if (!PnpRootDeviceObject
) {
929 CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
930 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
933 if (!PhysicalDeviceObject
) {
934 CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
935 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
938 InitializeListHead(&DeviceExtension
->DeviceListHead
);
940 DeviceExtension
->DeviceListCount
= 0;
942 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
944 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
946 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
948 DPRINT("Done AddDevice()\n");
950 return STATUS_SUCCESS
;
957 IN PDRIVER_OBJECT DriverObject
,
958 IN PUNICODE_STRING RegistryPath
)
962 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
963 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
964 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
966 return STATUS_SUCCESS
;