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

pnprlist.h File Reference

Go to the source code of this file.

Classes

struct  _RELATION_LIST_ENTRY
struct  _RELATION_LIST
struct  _PENDING_RELATIONS_LIST_ENTRY

Typedefs

typedef _RELATION_LIST_ENTRY RELATION_LIST_ENTRY
typedef _RELATION_LIST_ENTRYPRELATION_LIST_ENTRY
typedef _RELATION_LIST RELATION_LIST
typedef _RELATION_LISTPRELATION_LIST
typedef _PENDING_RELATIONS_LIST_ENTRY PENDING_RELATIONS_LIST_ENTRY
typedef _PENDING_RELATIONS_LIST_ENTRYPPENDING_RELATIONS_LIST_ENTRY

Functions

NTSTATUS IopAddRelationToList (IN PRELATION_LIST List, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DirectDescendant, IN BOOLEAN Tagged)
NTSTATUS IopCompressRelationList (IN OUT PRELATION_LIST *List)
BOOLEAN IopEnumerateRelations (IN PRELATION_LIST List, IN OUT PULONG Marker, OUT PDEVICE_OBJECT *PhysicalDevice, OUT BOOLEAN *DirectDescendant, OPTIONAL OUT BOOLEAN *Tagged, OPTIONAL BOOLEAN Reverse)
VOID IopFreeRelationList (IN PRELATION_LIST List)
ULONG IopGetRelationsCount (IN PRELATION_LIST List)
ULONG IopGetRelationsTaggedCount (IN PRELATION_LIST List)
BOOLEAN IopIsRelationInList (IN PRELATION_LIST List, IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopMergeRelationLists (IN OUT PRELATION_LIST TargetList, IN PRELATION_LIST SourceList, IN BOOLEAN Tagged)
NTSTATUS IopRemoveIndirectRelationsFromList (IN PRELATION_LIST List)
NTSTATUS IopRemoveRelationFromList (IN PRELATION_LIST List, IN PDEVICE_OBJECT DeviceObject)
VOID IopSetAllRelationsTags (IN PRELATION_LIST List, IN BOOLEAN Tagged)
NTSTATUS IopSetRelationsTag (IN PRELATION_LIST List, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Tagged)

Variables

PRELATION_LIST IopAllocateRelationList (VOID)


Typedef Documentation

typedef struct _PENDING_RELATIONS_LIST_ENTRY PENDING_RELATIONS_LIST_ENTRY
 

Referenced by IopChainDereferenceComplete().

typedef struct _PENDING_RELATIONS_LIST_ENTRY * PPENDING_RELATIONS_LIST_ENTRY
 

typedef struct _RELATION_LIST * PRELATION_LIST
 

typedef struct _RELATION_LIST_ENTRY * PRELATION_LIST_ENTRY
 

Referenced by IopAddRelationToList(), and IopCompressRelationList().

typedef struct _RELATION_LIST RELATION_LIST
 

Referenced by IopAllocateRelationList().

typedef struct _RELATION_LIST_ENTRY RELATION_LIST_ENTRY
 

Referenced by IopAddRelationToList().


Function Documentation

NTSTATUS IopAddRelationToList IN PRELATION_LIST  List,
IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  DirectDescendant,
IN BOOLEAN  Tagged
 

Definition at line 55 of file pnprlist.c.

References ASSERT, _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, ExAllocatePool, IopNumberDeviceNodes, _DEVICE_NODE::Level, List, _RELATION_LIST_ENTRY::MaxCount, NULL, ObReferenceObject, PAGED_CODE, PagedPool, PRELATION_LIST_ENTRY, RELATION_FLAG_DESCENDANT, RELATION_FLAG_TAGGED, RELATION_FLAGS, and RELATION_LIST_ENTRY.

Referenced by IopInvalidateRelationsInList(), IopMergeRelationLists(), and IopProcessRelation().

00064 : 00065 00066 Adds an element to a relation list. 00067 00068 If this is the first DeviceObject of a particular level then a new 00069 RELATION_LIST_ENTRY will be allocated. 00070 00071 This routine should only be called on an uncompressed relation list, 00072 otherwise it is likely that STATUS_INVALID_PARAMETER will be returned. 00073 00074 Arguments: 00075 00076 List Relation list to which the DeviceObject is added. 00077 00078 DeviceObject DeviceObject to be added to List. It must be a 00079 PhysicalDeviceObject (PDO). 00080 00081 DirectDescendant Indicates whether DeviceObject is a direct descendant of 00082 the original target device of this remove. 00083 00084 Tagged Indicates whether DeviceObject should be tagged in List. 00085 00086 Return Value: 00087 00088 STATUS_SUCCESS 00089 00090 The DeviceObject was added successfully. 00091 00092 STATUS_OBJECT_NAME_COLLISION 00093 00094 The DeviceObject already exists in the relation list. 00095 00096 STATUS_INSUFFICIENT_RESOURCES 00097 00098 There isn't enough PagedPool available to allocate a new 00099 RELATION_LIST_ENTRY. 00100 00101 STATUS_INVALID_PARAMETER 00102 00103 The level of the DEVICE_NODE associated with DeviceObject is less than 00104 FirstLevel or greater than the MaxLevel. 00105 00106 STATUS_NO_SUCH_DEVICE 00107 00108 DeviceObject is not a PhysicalDeviceObject (PDO), it doesn't have a 00109 DEVICE_NODE associated with it. 00110 00111 --*/ 00112 00113 { 00114 PDEVICE_NODE deviceNode; 00115 PRELATION_LIST_ENTRY entry; 00116 ULONG level; 00117 ULONG index; 00118 ULONG flags; 00119 00120 PAGED_CODE(); 00121 00122 flags = 0; 00123 00124 if (Tagged) { 00125 Tagged = 1; 00126 flags |= RELATION_FLAG_TAGGED; 00127 } 00128 00129 if (DirectDescendant) { 00130 flags |= RELATION_FLAG_DESCENDANT; 00131 } 00132 00133 if ((deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode) != NULL) { 00134 level = deviceNode->Level; 00135 00136 // 00137 // Since this routine is called with the DeviceNode Tree locked and 00138 // List is initially allocated with enough entries to hold the deepest 00139 // DEVICE_NODE this ASSERT should never fire. If it does then either 00140 // the tree is changing or we were given a compressed list. 00141 // 00142 ASSERT(List->FirstLevel <= level && level <= List->MaxLevel); 00143 00144 if (List->FirstLevel <= level && level <= List->MaxLevel) { 00145 00146 if ((entry = List->Entries[ level - List->FirstLevel ]) == NULL) { 00147 00148 // 00149 // This is the first DeviceObject of its level, allocate a new 00150 // RELATION_LIST_ENTRY. 00151 // 00152 entry = ExAllocatePool( PagedPool, 00153 sizeof(RELATION_LIST_ENTRY) + 00154 IopNumberDeviceNodes * sizeof(PDEVICE_OBJECT)); 00155 00156 if (entry == NULL) { 00157 return STATUS_INSUFFICIENT_RESOURCES; 00158 } 00159 00160 // 00161 // We always allocate enough Devices to hold the whole tree as 00162 // a simplification. Since each entry is a PDEVICE_OBJECT and 00163 // there is generally under 50 devices on a machine this means 00164 // under 1K for each entry. The excess space will be freed when 00165 // the list is compressed. 00166 // 00167 entry->Count = 0; 00168 entry->MaxCount = IopNumberDeviceNodes; 00169 00170 List->Entries[ level - List->FirstLevel ] = entry; 00171 } 00172 00173 // 00174 // There should always be room for a DeviceObject since the Entry is 00175 // initially dimensioned large enough to hold all the DEVICE_NODES 00176 // in the system. 00177 // 00178 ASSERT(entry->Count < entry->MaxCount); 00179 00180 if (entry->Count < entry->MaxCount) { 00181 // 00182 // Search the list to see if DeviceObject has already been 00183 // added. 00184 // 00185 for (index = 0; index < entry->Count; index++) { 00186 if (((ULONG_PTR)entry->Devices[ index ] & ~RELATION_FLAGS) == (ULONG_PTR)DeviceObject) { 00187 00188 // 00189 // DeviceObject already exists in the list. However 00190 // the Direct Descendant flag may differ. We will 00191 // override it if DirectDescendant is TRUE. This could 00192 // happen if we merged two relation lists. 00193 00194 if (DirectDescendant) { 00195 entry->Devices[ index ] = (PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ index ] | RELATION_FLAG_DESCENDANT); 00196 } 00197 00198 return STATUS_OBJECT_NAME_COLLISION; 00199 } 00200 } 00201 } else { 00202 // 00203 // There isn't room in the Entry for another DEVICE_OBJECT, the 00204 // list has probably already been compressed. 00205 // 00206 return STATUS_INVALID_PARAMETER; 00207 } 00208 00209 // 00210 // Take out a reference on DeviceObject, we will release it when we 00211 // free the list or remove the DeviceObject from the list. 00212 // 00213 ObReferenceObject( DeviceObject ); 00214 00215 entry->Devices[ index ] = (PDEVICE_OBJECT)((ULONG_PTR)DeviceObject | flags); 00216 entry->Count++; 00217 00218 List->Count++; 00219 List->TagCount += Tagged; 00220 00221 return STATUS_SUCCESS; 00222 } else { 00223 // 00224 // There isn't an Entry available for the level of this 00225 // DEVICE_OBJECT, the list has probably already been compressed. 00226 // 00227 00228 return STATUS_INVALID_PARAMETER; 00229 } 00230 } else { 00231 // 00232 // DeviceObject is not a PhysicalDeviceObject (PDO). 00233 // 00234 return STATUS_NO_SUCH_DEVICE; 00235 } 00236 }

NTSTATUS IopCompressRelationList IN OUT PRELATION_LIST List  ) 
 

Definition at line 286 of file pnprlist.c.

References ASSERT, _RELATION_LIST::Count, _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, _RELATION_LIST::Entries, ExAllocatePool, ExFreePool(), _RELATION_LIST::FirstLevel, List, _RELATION_LIST_ENTRY::MaxCount, _RELATION_LIST::MaxLevel, NULL, PAGED_CODE, PagedPool, PDEVICE_OBJECT, PRELATION_LIST_ENTRY, and _RELATION_LIST::TagCount.

Referenced by IopLockDeviceRemovalRelations().

00292 : 00293 00294 Compresses the relation list by reallocating the list and all the entries so 00295 that they a just large enough to hold their current contents. 00296 00297 Once a list has been compressed IopAddRelationToList and 00298 IopMergeRelationLists targetting this list are both likely to fail. 00299 00300 Arguments: 00301 00302 List Relation List to compress. 00303 00304 Return Value: 00305 00306 STATUS_SUCCESS 00307 00308 The list was compressed. Although this routine does allocate memory and 00309 the allocation can fail, the routine itself will never fail. Since the 00310 memory we are allocating is always smaller then the memory it is 00311 replacing we just keep the old memory if the allocation fails. 00312 00313 --*/ 00314 00315 { 00316 PRELATION_LIST oldList, newList; 00317 PRELATION_LIST_ENTRY oldEntry, newEntry; 00318 ULONG lowestLevel; 00319 ULONG highestLevel; 00320 ULONG index; 00321 00322 PAGED_CODE(); 00323 00324 oldList = *List; 00325 00326 // 00327 // Initialize lowestLevel and highestLevel with illegal values chosen so 00328 // that the first real entry will override them. 00329 // 00330 lowestLevel = oldList->MaxLevel; 00331 highestLevel = oldList->FirstLevel; 00332 00333 // 00334 // Loop through the list looking for allocated entries. 00335 // 00336 for (index = 0; index <= (oldList->MaxLevel - oldList->FirstLevel); index++) { 00337 00338 if ((oldEntry = oldList->Entries[ index ]) != NULL) { 00339 // 00340 // This entry is allocated, update lowestLevel and highestLevel if 00341 // necessary. 00342 // 00343 if (lowestLevel > index) { 00344 lowestLevel = index; 00345 } 00346 00347 if (highestLevel < index) { 00348 highestLevel = index; 00349 } 00350 00351 if (oldEntry->Count < oldEntry->MaxCount) { 00352 00353 // 00354 // This entry is only partially full. Allocate a new entry 00355 // which is just the right size to hold the current number of 00356 // PDEVICE_OBJECTs. 00357 // 00358 newEntry = ExAllocatePool( PagedPool, 00359 sizeof(RELATION_LIST_ENTRY) + 00360 (oldEntry->Count - 1) * sizeof(PDEVICE_OBJECT)); 00361 00362 if (newEntry != NULL) { 00363 00364 // 00365 // Initialize Count and MaxCount to the number of 00366 // PDEVICE_OBJECTs in the old entry. 00367 // 00368 newEntry->Count = oldEntry->Count; 00369 newEntry->MaxCount = oldEntry->Count; 00370 00371 // 00372 // Copy the PDEVICE_OBJECTs from the old entry to the new 00373 // one. 00374 // 00375 RtlCopyMemory( newEntry->Devices, 00376 oldEntry->Devices, 00377 oldEntry->Count * sizeof(PDEVICE_OBJECT)); 00378 00379 // 00380 // Free the old entry and store the new entry in the list. 00381 // 00382 ExFreePool( oldEntry ); 00383 00384 oldList->Entries[ index ] = newEntry; 00385 } 00386 } 00387 } 00388 } 00389 00390 // 00391 // Assert that the old list isn't empty. 00392 // 00393 ASSERT(lowestLevel <= highestLevel); 00394 00395 if (lowestLevel > highestLevel) { 00396 // 00397 // The list is empty - we shouldn't get asked to compress an empty list 00398 // but lets do it anyways. 00399 // 00400 lowestLevel = 0; 00401 highestLevel = 0; 00402 } 00403 00404 // 00405 // Check if the old list had unused entries at the beginning or the end of 00406 // the Entries array. 00407 // 00408 if (lowestLevel != oldList->FirstLevel || highestLevel != oldList->MaxLevel) { 00409 00410 // 00411 // Allocate a new List with just enough Entries to hold those between 00412 // FirstLevel and MaxLevel inclusive. 00413 // 00414 newList = ExAllocatePool( PagedPool, 00415 sizeof(RELATION_LIST) + 00416 (highestLevel - lowestLevel) * sizeof(PRELATION_LIST_ENTRY)); 00417 00418 if (newList != NULL) { 00419 // 00420 // Copy the old list to the new list and return it to the caller. 00421 // 00422 newList->Count = oldList->Count; 00423 newList->TagCount = oldList->TagCount; 00424 newList->FirstLevel = lowestLevel; 00425 newList->MaxLevel = highestLevel; 00426 00427 RtlCopyMemory( newList->Entries, 00428 &oldList->Entries[ lowestLevel ], 00429 (highestLevel - lowestLevel + 1) * sizeof(PRELATION_LIST_ENTRY)); 00430 00431 ExFreePool( oldList ); 00432 00433 *List = newList; 00434 } 00435 } 00436 00437 return STATUS_SUCCESS; 00438 }

BOOLEAN IopEnumerateRelations IN PRELATION_LIST  List,
IN OUT PULONG  Marker,
OUT PDEVICE_OBJECT PhysicalDevice,
OUT BOOLEAN *  DirectDescendant,
OPTIONAL OUT BOOLEAN *  Tagged,
OPTIONAL BOOLEAN  Reverse
 

Referenced by IopDeleteLockedDeviceNodes(), IopInvalidateRelationsInList(), IopLockDeviceRemovalRelations(), and IopUnlockDeviceRemovalRelations().

VOID IopFreeRelationList IN PRELATION_LIST  List  ) 
 

Definition at line 709 of file pnprlist.c.

References _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, ExFreePool(), List, NULL, ObDereferenceObject, PAGED_CODE, and RELATION_FLAGS.

Referenced by IopDelayedRemoveWorker(), IopInvalidateRelationsInList(), IopLockDeviceRemovalRelations(), IopProcessCompletedEject(), and IopProcessRelation().

00715 : 00716 00717 Free a relation list allocated by IopAllocateRelationList. 00718 00719 Arguments: 00720 00721 List The list to be freed. 00722 00723 Return Value: 00724 00725 NONE. 00726 00727 --*/ 00728 00729 { 00730 PRELATION_LIST_ENTRY entry; 00731 ULONG levelIndex; 00732 ULONG entryIndex; 00733 00734 PAGED_CODE(); 00735 00736 // 00737 // Search the list looking for allocated Entries. 00738 // 00739 for (levelIndex = 0; levelIndex <= (List->MaxLevel - List->FirstLevel); levelIndex++) { 00740 00741 if ((entry = List->Entries[ levelIndex ]) != NULL) { 00742 // 00743 // This entry has been allocated. 00744 // 00745 for (entryIndex = 0; entryIndex < entry->Count; entryIndex++) { 00746 // 00747 // Dereference all the Devices in the entry. 00748 // 00749 ObDereferenceObject((PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ entryIndex ] & ~RELATION_FLAGS)); 00750 } 00751 // 00752 // Free the Entry. 00753 // 00754 ExFreePool( entry ); 00755 } 00756 } 00757 00758 // 00759 // Free the list. It isn't necessary to dereference the DeviceObject that 00760 // was the original target that caused the list to be created. This 00761 // DeviceObject is also in one of the Entries and its reference is taken 00762 // and released there. 00763 // 00764 ExFreePool( List ); 00765 }

ULONG IopGetRelationsCount IN PRELATION_LIST  List  ) 
 

Referenced by IopChainDereferenceComplete().

ULONG IopGetRelationsTaggedCount IN PRELATION_LIST  List  ) 
 

Referenced by IopChainDereferenceComplete().

BOOLEAN IopIsRelationInList IN PRELATION_LIST  List,
IN PDEVICE_OBJECT  DeviceObject
 

Referenced by IopProcessRelation().

NTSTATUS IopMergeRelationLists IN OUT PRELATION_LIST  TargetList,
IN PRELATION_LIST  SourceList,
IN BOOLEAN  Tagged
 

Definition at line 900 of file pnprlist.c.

References ASSERT, _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, FALSE, IopAddRelationToList(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and RELATION_FLAGS.

Referenced by IopProcessRelation().

00908 : 00909 00910 Merges two relation lists by copying all the relations from the source list 00911 to the target list. Source list remains unchanged. 00912 00913 Arguments: 00914 00915 TargetList List to which the relations from Sourcelist are added. 00916 00917 SourceList List of relations to be added to TargetList. 00918 00919 Tagged TRUE if relations from SourceList should be tagged when added to 00920 TargetList. If FALSE then relations added from SourceList are 00921 untagged. 00922 00923 Return Value: 00924 00925 STATUS_SUCCESS 00926 00927 All the relations in SourceList were added to TargetList successfully. 00928 00929 STATUS_OBJECT_NAME_COLLISION 00930 00931 One of the relations in SourceList already exists in TargetList. This 00932 is a fatal error and TargetList may already have some of the relations 00933 from SourceList added. This could be dealt with more gracefully if 00934 necessary but the current callers of IopMergeRelationLists avoid this 00935 situation. 00936 00937 STATUS_INSUFFICIENT_RESOURCES 00938 00939 There isn't enough PagedPool available to allocate a new 00940 RELATION_LIST_ENTRY. 00941 00942 STATUS_INVALID_PARAMETER 00943 00944 The level of one of the relations in SourceList is less than FirstLevel 00945 or greater than the MaxLevel. This is a fatal error and TargetList may 00946 already have some of the relations from SourceList added. The only way 00947 this could happen is if the tree lock isn't held or if TargetList has 00948 been compressed by IopCompressRelationList. Both situations would be 00949 bugs in the caller. 00950 00951 STATUS_NO_SUCH_DEVICE 00952 00953 One of the relations in SourceList is not a PhysicalDeviceObject (PDO), 00954 it doesn't have a DEVICE_NODE associated with it. This is a fatal error 00955 and TargetList may already have some of the relations from SourceList 00956 added. This should never happen since it was a PDO when it was added to 00957 SourceList. 00958 00959 00960 --*/ 00961 00962 { 00963 PRELATION_LIST_ENTRY entry; 00964 ULONG levelIndex; 00965 ULONG entryIndex; 00966 NTSTATUS status = STATUS_SUCCESS; 00967 00968 PAGED_CODE(); 00969 00970 // 00971 // For each level entry in SourceList 00972 // 00973 for (levelIndex = 0; 00974 levelIndex <= (SourceList->MaxLevel - SourceList->FirstLevel); 00975 levelIndex++) { 00976 00977 if ((entry = SourceList->Entries[ levelIndex ]) != NULL) { 00978 // 00979 // The Entry has Devices 00980 // 00981 for (entryIndex = 0; entryIndex < entry->Count; entryIndex++) { 00982 // 00983 // For each Device in the Entry, add it to the target List. 00984 // 00985 status = IopAddRelationToList( TargetList, 00986 (PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ entryIndex ] & ~RELATION_FLAGS), 00987 FALSE, 00988 Tagged); 00989 00990 // 00991 // BUGBUG - Need to handle STATUS_INSUFFICIENT_RESOURCES more 00992 // gracefully. Currently the only way this can happen is 00993 // during Eject and that code isn't enabled yet. 00994 // 00995 ASSERT(NT_SUCCESS(status)); 00996 00997 if (!NT_SUCCESS(status)) { 00998 // 00999 // BUGBUG - We should undo the damage we've done to 01000 // TargetList by removing those relations we've added from 01001 // SourceList. 01002 // 01003 break; 01004 } 01005 } 01006 } 01007 } 01008 01009 return status; 01010 }

NTSTATUS IopRemoveIndirectRelationsFromList IN PRELATION_LIST  List  ) 
 

Definition at line 1013 of file pnprlist.c.

References _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, ExFreePool(), List, NULL, ObDereferenceObject, PAGED_CODE, RELATION_FLAG_DESCENDANT, RELATION_FLAG_TAGGED, and RELATION_FLAGS.

01019 : 01020 01021 Removes all the relations without the DirectDescendant flag from a relation 01022 list. 01023 01024 Arguments: 01025 01026 List List from which to remove the relations. 01027 01028 01029 Return Value: 01030 01031 STATUS_SUCCESS 01032 01033 The relations were removed successfully. 01034 01035 --*/ 01036 01037 { 01038 PDEVICE_OBJECT deviceObject; 01039 PRELATION_LIST_ENTRY entry; 01040 ULONG level; 01041 LONG index; 01042 01043 PAGED_CODE(); 01044 01045 // 01046 // For each Entry in the list. 01047 // 01048 for (level = List->FirstLevel; level <= List->MaxLevel; level++) { 01049 01050 // 01051 // If the entry is allocated. 01052 // 01053 if ((entry = List->Entries[ level - List->FirstLevel ]) != NULL) { 01054 01055 // 01056 // For each Device in the list. 01057 // 01058 for (index = entry->Count - 1; index >= 0; index--) { 01059 if (!((ULONG_PTR)entry->Devices[ index ] & RELATION_FLAG_DESCENDANT)) { 01060 01061 deviceObject = (PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ index ] & ~RELATION_FLAGS); 01062 01063 ObDereferenceObject( deviceObject ); 01064 01065 if ((ULONG_PTR)entry->Devices[ index ] & RELATION_FLAG_TAGGED) { 01066 List->TagCount--; 01067 } 01068 01069 if (index < ((LONG)entry->Count - 1)) { 01070 01071 RtlMoveMemory( &entry->Devices[ index ], 01072 &entry->Devices[ index + 1 ], 01073 (entry->Count - index - 1) * sizeof(PDEVICE_OBJECT)); 01074 } 01075 01076 if (--entry->Count == 0) { 01077 List->Entries[ level - List->FirstLevel ] = NULL; 01078 ExFreePool(entry); 01079 } 01080 01081 List->Count--; 01082 } 01083 } 01084 } 01085 } 01086 return STATUS_SUCCESS; 01087 }

NTSTATUS IopRemoveRelationFromList IN PRELATION_LIST  List,
IN PDEVICE_OBJECT  DeviceObject
 

Referenced by IopDeleteLockedDeviceNode(), IopProcessRelation(), and IopUnlockDeviceRemovalRelations().

VOID IopSetAllRelationsTags IN PRELATION_LIST  List,
IN BOOLEAN  Tagged
 

Referenced by IopDelayedRemoveWorker(), and IopInvalidateRelationsInList().

NTSTATUS IopSetRelationsTag IN PRELATION_LIST  List,
IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  Tagged
 

Definition at line 1232 of file pnprlist.c.

References _RELATION_LIST_ENTRY::Count, _RELATION_LIST_ENTRY::Devices, _DEVICE_NODE::Level, List, NULL, PAGED_CODE, RELATION_FLAG_TAGGED, and RELATION_FLAGS.

Referenced by IopChainDereferenceComplete(), and IopInvalidateRelationsInList().

01240 : 01241 01242 Sets or clears a tag on a specified relation in a relations list. This 01243 routine is also used by some callers to determine if a relation exists in 01244 a list and if so to set the tag. 01245 01246 Arguments: 01247 01248 List List containing relation to be tagged or untagged. 01249 01250 DeviceObject Relation to be tagged or untagged. 01251 01252 Tagged TRUE if relation is to be tagged, FALSE if it is to be 01253 untagged. 01254 01255 Return Value: 01256 01257 STATUS_SUCCESS 01258 01259 The relation was tagged successfully. 01260 01261 STATUS_NO_SUCH_DEVICE 01262 01263 The relation doesn't exist in the list. 01264 01265 --*/ 01266 01267 { 01268 PDEVICE_NODE deviceNode; 01269 PRELATION_LIST_ENTRY entry; 01270 ULONG level; 01271 LONG index; 01272 01273 PAGED_CODE(); 01274 01275 if ((deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode) != NULL) { 01276 // 01277 // DeviceObject is a PhysicalDeviceObject (PDO), get its level. 01278 // 01279 level = deviceNode->Level; 01280 01281 if (List->FirstLevel <= level && level <= List->MaxLevel) { 01282 // 01283 // The level is within the range of levels in this List. 01284 // 01285 if ((entry = List->Entries[ level - List->FirstLevel ]) != NULL) { 01286 // 01287 // The Entry for this level is allocated. Search each device 01288 // in the Entry looking for a match. 01289 // 01290 for (index = entry->Count - 1; index >= 0; index--) { 01291 01292 if (((ULONG_PTR)entry->Devices[ index ] & ~RELATION_FLAGS) == (ULONG_PTR)DeviceObject) { 01293 01294 // 01295 // We found a match 01296 // 01297 if ((ULONG_PTR)entry->Devices[ index ] & RELATION_FLAG_TAGGED) { 01298 // 01299 // The relation is already tagged so to simplify the 01300 // logic below decrement the TagCount. We'll 01301 // increment it later if the caller still wants it 01302 // to be tagged. 01303 // 01304 List->TagCount--; 01305 } 01306 01307 if (Tagged) { 01308 // 01309 // Set the tag and increment the number of tagged 01310 // relations. 01311 // 01312 entry->Devices[ index ] = (PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ index ] | RELATION_FLAG_TAGGED); 01313 List->TagCount++; 01314 } else { 01315 // 01316 // Clear the tag. 01317 // 01318 entry->Devices[ index ] = (PDEVICE_OBJECT)((ULONG_PTR)entry->Devices[ index ] & ~RELATION_FLAG_TAGGED); 01319 } 01320 01321 return STATUS_SUCCESS; 01322 } 01323 } 01324 } 01325 } 01326 } 01327 01328 // 01329 // It wasn't a PDO 01330 // or the level wasn't in the range of levels in this list 01331 // or there are no DeviceObjects at the same level in this list 01332 // or the DeviceObject isn't in the Entry for its level in this list 01333 // 01334 return STATUS_NO_SUCH_DEVICE; 01335 }


Variable Documentation

PRELATION_LIST IopAllocateRelationList(VOID)
 


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