mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 02:46:57 +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 */
|
/* 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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue