Fix device node structure to be compatible with MS Windows Vista

Send GUID_DEVICE_ENUMERATED event
umpnpmgr: react on GUID_DEVICE_ENUMERATED, not GUID_DEVICE_ARRIVAL
IopEnumerateDevice: Set DNF_ENUMERATED and DO_BUS_ENUMERATED_DEVICE when required
IopEnumerateDevice: Continue to process PDOs, even if one failed

svn path=/trunk/; revision=35543
This commit is contained in:
Hervé Poussineau 2008-08-22 21:43:42 +00:00
parent 03d12cf07b
commit dcc142c4a1
6 changed files with 121 additions and 55 deletions

View file

@ -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;

View file

@ -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);

View file

@ -23,6 +23,7 @@ Author:
//
#include <umtypes.h>
#include <ifssupp.h>
#include <potypes.h>
//
// 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;
//

View file

@ -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

View file

@ -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:

View file

@ -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);