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 // Resource requirement list
38 PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
;
39 } PNPROOT_DEVICE
, *PPNPROOT_DEVICE
;
48 } PNPROOT_DEVICE_STATE
;
53 typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
55 // Pointer to device object, this device extension is associated with
56 PDEVICE_OBJECT DeviceObject
;
57 // Wether this device extension is for an FDO or PDO
59 // Wether the device is removed
61 // Current device power state for the device
62 DEVICE_POWER_STATE DevicePowerState
;
63 } PNPROOT_COMMON_DEVICE_EXTENSION
, *PPNPROOT_COMMON_DEVICE_EXTENSION
;
66 /* Physical Device Object device extension for a child device */
67 typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
70 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
72 UNICODE_STRING DeviceID
;
74 UNICODE_STRING InstanceID
;
75 // Resource requirement list
76 PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
;
77 } PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
80 /* Functional Device Object device extension for the PCI driver device object */
81 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
84 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
85 // Physical Device Object
87 // Lower device object
89 // Current state of the driver
90 PNPROOT_DEVICE_STATE State
;
91 // Namespace device list
92 LIST_ENTRY DeviceListHead
;
93 // Number of (not removed) devices in device list
94 ULONG DeviceListCount
;
95 // Lock for namespace device list
96 // FIXME: Use fast mutex instead?
97 KSPIN_LOCK DeviceListLock
;
98 } PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
104 PDEVICE_OBJECT PnpRootDeviceObject
;
107 /* FUNCTIONS *****************************************************************/
109 /* Physical Device Object routines */
113 PDEVICE_OBJECT
*PhysicalDeviceObject
)
115 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
116 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
117 PPNPROOT_DEVICE Device
;
120 /* This function should be obsoleted soon */
124 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
126 Device
= (PPNPROOT_DEVICE
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNPROOT_DEVICE
), TAG_PNP_ROOT
);
128 return STATUS_INSUFFICIENT_RESOURCES
;
130 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
132 Status
= IoCreateDevice(
133 PnpRootDeviceObject
->DriverObject
,
134 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
136 FILE_DEVICE_CONTROLLER
,
137 FILE_AUTOGENERATED_DEVICE_NAME
,
140 if (!NT_SUCCESS(Status
)) {
141 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
146 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
148 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
150 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
152 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
154 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
156 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
158 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
160 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
162 if (!IopCreateUnicodeString(
163 &PdoDeviceExtension
->DeviceID
,
169 DPRINT("IopCreateUnicodeString() failed\n");
172 if (!IopCreateUnicodeString(
173 &PdoDeviceExtension
->InstanceID
,
178 DPRINT("IopCreateUnicodeString() failed\n");
181 ExInterlockedInsertTailList(
182 &DeviceExtension
->DeviceListHead
,
184 &DeviceExtension
->DeviceListLock
);
186 DeviceExtension
->DeviceListCount
++;
188 *PhysicalDeviceObject
= Device
->Pdo
;
190 return STATUS_SUCCESS
;
196 IN PDEVICE_OBJECT DeviceObject
,
198 PIO_STACK_LOCATION IrpSp
)
200 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
201 UNICODE_STRING String
;
206 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
208 // Irp->IoStatus.Information = 0;
210 Status
= STATUS_SUCCESS
;
212 RtlInitUnicodeString(&String
, NULL
);
214 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
215 case BusQueryDeviceID
:
216 Status
= IopCreateUnicodeString(
218 DeviceExtension
->DeviceID
.Buffer
,
221 DPRINT("DeviceID: %S\n", String
.Buffer
);
223 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
226 case BusQueryHardwareIDs
:
227 case BusQueryCompatibleIDs
:
228 Status
= STATUS_NOT_IMPLEMENTED
;
231 case BusQueryInstanceID
:
232 Status
= IopCreateUnicodeString(
234 DeviceExtension
->InstanceID
.Buffer
,
237 DPRINT("InstanceID: %S\n", String
.Buffer
);
239 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
242 case BusQueryDeviceSerialNumber
:
244 Status
= STATUS_NOT_IMPLEMENTED
;
253 IN PDEVICE_OBJECT DeviceObject
,
255 PIO_STACK_LOCATION IrpSp
)
257 PCM_RESOURCE_LIST ResourceList
;
258 ULONG ResourceListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
);
260 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
261 if (ResourceList
== NULL
)
262 return STATUS_INSUFFICIENT_RESOURCES
;
264 ResourceList
->Count
= 0;
266 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
268 return STATUS_SUCCESS
;
273 PdoQueryResourceRequirements(
274 IN PDEVICE_OBJECT DeviceObject
,
276 PIO_STACK_LOCATION IrpSp
)
278 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
279 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
280 ULONG ResourceListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
);
284 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
286 if (DeviceExtension
->ResourceRequirementsList
== NULL
)
288 /* Create an empty resource list */
289 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
290 if (ResourceList
== NULL
)
291 return STATUS_INSUFFICIENT_RESOURCES
;
293 RtlZeroMemory(ResourceList
, ResourceListSize
);
294 ResourceList
->ListSize
= ResourceListSize
;
296 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
300 /* Copy existing resource requirement list */
301 ResourceList
= ExAllocatePool(PagedPool
, DeviceExtension
->ResourceRequirementsList
->ListSize
);
302 if (ResourceList
== NULL
)
303 return STATUS_INSUFFICIENT_RESOURCES
;
307 DeviceExtension
->ResourceRequirementsList
,
308 DeviceExtension
->ResourceRequirementsList
->ListSize
);
309 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
312 return STATUS_SUCCESS
;
317 * FUNCTION: Handle Plug and Play IRPs for the child device
319 * DeviceObject = Pointer to physical device object of the child device
320 * Irp = Pointer to IRP that should be handled
325 PnpRootPdoPnpControl(
326 PDEVICE_OBJECT DeviceObject
,
329 PIO_STACK_LOCATION IrpSp
;
334 Status
= Irp
->IoStatus
.Status
;
336 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
338 switch (IrpSp
->MinorFunction
) {
340 case IRP_MN_QUERY_BUS_INFORMATION
:
343 case IRP_MN_QUERY_DEVICE_RELATIONS
:
344 /* FIXME: Handle for TargetDeviceRelation */
348 case IRP_MN_QUERY_ID
:
349 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
352 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
353 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
356 case IRP_MN_QUERY_RESOURCES
:
357 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
360 case IRP_MN_START_DEVICE
:
361 case IRP_MN_QUERY_STOP_DEVICE
:
362 case IRP_MN_CANCEL_STOP_DEVICE
:
363 case IRP_MN_STOP_DEVICE
:
364 case IRP_MN_QUERY_REMOVE_DEVICE
:
365 case IRP_MN_CANCEL_REMOVE_DEVICE
:
366 case IRP_MN_REMOVE_DEVICE
:
367 case IRP_MN_SURPRISE_REMOVAL
:
368 Status
= STATUS_SUCCESS
;
372 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
376 Irp
->IoStatus
.Status
= Status
;
377 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
379 DPRINT("Leaving. Status 0x%X\n", Status
);
386 * FUNCTION: Handle power management IRPs for the child device
388 * DeviceObject = Pointer to physical device object of the child device
389 * Irp = Pointer to IRP that should be handled
394 PnpRootPdoPowerControl(
395 PDEVICE_OBJECT DeviceObject
,
398 PIO_STACK_LOCATION IrpSp
;
403 Status
= Irp
->IoStatus
.Status
;
405 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
407 switch (IrpSp
->MinorFunction
) {
409 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
410 Status
= STATUS_NOT_IMPLEMENTED
;
414 Irp
->IoStatus
.Status
= Status
;
415 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
417 DPRINT("Leaving. Status 0x%X\n", Status
);
423 /* Functional Device Object routines */
426 PnpRootReadRegistryBinary(
428 IN PWSTR ValueKeyName
,
431 OBJECT_ATTRIBUTES ObjectAttributes
;
432 UNICODE_STRING KeyNameU
;
433 UNICODE_STRING ValueKeyNameU
;
434 KEY_VALUE_PARTIAL_INFORMATION Size
;
435 PKEY_VALUE_PARTIAL_INFORMATION Data
= NULL
;
436 ULONG DataSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
442 RtlInitUnicodeString(&KeyNameU
, KeyName
);
443 RtlInitUnicodeString(&ValueKeyNameU
, ValueKeyName
);
445 InitializeObjectAttributes(
448 OBJ_CASE_INSENSITIVE
,
450 NULL
); /* Security descriptor */
451 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &ObjectAttributes
);
452 if (!NT_SUCCESS(Status
))
454 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
458 Status
= ZwQueryValueKey(
461 KeyValuePartialInformation
,
464 if (Status
!= STATUS_BUFFER_OVERFLOW
)
466 DPRINT("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status
);
471 while (Status
== STATUS_BUFFER_OVERFLOW
)
474 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
475 Data
= (PKEY_VALUE_PARTIAL_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, DataSize
, TAG_PNP_ROOT
);
478 DPRINT("ExAllocatePoolWithTag() failed\n", Status
);
483 Status
= ZwQueryValueKey(
486 KeyValuePartialInformation
,
489 if (NT_SUCCESS(Status
))
491 *Buffer
= ExAllocatePoolWithTag(PagedPool
, Data
->DataLength
, TAG_PNP_ROOT
);
494 DPRINT("ExAllocatePoolWithTag() failed\n", Status
);
495 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
509 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
516 PnpRootFdoReadDeviceInfo(
517 PPNPROOT_DEVICE Device
)
519 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
520 PUNICODE_STRING DeviceDesc
;
521 WCHAR KeyName
[MAX_PATH
];
526 /* Retrieve configuration from Enum key */
528 DeviceDesc
= &Device
->DeviceDescription
;
530 wcscpy(KeyName
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
531 wcscat(KeyName
, ENUM_NAME_ROOT
);
532 wcscat(KeyName
, L
"\\");
533 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
534 wcscat(KeyName
, L
"\\");
535 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
537 DPRINT("KeyName %S\n", KeyName
);
539 /* 1. Read informations in instance key */
540 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
542 RtlInitUnicodeString(DeviceDesc
, NULL
);
544 QueryTable
[0].Name
= L
"DeviceDesc";
545 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
546 QueryTable
[0].EntryContext
= DeviceDesc
;
548 Status
= RtlQueryRegistryValues(
549 RTL_REGISTRY_ABSOLUTE
| RTL_REGISTRY_OPTIONAL
,
555 DPRINT("RtlQueryRegistryValues() returned status 0x%08lx\n", Status
);
557 if (!NT_SUCCESS(Status
))
562 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
564 /* 2. Read informations in instance key, LogConf subkey */
565 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
566 wcscat(KeyName
, L
"\\LogConf");
568 Status
= PnpRootReadRegistryBinary(
570 L
"BasicConfigVector",
571 (PVOID
*)&Device
->ResourceRequirementsList
);
573 DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status
);
575 if (!NT_SUCCESS(Status
))
580 return STATUS_SUCCESS
;
585 PnpRootFdoEnumerateDevices(
586 PDEVICE_OBJECT DeviceObject
)
588 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
589 OBJECT_ATTRIBUTES ObjectAttributes
, SubKeyAttributes
;
590 PKEY_BASIC_INFORMATION KeyInfo
, SubKeyInfo
;
591 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" ENUM_NAME_ROOT
);
592 UNICODE_STRING SubKeyName
;
593 PPNPROOT_DEVICE Device
;
594 WCHAR Buffer
[MAX_PATH
];
595 HANDLE KeyHandle
, SubKeyHandle
;
599 ULONG Index1
, Index2
;
603 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
605 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
606 KeyInfo
= ExAllocatePoolWithTag(PagedPool
, BufferSize
, TAG_PNP_ROOT
);
609 return STATUS_INSUFFICIENT_RESOURCES
;
611 SubKeyInfo
= ExAllocatePoolWithTag(PagedPool
, BufferSize
, TAG_PNP_ROOT
);
614 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
615 return STATUS_INSUFFICIENT_RESOURCES
;
618 InitializeObjectAttributes(
621 OBJ_CASE_INSENSITIVE
,
625 Status
= ZwOpenKey(&KeyHandle
, KEY_ENUMERATE_SUB_KEYS
, &ObjectAttributes
);
626 if (!NT_SUCCESS(Status
))
628 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
629 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
630 ExFreePoolWithTag(SubKeyInfo
, TAG_PNP_ROOT
);
634 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
635 there are more entries in the list than found in the registry as some
636 drivers are passed on the command line */
637 // DeviceExtension->DeviceListCount = 0;
639 /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
640 * KeyHandle. We'll first do a first enumeration to have first level keys,
641 * and an inner one to have the real devices list.
647 Status
= ZwEnumerateKey(
654 if (!NT_SUCCESS(Status
))
656 DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status
);
660 /* Terminate the string */
661 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
664 RtlInitUnicodeString(&SubKeyName
, KeyInfo
->Name
);
665 InitializeObjectAttributes(
670 NULL
); /* Security descriptor */
671 Status
= ZwOpenKey(&SubKeyHandle
, KEY_ENUMERATE_SUB_KEYS
, &SubKeyAttributes
);
672 if (!NT_SUCCESS(Status
))
674 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
678 /* Enumerate the sub-keys */
682 Status
= ZwEnumerateKey(
689 if (!NT_SUCCESS(Status
))
691 DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status
);
695 /* Terminate the string */
696 SubKeyInfo
->Name
[SubKeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
698 Device
= (PPNPROOT_DEVICE
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNPROOT_DEVICE
), TAG_PNP_ROOT
);
702 DPRINT("ExAllocatePoolWithTag() failed\n");
706 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
708 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
711 DPRINT("IopCreateUnicodeString() failed\n");
714 wcscpy(Buffer
, ENUM_NAME_ROOT
);
715 wcscat(Buffer
, L
"\\");
716 wcscat(Buffer
, KeyInfo
->Name
);
718 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
721 DPRINT("IopCreateUnicodeString() failed\n");
724 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
726 if (!IopCreateUnicodeString(
732 DPRINT("IopCreateUnicodeString() failed\n");
735 Status
= PnpRootFdoReadDeviceInfo(Device
);
736 if (!NT_SUCCESS(Status
))
739 DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n", Status
);
742 ExInterlockedInsertTailList(
743 &DeviceExtension
->DeviceListHead
,
745 &DeviceExtension
->DeviceListLock
);
747 DeviceExtension
->DeviceListCount
++;
752 ZwClose(SubKeyHandle
);
758 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
759 ExFreePoolWithTag(SubKeyInfo
, TAG_PNP_ROOT
);
761 return STATUS_SUCCESS
;
766 PnpRootQueryBusRelations(
767 IN PDEVICE_OBJECT DeviceObject
,
769 IN PIO_STACK_LOCATION IrpSp
)
771 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
772 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
773 PDEVICE_RELATIONS Relations
;
774 PLIST_ENTRY CurrentEntry
;
775 PPNPROOT_DEVICE Device
;
782 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
783 if (!NT_SUCCESS(Status
))
786 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
788 if (Irp
->IoStatus
.Information
)
790 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
791 structure so we must merge this structure with our own */
794 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
795 (DeviceExtension
->DeviceListCount
- 1);
797 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
799 return STATUS_INSUFFICIENT_RESOURCES
;
801 Relations
->Count
= DeviceExtension
->DeviceListCount
;
804 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
805 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
807 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
811 /* Create a physical device object for the
812 device as it does not already have one */
813 Status
= IoCreateDevice(
814 DeviceObject
->DriverObject
,
815 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
817 FILE_DEVICE_CONTROLLER
,
818 FILE_AUTOGENERATED_DEVICE_NAME
,
821 if (!NT_SUCCESS(Status
))
823 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
824 ExFreePool(Relations
);
828 DPRINT("Created PDO 0x%p\n", Device
->Pdo
);
830 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
832 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
834 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
836 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
838 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
840 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
842 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
844 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
846 if (!IopCreateUnicodeString(
847 &PdoDeviceExtension
->DeviceID
,
848 Device
->DeviceID
.Buffer
,
851 DPRINT("Insufficient resources\n");
855 DPRINT("DeviceID: %wZ PDO %p\n",
856 &PdoDeviceExtension
->DeviceID
,
859 if (!IopCreateUnicodeString(
860 &PdoDeviceExtension
->InstanceID
,
861 Device
->InstanceID
.Buffer
,
864 DPRINT("Insufficient resources\n");
868 DPRINT("InstanceID: %wZ PDO %p\n",
869 &PdoDeviceExtension
->InstanceID
,
872 if (Device
->ResourceRequirementsList
!= NULL
)
874 PdoDeviceExtension
->ResourceRequirementsList
= ExAllocatePoolWithTag(
876 Device
->ResourceRequirementsList
->ListSize
,
878 if (PdoDeviceExtension
->ResourceRequirementsList
)
881 PdoDeviceExtension
->ResourceRequirementsList
,
882 Device
->ResourceRequirementsList
,
883 Device
->ResourceRequirementsList
->ListSize
);
888 DPRINT("ExAllocatePoolWithTag() failed\n");
892 DPRINT("ResourceRequirementsList: %p PDO %p\n",
893 PdoDeviceExtension
->ResourceRequirementsList
,
897 /* Reference the physical device object. The PnP manager
898 will dereference it again when it is no longer needed */
899 ObReferenceObject(Device
->Pdo
);
901 Relations
->Objects
[i
] = Device
->Pdo
;
905 CurrentEntry
= CurrentEntry
->Flink
;
908 if (NT_SUCCESS(Status
))
910 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
914 Irp
->IoStatus
.Information
= 0;
922 PnpRootQueryDeviceRelations(
923 IN PDEVICE_OBJECT DeviceObject
,
925 IN PIO_STACK_LOCATION IrpSp
)
931 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
933 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
937 Status
= STATUS_NOT_IMPLEMENTED
;
945 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
947 * DeviceObject = Pointer to functional device object of the root bus driver
948 * Irp = Pointer to IRP that should be handled
954 PnpRootFdoPnpControl(
955 IN PDEVICE_OBJECT DeviceObject
,
958 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
959 PIO_STACK_LOCATION IrpSp
;
964 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
966 Status
= Irp
->IoStatus
.Status
;
968 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
970 switch (IrpSp
->MinorFunction
) {
971 case IRP_MN_QUERY_DEVICE_RELATIONS
:
972 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
975 case IRP_MN_START_DEVICE
:
976 DeviceExtension
->State
= dsStarted
;
977 Status
= STATUS_SUCCESS
;
980 case IRP_MN_STOP_DEVICE
:
981 /* Root device cannot be stopped */
982 Status
= STATUS_UNSUCCESSFUL
;
986 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
987 Status
= STATUS_NOT_IMPLEMENTED
;
991 if (Status
!= STATUS_PENDING
) {
992 Irp
->IoStatus
.Status
= Status
;
993 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
996 DPRINT("Leaving. Status 0x%X\n", Status
);
1003 * FUNCTION: Handle power management IRPs for the root bus device object
1005 * DeviceObject = Pointer to functional device object of the root bus driver
1006 * Irp = Pointer to IRP that should be handled
1012 PnpRootFdoPowerControl(
1013 IN PDEVICE_OBJECT DeviceObject
,
1016 PIO_STACK_LOCATION IrpSp
;
1021 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1023 switch (IrpSp
->MinorFunction
) {
1025 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1026 Status
= STATUS_NOT_IMPLEMENTED
;
1030 if (Status
!= STATUS_PENDING
) {
1031 Irp
->IoStatus
.Status
= Status
;
1032 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1035 DPRINT("Leaving. Status 0x%X\n", Status
);
1042 * FUNCTION: Handle Plug and Play IRPs
1044 * DeviceObject = Pointer to PDO or FDO
1045 * Irp = Pointer to IRP that should be handled
1052 IN PDEVICE_OBJECT DeviceObject
,
1055 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
1058 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1060 DPRINT("DeviceObject 0x%p DeviceExtension 0x%p IsFDO %d\n",
1063 DeviceExtension
->IsFDO
);
1065 if (DeviceExtension
->IsFDO
) {
1066 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
1068 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
1076 * FUNCTION: Handle power management IRPs
1078 * DeviceObject = Pointer to PDO or FDO
1079 * Irp = Pointer to IRP that should be handled
1085 PnpRootPowerControl(
1086 IN PDEVICE_OBJECT DeviceObject
,
1089 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
1092 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1094 if (DeviceExtension
->IsFDO
) {
1095 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
1097 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
1107 IN PDRIVER_OBJECT DriverObject
,
1108 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1110 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
1115 Status
= IoCreateDevice(
1117 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
1119 FILE_DEVICE_BUS_EXTENDER
,
1120 FILE_DEVICE_SECURE_OPEN
,
1122 &PnpRootDeviceObject
);
1123 if (!NT_SUCCESS(Status
)) {
1124 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1127 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
1129 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
1131 DeviceExtension
->Common
.IsFDO
= TRUE
;
1133 DeviceExtension
->State
= dsStopped
;
1135 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
1136 PnpRootDeviceObject
,
1137 PhysicalDeviceObject
);
1139 if (!PnpRootDeviceObject
) {
1140 CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject
);
1141 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1144 if (!PhysicalDeviceObject
) {
1145 CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject
);
1146 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1149 InitializeListHead(&DeviceExtension
->DeviceListHead
);
1151 DeviceExtension
->DeviceListCount
= 0;
1153 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
1155 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1157 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
1159 DPRINT("Done AddDevice()\n");
1161 return STATUS_SUCCESS
;
1168 IN PDRIVER_OBJECT DriverObject
,
1169 IN PUNICODE_STRING RegistryPath
)
1173 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
1174 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
1175 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
1177 return STATUS_SUCCESS
;