ReactOS 0.4.15-dev-7907-g95bf896
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.
 
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 NULL
Definition: types.h:112
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

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{
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}
@ DeviceNode
Definition: Node.h:9
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ DeviceNodeRemoved
Definition: iotypes.h:439
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:876
#define TAG_IO_DEVNODE
Definition: tag.h:90
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ 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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define DPRINT
Definition: sndvol32.h:71
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204

◆ 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}

◆ 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}

Referenced by IoReportDetectedDevice(), PiControlInitializeDevice(), 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;
70 PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
71 }
72
73 DPRINT("Allocated devnode 0x%p\n", DeviceNode);
74
75 /* Return the node */
76 return DeviceNode;
77}
#define PAGED_CODE()
#define InterlockedIncrement
Definition: armddk.h:53
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
LONG IopNumberDeviceNodes
Definition: devnode.c:21
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
@ DeviceNodeUninitialized
Definition: iotypes.h:422

◆ 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

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}
enum _PNP_DEVNODE_STATE PNP_DEVNODE_STATE
#define DEVNODE_HISTORY_SIZE
Definition: iotypes.h:869

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

Variable Documentation

◆ IopDeviceTreeLock

◆ IopNumberDeviceNodes

LONG IopNumberDeviceNodes

Definition at line 21 of file devnode.c.

Referenced by PipAllocateDeviceNode().

◆ IopRootDeviceNode