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 (!RtlCreateUnicodeString(
163 &PdoDeviceExtension
->DeviceID
,
165 L
"\\LEGACY_UNKNOWN"))
168 DPRINT("RtlCreateUnicodeString() failed\n");
171 if (!RtlCreateUnicodeString(
172 &PdoDeviceExtension
->InstanceID
,
176 DPRINT("RtlCreateUnicodeString() failed\n");
179 ExInterlockedInsertTailList(
180 &DeviceExtension
->DeviceListHead
,
182 &DeviceExtension
->DeviceListLock
);
184 DeviceExtension
->DeviceListCount
++;
186 *PhysicalDeviceObject
= Device
->Pdo
;
188 return STATUS_SUCCESS
;
194 IN PDEVICE_OBJECT DeviceObject
,
196 PIO_STACK_LOCATION IrpSp
)
198 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
199 UNICODE_STRING String
;
204 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
206 // Irp->IoStatus.Information = 0;
208 Status
= STATUS_SUCCESS
;
210 RtlInitUnicodeString(&String
, NULL
);
212 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
213 case BusQueryDeviceID
:
214 Status
= RtlDuplicateUnicodeString(TRUE
,
215 &DeviceExtension
->DeviceID
,
218 DPRINT("DeviceID: %wZ\n", &String
);
220 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
223 case BusQueryHardwareIDs
:
224 case BusQueryCompatibleIDs
:
225 Status
= STATUS_NOT_IMPLEMENTED
;
228 case BusQueryInstanceID
:
229 Status
= RtlDuplicateUnicodeString(TRUE
,
230 &DeviceExtension
->InstanceID
,
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 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
275 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
276 ULONG ResourceListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
);
280 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
282 if (DeviceExtension
->ResourceRequirementsList
== NULL
)
284 /* Create an empty resource list */
285 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
286 if (ResourceList
== NULL
)
287 return STATUS_INSUFFICIENT_RESOURCES
;
289 RtlZeroMemory(ResourceList
, ResourceListSize
);
290 ResourceList
->ListSize
= ResourceListSize
;
292 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
296 /* Copy existing resource requirement list */
297 ResourceList
= ExAllocatePool(PagedPool
, DeviceExtension
->ResourceRequirementsList
->ListSize
);
298 if (ResourceList
== NULL
)
299 return STATUS_INSUFFICIENT_RESOURCES
;
303 DeviceExtension
->ResourceRequirementsList
,
304 DeviceExtension
->ResourceRequirementsList
->ListSize
);
305 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
308 return STATUS_SUCCESS
;
313 * FUNCTION: Handle Plug and Play IRPs for the child device
315 * DeviceObject = Pointer to physical device object of the child device
316 * Irp = Pointer to IRP that should be handled
321 PnpRootPdoPnpControl(
322 PDEVICE_OBJECT DeviceObject
,
325 PIO_STACK_LOCATION IrpSp
;
330 Status
= Irp
->IoStatus
.Status
;
332 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
334 switch (IrpSp
->MinorFunction
) {
336 case IRP_MN_QUERY_BUS_INFORMATION
:
339 case IRP_MN_QUERY_DEVICE_RELATIONS
:
340 /* FIXME: Handle for TargetDeviceRelation */
344 case IRP_MN_QUERY_ID
:
345 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
348 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
349 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
352 case IRP_MN_QUERY_RESOURCES
:
353 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
356 case IRP_MN_START_DEVICE
:
357 case IRP_MN_QUERY_STOP_DEVICE
:
358 case IRP_MN_CANCEL_STOP_DEVICE
:
359 case IRP_MN_STOP_DEVICE
:
360 case IRP_MN_QUERY_REMOVE_DEVICE
:
361 case IRP_MN_CANCEL_REMOVE_DEVICE
:
362 case IRP_MN_REMOVE_DEVICE
:
363 case IRP_MN_SURPRISE_REMOVAL
:
364 Status
= STATUS_SUCCESS
;
368 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
372 Irp
->IoStatus
.Status
= Status
;
373 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
375 DPRINT("Leaving. Status 0x%X\n", Status
);
382 * FUNCTION: Handle power management IRPs for the child device
384 * DeviceObject = Pointer to physical device object of the child device
385 * Irp = Pointer to IRP that should be handled
390 PnpRootPdoPowerControl(
391 PDEVICE_OBJECT DeviceObject
,
394 PIO_STACK_LOCATION IrpSp
;
399 Status
= Irp
->IoStatus
.Status
;
401 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
403 switch (IrpSp
->MinorFunction
) {
405 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
406 Status
= STATUS_NOT_IMPLEMENTED
;
410 Irp
->IoStatus
.Status
= Status
;
411 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
413 DPRINT("Leaving. Status 0x%X\n", Status
);
419 /* Functional Device Object routines */
422 PnpRootReadRegistryBinary(
424 IN PWSTR ValueKeyName
,
427 OBJECT_ATTRIBUTES ObjectAttributes
;
428 UNICODE_STRING KeyNameU
;
429 UNICODE_STRING ValueKeyNameU
;
430 KEY_VALUE_PARTIAL_INFORMATION Size
;
431 PKEY_VALUE_PARTIAL_INFORMATION Data
= NULL
;
432 ULONG DataSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
438 RtlInitUnicodeString(&KeyNameU
, KeyName
);
439 RtlInitUnicodeString(&ValueKeyNameU
, ValueKeyName
);
441 InitializeObjectAttributes(
444 OBJ_CASE_INSENSITIVE
,
446 NULL
); /* Security descriptor */
447 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &ObjectAttributes
);
448 if (!NT_SUCCESS(Status
))
450 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
454 Status
= ZwQueryValueKey(
457 KeyValuePartialInformation
,
460 if (Status
!= STATUS_BUFFER_OVERFLOW
)
462 DPRINT("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status
);
467 while (Status
== STATUS_BUFFER_OVERFLOW
)
470 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
471 Data
= (PKEY_VALUE_PARTIAL_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, DataSize
, TAG_PNP_ROOT
);
474 DPRINT("ExAllocatePoolWithTag() failed\n", Status
);
479 Status
= ZwQueryValueKey(
482 KeyValuePartialInformation
,
485 if (NT_SUCCESS(Status
))
487 *Buffer
= ExAllocatePoolWithTag(PagedPool
, Data
->DataLength
, TAG_PNP_ROOT
);
490 DPRINT("ExAllocatePoolWithTag() failed\n", Status
);
491 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
505 ExFreePoolWithTag(Data
, TAG_PNP_ROOT
);
512 PnpRootFdoReadDeviceInfo(
513 PPNPROOT_DEVICE Device
)
515 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
516 PUNICODE_STRING DeviceDesc
;
517 WCHAR KeyName
[MAX_PATH
];
522 /* Retrieve configuration from Enum key */
524 DeviceDesc
= &Device
->DeviceDescription
;
526 wcscpy(KeyName
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
527 wcscat(KeyName
, ENUM_NAME_ROOT
);
528 wcscat(KeyName
, L
"\\");
529 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
530 wcscat(KeyName
, L
"\\");
531 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
533 DPRINT("KeyName %S\n", KeyName
);
535 /* 1. Read informations in instance key */
536 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
538 RtlInitUnicodeString(DeviceDesc
, NULL
);
540 QueryTable
[0].Name
= L
"DeviceDesc";
541 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
542 QueryTable
[0].EntryContext
= DeviceDesc
;
544 Status
= RtlQueryRegistryValues(
545 RTL_REGISTRY_ABSOLUTE
| RTL_REGISTRY_OPTIONAL
,
551 DPRINT("RtlQueryRegistryValues() returned status 0x%08lx\n", Status
);
553 if (!NT_SUCCESS(Status
))
558 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
560 /* 2. Read informations in instance key, LogConf subkey */
561 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
562 wcscat(KeyName
, L
"\\LogConf");
564 Status
= PnpRootReadRegistryBinary(
566 L
"BasicConfigVector",
567 (PVOID
*)&Device
->ResourceRequirementsList
);
569 DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status
);
571 if (!NT_SUCCESS(Status
))
576 return STATUS_SUCCESS
;
581 PnpRootFdoEnumerateDevices(
582 PDEVICE_OBJECT DeviceObject
)
584 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
585 OBJECT_ATTRIBUTES ObjectAttributes
, SubKeyAttributes
;
586 PKEY_BASIC_INFORMATION KeyInfo
, SubKeyInfo
;
587 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" ENUM_NAME_ROOT
);
588 UNICODE_STRING SubKeyName
;
589 PPNPROOT_DEVICE Device
;
590 WCHAR Buffer
[MAX_PATH
];
591 HANDLE KeyHandle
, SubKeyHandle
;
595 ULONG Index1
, Index2
;
599 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
601 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
602 KeyInfo
= ExAllocatePoolWithTag(PagedPool
, BufferSize
, TAG_PNP_ROOT
);
605 return STATUS_INSUFFICIENT_RESOURCES
;
607 SubKeyInfo
= ExAllocatePoolWithTag(PagedPool
, BufferSize
, TAG_PNP_ROOT
);
610 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
611 return STATUS_INSUFFICIENT_RESOURCES
;
614 InitializeObjectAttributes(
617 OBJ_CASE_INSENSITIVE
,
621 Status
= ZwOpenKey(&KeyHandle
, KEY_ENUMERATE_SUB_KEYS
, &ObjectAttributes
);
622 if (!NT_SUCCESS(Status
))
624 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
625 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
626 ExFreePoolWithTag(SubKeyInfo
, TAG_PNP_ROOT
);
630 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
631 there are more entries in the list than found in the registry as some
632 drivers are passed on the command line */
633 // DeviceExtension->DeviceListCount = 0;
635 /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
636 * KeyHandle. We'll first do a first enumeration to have first level keys,
637 * and an inner one to have the real devices list.
643 Status
= ZwEnumerateKey(
650 if (!NT_SUCCESS(Status
))
652 DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status
);
656 /* Terminate the string */
657 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
660 RtlInitUnicodeString(&SubKeyName
, KeyInfo
->Name
);
661 InitializeObjectAttributes(
666 NULL
); /* Security descriptor */
667 Status
= ZwOpenKey(&SubKeyHandle
, KEY_ENUMERATE_SUB_KEYS
, &SubKeyAttributes
);
668 if (!NT_SUCCESS(Status
))
670 DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status
);
674 /* Enumerate the sub-keys */
678 Status
= ZwEnumerateKey(
685 if (!NT_SUCCESS(Status
))
687 DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status
);
691 /* Terminate the string */
692 SubKeyInfo
->Name
[SubKeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
694 Device
= (PPNPROOT_DEVICE
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNPROOT_DEVICE
), TAG_PNP_ROOT
);
698 DPRINT("ExAllocatePoolWithTag() failed\n");
702 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
704 if (!RtlCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
))
707 DPRINT("RtlCreateUnicodeString() failed\n");
710 wcscpy(Buffer
, ENUM_NAME_ROOT
);
711 wcscat(Buffer
, L
"\\");
712 wcscat(Buffer
, KeyInfo
->Name
);
714 if (!RtlCreateUnicodeString(&Device
->DeviceID
, Buffer
))
717 DPRINT("RtlCreateUnicodeString() failed\n");
720 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
722 if (!RtlCreateUnicodeString(
727 DPRINT("RtlCreateUnicodeString() failed\n");
730 Status
= PnpRootFdoReadDeviceInfo(Device
);
731 if (!NT_SUCCESS(Status
))
734 DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n", Status
);
737 ExInterlockedInsertTailList(
738 &DeviceExtension
->DeviceListHead
,
740 &DeviceExtension
->DeviceListLock
);
742 DeviceExtension
->DeviceListCount
++;
747 ZwClose(SubKeyHandle
);
753 ExFreePoolWithTag(KeyInfo
, TAG_PNP_ROOT
);
754 ExFreePoolWithTag(SubKeyInfo
, TAG_PNP_ROOT
);
756 return STATUS_SUCCESS
;
761 PnpRootQueryBusRelations(
762 IN PDEVICE_OBJECT DeviceObject
,
764 IN PIO_STACK_LOCATION IrpSp
)
766 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
767 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
768 PDEVICE_RELATIONS Relations
;
769 PLIST_ENTRY CurrentEntry
;
770 PPNPROOT_DEVICE Device
;
777 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
778 if (!NT_SUCCESS(Status
))
781 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
783 if (Irp
->IoStatus
.Information
)
785 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
786 structure so we must merge this structure with our own */
789 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
790 (DeviceExtension
->DeviceListCount
- 1);
792 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
794 return STATUS_INSUFFICIENT_RESOURCES
;
796 Relations
->Count
= DeviceExtension
->DeviceListCount
;
799 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
800 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
802 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
806 /* Create a physical device object for the
807 device as it does not already have one */
808 Status
= IoCreateDevice(
809 DeviceObject
->DriverObject
,
810 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
812 FILE_DEVICE_CONTROLLER
,
813 FILE_AUTOGENERATED_DEVICE_NAME
,
816 if (!NT_SUCCESS(Status
))
818 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
819 ExFreePool(Relations
);
823 DPRINT("Created PDO 0x%p\n", Device
->Pdo
);
825 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
827 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
829 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
831 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
833 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
835 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
837 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
839 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
841 if (!RtlCreateUnicodeString(
842 &PdoDeviceExtension
->DeviceID
,
843 Device
->DeviceID
.Buffer
))
845 DPRINT("Insufficient resources\n");
849 DPRINT("DeviceID: %wZ PDO %p\n",
850 &PdoDeviceExtension
->DeviceID
,
853 if (!RtlCreateUnicodeString(
854 &PdoDeviceExtension
->InstanceID
,
855 Device
->InstanceID
.Buffer
))
857 DPRINT("Insufficient resources\n");
861 DPRINT("InstanceID: %wZ PDO %p\n",
862 &PdoDeviceExtension
->InstanceID
,
865 if (Device
->ResourceRequirementsList
!= NULL
)
867 PdoDeviceExtension
->ResourceRequirementsList
= ExAllocatePoolWithTag(
869 Device
->ResourceRequirementsList
->ListSize
,
871 if (PdoDeviceExtension
->ResourceRequirementsList
)
874 PdoDeviceExtension
->ResourceRequirementsList
,
875 Device
->ResourceRequirementsList
,
876 Device
->ResourceRequirementsList
->ListSize
);
881 DPRINT("ExAllocatePoolWithTag() failed\n");
885 DPRINT("ResourceRequirementsList: %p PDO %p\n",
886 PdoDeviceExtension
->ResourceRequirementsList
,
890 /* Reference the physical device object. The PnP manager
891 will dereference it again when it is no longer needed */
892 ObReferenceObject(Device
->Pdo
);
894 Relations
->Objects
[i
] = Device
->Pdo
;
898 CurrentEntry
= CurrentEntry
->Flink
;
901 if (NT_SUCCESS(Status
))
903 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
907 Irp
->IoStatus
.Information
= 0;
915 PnpRootQueryDeviceRelations(
916 IN PDEVICE_OBJECT DeviceObject
,
918 IN PIO_STACK_LOCATION IrpSp
)
924 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
926 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
930 Status
= STATUS_NOT_IMPLEMENTED
;
938 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
940 * DeviceObject = Pointer to functional device object of the root bus driver
941 * Irp = Pointer to IRP that should be handled
947 PnpRootFdoPnpControl(
948 IN PDEVICE_OBJECT DeviceObject
,
951 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
952 PIO_STACK_LOCATION IrpSp
;
957 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
959 Status
= Irp
->IoStatus
.Status
;
961 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
963 switch (IrpSp
->MinorFunction
) {
964 case IRP_MN_QUERY_DEVICE_RELATIONS
:
965 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
968 case IRP_MN_START_DEVICE
:
969 DeviceExtension
->State
= dsStarted
;
970 Status
= STATUS_SUCCESS
;
973 case IRP_MN_STOP_DEVICE
:
974 /* Root device cannot be stopped */
975 Status
= STATUS_UNSUCCESSFUL
;
979 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
980 Status
= STATUS_NOT_IMPLEMENTED
;
984 if (Status
!= STATUS_PENDING
) {
985 Irp
->IoStatus
.Status
= Status
;
986 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
989 DPRINT("Leaving. Status 0x%X\n", Status
);
996 * FUNCTION: Handle power management IRPs for the root bus device object
998 * DeviceObject = Pointer to functional device object of the root bus driver
999 * Irp = Pointer to IRP that should be handled
1005 PnpRootFdoPowerControl(
1006 IN PDEVICE_OBJECT DeviceObject
,
1009 PIO_STACK_LOCATION IrpSp
;
1014 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1016 switch (IrpSp
->MinorFunction
) {
1018 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1019 Status
= STATUS_NOT_IMPLEMENTED
;
1023 if (Status
!= STATUS_PENDING
) {
1024 Irp
->IoStatus
.Status
= Status
;
1025 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1028 DPRINT("Leaving. Status 0x%X\n", Status
);
1035 * FUNCTION: Handle Plug and Play IRPs
1037 * DeviceObject = Pointer to PDO or FDO
1038 * Irp = Pointer to IRP that should be handled
1045 IN PDEVICE_OBJECT DeviceObject
,
1048 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
1051 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1053 DPRINT("DeviceObject 0x%p DeviceExtension 0x%p IsFDO %d\n",
1056 DeviceExtension
->IsFDO
);
1058 if (DeviceExtension
->IsFDO
) {
1059 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
1061 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
1069 * FUNCTION: Handle power management IRPs
1071 * DeviceObject = Pointer to PDO or FDO
1072 * Irp = Pointer to IRP that should be handled
1078 PnpRootPowerControl(
1079 IN PDEVICE_OBJECT DeviceObject
,
1082 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
1085 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1087 if (DeviceExtension
->IsFDO
) {
1088 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
1090 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
1100 IN PDRIVER_OBJECT DriverObject
,
1101 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1103 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
1108 Status
= IoCreateDevice(
1110 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
1112 FILE_DEVICE_BUS_EXTENDER
,
1113 FILE_DEVICE_SECURE_OPEN
,
1115 &PnpRootDeviceObject
);
1116 if (!NT_SUCCESS(Status
)) {
1117 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1120 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
1122 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
1124 DeviceExtension
->Common
.IsFDO
= TRUE
;
1126 DeviceExtension
->State
= dsStopped
;
1128 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
1129 PnpRootDeviceObject
,
1130 PhysicalDeviceObject
);
1132 if (!PnpRootDeviceObject
) {
1133 CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject
);
1134 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1137 if (!PhysicalDeviceObject
) {
1138 CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject
);
1139 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
1142 InitializeListHead(&DeviceExtension
->DeviceListHead
);
1144 DeviceExtension
->DeviceListCount
= 0;
1146 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
1148 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1150 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
1152 DPRINT("Done AddDevice()\n");
1154 return STATUS_SUCCESS
;
1161 IN PDRIVER_OBJECT DriverObject
,
1162 IN PUNICODE_STRING RegistryPath
)
1166 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
1167 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
1168 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
1170 return STATUS_SUCCESS
;