1 /* $Id: pnproot.c,v 1.19 2003/12/30 18:52:04 fireball Exp $
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 ******************************************************************/
14 #include <ddk/ntddk.h>
15 #include <reactos/bugcodes.h>
16 #include <internal/io.h>
17 #include <rosrtl/string.h>
20 #include <internal/debug.h>
22 /* GLOBALS *******************************************************************/
24 #define ENUM_NAME_ROOT L"Root"
26 /* DATA **********************************************************************/
28 typedef struct _PNPROOT_DEVICE
{
29 // Entry on device list
31 // Physical Device Object of device
34 UNICODE_STRING ServiceName
;
36 UNICODE_STRING DeviceID
;
38 UNICODE_STRING InstanceID
;
40 UNICODE_STRING DeviceDescription
;
41 } PNPROOT_DEVICE
, *PPNPROOT_DEVICE
;
49 } PNPROOT_DEVICE_STATE
;
54 typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
56 // Pointer to device object, this device extension is associated with
57 PDEVICE_OBJECT DeviceObject
;
58 // Wether this device extension is for an FDO or PDO
60 // Wether the device is removed
62 // Current device power state for the device
63 DEVICE_POWER_STATE DevicePowerState
;
64 } __attribute((packed
)) PNPROOT_COMMON_DEVICE_EXTENSION
, *PPNPROOT_COMMON_DEVICE_EXTENSION
;
66 #elif defined(_MSC_VER)
69 typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
71 // Pointer to device object, this device extension is associated with
72 PDEVICE_OBJECT DeviceObject
;
73 // Wether this device extension is for an FDO or PDO
75 // Wether the device is removed
77 // Current device power state for the device
78 DEVICE_POWER_STATE DevicePowerState
;
79 } PNPROOT_COMMON_DEVICE_EXTENSION
, *PPNPROOT_COMMON_DEVICE_EXTENSION
;
83 #error Unknown compiler for structure packing
89 /* Physical Device Object device extension for a child device */
90 typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
93 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
95 UNICODE_STRING DeviceID
;
97 UNICODE_STRING InstanceID
;
98 } __attribute((packed
)) PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
100 #elif defined(_MSC_VER)
102 #include <pshpack1.h>
103 typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
105 // Common device data
106 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
108 UNICODE_STRING DeviceID
;
110 UNICODE_STRING InstanceID
;
111 } PNPROOT_PDO_DEVICE_EXTENSION
, *PPNPROOT_PDO_DEVICE_EXTENSION
;
115 #error Unknown compiler for structure packing
119 #if defined(__GNUC__)
121 /* Functional Device Object device extension for the PCI driver device object */
122 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
124 // Common device data
125 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
126 // Physical Device Object
128 // Lower device object
130 // Current state of the driver
131 PNPROOT_DEVICE_STATE State
;
132 // Namespace device list
133 LIST_ENTRY DeviceListHead
;
134 // Number of (not removed) devices in device list
135 ULONG DeviceListCount
;
136 // Lock for namespace device list
137 // FIXME: Use fast mutex instead?
138 KSPIN_LOCK DeviceListLock
;
139 } __attribute((packed
)) PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
141 #elif defined(_MSC_VER)
143 #include <pshpack1.h>
144 typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
146 // Common device data
147 PNPROOT_COMMON_DEVICE_EXTENSION Common
;
148 // Physical Device Object
150 // Lower device object
152 // Current state of the driver
153 PNPROOT_DEVICE_STATE State
;
154 // Namespace device list
155 LIST_ENTRY DeviceListHead
;
156 // Number of (not removed) devices in device list
157 ULONG DeviceListCount
;
158 // Lock for namespace device list
159 // FIXME: Use fast mutex instead?
160 KSPIN_LOCK DeviceListLock
;
161 } PNPROOT_FDO_DEVICE_EXTENSION
, *PPNPROOT_FDO_DEVICE_EXTENSION
;
165 #error Unknown compiler for structure packing
170 PDEVICE_OBJECT PnpRootDeviceObject
;
173 /* FUNCTIONS *****************************************************************/
175 /* Physical Device Object routines */
179 PDEVICE_OBJECT
*PhysicalDeviceObject
)
181 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
182 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
183 PPNPROOT_DEVICE Device
;
186 /* This function should be obsoleted soon */
190 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
192 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
194 return STATUS_INSUFFICIENT_RESOURCES
;
196 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
198 Status
= IoCreateDevice(
199 PnpRootDeviceObject
->DriverObject
,
200 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
202 FILE_DEVICE_CONTROLLER
,
206 if (!NT_SUCCESS(Status
)) {
207 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
212 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
214 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
216 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
218 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
220 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
222 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
224 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
226 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
228 if (!IopCreateUnicodeString(
229 &PdoDeviceExtension
->DeviceID
,
235 DPRINT("IopCreateUnicodeString() failed\n");
238 if (!IopCreateUnicodeString(
239 &PdoDeviceExtension
->InstanceID
,
244 DPRINT("IopCreateUnicodeString() failed\n");
247 ExInterlockedInsertTailList(
248 &DeviceExtension
->DeviceListHead
,
250 &DeviceExtension
->DeviceListLock
);
252 DeviceExtension
->DeviceListCount
++;
254 *PhysicalDeviceObject
= Device
->Pdo
;
256 return STATUS_SUCCESS
;
262 IN PDEVICE_OBJECT DeviceObject
,
264 PIO_STACK_LOCATION IrpSp
)
266 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension
;
267 UNICODE_STRING String
;
272 DeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
274 // Irp->IoStatus.Information = 0;
276 Status
= STATUS_SUCCESS
;
278 RtlInitUnicodeString(&String
, NULL
);
280 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
281 case BusQueryDeviceID
:
282 Status
= IopCreateUnicodeString(
284 DeviceExtension
->DeviceID
.Buffer
,
287 DPRINT("DeviceID: %S\n", String
.Buffer
);
289 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
292 case BusQueryHardwareIDs
:
293 case BusQueryCompatibleIDs
:
294 Status
= STATUS_NOT_IMPLEMENTED
;
297 case BusQueryInstanceID
:
298 Status
= IopCreateUnicodeString(
300 DeviceExtension
->InstanceID
.Buffer
,
303 DPRINT("InstanceID: %S\n", String
.Buffer
);
305 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
308 case BusQueryDeviceSerialNumber
:
310 Status
= STATUS_NOT_IMPLEMENTED
;
318 PnpRootPdoPnpControl(
319 PDEVICE_OBJECT DeviceObject
,
322 * FUNCTION: Handle Plug and Play IRPs for the child device
324 * DeviceObject = Pointer to physical device object of the child device
325 * Irp = Pointer to IRP that should be handled
330 PIO_STACK_LOCATION IrpSp
;
335 Status
= Irp
->IoStatus
.Status
;
337 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
339 switch (IrpSp
->MinorFunction
) {
341 case IRP_MN_CANCEL_REMOVE_DEVICE
:
344 case IRP_MN_CANCEL_STOP_DEVICE
:
347 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
353 case IRP_MN_QUERY_BUS_INFORMATION
:
356 case IRP_MN_QUERY_CAPABILITIES
:
359 case IRP_MN_QUERY_DEVICE_RELATIONS
:
360 /* FIXME: Possibly handle for RemovalRelations */
363 case IRP_MN_QUERY_DEVICE_TEXT
:
366 case IRP_MN_QUERY_ID
:
367 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
370 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
373 case IRP_MN_QUERY_REMOVE_DEVICE
:
376 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
379 case IRP_MN_QUERY_RESOURCES
:
382 case IRP_MN_QUERY_STOP_DEVICE
:
385 case IRP_MN_REMOVE_DEVICE
:
388 case IRP_MN_SET_LOCK
:
391 case IRP_MN_START_DEVICE
:
394 case IRP_MN_STOP_DEVICE
:
397 case IRP_MN_SURPRISE_REMOVAL
:
401 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
405 Irp
->IoStatus
.Status
= Status
;
406 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
408 DPRINT("Leaving. Status 0x%X\n", Status
);
414 PnpRootPdoPowerControl(
415 PDEVICE_OBJECT DeviceObject
,
418 * FUNCTION: Handle power management IRPs for the child device
420 * DeviceObject = Pointer to physical device object of the child device
421 * Irp = Pointer to IRP that should be handled
426 PIO_STACK_LOCATION IrpSp
;
431 Status
= Irp
->IoStatus
.Status
;
433 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
435 switch (IrpSp
->MinorFunction
) {
437 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
441 Irp
->IoStatus
.Status
= Status
;
442 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
444 DPRINT("Leaving. Status 0x%X\n", Status
);
450 /* Functional Device Object routines */
453 PnpRootFdoReadDeviceInfo(
454 PPNPROOT_DEVICE Device
)
456 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
457 PUNICODE_STRING DeviceDesc
;
458 WCHAR KeyName
[MAX_PATH
];
463 /* Retrieve configuration from Enum key */
465 DeviceDesc
= &Device
->DeviceDescription
;
467 wcscpy(KeyName
, ENUM_NAME_ROOT
);
468 wcscat(KeyName
, L
"\\");
469 wcscat(KeyName
, Device
->ServiceName
.Buffer
);
470 wcscat(KeyName
, L
"\\");
471 wcscat(KeyName
, Device
->InstanceID
.Buffer
);
473 DPRINT("KeyName %S\n", KeyName
);
475 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
477 RtlInitUnicodeString(DeviceDesc
, NULL
);
479 QueryTable
[0].Name
= L
"DeviceDesc";
480 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
481 QueryTable
[0].EntryContext
= DeviceDesc
;
483 Status
= RtlQueryRegistryValues(
490 DPRINT("RtlQueryRegistryValues() returned status %x\n", Status
);
492 if (!NT_SUCCESS(Status
))
497 DPRINT("Got device description: %S\n", DeviceDesc
->Buffer
);
499 return STATUS_SUCCESS
;
504 PnpRootFdoEnumerateDevices(
505 PDEVICE_OBJECT DeviceObject
)
507 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
508 OBJECT_ATTRIBUTES ObjectAttributes
;
509 PKEY_BASIC_INFORMATION KeyInfo
;
510 UNICODE_STRING KeyName
;
511 PPNPROOT_DEVICE Device
;
512 WCHAR Buffer
[MAX_PATH
];
521 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
523 BufferSize
= sizeof(KEY_BASIC_INFORMATION
) + (MAX_PATH
+1) * sizeof(WCHAR
);
524 KeyInfo
= ExAllocatePool(PagedPool
, BufferSize
);
527 return STATUS_INSUFFICIENT_RESOURCES
;
530 RtlRosInitUnicodeStringFromLiteral(
532 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
535 InitializeObjectAttributes(
538 OBJ_CASE_INSENSITIVE
,
542 Status
= NtOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
543 if (!NT_SUCCESS(Status
))
545 DPRINT("NtOpenKey() failed (Status %x)\n", Status
);
550 /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
551 there are more entries in the list than found in the registry as some
552 drivers are passed on the command line */
553 // DeviceExtension->DeviceListCount = 0;
557 Status
= ZwEnumerateKey(
564 if (!NT_SUCCESS(Status
))
566 DPRINT("ZwEnumerateKey() (Status %x)\n", Status
);
570 /* Terminate the string */
571 KeyInfo
->Name
[KeyInfo
->NameLength
/ sizeof(WCHAR
)] = 0;
573 Device
= (PPNPROOT_DEVICE
)ExAllocatePool(PagedPool
, sizeof(PNPROOT_DEVICE
));
580 RtlZeroMemory(Device
, sizeof(PNPROOT_DEVICE
));
582 if (!IopCreateUnicodeString(&Device
->ServiceName
, KeyInfo
->Name
, PagedPool
))
585 DPRINT("IopCreateUnicodeString() failed\n");
588 wcscpy(Buffer
, ENUM_NAME_ROOT
);
589 wcscat(Buffer
, L
"\\");
590 wcscat(Buffer
, KeyInfo
->Name
);
592 if (!IopCreateUnicodeString(&Device
->DeviceID
, Buffer
, PagedPool
))
595 DPRINT("IopCreateUnicodeString() failed\n");
598 DPRINT("Got entry: %S\n", Device
->DeviceID
.Buffer
);
600 if (!IopCreateUnicodeString(
606 DPRINT("IopCreateUnicodeString() failed\n");
609 Status
= PnpRootFdoReadDeviceInfo(Device
);
610 if (!NT_SUCCESS(Status
))
612 DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status
);
616 ExInterlockedInsertTailList(
617 &DeviceExtension
->DeviceListHead
,
619 &DeviceExtension
->DeviceListLock
);
621 DeviceExtension
->DeviceListCount
++;
626 DPRINT("Entries found: %d\n", Index
);
632 return STATUS_SUCCESS
;
637 PnpRootQueryBusRelations(
638 IN PDEVICE_OBJECT DeviceObject
,
640 IN PIO_STACK_LOCATION IrpSp
)
642 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension
;
643 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
644 PDEVICE_RELATIONS Relations
;
645 PLIST_ENTRY CurrentEntry
;
646 PPNPROOT_DEVICE Device
;
653 Status
= PnpRootFdoEnumerateDevices(DeviceObject
);
654 if (!NT_SUCCESS(Status
))
657 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
659 if (Irp
->IoStatus
.Information
)
661 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
662 structure so we must merge this structure with our own */
665 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
666 (DeviceExtension
->DeviceListCount
- 1);
668 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
670 return STATUS_INSUFFICIENT_RESOURCES
;
672 Relations
->Count
= DeviceExtension
->DeviceListCount
;
675 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
676 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
678 Device
= CONTAINING_RECORD(CurrentEntry
, PNPROOT_DEVICE
, ListEntry
);
682 /* Create a physical device object for the
683 device as it does not already have one */
684 Status
= IoCreateDevice(
685 DeviceObject
->DriverObject
,
686 sizeof(PNPROOT_PDO_DEVICE_EXTENSION
),
688 FILE_DEVICE_CONTROLLER
,
692 if (!NT_SUCCESS(Status
))
694 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
695 ExFreePool(Relations
);
699 DPRINT("Created PDO %x\n", Device
->Pdo
);
701 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
703 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
705 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
707 PdoDeviceExtension
= (PPNPROOT_PDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
709 RtlZeroMemory(PdoDeviceExtension
, sizeof(PNPROOT_PDO_DEVICE_EXTENSION
));
711 PdoDeviceExtension
->Common
.IsFDO
= FALSE
;
713 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
715 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
717 if (!IopCreateUnicodeString(
718 &PdoDeviceExtension
->DeviceID
,
719 Device
->DeviceID
.Buffer
,
722 DPRINT("Insufficient resources\n");
726 DPRINT("DeviceID: %S PDO %x\n",
727 PdoDeviceExtension
->DeviceID
.Buffer
,
730 if (!IopCreateUnicodeString(
731 &PdoDeviceExtension
->InstanceID
,
732 Device
->InstanceID
.Buffer
,
735 DPRINT("Insufficient resources\n");
741 /* Reference the physical device object. The PnP manager
742 will dereference it again when it is no longer needed */
743 ObReferenceObject(Device
->Pdo
);
745 Relations
->Objects
[i
] = Device
->Pdo
;
749 CurrentEntry
= CurrentEntry
->Flink
;
752 if (NT_SUCCESS(Status
))
754 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
758 Irp
->IoStatus
.Information
= 0;
766 PnpRootQueryDeviceRelations(
767 IN PDEVICE_OBJECT DeviceObject
,
769 IN PIO_STACK_LOCATION IrpSp
)
775 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
777 Status
= PnpRootQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
781 Status
= STATUS_NOT_IMPLEMENTED
;
790 PnpRootFdoPnpControl(
791 IN PDEVICE_OBJECT DeviceObject
,
794 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
796 * DeviceObject = Pointer to functional device object of the root bus driver
797 * Irp = Pointer to IRP that should be handled
802 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
803 PIO_STACK_LOCATION IrpSp
;
808 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
810 Status
= Irp
->IoStatus
.Status
;
812 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
814 switch (IrpSp
->MinorFunction
) {
815 case IRP_MN_QUERY_DEVICE_RELATIONS
:
816 Status
= PnpRootQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
819 case IRP_MN_START_DEVICE
:
820 DeviceExtension
->State
= dsStarted
;
821 Status
= STATUS_SUCCESS
;
824 case IRP_MN_STOP_DEVICE
:
825 /* Root device cannot be stopped */
826 Status
= STATUS_UNSUCCESSFUL
;
830 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
831 Status
= STATUS_NOT_IMPLEMENTED
;
835 if (Status
!= STATUS_PENDING
) {
836 Irp
->IoStatus
.Status
= Status
;
837 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
840 DPRINT("Leaving. Status 0x%X\n", Status
);
848 PnpRootFdoPowerControl(
849 IN PDEVICE_OBJECT DeviceObject
,
852 * FUNCTION: Handle power management IRPs for the root bus device object
854 * DeviceObject = Pointer to functional device object of the root bus driver
855 * Irp = Pointer to IRP that should be handled
860 PIO_STACK_LOCATION IrpSp
;
865 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
867 switch (IrpSp
->MinorFunction
) {
869 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
870 Status
= STATUS_NOT_IMPLEMENTED
;
874 if (Status
!= STATUS_PENDING
) {
875 Irp
->IoStatus
.Status
= Status
;
876 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
879 DPRINT("Leaving. Status 0x%X\n", Status
);
888 IN PDEVICE_OBJECT DeviceObject
,
891 * FUNCTION: Handle Plug and Play IRPs
893 * DeviceObject = Pointer to PDO or FDO
894 * Irp = Pointer to IRP that should be handled
899 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
902 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
904 DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
907 DeviceExtension
->IsFDO
);
909 if (DeviceExtension
->IsFDO
) {
910 Status
= PnpRootFdoPnpControl(DeviceObject
, Irp
);
912 Status
= PnpRootPdoPnpControl(DeviceObject
, Irp
);
922 IN PDEVICE_OBJECT DeviceObject
,
925 * FUNCTION: Handle power management IRPs
927 * DeviceObject = Pointer to PDO or FDO
928 * Irp = Pointer to IRP that should be handled
933 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension
;
936 DeviceExtension
= (PPNPROOT_COMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
938 if (DeviceExtension
->IsFDO
) {
939 Status
= PnpRootFdoPowerControl(DeviceObject
, Irp
);
941 Status
= PnpRootPdoPowerControl(DeviceObject
, Irp
);
951 IN PDRIVER_OBJECT DriverObject
,
952 IN PDEVICE_OBJECT PhysicalDeviceObject
)
954 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension
;
959 Status
= IoCreateDevice(
961 sizeof(PNPROOT_FDO_DEVICE_EXTENSION
),
963 FILE_DEVICE_BUS_EXTENDER
,
964 FILE_DEVICE_SECURE_OPEN
,
966 &PnpRootDeviceObject
);
967 if (!NT_SUCCESS(Status
)) {
968 CPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
969 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED
);
972 DeviceExtension
= (PPNPROOT_FDO_DEVICE_EXTENSION
)PnpRootDeviceObject
->DeviceExtension
;
974 RtlZeroMemory(DeviceExtension
, sizeof(PNPROOT_FDO_DEVICE_EXTENSION
));
976 DeviceExtension
->Common
.IsFDO
= TRUE
;
978 DeviceExtension
->State
= dsStopped
;
980 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(
982 PhysicalDeviceObject
);
984 if (!PnpRootDeviceObject
) {
985 CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject
);
986 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED
);
989 if (!PhysicalDeviceObject
) {
990 CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject
);
991 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED
);
994 InitializeListHead(&DeviceExtension
->DeviceListHead
);
996 DeviceExtension
->DeviceListCount
= 0;
998 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
1000 PnpRootDeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1002 //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
1004 DPRINT("Done AddDevice()\n");
1006 return STATUS_SUCCESS
;
1013 IN PDRIVER_OBJECT DriverObject
,
1014 IN PUNICODE_STRING RegistryPath
)
1018 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
) PnpRootPnpControl
;
1019 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = (PDRIVER_DISPATCH
) PnpRootPowerControl
;
1020 DriverObject
->DriverExtension
->AddDevice
= PnpRootAddDevice
;
1022 return STATUS_SUCCESS
;