diff --git a/reactos/base/services/umpnpmgr/umpnpmgr.c b/reactos/base/services/umpnpmgr/umpnpmgr.c index 0253fc536c0..c778c228f68 100644 --- a/reactos/base/services/umpnpmgr/umpnpmgr.c +++ b/reactos/base/services/umpnpmgr/umpnpmgr.c @@ -2165,7 +2165,7 @@ PnpEventThread(LPVOID lpParameter) /* Process the pnp event */ DPRINT("Received PnP Event\n"); - if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus)) + if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ENUMERATED, &RpcStatus)) { DeviceInstallParams* Params; DWORD len; diff --git a/reactos/base/setup/usetup/interface/devinst.c b/reactos/base/setup/usetup/interface/devinst.c index f5ae9c0a1f4..a646624113f 100644 --- a/reactos/base/setup/usetup/interface/devinst.c +++ b/reactos/base/setup/usetup/interface/devinst.c @@ -366,7 +366,7 @@ EventThread(IN LPVOID lpParameter) /* Process the pnp event */ DPRINT("Received PnP Event\n"); - if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ARRIVAL)) + if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ENUMERATED)) { DPRINT1("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds); InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds); diff --git a/reactos/include/ndk/iotypes.h b/reactos/include/ndk/iotypes.h index 42f7644ef95..d19d4ad0307 100644 --- a/reactos/include/ndk/iotypes.h +++ b/reactos/include/ndk/iotypes.h @@ -23,6 +23,7 @@ Author: // #include #include +#include // // I/O Completion Access Rights @@ -321,6 +322,18 @@ typedef enum _FSINFOCLASS #endif +// +// Dock Profile Status +// +typedef enum _PROFILE_STATUS +{ + DOCK_NOTDOCKDEVICE, + DOCK_QUIESCENT, + DOCK_ARRIVING, + DOCK_DEPARTING, + DOCK_EJECTIRP_COMPLETED +} PROFILE_STATUS, *PPROFILE_STATUS; + // // Device Node States // @@ -740,17 +753,18 @@ typedef struct _IO_CLIENT_EXTENSION // typedef struct _DEVICE_NODE { - struct _DEVICE_NODE *Parent; - struct _DEVICE_NODE *PrevSibling; - struct _DEVICE_NODE *NextSibling; + struct _DEVICE_NODE *Sibling; struct _DEVICE_NODE *Child; + struct _DEVICE_NODE *Parent; + struct _DEVICE_NODE *LastChild; ULONG Level; struct _PO_DEVICE_NOTIFY *Notify; + PO_IRP_MANAGER PoIrpManager; PNP_DEVNODE_STATE State; PNP_DEVNODE_STATE PreviousState; PNP_DEVNODE_STATE StateHistory[20]; ULONG StateHistoryEntry; - INT CompletionStatus; + LONG CompletionStatus; PIRP PendingIrp; ULONG Flags; ULONG UserFlags; @@ -786,10 +800,13 @@ typedef struct _DEVICE_NODE struct _DEVICE_NODE *NextResourceDeviceNode; } OverUsed2; PCM_RESOURCE_LIST BootResources; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + PCM_RESOURCE_LIST BootResourcesTranslated; +#endif ULONG CapabilityFlags; struct { - ULONG DockStatus; + PROFILE_STATUS DockStatus; LIST_ENTRY ListEntry; WCHAR *SerialNumber; } DockInfo; @@ -799,6 +816,9 @@ typedef struct _DEVICE_NODE ULONG DriverUnloadRetryCount; struct _DEVICE_NODE *PreviousParent; ULONG DeletedChidren; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + ULONG NumaNodeIndex; +#endif } DEVICE_NODE, *PDEVICE_NODE; // diff --git a/reactos/include/ndk/potypes.h b/reactos/include/ndk/potypes.h index 6627aabe037..91f7f6be3d7 100644 --- a/reactos/include/ndk/potypes.h +++ b/reactos/include/ndk/potypes.h @@ -107,6 +107,22 @@ typedef struct _PO_DEVICE_NOTIFY ULONG ActiveChild; } PO_DEVICE_NOTIFY, *PPO_DEVICE_NOTIFY; +// +// Power IRP Queue +// +typedef struct _PO_IRP_QUEUE +{ + PIRP CurrentIrp; + PIRP PendingIrpList; +} PO_IRP_QUEUE, *PPO_IRP_QUEUE; + +// Power IRP Manager +typedef struct _PO_IRP_MANAGER +{ + PO_IRP_QUEUE DeviceIrpQueue; + PO_IRP_QUEUE SystemIrpQueue; +} PO_IRP_MANAGER, *PPO_IRP_MANAGER; + #endif // !NTOS_MODE_USER #endif // _POTYPES_H diff --git a/reactos/ntoskrnl/io/pnpmgr/plugplay.c b/reactos/ntoskrnl/io/pnpmgr/plugplay.c index e7bdf2ffd7c..fda41f45eb8 100644 --- a/reactos/ntoskrnl/io/pnpmgr/plugplay.c +++ b/reactos/ntoskrnl/io/pnpmgr/plugplay.c @@ -128,7 +128,7 @@ IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance) /* Traversal of all children nodes */ for (ChildNode = Node->Child; ChildNode != NULL; - ChildNode = ChildNode->NextSibling) + ChildNode = ChildNode->Sibling) { DeviceObject = IopTraverseDeviceNode(ChildNode, DeviceInstance); if (DeviceObject != NULL) @@ -360,7 +360,7 @@ IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData) break; case PNP_GET_SIBLING_DEVICE: - RelatedDeviceNode = DeviceNode->NextSibling; + RelatedDeviceNode = DeviceNode->Sibling; break; default: diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index bce99201e6e..4b96764b935 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -384,19 +384,21 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node; - if (ParentNode) - { - KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); - Node->Parent = ParentNode; - Node->NextSibling = ParentNode->Child; - if (ParentNode->Child != NULL) - { - ParentNode->Child->PrevSibling = Node; - } - ParentNode->Child = Node; - KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); - Node->Level = ParentNode->Level + 1; - } + if (ParentNode) + { + KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); + Node->Parent = ParentNode; + if (ParentNode->LastChild != NULL) + ParentNode->LastChild->Sibling = Node; + else + ParentNode->Child = Node; + ParentNode->LastChild = Node; + KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); + Node->Level = ParentNode->Level + 1; + } + + if (PhysicalDeviceObject) + PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; *DeviceNode = Node; @@ -407,6 +409,7 @@ NTSTATUS IopFreeDeviceNode(PDEVICE_NODE DeviceNode) { KIRQL OldIrql; + PDEVICE_NODE PrevSibling = NULL; /* All children must be deleted before a parent is deleted */ ASSERT(!DeviceNode->Child); @@ -417,24 +420,30 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode) ObDereferenceObject(DeviceNode->PhysicalDeviceObject); - /* Unlink from parent if it exists */ + /* Get previous sibling */ + if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode) + { + PrevSibling = DeviceNode->Parent->Child; + while (PrevSibling->Sibling != DeviceNode) + PrevSibling = PrevSibling->Sibling; + } - if ((DeviceNode->Parent) && (DeviceNode->Parent->Child == DeviceNode)) - { - DeviceNode->Parent->Child = DeviceNode->NextSibling; - } + /* Unlink from parent if it exists */ + if (DeviceNode->Parent) + { + if (DeviceNode->Parent->LastChild == DeviceNode) + { + DeviceNode->Parent->LastChild = PrevSibling; + if (PrevSibling) + PrevSibling->Sibling = NULL; + } + if (DeviceNode->Parent->Child == DeviceNode) + DeviceNode->Parent->Child = DeviceNode->Sibling; + } - /* Unlink from sibling list */ - - if (DeviceNode->PrevSibling) - { - DeviceNode->PrevSibling->NextSibling = DeviceNode->NextSibling; - } - - if (DeviceNode->NextSibling) - { - DeviceNode->NextSibling->PrevSibling = DeviceNode->PrevSibling; - } + /* Unlink from sibling list */ + if (PrevSibling) + PrevSibling->Sibling = DeviceNode->Sibling; KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); @@ -547,7 +556,7 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) /* Traversal of all children nodes */ for (ChildDeviceNode = ParentDeviceNode->Child; ChildDeviceNode != NULL; - ChildDeviceNode = ChildDeviceNode->NextSibling) + ChildDeviceNode = ChildDeviceNode->Sibling) { /* Pass the current device node to the action routine */ Context->DeviceNode = ChildDeviceNode; @@ -1656,7 +1665,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, if (!IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER)) { /* Report the device to the user-mode pnp manager */ - IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, + IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED, &DeviceNode->InstancePath); } @@ -1671,6 +1680,7 @@ IopEnumerateDevice( PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); DEVICETREE_TRAVERSE_CONTEXT Context; PDEVICE_RELATIONS DeviceRelations; + PDEVICE_OBJECT ChildDeviceObject; IO_STATUS_BLOCK IoStatusBlock; PDEVICE_NODE ChildDeviceNode; IO_STACK_LOCATION Stack; @@ -1679,6 +1689,12 @@ IopEnumerateDevice( DPRINT("DeviceObject 0x%p\n", DeviceObject); + DPRINT("Sending GUID_DEVICE_ARRIVAL\n"); + + /* Report the device to the user-mode pnp manager */ + IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, + &DeviceNode->InstancePath); + DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); Stack.Parameters.QueryDeviceRelations.Type = BusRelations; @@ -1709,24 +1725,38 @@ IopEnumerateDevice( */ for (i = 0; i < DeviceRelations->Count; i++) { - if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL) + ChildDeviceObject = DeviceRelations->Objects[i]; + ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0); + + ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject); + if (!ChildDeviceNode) { - ObDereferenceObject(DeviceRelations->Objects[i]); - continue; + /* One doesn't exist, create it */ + Status = IopCreateDeviceNode( + DeviceNode, + ChildDeviceObject, + NULL, + &ChildDeviceNode); + if (NT_SUCCESS(Status)) + { + /* Mark the node as enumerated */ + ChildDeviceNode->Flags |= DNF_ENUMERATED; + + /* Mark the DO as bus enumerated */ + ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE; + } + else + { + /* Ignore this DO */ + DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u\n", Status, i); + ObDereferenceObject(ChildDeviceNode); + } } - Status = IopCreateDeviceNode( - DeviceNode, - DeviceRelations->Objects[i], - NULL, - &ChildDeviceNode); - DeviceNode->Flags |= DNF_ENUMERATED; - if (!NT_SUCCESS(Status)) + else { - DPRINT("No resources\n"); - for (i = 0; i < DeviceRelations->Count; i++) - ObDereferenceObject(DeviceRelations->Objects[i]); - ExFreePool(DeviceRelations); - return Status; + /* Mark it as enumerated */ + ChildDeviceNode->Flags |= DNF_ENUMERATED; + ObDereferenceObject(ChildDeviceObject); } } ExFreePool(DeviceRelations);