Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

devnode.c File Reference

#include "iop.h"

Go to the source code of this file.

Classes

struct  _ENUM_CONTEXT

Typedefs

typedef _ENUM_CONTEXT ENUM_CONTEXT
typedef _ENUM_CONTEXTPENUM_CONTEXT

Functions

NTSTATUS IopForAllDeviceNodesCallback (IN PDEVICE_NODE DeviceNode, IN PVOID Context)
PDEVICE_NODE IopAllocateDeviceNode (IN PDEVICE_OBJECT PhysicalDeviceObject)
NTSTATUS IopForAllDeviceNodes (IN PENUM_CALLBACK Callback, IN PVOID Context)
NTSTATUS IopForAllChildDeviceNodes (IN PDEVICE_NODE Parent, IN PENUM_CALLBACK Callback, IN PVOID Context)
VOID IopDestroyDeviceNode (IN PDEVICE_NODE DeviceNode)
VOID IopInsertTreeDeviceNode (IN PDEVICE_NODE ParentNode, IN PDEVICE_NODE DeviceNode)
VOID IopRemoveTreeDeviceNode (IN PDEVICE_NODE DeviceNode)


Typedef Documentation

typedef struct _ENUM_CONTEXT ENUM_CONTEXT
 

typedef struct _ENUM_CONTEXT * PENUM_CONTEXT
 

Referenced by IopForAllDeviceNodesCallback().


Function Documentation

PDEVICE_NODE IopAllocateDeviceNode IN PDEVICE_OBJECT  PhysicalDeviceObject  ) 
 

Definition at line 56 of file devnode.c.

References _DEVICE_NODE::BusNumber, _DEVICE_NODE::ChildBusNumber, _DEVICE_NODE::ChildBusTypeIndex, _DEVICE_NODE::ChildInterfaceType, DEVICE_NODE, _DEVICE_NODE::DeviceArbiterList, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DEVICE_NODE::DeviceTranslatorList, DO_DEVICE_INITIALIZING, _DEVICE_NODE::DockInfo, _DEVICE_NODE::EnumerationMutex, ExAllocatePoolWithTag, _DEVICE_NODE::Flags, _DEVICE_NODE::InterfaceType, IOP_DNOD_TAG, IopNumberDeviceNodes, KeInitializeEvent, NonPagedPool, NULL, PAGED_CODE, _DEVICE_NODE::PendedSetInterfaceState, _DEVICE_NODE::PhysicalDeviceObject, _DEVICE_NODE::TargetDeviceNotify, TRUE, and USHORT.

Referenced by IopEnumerateDevice(), IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), and IoReportDetectedDevice().

00062 : 00063 00064 This function allocates a device node from nonpaged pool and initializes 00065 the fields which do not require to hold lock to do so. Since adding 00066 the device node to pnp mgr's device node tree requires acquiring lock, 00067 this routine does not add the device node to device node tree. 00068 00069 Arguments: 00070 00071 PhysicalDeviceObject - Supplies a pointer to its corresponding physical device 00072 object. 00073 00074 Return Value: 00075 00076 a pointer to the newly created device node. Null is returned if failed. 00077 00078 --*/ 00079 { 00080 PDEVICE_NODE deviceNode; 00081 00082 PAGED_CODE(); 00083 00084 deviceNode = ExAllocatePoolWithTag( 00085 NonPagedPool, 00086 sizeof(DEVICE_NODE), 00087 IOP_DNOD_TAG 00088 ); 00089 00090 if (deviceNode == NULL ){ 00091 return NULL; 00092 } 00093 00094 InterlockedIncrement (&IopNumberDeviceNodes); 00095 00096 RtlZeroMemory(deviceNode, sizeof(DEVICE_NODE)); 00097 deviceNode->InterfaceType = InterfaceTypeUndefined; 00098 deviceNode->BusNumber = (ULONG)-1; 00099 deviceNode->ChildInterfaceType = InterfaceTypeUndefined; 00100 deviceNode->ChildBusNumber = (ULONG)-1; 00101 deviceNode->ChildBusTypeIndex = (USHORT)-1; 00102 00103 KeInitializeEvent( &deviceNode->EnumerationMutex, 00104 SynchronizationEvent, 00105 TRUE ); 00106 00107 InitializeListHead(&deviceNode->DeviceArbiterList); 00108 InitializeListHead(&deviceNode->DeviceTranslatorList); 00109 00110 if (PhysicalDeviceObject){ 00111 00112 deviceNode->PhysicalDeviceObject = PhysicalDeviceObject; 00113 PhysicalDeviceObject->DeviceObjectExtension->DeviceNode = (PVOID)deviceNode; 00114 PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00115 } 00116 00117 InitializeListHead(&deviceNode->TargetDeviceNotify); 00118 00119 InitializeListHead(&deviceNode->DockInfo.ListEntry); 00120 00121 InitializeListHead(&deviceNode->PendedSetInterfaceState); 00122 00123 return deviceNode; 00124 }

VOID IopDestroyDeviceNode IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 297 of file devnode.c.

References ASSERT, DNF_LEGACY_RESOURCE_DEVICENODE, DNUF_NOT_DISABLEABLE, DO_BUS_ENUMERATED_DEVICE, ExFreePool(), IopNumberDeviceNodes, IopUncacheInterfaceInformation(), KeBugCheckEx(), _PENDING_SET_INTERFACE_STATE::LinkName, NULL, ObDereferenceObject, _DEVICE_NODE::OverUsed1, _DEVICE_NODE::OverUsed2, PAGED_CODE, PINTERFACE, PNP_ERR_ACTIVE_PDO_FREED, PPENDING_SET_INTERFACE_STATE, and PPI_RESOURCE_TRANSLATOR_ENTRY.

00303 : 00304 00305 This function is invoked by IopDeleteDevice to clean up the device object's 00306 device node structure. 00307 00308 Arguments: 00309 00310 DeviceNode - Supplies a pointer to the device node whose subtree is to be walked. 00311 00312 Context - Supplies a context which contains the caller specified call back 00313 function and parameter. 00314 00315 Return Value: 00316 00317 NTSTATUS value. 00318 00319 --*/ 00320 00321 { 00322 PLIST_ENTRY listHead, nextEntry, entry; 00323 PPI_RESOURCE_TRANSLATOR_ENTRY handlerEntry; 00324 PINTERFACE interface; 00325 00326 PAGED_CODE(); 00327 00328 if (DeviceNode) { 00329 00330 if ((DeviceNode->PhysicalDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE) && 00331 DeviceNode->Parent != NULL) { 00332 00333 KeBugCheckEx( PNP_DETECTED_FATAL_ERROR, 00334 PNP_ERR_ACTIVE_PDO_FREED, 00335 (ULONG_PTR)DeviceNode->PhysicalDeviceObject, 00336 0, 00337 0); 00338 } 00339 00340 #if DBG 00341 00342 // 00343 // If Only Parent is NOT NULL, most likely the driver forgot to 00344 // release resources before deleting its FDO. (The driver previously 00345 // call legacy assign resource interface.) 00346 // 00347 00348 ASSERT(DeviceNode->Child == NULL && 00349 DeviceNode->Sibling == NULL && 00350 DeviceNode->LastChild == NULL 00351 ); 00352 00353 ASSERT(DeviceNode->DockInfo.SerialNumber == NULL && 00354 IsListEmpty(&DeviceNode->DockInfo.ListEntry)); 00355 00356 if (DeviceNode->PhysicalDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE) { 00357 ASSERT (DeviceNode->Parent == 0); 00358 } 00359 00360 if (DeviceNode->PreviousResourceList) { 00361 ExFreePool(DeviceNode->PreviousResourceList); 00362 } 00363 if (DeviceNode->PreviousResourceRequirements) { 00364 ExFreePool(DeviceNode->PreviousResourceRequirements); 00365 } 00366 00367 // 00368 // device should not appear to be not-disableable if/when we get here 00369 // if either of these two lines ASSERT, email: jamiehun 00370 // 00371 00372 ASSERT((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) == 0); 00373 ASSERT(DeviceNode->DisableableDepends == 0); 00374 00375 #endif 00376 // 00377 // If this devicenode is our internal one used for legacy 00378 // resource allocation, then clean up. Find this devicenode 00379 // in the list of legacy resource devnodes hanging off the 00380 // legacy devicenode in the tree and remove it. 00381 // 00382 // BUGBUG: SantoshJ 10/15/99: We should be releasing 00383 // resources assigned to this device. 00384 // 00385 00386 if (DeviceNode->Flags & DNF_LEGACY_RESOURCE_DEVICENODE) { 00387 00388 PDEVICE_NODE resourceDeviceNode; 00389 00390 for ( resourceDeviceNode = (PDEVICE_NODE)DeviceNode->OverUsed1.LegacyDeviceNode; 00391 resourceDeviceNode; 00392 resourceDeviceNode = resourceDeviceNode->OverUsed2.NextResourceDeviceNode) { 00393 00394 if (resourceDeviceNode->OverUsed2.NextResourceDeviceNode == DeviceNode) { 00395 00396 resourceDeviceNode->OverUsed2.NextResourceDeviceNode = DeviceNode->OverUsed2.NextResourceDeviceNode; 00397 break; 00398 00399 } 00400 } 00401 } 00402 00403 if (DeviceNode->DuplicatePDO) { 00404 ObDereferenceObject(DeviceNode->DuplicatePDO); 00405 } 00406 if (DeviceNode->ServiceName.Length != 0) { 00407 ExFreePool(DeviceNode->ServiceName.Buffer); 00408 } 00409 if (DeviceNode->InstancePath.Length != 0) { 00410 ExFreePool(DeviceNode->InstancePath.Buffer); 00411 } 00412 if (DeviceNode->ResourceRequirements) { 00413 ExFreePool(DeviceNode->ResourceRequirements); 00414 } 00415 00416 // 00417 // Dereference all the arbiters and translators on this PDO. 00418 // 00419 IopUncacheInterfaceInformation(DeviceNode->PhysicalDeviceObject) ; 00420 00421 // 00422 // Release any pended IoSetDeviceInterface structures 00423 // 00424 00425 while (!IsListEmpty(&DeviceNode->PendedSetInterfaceState)) { 00426 00427 PPENDING_SET_INTERFACE_STATE entry; 00428 00429 entry = (PPENDING_SET_INTERFACE_STATE)RemoveHeadList(&DeviceNode->PendedSetInterfaceState); 00430 00431 ExFreePool(entry->LinkName.Buffer); 00432 00433 ExFreePool(entry); 00434 } 00435 00436 DeviceNode->PhysicalDeviceObject->DeviceObjectExtension->DeviceNode = NULL; 00437 ExFreePool(DeviceNode); 00438 IopNumberDeviceNodes--; 00439 } 00440 } //

NTSTATUS IopForAllChildDeviceNodes IN PDEVICE_NODE  Parent,
IN PENUM_CALLBACK  Callback,
IN PVOID  Context
 

Definition at line 179 of file devnode.c.

References NT_SUCCESS, NTSTATUS(), PAGED_CODE, and _DEVICE_NODE::Sibling.

Referenced by IopForAllDeviceNodes(), IopForAllDeviceNodesCallback(), IopProcessAddDevicesWorker(), IopProcessAssignResourcesWorker(), and IopProcessStartDevicesWorker().

00187 : 00188 00189 This function walks the Parent's device node subtree and perform caller specified 00190 'Callback' function for each device node under Parent. 00191 00192 Note, befor calling this rotuine, callers must acquire the enumeration mutex 00193 of the 'Parent' device node to make sure its children won't go away unless the 00194 call tells them to. 00195 00196 Arguments: 00197 00198 Parent - Supplies a pointer to the device node whose subtree is to be walked. 00199 00200 Callback - Supplies the call back routine for each device node. 00201 00202 Context - Supplies a parameter/context for the callback function. 00203 00204 Return Value: 00205 00206 NTSTATUS value. 00207 00208 --*/ 00209 00210 { 00211 PDEVICE_NODE nextChild = Parent->Child; 00212 PDEVICE_NODE child; 00213 NTSTATUS status = STATUS_SUCCESS; 00214 00215 PAGED_CODE(); 00216 00217 // 00218 // Process siblings until we find the end of the sibling list or 00219 // the Callback() returns FALSE. Set result = TRUE at the top of 00220 // the loop so that if there are no siblings we will return TRUE, 00221 // e.g. Keep Enumerating. 00222 // 00223 // Note, we need to find next child before calling Callback function 00224 // in case the current child is deleted by the Callback function. 00225 // 00226 00227 while (nextChild && NT_SUCCESS(status)) { 00228 child = nextChild; 00229 nextChild = child->Sibling; 00230 status = Callback(child, Context); 00231 } 00232 00233 return status; 00234 }

NTSTATUS IopForAllDeviceNodes IN PENUM_CALLBACK  Callback,
IN PVOID  Context
 

Definition at line 127 of file devnode.c.

References _ENUM_CONTEXT::CallersCallback, _ENUM_CONTEXT::CallersContext, IopAcquireEnumerationLock, IopForAllChildDeviceNodes(), IopForAllDeviceNodesCallback(), IopReleaseEnumerationLock, IopRootDeviceNode, NTSTATUS(), PAGED_CODE, and PENUM_CALLBACK.

Referenced by IopProcessNewProfileWorker().

00134 : 00135 00136 This function walks the device node tree and perform caller specified 00137 'Callback' function for each device node. 00138 00139 Note, this routine (or its worker routine) traverses the tree in a top 00140 down manner. 00141 00142 Arguments: 00143 00144 Callback - Supplies the call back routine for each device node. 00145 00146 Context - Supplies a parameter/context for the callback function. 00147 00148 Return Value: 00149 00150 Status returned from Callback, if not successfull then the tree walking stops. 00151 00152 --*/ 00153 { 00154 ENUM_CONTEXT enumContext; 00155 NTSTATUS status; 00156 00157 PAGED_CODE(); 00158 00159 enumContext.CallersCallback = Callback; 00160 enumContext.CallersContext = Context; 00161 00162 // 00163 // Start with a pointer to the root device node, recursively examine all the 00164 // children until we the callback function says stop or we've looked at all 00165 // of them. 00166 // 00167 00168 IopAcquireEnumerationLock(IopRootDeviceNode); 00169 00170 status = IopForAllChildDeviceNodes(IopRootDeviceNode, 00171 IopForAllDeviceNodesCallback, 00172 (PVOID)&enumContext ); 00173 00174 IopReleaseEnumerationLock(IopRootDeviceNode); 00175 return status; 00176 }

NTSTATUS IopForAllDeviceNodesCallback IN PDEVICE_NODE  DeviceNode,
IN PVOID  Context
 

Definition at line 237 of file devnode.c.

References _ENUM_CONTEXT::CallersCallback, _ENUM_CONTEXT::CallersContext, IopAcquireEnumerationLock, IopForAllChildDeviceNodes(), IopForAllDeviceNodesCallback(), IopReleaseEnumerationLock, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and PENUM_CONTEXT.

Referenced by IopForAllDeviceNodes(), and IopForAllDeviceNodesCallback().

00244 : 00245 00246 This function is the worker routine for IopForAllChildDeviceNodes routine. 00247 00248 Arguments: 00249 00250 DeviceNode - Supplies a pointer to the device node whose subtree is to be walked. 00251 00252 Context - Supplies a context which contains the caller specified call back 00253 function and parameter. 00254 00255 Return Value: 00256 00257 NTSTATUS value. 00258 00259 --*/ 00260 00261 { 00262 PENUM_CONTEXT enumContext; 00263 NTSTATUS status; 00264 00265 PAGED_CODE(); 00266 00267 enumContext = (PENUM_CONTEXT)Context; 00268 00269 // 00270 // First call the caller's callback for this devnode 00271 // 00272 00273 status = 00274 enumContext->CallersCallback(DeviceNode, enumContext->CallersContext); 00275 00276 if (NT_SUCCESS(status)) { 00277 00278 // 00279 // Now enumerate the children, if any. 00280 // 00281 00282 IopAcquireEnumerationLock(DeviceNode); 00283 00284 if( DeviceNode->Child) { 00285 00286 status = IopForAllChildDeviceNodes( 00287 DeviceNode, 00288 IopForAllDeviceNodesCallback, 00289 Context); 00290 } 00291 IopReleaseEnumerationLock(DeviceNode); 00292 } 00293 00294 return status; 00295 } VOID

VOID IopInsertTreeDeviceNode IN PDEVICE_NODE  ParentNode,
IN PDEVICE_NODE  DeviceNode
 

Definition at line 447 of file devnode.c.

References ASSERT, IoDeviceNodeTreeSequence, IopMaxDeviceNodeLevel, IopRootDeviceNode, NULL, and _DEVICE_NODE::Parent.

Referenced by IopEnumerateDevice(), IopInitializeDeviceInstanceKey(), and IoReportDetectedDevice().

00452 { 00453 PDEVICE_NODE deviceNode; 00454 PLIST_ENTRY *p; 00455 LONG i; 00456 00457 // 00458 // Put this devnode at the end of the parent's list of children. 00459 // 00460 00461 DeviceNode->Parent = ParentNode; 00462 if (ParentNode->LastChild) { 00463 ASSERT(ParentNode->LastChild->Sibling == NULL); 00464 ParentNode->LastChild->Sibling = DeviceNode; 00465 ParentNode->LastChild = DeviceNode; 00466 } else { 00467 ASSERT(ParentNode->Child == NULL); 00468 ParentNode->Child = ParentNode->LastChild = DeviceNode; 00469 } 00470 00471 // 00472 // Determine the depth of the devnode. 00473 // 00474 00475 for (deviceNode = DeviceNode; 00476 deviceNode != IopRootDeviceNode; 00477 deviceNode = deviceNode->Parent) { 00478 DeviceNode->Level++; 00479 } 00480 00481 if (DeviceNode->Level > IopMaxDeviceNodeLevel) { 00482 IopMaxDeviceNodeLevel = DeviceNode->Level; 00483 } 00484 00485 // 00486 // Tree has changed 00487 // 00488 00489 IoDeviceNodeTreeSequence += 1; 00490 }

VOID IopRemoveTreeDeviceNode IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 494 of file devnode.c.

References _DEVICE_NODE::Child, IopOrphanNotification(), _DEVICE_NODE::LastChild, NULL, _DEVICE_NODE::Parent, and _DEVICE_NODE::Sibling.

Referenced by IopDeleteLockedDeviceNode(), and IopUnlockDeviceRemovalRelations().

00499 : 00500 00501 This function removes the device node from the device node tree 00502 00503 N.B. The caller must own the device tree lock of the parent's enumeration lock 00504 00505 Arguments: 00506 00507 DeviceNode - Device node to remove 00508 00509 Return Value: 00510 00511 00512 --*/ 00513 { 00514 PDEVICE_NODE *Node; 00515 00516 // 00517 // Ulink the pointer to this device node. (If this is the 00518 // first entry, unlink it from the parents child pointer, else 00519 // remove it from the sibling list) 00520 // 00521 00522 Node = &DeviceNode->Parent->Child; 00523 while (*Node != DeviceNode) { 00524 Node = &(*Node)->Sibling; 00525 } 00526 *Node = DeviceNode->Sibling; 00527 00528 if (DeviceNode->Parent->Child == NULL) { 00529 DeviceNode->Parent->LastChild = NULL; 00530 } else { 00531 while (*Node) { 00532 Node = &(*Node)->Sibling; 00533 } 00534 DeviceNode->Parent->LastChild = CONTAINING_RECORD(Node, DEVICE_NODE, Sibling); 00535 } 00536 00537 00538 // 00539 // Orphan any outstanding device change notifications on these nodes. 00540 // 00541 IopOrphanNotification(DeviceNode); 00542 00543 // 00544 // No longer linked 00545 // 00546 00547 DeviceNode->Parent = NULL; 00548 DeviceNode->Child = NULL; 00549 DeviceNode->Sibling = NULL; 00550 DeviceNode->LastChild = NULL; 00551 }


Generated on Sat May 15 19:43:27 2004 for test by doxygen 1.3.7