1 /* $Id: pnproot.c,v 1.6 2001/09/16 13:19:32 chorns 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>
16 #include <internal/registry.h>
19 #include <internal/debug.h>
21 /* GLOBALS *******************************************************************/
23 #define ENUM_NAME_ROOT L"Root"
25 /* DATA **********************************************************************/
27 typedef struct _PNPROOT_DEVICE
{
28 // Entry on device list
30 // Physical Device Object of device
33 UNICODE_STRING ServiceName
;
35 UNICODE_STRING DeviceID
;
37 UNICODE_STRING InstanceID
;
39 UNICODE_STRING DeviceDescription
;
40 } PNPROOT_DEVICE
, *PPNPROOT_DEVICE
;
48 } PNPROOT_DEVICE_STATE
;
51 typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
53 // Pointer to device object, this device extension is associated with
54 PDEVICE_OBJECT DeviceObject
;
55 // Wether this device extension is for an FDO or PDO
57 // Wether the device is removed
59 // Current device power state for the device
60 DEVICE_POWER_STATE DevicePowerState
;
61 } __attribute((packed
)) 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
;
69 UNICODE_STRING DeviceID
;
71 UNICODE_STRING InstanceID
;
72 } __attribute((packed
)) PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
74 /* Functional Device Object device extension for the PCI driver device object */
75 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
78 PNPROOT_COMMON_DEVICE_EXTENSION
;
79 // Physical Device Object
81 // Lower device object
83 // Current state of the driver
84 PNPROOT_DEVICE_STATE State
;
85 // Namespace device list
86 LIST_ENTRY DeviceListHead
;
87 // Number of (not removed) devices in device list
88 ULONG DeviceListCount
;
89 // Lock for namespace device list
90 // FIXME: Use fast mutex instead?
91 KSPIN_LOCK DeviceListLock
;
92 } __attribute((packed
)) PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
95 PDEVICE_OBJECT PnpRootDeviceObject
;
98 /* FUNCTIONS *****************************************************************/
100 /* Physical Device Object routines */
104 PDEVICE_OBJECT
*PhysicalDeviceObject
)
106 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
107 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
108 PPNPROOT_DEVICE Device
;
111 /* This function should be obsoleted soon */
115 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
117 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
119 return STATUS_INSUFFICIENT_RESOURCES
;
121 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
123 Status
= IoCreateDevice(
124 PnpRootDeviceObject
->DriverObject
,
125 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
127 FILE_DEVICE_CONTROLLER
,
131 if (!NT_SUCCESS(Status
)) {
132 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
137 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
139 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
141 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
143 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
145 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
147 PdoDeviceExtension
->IsFDO
= FALSE
;
149 PdoDeviceExtension
->DeviceObject
= Device
->Pdo
;
151 PdoDeviceExtension
->DevicePowerState
= PowerDeviceD0
;
153 if (!IopCreateUnicodeString(
154 &PdoDeviceExtension
->DeviceID
,
160 DPRINT("IopCreateUnicodeString() failed\n");
163 if (!IopCreateUnicodeString(
164 &PdoDeviceExtension
->InstanceID
,
169 DPRINT("IopCreateUnicodeString() failed\n");
172 ExInterlockedInsertTailList(
173 &DeviceExtension
->DeviceListHead
,
175 &DeviceExtension
->DeviceListLock
);
177 DeviceExtension
->DeviceListCount
++;
179 *PhysicalDeviceObject
= Device
->Pdo
;
181 return STATUS_SUCCESS
;
187 IN PDEVICE_OBJECT DeviceObject
,
189 PIO_STACK_LOCATION IrpSp
)
191 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
192 UNICODE_STRING String
;
197 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
199 // Irp->IoStatus.Information = 0;
201 Status
= STATUS_SUCCESS
;
203 RtlInitUnicodeString(&String
, NULL
);
205 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
206 case BusQueryDeviceID
:
207 Status
= IopCreateUnicodeString(
209 DeviceExtension
->DeviceID
.Buffer
,
212 DPRINT("DeviceID: %S\n", String
.Buffer
);
214 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
217 case BusQueryHardwareIDs
:
218 case BusQueryCompatibleIDs
:
219 Status
= STATUS_NOT_IMPLEMENTED
;
222 case BusQueryInstanceID
:
223 Status
= IopCreateUnicodeString(
225 DeviceExtension
->InstanceID
.Buffer
,
228 DPRINT("InstanceID: %S\n", String
.Buffer
);
230 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
233 case BusQueryDeviceSerialNumber
:
235 Status
= STATUS_NOT_IMPLEMENTED
;
243 PnpRootPdoPnpControl(
244 PDEVICE_OBJECT DeviceObject
,
247 * FUNCTION: Handle Plug and Play IRPs for the child device
249 * DeviceObject = Pointer to physical device object of the child device
250 * Irp = Pointer to IRP that should be handled
255 PIO_STACK_LOCATION IrpSp
;
260 Status
= Irp
->IoStatus
.Status
;
262 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
264 switch (IrpSp
->MinorFunction
) {
266 case IRP_MN_CANCEL_REMOVE_DEVICE
:
269 case IRP_MN_CANCEL_STOP_DEVICE
:
272 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
278 case IRP_MN_QUERY_BUS_INFORMATION
:
281 case IRP_MN_QUERY_CAPABILITIES
:
284 case IRP_MN_QUERY_DEVICE_RELATIONS
:
285 /* FIXME: Possibly handle for RemovalRelations */
288 case IRP_MN_QUERY_DEVICE_TEXT
:
291 case IRP_MN_QUERY_ID
:
292 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
295 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
298 case IRP_MN_QUERY_REMOVE_DEVICE
:
301 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
304 case IRP_MN_QUERY_RESOURCES
:
307 case IRP_MN_QUERY_STOP_DEVICE
:
310 case IRP_MN_REMOVE_DEVICE
:
313 case IRP_MN_SET_LOCK
:
316 case IRP_MN_START_DEVICE
:
319 case IRP_MN_STOP_DEVICE
:
322 case IRP_MN_SURPRISE_REMOVAL
:
326 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
330 Irp
->IoStatus
.Status
= Status
;
331 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
333 DPRINT("Leaving. Status 0x%X\n", Status
);
339 PnpRootPdoPowerControl(
340 PDEVICE_OBJECT DeviceObject
,
343 * FUNCTION: Handle power management IRPs for the child device
345 * DeviceObject = Pointer to physical device object of the child device
346 * Irp = Pointer to IRP that should be handled
351 PIO_STACK_LOCATION IrpSp
;
356 Status
= Irp
->IoStatus
.Status
;
358 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
360 switch (IrpSp
->MinorFunction
) {
362 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
366 Irp
->IoStatus
.Status
= Status
;
367 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
369 DPRINT("Leaving. Status 0x%X\n", Status
);
375 /* Functional Device Object routines */
378 PnpRootFdoReadDeviceInfo(
379 PPNPROOT_DEVICE Device
)
381 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
382 PUNICODE_STRING DeviceDesc
;
383 WCHAR KeyName
[MAX_PATH
];
389 /* Retrieve configuration from Enum key */
391 DeviceDesc
= &Device
->DeviceDescription
;
393 wcscpy(KeyName
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
394 wcscat(KeyName
, ENUM_NAME_ROOT
);
395 wcscat(KeyName
, L
"\\");
396 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
397 wcscat(KeyName
, L
"\\");
398 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
400 DPRINT("KeyName %S\n", KeyName
);
402 Status
= RtlpGetRegistryHandle(
403 RTL_REGISTRY_ABSOLUTE
,
407 if (!NT_SUCCESS(Status
))
409 DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
413 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
415 RtlInitUnicodeString(DeviceDesc
, NULL
);
417 QueryTable
[0].Name
= L
"DeviceDesc";
418 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
419 QueryTable
[0].EntryContext
= DeviceDesc
;
421 Status
= RtlQueryRegistryValues(
430 DPRINT("RtlQueryRegistryValues() returned status %x\n", Status
);
432 if (!NT_SUCCESS(Status
))
437 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
439 return STATUS_SUCCESS
;
444 PnpRootFdoEnumerateDevices(
445 PDEVICE_OBJECT DeviceObject
)
447 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
448 OBJECT_ATTRIBUTES ObjectAttributes
;
449 PKEY_BASIC_INFORMATION KeyInfo
;
450 UNICODE_STRING KeyName
;
451 PPNPROOT_DEVICE Device
;
452 WCHAR Buffer
[MAX_PATH
];
461 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
463 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
464 KeyInfo
= ExAllocatePool(PagedPool
, BufferSize
);
467 return STATUS_INSUFFICIENT_RESOURCES
;
470 RtlInitUnicodeString(
472 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
475 InitializeObjectAttributes(
478 OBJ_CASE_INSENSITIVE
,
482 Status
= NtOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
483 if (!NT_SUCCESS(Status
))
485 DPRINT("NtOpenKey() failed (Status %x)\n", Status
);
490 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
491 there are more entries in the list than found in the registry as some
492 drivers are passed on the command line */
493 // DeviceExtension->DeviceListCount = 0;
497 Status
= ZwEnumerateKey(
504 if (!NT_SUCCESS(Status
))
506 DPRINT("ZwEnumerateKey() (Status %x)\n", Status
);
510 /* Terminate the string */
511 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
513 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
520 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
522 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
525 DPRINT("IopCreateUnicodeString() failed\n");
528 wcscpy(Buffer
, ENUM_NAME_ROOT
);
529 wcscat(Buffer
, L
"\\");
530 wcscat(Buffer
, KeyInfo
->Name
);
532 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
535 DPRINT("IopCreateUnicodeString() failed\n");
538 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
540 if (!IopCreateUnicodeString(
546 DPRINT("IopCreateUnicodeString() failed\n");
549 Status
= PnpRootFdoReadDeviceInfo(Device
);
550 if (!NT_SUCCESS(Status
))
552 DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status
);
556 ExInterlockedInsertTailList(
557 &DeviceExtension
->DeviceListHead
,
559 &DeviceExtension
->DeviceListLock
);
561 DeviceExtension
->DeviceListCount
++;
566 DPRINT("Entries found: %d\n", Index
);
572 return STATUS_SUCCESS
;
577 PnpRootQueryBusRelations(
578 IN PDEVICE_OBJECT DeviceObject
,
580 IN PIO_STACK_LOCATION IrpSp
)
582 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
583 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
584 PDEVICE_RELATIONS Relations
;
585 PLIST_ENTRY CurrentEntry
;
586 PPNPROOT_DEVICE Device
;
593 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
594 if (!NT_SUCCESS(Status
))
597 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
599 if (Irp
->IoStatus
.Information
)
601 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
602 structure so we must merge this structure with our own */
605 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
606 (DeviceExtension
->DeviceListCount
- 1);
608 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
610 return STATUS_INSUFFICIENT_RESOURCES
;
612 Relations
->Count
= DeviceExtension
->DeviceListCount
;
615 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
616 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
618 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
622 /* Create a physical device object for the
623 device as it does not already have one */
624 Status
= IoCreateDevice(
625 DeviceObject
->DriverObject
,
626 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
628 FILE_DEVICE_CONTROLLER
,
632 if (!NT_SUCCESS(Status
))
634 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
635 ExFreePool(Relations
);
639 DPRINT("Created PDO %x\n", Device
->Pdo
);
641 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
643 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
645 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
647 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
649 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
651 PdoDeviceExtension
->IsFDO
= FALSE
;
653 PdoDeviceExtension
->DeviceObject
= Device
->Pdo
;
655 PdoDeviceExtension
->DevicePowerState
= PowerDeviceD0
;
657 if (!IopCreateUnicodeString(
658 &PdoDeviceExtension
->DeviceID
,
659 Device
->DeviceID
.Buffer
,
662 DPRINT("Insufficient resources\n");
666 DPRINT("DeviceID: %S PDO %x\n",
667 PdoDeviceExtension
->DeviceID
.Buffer
,
670 if (!IopCreateUnicodeString(
671 &PdoDeviceExtension
->InstanceID
,
672 Device
->InstanceID
.Buffer
,
675 DPRINT("Insufficient resources\n");
681 /* Reference the physical device object. The PnP manager
682 will dereference it again when it is no longer needed */
683 ObReferenceObject(Device
->Pdo
);
685 Relations
->Objects
[i
] = Device
->Pdo
;
689 CurrentEntry
= CurrentEntry
->Flink
;
692 if (NT_SUCCESS(Status
))
694 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
698 Irp
->IoStatus
.Information
= 0;
706 PnpRootQueryDeviceRelations(
707 IN PDEVICE_OBJECT DeviceObject
,
709 IN PIO_STACK_LOCATION IrpSp
)
715 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
717 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
721 Status
= STATUS_NOT_IMPLEMENTED
;
730 PnpRootFdoPnpControl(
731 IN PDEVICE_OBJECT DeviceObject
,
734 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
736 * DeviceObject = Pointer to functional device object of the root bus driver
737 * Irp = Pointer to IRP that should be handled
742 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
743 PIO_STACK_LOCATION IrpSp
;
748 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
750 Status
= Irp
->IoStatus
.Status
;
752 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
754 switch (IrpSp
->MinorFunction
) {
755 case IRP_MN_QUERY_DEVICE_RELATIONS
:
756 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
759 case IRP_MN_START_DEVICE
:
760 DeviceExtension
->State
= dsStarted
;
761 Status
= STATUS_SUCCESS
;
764 case IRP_MN_STOP_DEVICE
:
765 /* Root device cannot be stopped */
766 Status
= STATUS_UNSUCCESSFUL
;
770 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
771 Status
= STATUS_NOT_IMPLEMENTED
;
775 if (Status
!= STATUS_PENDING
) {
776 Irp
->IoStatus
.Status
= Status
;
777 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
780 DPRINT("Leaving. Status 0x%X\n", Status
);
788 PnpRootFdoPowerControl(
789 IN PDEVICE_OBJECT DeviceObject
,
792 * FUNCTION: Handle power management IRPs for the root bus device object
794 * DeviceObject = Pointer to functional device object of the root bus driver
795 * Irp = Pointer to IRP that should be handled
800 PIO_STACK_LOCATION IrpSp
;
805 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
807 switch (IrpSp
->MinorFunction
) {
809 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
810 Status
= STATUS_NOT_IMPLEMENTED
;
814 if (Status
!= STATUS_PENDING
) {
815 Irp
->IoStatus
.Status
= Status
;
816 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
819 DPRINT("Leaving. Status 0x%X\n", Status
);
828 IN PDEVICE_OBJECT DeviceObject
,
831 * FUNCTION: Handle Plug and Play IRPs
833 * DeviceObject = Pointer to PDO or FDO
834 * Irp = Pointer to IRP that should be handled
839 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
842 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
844 DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
847 DeviceExtension
->IsFDO
);
849 if (DeviceExtension
->IsFDO
) {
850 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
852 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
862 IN PDEVICE_OBJECT DeviceObject
,
865 * FUNCTION: Handle power management IRPs
867 * DeviceObject = Pointer to PDO or FDO
868 * Irp = Pointer to IRP that should be handled
873 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
876 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
878 if (DeviceExtension
->IsFDO
) {
879 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
881 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
891 IN PDRIVER_OBJECT DriverObject
,
892 IN PDEVICE_OBJECT PhysicalDeviceObject
)
894 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
899 Status
= IoCreateDevice(
901 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
903 FILE_DEVICE_BUS_EXTENDER
,
904 FILE_DEVICE_SECURE_OPEN
,
906 &PnpRootDeviceObject
);
907 if (!NT_SUCCESS(Status
)) {
908 CPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
909 KeBugCheck(PHASE1_INITIALIZATION_FAILED
);
912 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
914 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
916 DeviceExtension
->IsFDO
= TRUE
;
918 DeviceExtension
->State
= dsStopped
;
920 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
922 PhysicalDeviceObject
);
924 if (!PnpRootDeviceObject
) {
925 CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
926 KeBugCheck(PHASE1_INITIALIZATION_FAILED
);
929 if (!PhysicalDeviceObject
) {
930 CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
931 KeBugCheck(PHASE1_INITIALIZATION_FAILED
);
934 InitializeListHead(&DeviceExtension
->DeviceListHead
);
936 DeviceExtension
->DeviceListCount
= 0;
938 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
940 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
942 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
944 DPRINT("Done AddDevice()\n");
946 return STATUS_SUCCESS
;
953 IN PDRIVER_OBJECT DriverObject
,
954 IN PUNICODE_STRING RegistryPath
)
958 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PnpRootPnpControl
;
959 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PnpRootPowerControl
;
960 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
962 return STATUS_SUCCESS
;