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
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
413 wcscat(KeyName
, ENUM_NAME_ROOT
);
414 wcscat(KeyName
, L
"\\");
415 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
416 wcscat(KeyName
, L
"\\");
417 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
419 DPRINT("KeyName %S\n", KeyName
);
421 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
423 RtlInitUnicodeString(DeviceDesc
, NULL
);
425 QueryTable
[0].Name
= L
"DeviceDesc";
426 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
427 QueryTable
[0].EntryContext
= DeviceDesc
;
429 Status
= RtlQueryRegistryValues(
430 RTL_REGISTRY_ABSOLUTE
,
436 DPRINT("RtlQueryRegistryValues() returned status %x\n", Status
);
438 if (!NT_SUCCESS(Status
))
443 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
445 return STATUS_SUCCESS
;
450 PnpRootFdoEnumerateDevices(
451 PDEVICE_OBJECT DeviceObject
)
453 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
454 OBJECT_ATTRIBUTES ObjectAttributes
;
455 PKEY_BASIC_INFORMATION KeyInfo
;
456 UNICODE_STRING KeyName
;
457 PPNPROOT_DEVICE Device
;
458 WCHAR Buffer
[MAX_PATH
];
467 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
469 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
470 KeyInfo
= ExAllocatePool(PagedPool
, BufferSize
);
473 return STATUS_INSUFFICIENT_RESOURCES
;
476 RtlRosInitUnicodeStringFromLiteral(
478 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
481 InitializeObjectAttributes(
484 OBJ_CASE_INSENSITIVE
,
488 Status
= NtOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
489 if (!NT_SUCCESS(Status
))
491 DPRINT("NtOpenKey() failed (Status %x)\n", Status
);
496 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
497 there are more entries in the list than found in the registry as some
498 drivers are passed on the command line */
499 // DeviceExtension->DeviceListCount = 0;
503 Status
= ZwEnumerateKey(
510 if (!NT_SUCCESS(Status
))
512 DPRINT("ZwEnumerateKey() (Status %x)\n", Status
);
516 /* Terminate the string */
517 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
519 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
526 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
528 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
531 DPRINT("IopCreateUnicodeString() failed\n");
534 wcscpy(Buffer
, ENUM_NAME_ROOT
);
535 wcscat(Buffer
, L
"\\");
536 wcscat(Buffer
, KeyInfo
->Name
);
538 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
541 DPRINT("IopCreateUnicodeString() failed\n");
544 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
546 if (!IopCreateUnicodeString(
552 DPRINT("IopCreateUnicodeString() failed\n");
555 Status
= PnpRootFdoReadDeviceInfo(Device
);
556 if (!NT_SUCCESS(Status
))
558 DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status
);
562 ExInterlockedInsertTailList(
563 &DeviceExtension
->DeviceListHead
,
565 &DeviceExtension
->DeviceListLock
);
567 DeviceExtension
->DeviceListCount
++;
572 DPRINT("Entries found: %d\n", Index
);
578 return STATUS_SUCCESS
;
583 PnpRootQueryBusRelations(
584 IN PDEVICE_OBJECT DeviceObject
,
586 IN PIO_STACK_LOCATION IrpSp
)
588 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
589 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
590 PDEVICE_RELATIONS Relations
;
591 PLIST_ENTRY CurrentEntry
;
592 PPNPROOT_DEVICE Device
;
599 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
600 if (!NT_SUCCESS(Status
))
603 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
605 if (Irp
->IoStatus
.Information
)
607 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
608 structure so we must merge this structure with our own */
611 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
612 (DeviceExtension
->DeviceListCount
- 1);
614 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
616 return STATUS_INSUFFICIENT_RESOURCES
;
618 Relations
->Count
= DeviceExtension
->DeviceListCount
;
621 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
622 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
624 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
628 /* Create a physical device object for the
629 device as it does not already have one */
630 Status
= IoCreateDevice(
631 DeviceObject
->DriverObject
,
632 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
634 FILE_DEVICE_CONTROLLER
,
638 if (!NT_SUCCESS(Status
))
640 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
641 ExFreePool(Relations
);
645 DPRINT("Created PDO %x\n", Device
->Pdo
);
647 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
649 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
651 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
653 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
655 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
657 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
659 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
661 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
663 if (!IopCreateUnicodeString(
664 &PdoDeviceExtension
->DeviceID
,
665 Device
->DeviceID
.Buffer
,
668 DPRINT("Insufficient resources\n");
672 DPRINT("DeviceID: %S PDO %x\n",
673 PdoDeviceExtension
->DeviceID
.Buffer
,
676 if (!IopCreateUnicodeString(
677 &PdoDeviceExtension
->InstanceID
,
678 Device
->InstanceID
.Buffer
,
681 DPRINT("Insufficient resources\n");
687 /* Reference the physical device object. The PnP manager
688 will dereference it again when it is no longer needed */
689 ObReferenceObject(Device
->Pdo
);
691 Relations
->Objects
[i
] = Device
->Pdo
;
695 CurrentEntry
= CurrentEntry
->Flink
;
698 if (NT_SUCCESS(Status
))
700 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
704 Irp
->IoStatus
.Information
= 0;
712 PnpRootQueryDeviceRelations(
713 IN PDEVICE_OBJECT DeviceObject
,
715 IN PIO_STACK_LOCATION IrpSp
)
721 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
723 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
727 Status
= STATUS_NOT_IMPLEMENTED
;
736 PnpRootFdoPnpControl(
737 IN PDEVICE_OBJECT DeviceObject
,
740 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
742 * DeviceObject = Pointer to functional device object of the root bus driver
743 * Irp = Pointer to IRP that should be handled
748 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
749 PIO_STACK_LOCATION IrpSp
;
754 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
756 Status
= Irp
->IoStatus
.Status
;
758 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
760 switch (IrpSp
->MinorFunction
) {
761 case IRP_MN_QUERY_DEVICE_RELATIONS
:
762 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
765 case IRP_MN_START_DEVICE
:
766 DeviceExtension
->State
= dsStarted
;
767 Status
= STATUS_SUCCESS
;
770 case IRP_MN_STOP_DEVICE
:
771 /* Root device cannot be stopped */
772 Status
= STATUS_UNSUCCESSFUL
;
776 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
777 Status
= STATUS_NOT_IMPLEMENTED
;
781 if (Status
!= STATUS_PENDING
) {
782 Irp
->IoStatus
.Status
= Status
;
783 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
786 DPRINT("Leaving. Status 0x%X\n", Status
);
794 PnpRootFdoPowerControl(
795 IN PDEVICE_OBJECT DeviceObject
,
798 * FUNCTION: Handle power management IRPs for the root bus device object
800 * DeviceObject = Pointer to functional device object of the root bus driver
801 * Irp = Pointer to IRP that should be handled
806 PIO_STACK_LOCATION IrpSp
;
811 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
813 switch (IrpSp
->MinorFunction
) {
815 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
816 Status
= STATUS_NOT_IMPLEMENTED
;
820 if (Status
!= STATUS_PENDING
) {
821 Irp
->IoStatus
.Status
= Status
;
822 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
825 DPRINT("Leaving. Status 0x%X\n", Status
);
834 IN PDEVICE_OBJECT DeviceObject
,
837 * FUNCTION: Handle Plug and Play IRPs
839 * DeviceObject = Pointer to PDO or FDO
840 * Irp = Pointer to IRP that should be handled
845 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
848 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
850 DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
853 DeviceExtension
->IsFDO
);
855 if (DeviceExtension
->IsFDO
) {
856 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
858 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
868 IN PDEVICE_OBJECT DeviceObject
,
871 * FUNCTION: Handle power management IRPs
873 * DeviceObject = Pointer to PDO or FDO
874 * Irp = Pointer to IRP that should be handled
879 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
882 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
884 if (DeviceExtension
->IsFDO
) {
885 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
887 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
897 IN PDRIVER_OBJECT DriverObject
,
898 IN PDEVICE_OBJECT PhysicalDeviceObject
)
900 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
905 Status
= IoCreateDevice(
907 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
909 FILE_DEVICE_BUS_EXTENDER
,
910 FILE_DEVICE_SECURE_OPEN
,
912 &PnpRootDeviceObject
);
913 if (!NT_SUCCESS(Status
)) {
914 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
917 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
919 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
921 DeviceExtension
->Common
.IsFDO
= TRUE
;
923 DeviceExtension
->State
= dsStopped
;
925 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
927 PhysicalDeviceObject
);
929 if (!PnpRootDeviceObject
) {
930 CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
931 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
934 if (!PhysicalDeviceObject
) {
935 CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
936 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
939 InitializeListHead(&DeviceExtension
->DeviceListHead
);
941 DeviceExtension
->DeviceListCount
= 0;
943 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
945 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
947 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
949 DPRINT("Done AddDevice()\n");
951 return STATUS_SUCCESS
;
958 IN PDRIVER_OBJECT DriverObject
,
959 IN PUNICODE_STRING RegistryPath
)
963 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
964 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
965 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
967 return STATUS_SUCCESS
;