ReactOS  0.4.15-dev-5112-g22d8c0f
devnode.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for devnode.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PDEVICE_NODE FASTCALL IopGetDeviceNode (_In_ PDEVICE_OBJECT DeviceObject)
 
PDEVICE_NODE PipAllocateDeviceNode (_In_opt_ PDEVICE_OBJECT PhysicalDeviceObject)
 
VOID PiInsertDevNode (_In_ PDEVICE_NODE DeviceNode, _In_ PDEVICE_NODE ParentNode)
 
PNP_DEVNODE_STATE PiSetDevNodeState (_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
 
VOID PiSetDevNodeProblem (_In_ PDEVICE_NODE DeviceNode, _In_ UINT32 Problem)
 
VOID PiClearDevNodeProblem (_In_ PDEVICE_NODE DeviceNode)
 
NTSTATUS IopFreeDeviceNode (_In_ PDEVICE_NODE DeviceNode)
 Creates a device node. More...
 
static NTSTATUS IopFindNextDeviceNodeForTraversal (_In_ PDEVICETREE_TRAVERSE_CONTEXT Context)
 
NTSTATUS IopTraverseDeviceTree (_In_ PDEVICETREE_TRAVERSE_CONTEXT Context)
 

Variables

PDEVICE_NODE IopRootDeviceNode
 
KSPIN_LOCK IopDeviceTreeLock
 
LONG IopNumberDeviceNodes
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file devnode.c.

Function Documentation

◆ IopFindNextDeviceNodeForTraversal()

static NTSTATUS IopFindNextDeviceNodeForTraversal ( _In_ PDEVICETREE_TRAVERSE_CONTEXT  Context)
static

Definition at line 402 of file devnode.c.

404 {
405  /* If we have a child, simply go down the tree */
406  if (Context->DeviceNode->Child != NULL)
407  {
408  ASSERT(Context->DeviceNode->Child->Parent == Context->DeviceNode);
409  Context->DeviceNode = Context->DeviceNode->Child;
410  return STATUS_SUCCESS;
411  }
412 
413  while (Context->DeviceNode != Context->FirstDeviceNode)
414  {
415  /* All children processed -- go sideways */
416  if (Context->DeviceNode->Sibling != NULL)
417  {
418  ASSERT(Context->DeviceNode->Sibling->Parent == Context->DeviceNode->Parent);
419  Context->DeviceNode = Context->DeviceNode->Sibling;
420  return STATUS_SUCCESS;
421  }
422 
423  /* We're the last sibling -- go back up */
424  ASSERT(Context->DeviceNode->Parent->LastChild == Context->DeviceNode);
425  Context->DeviceNode = Context->DeviceNode->Parent;
426 
427  /* We already visited the parent and all its children, so keep looking */
428  }
429 
430  /* Done with all children of the start node -- stop enumeration */
431  return STATUS_UNSUCCESSFUL;
432 }
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by IopTraverseDeviceTree().

◆ IopFreeDeviceNode()

NTSTATUS IopFreeDeviceNode ( _In_ PDEVICE_NODE  DeviceNode)

Creates a device node.

Parameters
[in]ParentNodePointer to parent device node
[in]PhysicalDeviceObjectPointer to PDO for device object. Pass NULL to have the root device node create one (eg. for legacy drivers)
[in]ServiceNameThe service (driver) name for a node. Pass NULL to set UNKNOWN as a service
[out]DeviceNodePointer to storage for created device node
Returns
Status, indicating the result of an operation

Definition at line 327 of file devnode.c.

329 {
330  KIRQL OldIrql;
331  PDEVICE_NODE PrevSibling = NULL;
332 
333  ASSERT(DeviceNode->PhysicalDeviceObject);
334  /* All children must be deleted before a parent is deleted */
335  ASSERT(DeviceNode->Child == NULL);
336  /* This is the only state where we are allowed to remove the node */
338  /* No notifications should be registered for this device */
339  ASSERT(IsListEmpty(&DeviceNode->TargetDeviceNotify));
340 
342 
343  /* Get previous sibling */
344  if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode)
345  {
346  PrevSibling = DeviceNode->Parent->Child;
347  while (PrevSibling->Sibling != DeviceNode)
348  PrevSibling = PrevSibling->Sibling;
349  }
350 
351  /* Unlink from parent if it exists */
352  if (DeviceNode->Parent)
353  {
354  if (DeviceNode->Parent->LastChild == DeviceNode)
355  {
356  DeviceNode->Parent->LastChild = PrevSibling;
357  if (PrevSibling)
358  PrevSibling->Sibling = NULL;
359  }
360  if (DeviceNode->Parent->Child == DeviceNode)
361  DeviceNode->Parent->Child = DeviceNode->Sibling;
362  }
363 
364  /* Unlink from sibling list */
365  if (PrevSibling)
366  PrevSibling->Sibling = DeviceNode->Sibling;
367 
369 
370  RtlFreeUnicodeString(&DeviceNode->InstancePath);
371 
372  RtlFreeUnicodeString(&DeviceNode->ServiceName);
373 
374  if (DeviceNode->ResourceList)
375  {
376  ExFreePool(DeviceNode->ResourceList);
377  }
378 
379  if (DeviceNode->ResourceListTranslated)
380  {
381  ExFreePool(DeviceNode->ResourceListTranslated);
382  }
383 
384  if (DeviceNode->ResourceRequirements)
385  {
386  ExFreePool(DeviceNode->ResourceRequirements);
387  }
388 
389  if (DeviceNode->BootResources)
390  {
391  ExFreePool(DeviceNode->BootResources);
392  }
393 
394  ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL;
396 
397  return STATUS_SUCCESS;
398 }
#define TAG_IO_DEVNODE
Definition: tag.h:87
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: Node.h:9
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:839
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ IopGetDeviceNode()

PDEVICE_NODE FASTCALL IopGetDeviceNode ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 27 of file devnode.c.

29 {
30  return ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
31 }
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ IopTraverseDeviceTree()

NTSTATUS IopTraverseDeviceTree ( _In_ PDEVICETREE_TRAVERSE_CONTEXT  Context)

Definition at line 435 of file devnode.c.

437 {
440 
441  DPRINT("Context 0x%p\n", Context);
442 
443  DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p Context 0x%p)\n",
444  Context->DeviceNode, Context->FirstDeviceNode, Context->Action, Context->Context);
445 
446  /* Start from the specified device node */
447  Context->DeviceNode = Context->FirstDeviceNode;
448 
449  /* Traverse the device tree */
450  do
451  {
452  DeviceNode = Context->DeviceNode;
453 
454  /* HACK: Keep a reference to the PDO so we can keep traversing the tree
455  * if the device is deleted. In a perfect world, children would have to be
456  * deleted before their parents, and we'd restart the traversal after
457  * deleting a device node. */
458  ObReferenceObject(DeviceNode->PhysicalDeviceObject);
459 
460  /* Call the action routine */
461  Status = (Context->Action)(DeviceNode, Context->Context);
462  if (NT_SUCCESS(Status))
463  {
464  /* Find next device node */
465  ASSERT(Context->DeviceNode == DeviceNode);
467  }
468 
469  /* We need to either abort or make progress */
470  ASSERT(!NT_SUCCESS(Status) || Context->DeviceNode != DeviceNode);
471 
472  ObDereferenceObject(DeviceNode->PhysicalDeviceObject);
473  } while (NT_SUCCESS(Status));
474 
476  {
477  /* The action routine just wanted to terminate the traversal with status
478  code STATUS_SUCCESS */
480  }
481 
482  return Status;
483 }
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS IopFindNextDeviceNodeForTraversal(_In_ PDEVICETREE_TRAVERSE_CONTEXT Context)
Definition: devnode.c:402
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ObReferenceObject
Definition: obfuncs.h:204
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

◆ PiClearDevNodeProblem()

VOID PiClearDevNodeProblem ( _In_ PDEVICE_NODE  DeviceNode)

Definition at line 141 of file devnode.c.

143 {
144  DeviceNode->Flags &= ~DNF_HAS_PROBLEM;
145  DeviceNode->Problem = 0;
146 }
#define DNF_HAS_PROBLEM
Definition: iotypes.h:183
Definition: Node.h:9

◆ PiInsertDevNode()

VOID PiInsertDevNode ( _In_ PDEVICE_NODE  DeviceNode,
_In_ PDEVICE_NODE  ParentNode 
)

Definition at line 80 of file devnode.c.

83 {
84  KIRQL oldIrql;
85 
86  ASSERT(DeviceNode->Parent == NULL);
87 
89  DeviceNode->Parent = ParentNode;
90  DeviceNode->Sibling = NULL;
91  if (ParentNode->LastChild == NULL)
92  {
93  ParentNode->Child = DeviceNode;
94  ParentNode->LastChild = DeviceNode;
95  }
96  else
97  {
98  ParentNode->LastChild->Sibling = DeviceNode;
99  ParentNode->LastChild = DeviceNode;
100  }
102  DeviceNode->Level = ParentNode->Level + 1;
103 
104  DPRINT("Inserted devnode 0x%p to parent 0x%p\n", DeviceNode, ParentNode);
105 }
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ASSERT(a)
Definition: mode.c:44
Definition: Node.h:9
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT
Definition: sndvol32.h:71

Referenced by IopInitializeDevice(), IoReportDetectedDevice(), and PiEnumerateDevice().

◆ PipAllocateDeviceNode()

PDEVICE_NODE PipAllocateDeviceNode ( _In_opt_ PDEVICE_OBJECT  PhysicalDeviceObject)

Definition at line 34 of file devnode.c.

36 {
38  PAGED_CODE();
39 
40  /* Allocate it */
41  DeviceNode = ExAllocatePoolZero(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE);
42  if (!DeviceNode)
43  {
44  return NULL;
45  }
46 
47  /* Statistics */
49 
50  /* Set it up */
51  DeviceNode->InterfaceType = InterfaceTypeUndefined;
52  DeviceNode->BusNumber = -1;
53  DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
54  DeviceNode->ChildBusNumber = -1;
55  DeviceNode->ChildBusTypeIndex = -1;
57 // KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, TRUE);
58  InitializeListHead(&DeviceNode->DeviceArbiterList);
59  InitializeListHead(&DeviceNode->DeviceTranslatorList);
60  InitializeListHead(&DeviceNode->TargetDeviceNotify);
61  InitializeListHead(&DeviceNode->DockInfo.ListEntry);
62  InitializeListHead(&DeviceNode->PendedSetInterfaceState);
63 
64  /* Check if there is a PDO */
66  {
67  /* Link it and remove the init flag */
68  DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject;
69  ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode;
71  }
72 
73  DPRINT("Allocated devnode 0x%p\n", DeviceNode);
74 
75  /* Return the node */
76  return DeviceNode;
77 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define TAG_IO_DEVNODE
Definition: tag.h:87
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1149
LONG IopNumberDeviceNodes
Definition: devnode.c:21
Definition: Node.h:9
#define InterlockedIncrement
Definition: armddk.h:53
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71
#define PAGED_CODE()

◆ PiSetDevNodeProblem()

VOID PiSetDevNodeProblem ( _In_ PDEVICE_NODE  DeviceNode,
_In_ UINT32  Problem 
)

Definition at line 132 of file devnode.c.

135 {
136  DeviceNode->Flags |= DNF_HAS_PROBLEM;
137  DeviceNode->Problem = Problem;
138 }
#define DNF_HAS_PROBLEM
Definition: iotypes.h:183
Definition: Node.h:9

Referenced by PiAttachFilterDriversCallback(), PiCallDriverAddDevice(), PiDevNodeStateMachine(), and PiUpdateDeviceState().

◆ PiSetDevNodeState()

PNP_DEVNODE_STATE PiSetDevNodeState ( _In_ PDEVICE_NODE  DeviceNode,
_In_ PNP_DEVNODE_STATE  NewState 
)

Definition at line 108 of file devnode.c.

111 {
112  KIRQL oldIrql;
113 
115 
116  PNP_DEVNODE_STATE prevState = DeviceNode->State;
117  if (prevState != NewState)
118  {
119  DeviceNode->State = NewState;
120  DeviceNode->PreviousState = prevState;
121  DeviceNode->StateHistory[DeviceNode->StateHistoryEntry++] = prevState;
122  DeviceNode->StateHistoryEntry %= DEVNODE_HISTORY_SIZE;
123  }
124 
126 
127  DPRINT("%wZ Changed state 0x%x => 0x%x\n", &DeviceNode->InstancePath, prevState, NewState);
128  return prevState;
129 }
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
enum _PNP_DEVNODE_STATE PNP_DEVNODE_STATE
Definition: Node.h:9
#define DEVNODE_HISTORY_SIZE
Definition: iotypes.h:832
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT
Definition: sndvol32.h:71

Referenced by IopAssignDeviceResources(), IopInitializePlugPlayServices(), IopQueryRemoveChildDevices(), IopSendRemoveDevice(), IoReportDetectedDevice(), PiCallDriverAddDevice(), PiDevNodeStateMachine(), PiEnumerateDevice(), PiInitializeDevNode(), PiStartDeviceFinal(), and PiUpdateDeviceState().

Variable Documentation

◆ IopDeviceTreeLock

◆ IopNumberDeviceNodes

LONG IopNumberDeviceNodes

Definition at line 21 of file devnode.c.

Referenced by PipAllocateDeviceNode().

◆ IopRootDeviceNode