mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 05:02:48 +00:00
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:
parent
03d12cf07b
commit
dcc142c4a1
6 changed files with 121 additions and 55 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue