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 */ /* Process the pnp event */
DPRINT("Received PnP Event\n"); 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; DeviceInstallParams* Params;
DWORD len; DWORD len;

View file

@ -366,7 +366,7 @@ EventThread(IN LPVOID lpParameter)
/* Process the pnp event */ /* Process the pnp event */
DPRINT("Received PnP Event\n"); 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); DPRINT1("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds); InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds);

View file

@ -23,6 +23,7 @@ Author:
// //
#include <umtypes.h> #include <umtypes.h>
#include <ifssupp.h> #include <ifssupp.h>
#include <potypes.h>
// //
// I/O Completion Access Rights // I/O Completion Access Rights
@ -321,6 +322,18 @@ typedef enum _FSINFOCLASS
#endif #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 // Device Node States
// //
@ -740,17 +753,18 @@ typedef struct _IO_CLIENT_EXTENSION
// //
typedef struct _DEVICE_NODE typedef struct _DEVICE_NODE
{ {
struct _DEVICE_NODE *Parent; struct _DEVICE_NODE *Sibling;
struct _DEVICE_NODE *PrevSibling;
struct _DEVICE_NODE *NextSibling;
struct _DEVICE_NODE *Child; struct _DEVICE_NODE *Child;
struct _DEVICE_NODE *Parent;
struct _DEVICE_NODE *LastChild;
ULONG Level; ULONG Level;
struct _PO_DEVICE_NOTIFY *Notify; struct _PO_DEVICE_NOTIFY *Notify;
PO_IRP_MANAGER PoIrpManager;
PNP_DEVNODE_STATE State; PNP_DEVNODE_STATE State;
PNP_DEVNODE_STATE PreviousState; PNP_DEVNODE_STATE PreviousState;
PNP_DEVNODE_STATE StateHistory[20]; PNP_DEVNODE_STATE StateHistory[20];
ULONG StateHistoryEntry; ULONG StateHistoryEntry;
INT CompletionStatus; LONG CompletionStatus;
PIRP PendingIrp; PIRP PendingIrp;
ULONG Flags; ULONG Flags;
ULONG UserFlags; ULONG UserFlags;
@ -786,10 +800,13 @@ typedef struct _DEVICE_NODE
struct _DEVICE_NODE *NextResourceDeviceNode; struct _DEVICE_NODE *NextResourceDeviceNode;
} OverUsed2; } OverUsed2;
PCM_RESOURCE_LIST BootResources; PCM_RESOURCE_LIST BootResources;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
PCM_RESOURCE_LIST BootResourcesTranslated;
#endif
ULONG CapabilityFlags; ULONG CapabilityFlags;
struct struct
{ {
ULONG DockStatus; PROFILE_STATUS DockStatus;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
WCHAR *SerialNumber; WCHAR *SerialNumber;
} DockInfo; } DockInfo;
@ -799,6 +816,9 @@ typedef struct _DEVICE_NODE
ULONG DriverUnloadRetryCount; ULONG DriverUnloadRetryCount;
struct _DEVICE_NODE *PreviousParent; struct _DEVICE_NODE *PreviousParent;
ULONG DeletedChidren; ULONG DeletedChidren;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
ULONG NumaNodeIndex;
#endif
} DEVICE_NODE, *PDEVICE_NODE; } DEVICE_NODE, *PDEVICE_NODE;
// //

View file

@ -107,6 +107,22 @@ typedef struct _PO_DEVICE_NOTIFY
ULONG ActiveChild; ULONG ActiveChild;
} PO_DEVICE_NOTIFY, *PPO_DEVICE_NOTIFY; } 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 // !NTOS_MODE_USER
#endif // _POTYPES_H #endif // _POTYPES_H

View file

@ -128,7 +128,7 @@ IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
/* Traversal of all children nodes */ /* Traversal of all children nodes */
for (ChildNode = Node->Child; for (ChildNode = Node->Child;
ChildNode != NULL; ChildNode != NULL;
ChildNode = ChildNode->NextSibling) ChildNode = ChildNode->Sibling)
{ {
DeviceObject = IopTraverseDeviceNode(ChildNode, DeviceInstance); DeviceObject = IopTraverseDeviceNode(ChildNode, DeviceInstance);
if (DeviceObject != NULL) if (DeviceObject != NULL)
@ -360,7 +360,7 @@ IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData)
break; break;
case PNP_GET_SIBLING_DEVICE: case PNP_GET_SIBLING_DEVICE:
RelatedDeviceNode = DeviceNode->NextSibling; RelatedDeviceNode = DeviceNode->Sibling;
break; break;
default: default:

View file

@ -384,19 +384,21 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node; ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node;
if (ParentNode) if (ParentNode)
{ {
KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
Node->Parent = ParentNode; Node->Parent = ParentNode;
Node->NextSibling = ParentNode->Child; if (ParentNode->LastChild != NULL)
if (ParentNode->Child != NULL) ParentNode->LastChild->Sibling = Node;
{ else
ParentNode->Child->PrevSibling = Node; ParentNode->Child = Node;
} ParentNode->LastChild = Node;
ParentNode->Child = Node; KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); Node->Level = ParentNode->Level + 1;
Node->Level = ParentNode->Level + 1; }
}
if (PhysicalDeviceObject)
PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
*DeviceNode = Node; *DeviceNode = Node;
@ -407,6 +409,7 @@ NTSTATUS
IopFreeDeviceNode(PDEVICE_NODE DeviceNode) IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PDEVICE_NODE PrevSibling = NULL;
/* All children must be deleted before a parent is deleted */ /* All children must be deleted before a parent is deleted */
ASSERT(!DeviceNode->Child); ASSERT(!DeviceNode->Child);
@ -417,24 +420,30 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
ObDereferenceObject(DeviceNode->PhysicalDeviceObject); 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)) /* Unlink from parent if it exists */
{ if (DeviceNode->Parent)
DeviceNode->Parent->Child = DeviceNode->NextSibling; {
} 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 */ /* Unlink from sibling list */
if (PrevSibling)
if (DeviceNode->PrevSibling) PrevSibling->Sibling = DeviceNode->Sibling;
{
DeviceNode->PrevSibling->NextSibling = DeviceNode->NextSibling;
}
if (DeviceNode->NextSibling)
{
DeviceNode->NextSibling->PrevSibling = DeviceNode->PrevSibling;
}
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
@ -547,7 +556,7 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context)
/* Traversal of all children nodes */ /* Traversal of all children nodes */
for (ChildDeviceNode = ParentDeviceNode->Child; for (ChildDeviceNode = ParentDeviceNode->Child;
ChildDeviceNode != NULL; ChildDeviceNode != NULL;
ChildDeviceNode = ChildDeviceNode->NextSibling) ChildDeviceNode = ChildDeviceNode->Sibling)
{ {
/* Pass the current device node to the action routine */ /* Pass the current device node to the action routine */
Context->DeviceNode = ChildDeviceNode; Context->DeviceNode = ChildDeviceNode;
@ -1656,7 +1665,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
if (!IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER)) if (!IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER))
{ {
/* Report the device to the user-mode pnp manager */ /* Report the device to the user-mode pnp manager */
IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
&DeviceNode->InstancePath); &DeviceNode->InstancePath);
} }
@ -1671,6 +1680,7 @@ IopEnumerateDevice(
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
DEVICETREE_TRAVERSE_CONTEXT Context; DEVICETREE_TRAVERSE_CONTEXT Context;
PDEVICE_RELATIONS DeviceRelations; PDEVICE_RELATIONS DeviceRelations;
PDEVICE_OBJECT ChildDeviceObject;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_NODE ChildDeviceNode; PDEVICE_NODE ChildDeviceNode;
IO_STACK_LOCATION Stack; IO_STACK_LOCATION Stack;
@ -1679,6 +1689,12 @@ IopEnumerateDevice(
DPRINT("DeviceObject 0x%p\n", DeviceObject); 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"); DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
Stack.Parameters.QueryDeviceRelations.Type = BusRelations; Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
@ -1709,24 +1725,38 @@ IopEnumerateDevice(
*/ */
for (i = 0; i < DeviceRelations->Count; i++) 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]); /* One doesn't exist, create it */
continue; 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( else
DeviceNode,
DeviceRelations->Objects[i],
NULL,
&ChildDeviceNode);
DeviceNode->Flags |= DNF_ENUMERATED;
if (!NT_SUCCESS(Status))
{ {
DPRINT("No resources\n"); /* Mark it as enumerated */
for (i = 0; i < DeviceRelations->Count; i++) ChildDeviceNode->Flags |= DNF_ENUMERATED;
ObDereferenceObject(DeviceRelations->Objects[i]); ObDereferenceObject(ChildDeviceObject);
ExFreePool(DeviceRelations);
return Status;
} }
} }
ExFreePool(DeviceRelations); ExFreePool(DeviceRelations);