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
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
11 /* INCLUDES ******************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 #define ENUM_NAME_ROOT L"Root"
21 /* DATA **********************************************************************/
23 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
;
46 } 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 } PNPROOT_COMMON_DEVICE_EXTENSION
, *PPNPROOT_COMMON_DEVICE_EXTENSION
;
64 /* Physical Device Object device extension for a child device */
65 typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
68 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
70 UNICODE_STRING DeviceID
;
72 UNICODE_STRING InstanceID
;
73 } PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
76 /* Functional Device Object device extension for the PCI driver device object */
77 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
80 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
81 // Physical Device Object
83 // Lower device object
85 // Current state of the driver
86 PNPROOT_DEVICE_STATE State
;
87 // Namespace device list
88 LIST_ENTRY DeviceListHead
;
89 // Number of (not removed) devices in device list
90 ULONG DeviceListCount
;
91 // Lock for namespace device list
92 // FIXME: Use fast mutex instead?
93 KSPIN_LOCK DeviceListLock
;
94 } PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
100 PDEVICE_OBJECT PnpRootDeviceObject
;
103 /* FUNCTIONS *****************************************************************/
105 /* Physical Device Object routines */
109 PDEVICE_OBJECT
*PhysicalDeviceObject
)
111 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
112 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
113 PPNPROOT_DEVICE Device
;
116 /* This function should be obsoleted soon */
120 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
122 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
124 return STATUS_INSUFFICIENT_RESOURCES
;
126 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
128 Status
= IoCreateDevice(
129 PnpRootDeviceObject
->DriverObject
,
130 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
132 FILE_DEVICE_CONTROLLER
,
136 if (!NT_SUCCESS(Status
)) {
137 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
142 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
144 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
146 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
148 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
150 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
152 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
154 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
156 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
158 if (!IopCreateUnicodeString(
159 &PdoDeviceExtension
->DeviceID
,
165 DPRINT("IopCreateUnicodeString() failed\n");
168 if (!IopCreateUnicodeString(
169 &PdoDeviceExtension
->InstanceID
,
174 DPRINT("IopCreateUnicodeString() failed\n");
177 ExInterlockedInsertTailList(
178 &DeviceExtension
->DeviceListHead
,
180 &DeviceExtension
->DeviceListLock
);
182 DeviceExtension
->DeviceListCount
++;
184 *PhysicalDeviceObject
= Device
->Pdo
;
186 return STATUS_SUCCESS
;
192 IN PDEVICE_OBJECT DeviceObject
,
194 PIO_STACK_LOCATION IrpSp
)
196 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
197 UNICODE_STRING String
;
202 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
204 // Irp->IoStatus.Information = 0;
206 Status
= STATUS_SUCCESS
;
208 RtlInitUnicodeString(&String
, NULL
);
210 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
211 case BusQueryDeviceID
:
212 Status
= IopCreateUnicodeString(
214 DeviceExtension
->DeviceID
.Buffer
,
217 DPRINT("DeviceID: %S\n", String
.Buffer
);
219 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
222 case BusQueryHardwareIDs
:
223 case BusQueryCompatibleIDs
:
224 Status
= STATUS_NOT_IMPLEMENTED
;
227 case BusQueryInstanceID
:
228 Status
= IopCreateUnicodeString(
230 DeviceExtension
->InstanceID
.Buffer
,
233 DPRINT("InstanceID: %S\n", String
.Buffer
);
235 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
238 case BusQueryDeviceSerialNumber
:
240 Status
= STATUS_NOT_IMPLEMENTED
;
249 IN PDEVICE_OBJECT DeviceObject
,
251 PIO_STACK_LOCATION IrpSp
)
253 PCM_RESOURCE_LIST ResourceList
;
254 ULONG ResourceListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
);
256 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
257 if (ResourceList
== NULL
)
258 return STATUS_INSUFFICIENT_RESOURCES
;
260 ResourceList
->Count
= 0;
262 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
264 return STATUS_SUCCESS
;
269 PdoQueryResourceRequirements(
270 IN PDEVICE_OBJECT DeviceObject
,
272 PIO_STACK_LOCATION IrpSp
)
274 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
275 ULONG ResourceListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
);
277 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
278 if (ResourceList
== NULL
)
279 return STATUS_INSUFFICIENT_RESOURCES
;
281 RtlZeroMemory(ResourceList
, ResourceListSize
);
282 ResourceList
->ListSize
= ResourceListSize
;
284 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
286 return STATUS_SUCCESS
;
291 * FUNCTION: Handle Plug and Play IRPs for the child device
293 * DeviceObject = Pointer to physical device object of the child device
294 * Irp = Pointer to IRP that should be handled
299 PnpRootPdoPnpControl(
300 PDEVICE_OBJECT DeviceObject
,
303 PIO_STACK_LOCATION IrpSp
;
308 Status
= Irp
->IoStatus
.Status
;
310 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
312 switch (IrpSp
->MinorFunction
) {
314 case IRP_MN_QUERY_BUS_INFORMATION
:
317 case IRP_MN_QUERY_DEVICE_RELATIONS
:
318 /* FIXME: Handle for TargetDeviceRelation */
322 case IRP_MN_QUERY_ID
:
323 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
326 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
327 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
330 case IRP_MN_QUERY_RESOURCES
:
331 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
334 case IRP_MN_START_DEVICE
:
335 case IRP_MN_QUERY_STOP_DEVICE
:
336 case IRP_MN_CANCEL_STOP_DEVICE
:
337 case IRP_MN_STOP_DEVICE
:
338 case IRP_MN_QUERY_REMOVE_DEVICE
:
339 case IRP_MN_CANCEL_REMOVE_DEVICE
:
340 case IRP_MN_REMOVE_DEVICE
:
341 case IRP_MN_SURPRISE_REMOVAL
:
342 Status
= STATUS_SUCCESS
;
346 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
350 Irp
->IoStatus
.Status
= Status
;
351 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
353 DPRINT("Leaving. Status 0x%X\n", Status
);
360 * FUNCTION: Handle power management IRPs for the child device
362 * DeviceObject = Pointer to physical device object of the child device
363 * Irp = Pointer to IRP that should be handled
368 PnpRootPdoPowerControl(
369 PDEVICE_OBJECT DeviceObject
,
372 PIO_STACK_LOCATION IrpSp
;
377 Status
= Irp
->IoStatus
.Status
;
379 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
381 switch (IrpSp
->MinorFunction
) {
383 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
384 Status
= STATUS_NOT_IMPLEMENTED
;
388 Irp
->IoStatus
.Status
= Status
;
389 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
391 DPRINT("Leaving. Status 0x%X\n", Status
);
397 /* Functional Device Object routines */
400 PnpRootFdoReadDeviceInfo(
401 PPNPROOT_DEVICE Device
)
403 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
404 PUNICODE_STRING DeviceDesc
;
405 WCHAR KeyName
[MAX_PATH
];
410 /* Retrieve configuration from Enum key */
412 DeviceDesc
= &Device
->DeviceDescription
;
414 wcscpy(KeyName
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
415 wcscat(KeyName
, ENUM_NAME_ROOT
);
416 wcscat(KeyName
, L
"\\");
417 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
418 wcscat(KeyName
, L
"\\");
419 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
421 DPRINT("KeyName %S\n", KeyName
);
423 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
425 RtlInitUnicodeString(DeviceDesc
, NULL
);
427 QueryTable
[0].Name
= L
"DeviceDesc";
428 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
429 QueryTable
[0].EntryContext
= DeviceDesc
;
431 Status
= RtlQueryRegistryValues(
432 RTL_REGISTRY_ABSOLUTE
,
438 DPRINT("RtlQueryRegistryValues() returned status %x\n", Status
);
440 if (!NT_SUCCESS(Status
))
445 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
447 return STATUS_SUCCESS
;
452 PnpRootFdoEnumerateDevices(
453 PDEVICE_OBJECT DeviceObject
)
455 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
456 OBJECT_ATTRIBUTES ObjectAttributes
;
457 PKEY_BASIC_INFORMATION KeyInfo
;
458 UNICODE_STRING KeyName
;
459 PPNPROOT_DEVICE Device
;
460 WCHAR Buffer
[MAX_PATH
];
469 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
471 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
472 KeyInfo
= ExAllocatePool(PagedPool
, BufferSize
);
475 return STATUS_INSUFFICIENT_RESOURCES
;
478 RtlRosInitUnicodeStringFromLiteral(
480 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
483 InitializeObjectAttributes(
486 OBJ_CASE_INSENSITIVE
,
490 Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
491 if (!NT_SUCCESS(Status
))
493 DPRINT("ZwOpenKey() failed (Status %x)\n", Status
);
498 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
499 there are more entries in the list than found in the registry as some
500 drivers are passed on the command line */
501 // DeviceExtension->DeviceListCount = 0;
505 Status
= ZwEnumerateKey(
512 if (!NT_SUCCESS(Status
))
514 DPRINT("ZwEnumerateKey() (Status %x)\n", Status
);
518 /* Terminate the string */
519 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
521 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
528 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
530 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
533 DPRINT("IopCreateUnicodeString() failed\n");
536 wcscpy(Buffer
, ENUM_NAME_ROOT
);
537 wcscat(Buffer
, L
"\\");
538 wcscat(Buffer
, KeyInfo
->Name
);
540 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
543 DPRINT("IopCreateUnicodeString() failed\n");
546 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
548 if (!IopCreateUnicodeString(
554 DPRINT("IopCreateUnicodeString() failed\n");
557 Status
= PnpRootFdoReadDeviceInfo(Device
);
558 if (!NT_SUCCESS(Status
))
560 DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status
);
564 ExInterlockedInsertTailList(
565 &DeviceExtension
->DeviceListHead
,
567 &DeviceExtension
->DeviceListLock
);
569 DeviceExtension
->DeviceListCount
++;
574 DPRINT("Entries found: %d\n", Index
);
580 return STATUS_SUCCESS
;
585 PnpRootQueryBusRelations(
586 IN PDEVICE_OBJECT DeviceObject
,
588 IN PIO_STACK_LOCATION IrpSp
)
590 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
591 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
592 PDEVICE_RELATIONS Relations
;
593 PLIST_ENTRY CurrentEntry
;
594 PPNPROOT_DEVICE Device
;
601 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
602 if (!NT_SUCCESS(Status
))
605 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
607 if (Irp
->IoStatus
.Information
)
609 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
610 structure so we must merge this structure with our own */
613 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
614 (DeviceExtension
->DeviceListCount
- 1);
616 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
618 return STATUS_INSUFFICIENT_RESOURCES
;
620 Relations
->Count
= DeviceExtension
->DeviceListCount
;
623 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
624 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
626 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
630 /* Create a physical device object for the
631 device as it does not already have one */
632 Status
= IoCreateDevice(
633 DeviceObject
->DriverObject
,
634 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
636 FILE_DEVICE_CONTROLLER
,
640 if (!NT_SUCCESS(Status
))
642 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
643 ExFreePool(Relations
);
647 DPRINT("Created PDO %x\n", Device
->Pdo
);
649 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
651 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
653 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
655 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
657 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
659 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
661 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
663 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
665 if (!IopCreateUnicodeString(
666 &PdoDeviceExtension
->DeviceID
,
667 Device
->DeviceID
.Buffer
,
670 DPRINT("Insufficient resources\n");
674 DPRINT1("DeviceID: %wZ PDO %p\n",
675 &PdoDeviceExtension
->DeviceID
,
678 if (!IopCreateUnicodeString(
679 &PdoDeviceExtension
->InstanceID
,
680 Device
->InstanceID
.Buffer
,
683 DPRINT("Insufficient resources\n");
687 DPRINT1("InstanceID: %wZ PDO %p\n",
688 &PdoDeviceExtension
->InstanceID
,
692 /* Reference the physical device object. The PnP manager
693 will dereference it again when it is no longer needed */
694 ObReferenceObject(Device
->Pdo
);
696 Relations
->Objects
[i
] = Device
->Pdo
;
700 CurrentEntry
= CurrentEntry
->Flink
;
703 if (NT_SUCCESS(Status
))
705 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
709 Irp
->IoStatus
.Information
= 0;
717 PnpRootQueryDeviceRelations(
718 IN PDEVICE_OBJECT DeviceObject
,
720 IN PIO_STACK_LOCATION IrpSp
)
726 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
728 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
732 Status
= STATUS_NOT_IMPLEMENTED
;
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
749 PnpRootFdoPnpControl(
750 IN PDEVICE_OBJECT DeviceObject
,
753 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
754 PIO_STACK_LOCATION IrpSp
;
759 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
761 Status
= Irp
->IoStatus
.Status
;
763 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
765 switch (IrpSp
->MinorFunction
) {
766 case IRP_MN_QUERY_DEVICE_RELATIONS
:
767 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
770 case IRP_MN_START_DEVICE
:
771 DeviceExtension
->State
= dsStarted
;
772 Status
= STATUS_SUCCESS
;
775 case IRP_MN_STOP_DEVICE
:
776 /* Root device cannot be stopped */
777 Status
= STATUS_UNSUCCESSFUL
;
781 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
782 Status
= STATUS_NOT_IMPLEMENTED
;
786 if (Status
!= STATUS_PENDING
) {
787 Irp
->IoStatus
.Status
= Status
;
788 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
791 DPRINT("Leaving. Status 0x%X\n", Status
);
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
807 PnpRootFdoPowerControl(
808 IN PDEVICE_OBJECT DeviceObject
,
811 PIO_STACK_LOCATION IrpSp
;
816 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
818 switch (IrpSp
->MinorFunction
) {
820 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
821 Status
= STATUS_NOT_IMPLEMENTED
;
825 if (Status
!= STATUS_PENDING
) {
826 Irp
->IoStatus
.Status
= Status
;
827 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
830 DPRINT("Leaving. Status 0x%X\n", Status
);
837 * FUNCTION: Handle Plug and Play IRPs
839 * DeviceObject = Pointer to PDO or FDO
840 * Irp = Pointer to IRP that should be handled
847 IN PDEVICE_OBJECT DeviceObject
,
850 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
853 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
855 DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
858 DeviceExtension
->IsFDO
);
860 if (DeviceExtension
->IsFDO
) {
861 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
863 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
871 * FUNCTION: Handle power management IRPs
873 * DeviceObject = Pointer to PDO or FDO
874 * Irp = Pointer to IRP that should be handled
881 IN PDEVICE_OBJECT DeviceObject
,
884 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
887 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
889 if (DeviceExtension
->IsFDO
) {
890 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
892 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
902 IN PDRIVER_OBJECT DriverObject
,
903 IN PDEVICE_OBJECT PhysicalDeviceObject
)
905 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
910 Status
= IoCreateDevice(
912 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
914 FILE_DEVICE_BUS_EXTENDER
,
915 FILE_DEVICE_SECURE_OPEN
,
917 &PnpRootDeviceObject
);
918 if (!NT_SUCCESS(Status
)) {
919 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
922 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
924 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
926 DeviceExtension
->Common
.IsFDO
= TRUE
;
928 DeviceExtension
->State
= dsStopped
;
930 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
932 PhysicalDeviceObject
);
934 if (!PnpRootDeviceObject
) {
935 CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
936 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
939 if (!PhysicalDeviceObject
) {
940 CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
941 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
944 InitializeListHead(&DeviceExtension
->DeviceListHead
);
946 DeviceExtension
->DeviceListCount
= 0;
948 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
950 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
952 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
954 DPRINT("Done AddDevice()\n");
956 return STATUS_SUCCESS
;
963 IN PDRIVER_OBJECT DriverObject
,
964 IN PUNICODE_STRING RegistryPath
)
968 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
969 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
970 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
972 return STATUS_SUCCESS
;