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

hashirp.h File Reference

Go to the source code of this file.

Defines

#define IRP_TRACKING_HASH_SIZE   256
#define IRP_TRACKING_HASH_PRIME   131

Typedefs

typedef enum _IOV_REFERENCE_TYPE IOV_REFERENCE_TYPE

Enumerations

enum  _IOV_REFERENCE_TYPE { IOVREFTYPE_PACKET = 0, IOVREFTYPE_POINTER }

Functions

VOID FASTCALL IovpTrackingDataInit (VOID)
PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataFindAndLock (IN PIRP Irp)
PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataCreateAndLock (IN PIRP Irp)
VOID FASTCALL IovpTrackingDataFree (IN PIOV_REQUEST_PACKET IrpTrackingData)
PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataFindPointer (IN PIRP Irp, OUT PLIST_ENTRY *HashHead)
VOID FASTCALL IovpTrackingDataAcquireLock (IN PIOV_REQUEST_PACKET IrpTrackingData)
VOID FASTCALL IovpTrackingDataReleaseLock (IN PIOV_REQUEST_PACKET IrpTrackingData)
VOID FASTCALL IovpTrackingDataReference (IN PIOV_REQUEST_PACKET IovPacket, IN IOV_REFERENCE_TYPE IovRefType)
VOID FASTCALL IovpTrackingDataDereference (IN PIOV_REQUEST_PACKET IovPacket, IN IOV_REFERENCE_TYPE IovRefType)
VOID FASTCALL IovpWatermarkIrp (IN PIRP Irp, IN ULONG Flags)
PIOV_SESSION_DATA FASTCALL IovpTrackingDataGetCurrentSessionData (IN PIOV_REQUEST_PACKET IovPacket)
PVOID FASTCALL IovpProtectedIrpMakeUntouchable (IN PIRP Irp OPTIONAL, IN BOOLEAN Permanent)
VOID FASTCALL IovpProtectedIrpMakeTouchable (IN PIRP Irp, IN PVOID *RestoreHandle)
VOID FASTCALL IovpProtectedIrpFree (IN PIRP Irp OPTIONAL, IN PVOID *RestoreHandle)
PIRP FASTCALL IovpProtectedIrpAllocate (IN CCHAR StackSize, IN BOOLEAN ChargeQuota, IN PETHREAD QuotaThread OPTIONAL)

Variables

ULONG IovpIrpTrackingSpewLevel


Define Documentation

#define IRP_TRACKING_HASH_PRIME   131
 

Definition at line 25 of file hashirp.h.

Referenced by IovpTrackingDataFindPointer().

#define IRP_TRACKING_HASH_SIZE   256
 

Definition at line 24 of file hashirp.h.

Referenced by IovpTrackingDataFindPointer(), and IovpTrackingDataInit().


Typedef Documentation

typedef enum _IOV_REFERENCE_TYPE IOV_REFERENCE_TYPE
 

Referenced by IovpTrackingDataReference().


Enumeration Type Documentation

enum _IOV_REFERENCE_TYPE
 

Enumeration values:
IOVREFTYPE_PACKET 
IOVREFTYPE_POINTER 

Definition at line 31 of file hashirp.h.

00031 { 00032 00033 IOVREFTYPE_PACKET = 0, 00034 IOVREFTYPE_POINTER 00035 00036 } IOV_REFERENCE_TYPE;


Function Documentation

PIRP FASTCALL IovpProtectedIrpAllocate IN CCHAR  StackSize,
IN BOOLEAN  ChargeQuota,
IN PETHREAD QuotaThread  OPTIONAL
 

Definition at line 686 of file hashirp.c.

References ASSERT, ExAllocatePoolWithTagPriority(), HighPoolPrioritySpecialPoolOverrun, IoSizeOfIrp, NonPagedPool, and POOL_TAG_PROTECTED_IRP.

Referenced by IovpAllocateIrp1(), and IovpSessionDataAttachSurrogate().

00693 : 00694 00695 This routine allocates an IRP from the special pool using the 00696 "replacement IRP" tag. 00697 00698 Arguments: 00699 00700 StackSize - Number of stack locations to give the new IRP 00701 00702 ChargeQuota - TRUE iff quota should be charged against QuotaThread 00703 00704 QuotaThread - See above 00705 00706 Return Value: 00707 00708 Pointer to the memory allocated. 00709 00710 --*/ 00711 { 00712 PIRP pSurrogateIrp; 00713 ULONG_PTR irpPtr; 00714 SIZE_T sizeOfAllocation; 00715 00716 // 00717 // We are allocating an IRP from the special pool. Since IRPs may come from 00718 // lookaside lists they may be ULONG aligned. The memory manager on the 00719 // other hand gaurentees quad-aligned allocations. So to catch all special 00720 // pool overrun bugs we "skew" the IRP right up to the edge. 00721 // 00722 sizeOfAllocation = IoSizeOfIrp(StackSize); 00723 00724 ASSERT((sizeOfAllocation % (sizeof(ULONG))) == 0); 00725 00726 // 00727 // ADRIAO BUGBUG 08/16/98 - Use a quota'd alloc function if one is available 00728 // later... 00729 // 00730 irpPtr = (ULONG_PTR) ExAllocatePoolWithTagPriority( 00731 NonPagedPool, 00732 sizeOfAllocation, 00733 POOL_TAG_PROTECTED_IRP, 00734 HighPoolPrioritySpecialPoolOverrun 00735 ); 00736 00737 pSurrogateIrp = (PIRP) (irpPtr); 00738 00739 return pSurrogateIrp; 00740 }

VOID FASTCALL IovpProtectedIrpFree IN PIRP Irp  OPTIONAL,
IN PVOID *  RestoreHandle
 

Definition at line 838 of file hashirp.c.

References ASSERT, and NULL.

Referenced by IovpFreeIrp(), IovpSessionDataAttachSurrogate(), and IovpSessionDataFinalizeSurrogate().

00844 : 00845 00846 This routine is called when the call stack has entirely unwound 00847 and the IRP has completed. At this point it is no longer really 00848 useful to hold the surrogate IRP around. As we are using the 00849 special pool currently, this routine needs to do nothing. 00850 00851 Arguments: 00852 00853 IrpTrackingData - Pointer to the IRP tracking data. 00854 00855 Return Value: 00856 00857 None. 00858 --*/ 00859 { 00860 ASSERT((*RestoreHandle) == NULL); 00861 }

VOID FASTCALL IovpProtectedIrpMakeTouchable IN PIRP  Irp,
IN PVOID *  RestoreHandle
 

Definition at line 807 of file hashirp.c.

References ASSERT, Irp, MmProtectSpecialPool(), and NULL.

Referenced by IovpCancelIrp(), and IovpInternalCompleteAfterWait().

00813 : 00814 00815 This routine makes the an IRP touchable if previously untouchable. 00816 00817 Arguments: 00818 00819 Irp - Pointer to the Irp to make untouchable 00820 RestoreHandle - Pointer to handle returned by IovpProtectedIrpMakeUntouchable 00821 00822 00823 Return Value: 00824 00825 None. 00826 --*/ 00827 { 00828 if (*RestoreHandle) { 00829 00830 ASSERT(*RestoreHandle == Irp); 00831 MmProtectSpecialPool(Irp, PAGE_READWRITE) ; 00832 *RestoreHandle = NULL ; 00833 } 00834 }

PVOID FASTCALL IovpProtectedIrpMakeUntouchable IN PIRP Irp  OPTIONAL,
IN BOOLEAN  Permanent
 

Definition at line 744 of file hashirp.c.

References ExFreePool(), Irp, MmProtectSpecialPool(), and NULL.

Referenced by IovpFreeIrp(), IovpInternalDeferredCompletion(), IovpSessionDataAttachSurrogate(), and IovpSessionDataFinalizeSurrogate().

00750 : 00751 00752 This routine makes the surrogate IRP untouchable. Currently, this is 00753 done by freeing the IRP back to the special pool. 00754 00755 Arguments: 00756 00757 Irp - Pointer to the Irp to make untouchable 00758 Permanent - TRUE iff Irp should not be made touchable again 00759 00760 00761 Return Value: 00762 00763 RestoreHandle to be passed to make the Irp touchable again, or to free it. 00764 00765 --*/ 00766 { 00767 ULONG howModified; 00768 00769 if (!Irp) { 00770 return NULL ; 00771 } 00772 00773 if (Permanent) { 00774 ExFreePool(Irp) ; 00775 return NULL; 00776 } 00777 00778 howModified = (ULONG) MmProtectSpecialPool(Irp, PAGE_NOACCESS); 00779 00780 switch(howModified) { 00781 00782 case (ULONG) -1: 00783 00784 // 00785 // Didn't come from special pool. 00786 // 00787 return NULL; 00788 00789 case 0: 00790 00791 // 00792 // Can't comply with request, ref counts, etc hold down page. 00793 // 00794 return NULL; 00795 00796 default: 00797 00798 // 00799 // Allocation has been successfully marked as untouchable. 00800 // 00801 return (PVOID) Irp; 00802 } 00803 }

VOID FASTCALL IovpTrackingDataAcquireLock IN PIOV_REQUEST_PACKET  IrpTrackingData  ) 
 

Referenced by IovpCallDriver2(), IovpCompleteRequest2(), IovpCompleteRequest3(), IovpCompleteRequest4(), IovpCompleteRequest5(), IovpInternalCompleteAfterWait(), IovpInternalDeferredCompletion(), and IovpTrackingDataFindAndLock().

PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataCreateAndLock IN PIRP  Irp  ) 
 

Definition at line 122 of file hashirp.c.

References ASSERT, _IOV_REQUEST_PACKET::AssertFlags, _IOV_REQUEST_PACKET::CallerIrql, ExAllocatePoolWithTag, _IOV_REQUEST_PACKET::Flags, _IOV_REQUEST_PACKET::HashLink, _IOV_REQUEST_PACKET::HeadPacket, IOV_REQUEST_PACKET, IOV_STACK_LOCATION, IovpIrpHashLock, IovpTrackingDataFindPointer(), IovpTrackingFlags, Irp, _IOV_REQUEST_PACKET::IrpLock, KeInitializeSpinLock(), _IOV_REQUEST_PACKET::LastLocation, NonPagedPool, NULL, _IOV_REQUEST_PACKET::pIovSessionData, _IOV_REQUEST_PACKET::PointerCount, POOL_TAG_TRACKING_DATA, _IOV_REQUEST_PACKET::PriorityBoost, _IOV_REQUEST_PACKET::RealIrpCompletionRoutine, _IOV_REQUEST_PACKET::RealIrpContext, _IOV_REQUEST_PACKET::RealIrpControl, _IOV_REQUEST_PACKET::ReferenceCount, _IOV_REQUEST_PACKET::RefTrackingCount, _IOV_REQUEST_PACKET::RestoreHandle, _IOV_REQUEST_PACKET::SessionHead, _IOV_REQUEST_PACKET::StackCount, _IRP::StackCount, _IOV_REQUEST_PACKET::SurrogateLink, _IOV_REQUEST_PACKET::TopStackLocation, _IOV_REQUEST_PACKET::TrackedIrp, and TRACKIRP_DBGPRINT.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), IovpCallDriver1(), and IovpSessionDataAttachSurrogate().

00127 : 00128 00129 This routine creates a tracking packet for a new IRP. The IRP does not get 00130 an initial reference count however. IovpTrackingDataReleaseLock must be 00131 called to drop the lock. 00132 00133 Arguments: 00134 00135 Irp - Irp to begin tracking. 00136 00137 Return Value: 00138 00139 iovPacket block, NULL if no memory. 00140 00141 --*/ 00142 { 00143 KIRQL oldIrql; 00144 PIOV_REQUEST_PACKET iovPacket; 00145 PLIST_ENTRY hashHead; 00146 ULONG trackingDataSize; 00147 LONG newCount; 00148 00149 ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql ); 00150 00151 iovPacket = IovpTrackingDataFindPointer(Irp, &hashHead) ; 00152 00153 ASSERT(!iovPacket) ; 00154 00155 // 00156 // One extra stack location is allocated as the "zero'th" is used to 00157 // simplify some logic... 00158 // 00159 trackingDataSize = sizeof(IOV_REQUEST_PACKET)+Irp->StackCount*sizeof(IOV_STACK_LOCATION) ; 00160 00161 iovPacket = ExAllocatePoolWithTag( 00162 NonPagedPool, 00163 trackingDataSize, 00164 POOL_TAG_TRACKING_DATA 00165 ); 00166 00167 if (!iovPacket) { 00168 00169 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00170 return iovPacket; 00171 } 00172 00173 //RtlZeroMemory(iovPacket, trackingDataSize) ; 00174 00175 // 00176 // From top to bottom, initialize the fields. Note that there is not a 00177 // "surrogateHead". If any code needs to find out the first entry in the 00178 // circularly linked list of IRPs (the first is the only non-surrogate IRP), 00179 // then HeadPacket should be used. Note that the link to the session is 00180 // stored by the headPacket, more on this later. 00181 // 00182 iovPacket->TrackedIrp = Irp; 00183 KeInitializeSpinLock( &iovPacket->IrpLock ); 00184 iovPacket->ReferenceCount = 1; 00185 iovPacket->PointerCount = 0; 00186 iovPacket->Flags = 0; 00187 InitializeListHead(&iovPacket->HashLink); 00188 InitializeListHead(&iovPacket->SurrogateLink); 00189 InitializeListHead(&iovPacket->SessionHead); 00190 iovPacket->HeadPacket = iovPacket; 00191 iovPacket->StackCount = Irp->StackCount; 00192 iovPacket->AssertFlags = IovpTrackingFlags; 00193 iovPacket->RealIrpCompletionRoutine = NULL; 00194 iovPacket->RealIrpControl = 0; 00195 iovPacket->RealIrpContext = NULL; 00196 iovPacket->TopStackLocation = 0; 00197 iovPacket->PriorityBoost = 0; 00198 iovPacket->LastLocation = 0; 00199 iovPacket->RefTrackingCount =0; 00200 iovPacket->RestoreHandle = NULL; 00201 iovPacket->pIovSessionData = NULL; 00202 00203 // 00204 // Place into hash table under lock (with the initial reference count) 00205 // 00206 InsertHeadList(hashHead, &iovPacket->HashLink); 00207 00208 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00209 00210 ExAcquireSpinLock( &iovPacket->IrpLock, &iovPacket->CallerIrql ); 00211 00212 newCount = InterlockedDecrement(&iovPacket->ReferenceCount); 00213 00214 // 00215 // If this assert gets hit it means somebody got hold of tracking data 00216 // at a very odd (and probably buggy) time. Actually, this might happen 00217 // if an IRP was cancelled right as it entered IoCallDriver... 00218 // 00219 //ASSERT(newCount == 0); 00220 00221 TRACKIRP_DBGPRINT(( 00222 " VRP CREATE(%x)->%x\n", 00223 Irp, 00224 iovPacket 00225 ), 3) ; 00226 00227 return iovPacket ; 00228 }

VOID FASTCALL IovpTrackingDataDereference IN PIOV_REQUEST_PACKET  IovPacket,
IN IOV_REFERENCE_TYPE  IovRefType
 

Definition at line 612 of file hashirp.c.

References ASSERT, ASSERT_SPINLOCK_HELD, IovpIrpHashLock, IOVREFTYPE_POINTER, NULL, and TRACKIRP_DBGPRINT.

Referenced by IovpCompleteRequest2(), IovpFreeIrp(), IovpInternalCompleteAfterWait(), IovpInternalDeferredCompletion(), IovpSessionDataDereference(), IovpSessionDataFinalizeSurrogate(), and IovpSwapSurrogateIrp().

00616 { 00617 KIRQL oldIrql; 00618 00619 ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock); 00620 ASSERT(IovPacket->ReferenceCount > 0); 00621 00622 TRACKIRP_DBGPRINT(( 00623 " VRP DEREF(%x) %x--\n", 00624 IovPacket, 00625 IovPacket->ReferenceCount 00626 ), 3) ; 00627 00628 if (IovRefType == IOVREFTYPE_POINTER) { 00629 00630 ASSERT(IovPacket->PointerCount > 0); 00631 00632 TRACKIRP_DBGPRINT(( 00633 " VRP DEREF2(%x) %x--\n", 00634 IovPacket, 00635 IovPacket->PointerCount 00636 ), 3) ; 00637 00638 IovPacket->PointerCount--; 00639 00640 if (IovPacket->PointerCount == 0) { 00641 00642 ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql ); 00643 00644 IovPacket->TrackedIrp->Flags &=~ IRPFLAG_EXAMINE_MASK; 00645 IovPacket->TrackedIrp = NULL; 00646 00647 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00648 } 00649 } 00650 InterlockedDecrement(&IovPacket->ReferenceCount); 00651 00652 ASSERT(IovPacket->ReferenceCount >= IovPacket->PointerCount); 00653 }

PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataFindAndLock IN PIRP  Irp  ) 
 

Definition at line 276 of file hashirp.c.

References ASSERT, _IOV_REQUEST_PACKET::CallerIrql, IovpIrpHashLock, IovpTrackingDataAcquireLock(), IovpTrackingDataFindPointer(), IovpTrackingDataReleaseLock(), Irp, NULL, _IOV_REQUEST_PACKET::ReferenceCount, _IOV_REQUEST_PACKET::TrackedIrp, and TRACKIRP_DBGPRINT.

Referenced by IovpCallDriver1(), IovpCancelIrp(), IovpCompleteRequest1(), IovpCompleteRequestApc(), IovpFreeIrp(), IovpInitializeIrp(), IovpSwapSurrogateIrp(), and IovpWatermarkIrp().

00281 : 00282 00283 This routine will return the tracking data for an IRP that is 00284 being tracked without a surrogate or the tracking data for with 00285 a surrogate if the surrogate IRP is what was passed in. 00286 00287 Arguments: 00288 00289 Irp - Irp to find. 00290 00291 Return Value: 00292 00293 IovPacket block, iff above conditions are satified. 00294 00295 --*/ 00296 { 00297 KIRQL oldIrql ; 00298 PIOV_REQUEST_PACKET iovPacket ; 00299 PLIST_ENTRY listHead; 00300 00301 ASSERT(Irp) ; 00302 ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql ); 00303 00304 iovPacket = IovpTrackingDataFindPointer(Irp, &listHead) ; 00305 00306 if (!iovPacket) { 00307 00308 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00309 return NULL; 00310 } 00311 00312 InterlockedIncrement(&iovPacket->ReferenceCount); 00313 00314 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00315 00316 IovpTrackingDataAcquireLock(iovPacket) ; 00317 iovPacket->CallerIrql = oldIrql; 00318 00319 InterlockedDecrement(&iovPacket->ReferenceCount); 00320 00321 if (iovPacket->TrackedIrp == NULL) { 00322 00323 ASSERT(0); 00324 // 00325 // Someone IRP is being mishandled, we got in a race condition where 00326 // we got the packet but the pointer count decayed to zero. Therefore 00327 // we do not want this packet so we will return NULL after dropping 00328 // it's lock. This sort of thing really shouldn't happen ya know. 00329 // 00330 IovpTrackingDataReleaseLock(iovPacket); 00331 return NULL; 00332 } 00333 00334 TRACKIRP_DBGPRINT(( 00335 " VRP FIND(%x)->%x\n", 00336 Irp, 00337 iovPacket 00338 ), 3) ; 00339 00340 return iovPacket; 00341 }

PIOV_REQUEST_PACKET FASTCALL IovpTrackingDataFindPointer IN PIRP  Irp,
OUT PLIST_ENTRY *  HashHead
 

Definition at line 345 of file hashirp.c.

References ASSERT_SPINLOCK_HELD, IovpIrpHashLock, IovpIrpTrackingTable, Irp, IRP_TRACKING_HASH_PRIME, IRP_TRACKING_HASH_SIZE, NULL, PAGE_SIZE, and _IOV_REQUEST_PACKET::TrackedIrp.

Referenced by IovpTrackingDataCreateAndLock(), and IovpTrackingDataFindAndLock().

00351 : 00352 00353 This routine returns a pointer to a pointer to the Irp tracking data. 00354 This function is meant to be called by other routines in this file. 00355 00356 N.B. The tracking lock is assumed to be held by the caller. 00357 00358 Arguments: 00359 00360 Irp - Irp to locate in the tracking table. 00361 00362 HashHead - If return is non-null, points to the 00363 list head that should be used to insert 00364 the IRP. 00365 00366 Return Value: 00367 00368 IrpTrackingData iff found, NULL otherwise. 00369 00370 --*/ 00371 { 00372 KIRQL oldIrql ; 00373 PIOV_REQUEST_PACKET iovPacket ; 00374 PLIST_ENTRY listEntry, listHead; 00375 UINT_PTR hash ; 00376 00377 ASSERT_SPINLOCK_HELD(&IovpIrpHashLock) ; 00378 00379 hash = (((UINT_PTR) Irp)/PAGE_SIZE)*IRP_TRACKING_HASH_PRIME ; 00380 hash %= IRP_TRACKING_HASH_SIZE ; 00381 00382 *HashHead = listHead = IovpIrpTrackingTable + hash ; 00383 00384 for(listEntry = listHead; 00385 listEntry->Flink != listHead; 00386 listEntry = listEntry->Flink) { 00387 00388 iovPacket = CONTAINING_RECORD(listEntry->Flink, IOV_REQUEST_PACKET, HashLink); 00389 00390 if (iovPacket->TrackedIrp == Irp) { 00391 00392 return iovPacket; 00393 } 00394 } 00395 00396 return NULL ; 00397 }

VOID FASTCALL IovpTrackingDataFree IN PIOV_REQUEST_PACKET  IrpTrackingData  ) 
 

Definition at line 232 of file hashirp.c.

References ASSERT, ExFreePool(), TRACKFLAG_REMOVED_FROM_TABLE, and TRACKIRP_DBGPRINT.

Referenced by IovpTrackingDataReleaseLock().

00237 : 00238 00239 This routine free's the tracking data. The tracking data should already 00240 have been removed from the table by a call to IovpTrackingDataReleaseLock 00241 with the ReferenceCount at 0. 00242 00243 Arguments: 00244 00245 IovPacket - Tracking data to free. 00246 00247 Return Value: 00248 00249 Nope. 00250 00251 --*/ 00252 { 00253 // 00254 // The list entry is inited to point back to itself when removed. The 00255 // pointer count should of course still be zero. 00256 // 00257 IovPacket->Flags|=TRACKFLAG_REMOVED_FROM_TABLE ; 00258 ASSERT(IsListEmpty(&IovPacket->HashLink)) ; 00259 00260 // 00261 // with no reference counts... 00262 // 00263 ASSERT(!IovPacket->ReferenceCount) ; 00264 ASSERT(!IovPacket->PointerCount) ; 00265 00266 TRACKIRP_DBGPRINT(( 00267 " VRP FREE(%x)x\n", 00268 IovPacket 00269 ), 3) ; 00270 00271 ExFreePool(IovPacket) ; 00272 }

PIOV_SESSION_DATA FASTCALL IovpTrackingDataGetCurrentSessionData IN PIOV_REQUEST_PACKET  IovPacket  ) 
 

Definition at line 657 of file hashirp.c.

References ASSERT, ASSERT_SPINLOCK_HELD, NULL, and TRACKFLAG_ACTIVE.

Referenced by IovpAssertIrpStackDownward(), IovpCallDriver1(), IovpCompleteRequest1(), IovpCompleteRequest2(), IovpFreeIrp(), IovpSessionDataFinalizeSurrogate(), and IovpSwapSurrogateIrp().

00660 { 00661 ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock); 00662 ASSERT_SPINLOCK_HELD(&IovPacket->HeadPacket->IrpLock); 00663 ASSERT((IovPacket->HeadPacket->pIovSessionData == NULL)|| 00664 (IovPacket->Flags&TRACKFLAG_ACTIVE)) ; 00665 00666 return IovPacket->HeadPacket->pIovSessionData; 00667 }

VOID FASTCALL IovpTrackingDataInit VOID   ) 
 

Definition at line 89 of file hashirp.c.

References IovpIrpHashLock, IovpIrpTrackingTable, IRP_TRACKING_HASH_SIZE, KeInitializeSpinLock(), and PAGED_CODE.

Referenced by IovpInitIrpTracking().

00094 : 00095 00096 This routine initializes all the important structures we use to track 00097 IRPs through the hash tables. 00098 00099 Arguments: 00100 00101 None 00102 00103 Return Value: 00104 00105 None 00106 00107 --*/ 00108 { 00109 ULONG i; 00110 00111 PAGED_CODE(); 00112 00113 KeInitializeSpinLock( &IovpIrpHashLock ); 00114 for(i=0; i<IRP_TRACKING_HASH_SIZE; i++) { 00115 00116 InitializeListHead(IovpIrpTrackingTable+i); 00117 } 00118 }

VOID FASTCALL IovpTrackingDataReference IN PIOV_REQUEST_PACKET  IovPacket,
IN IOV_REFERENCE_TYPE  IovRefType
 

Definition at line 584 of file hashirp.c.

References ASSERT_SPINLOCK_HELD, IOV_REFERENCE_TYPE, IOVREFTYPE_POINTER, and TRACKIRP_DBGPRINT.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), IovpCallDriver1(), IovpCompleteRequest3(), IovpSessionDataAttachSurrogate(), and IovpSessionDataReference().

00588 { 00589 ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock); 00590 00591 TRACKIRP_DBGPRINT(( 00592 " VRP REF(%x) %x++\n", 00593 IovPacket, 00594 IovPacket->ReferenceCount 00595 ), 3) ; 00596 00597 InterlockedIncrement(&IovPacket->ReferenceCount); 00598 if (IovRefType == IOVREFTYPE_POINTER) { 00599 00600 TRACKIRP_DBGPRINT(( 00601 " VRP REF2(%x) %x++\n", 00602 IovPacket, 00603 IovPacket->PointerCount 00604 ), 3) ; 00605 00606 IovPacket->PointerCount++; 00607 } 00608 }

VOID FASTCALL IovpTrackingDataReleaseLock IN PIOV_REQUEST_PACKET  IrpTrackingData  ) 
 

Definition at line 454 of file hashirp.c.

References ASSERT, ASSERT_SPINLOCK_HELD, _IOV_REQUEST_PACKET::CallerIrql, _IRP::Flags, _IOV_REQUEST_PACKET::HashLink, _IOV_REQUEST_PACKET::HeadPacket, IovpIrpHashLock, IovpTrackingDataFree(), _IOV_REQUEST_PACKET::IrpLock, NULL, _IOV_REQUEST_PACKET::pIovSessionData, _IOV_REQUEST_PACKET::PointerCount, _IOV_REQUEST_PACKET::ReferenceCount, _IOV_REQUEST_PACKET::SurrogateLink, and _IOV_REQUEST_PACKET::TrackedIrp.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), IovpCallDriver1(), IovpCallDriver2(), IovpCancelIrp(), IovpCompleteRequest1(), IovpCompleteRequest2(), IovpCompleteRequest3(), IovpCompleteRequest4(), IovpCompleteRequest5(), IovpCompleteRequestApc(), IovpFreeIrp(), IovpInitializeIrp(), IovpInternalCompleteAfterWait(), IovpInternalDeferredCompletion(), IovpSwapSurrogateIrp(), IovpTrackingDataFindAndLock(), and IovpWatermarkIrp().

00459 : 00460 00461 This routine releases the IRPs tracking data lock and adjusts the ref count 00462 as appropriate. If the reference count drops to zero, the tracking data is 00463 freed. 00464 00465 Arguments: 00466 00467 IovPacket - Pointer to the IRP tracking data. 00468 00469 Return Value: 00470 00471 None. 00472 00473 --*/ 00474 { 00475 BOOLEAN freeTrackingData; 00476 PIOV_REQUEST_PACKET iovCurPacket, iovHeadPacket, iovNextPacket; 00477 KIRQL oldIrql; 00478 00479 // 00480 // Pass one, delink anyone from the tree who's leaving, and assert that 00481 // no surrogates are left after a freed one. 00482 // 00483 iovCurPacket = iovHeadPacket = IovPacket->HeadPacket; 00484 while(1) { 00485 00486 ASSERT_SPINLOCK_HELD(&iovCurPacket->IrpLock); 00487 00488 iovNextPacket = CONTAINING_RECORD( 00489 iovCurPacket->SurrogateLink.Flink, 00490 IOV_REQUEST_PACKET, 00491 SurrogateLink 00492 ); 00493 00494 // 00495 // PointerCount is always referenced under the IRP lock. 00496 // 00497 if (iovCurPacket->PointerCount == 0) { 00498 00499 ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql ); 00500 00501 // 00502 // This field may be examined only under the hash lock. 00503 // 00504 if (iovCurPacket->TrackedIrp) { 00505 00506 iovCurPacket->TrackedIrp->Flags &=~ IRPFLAG_EXAMINE_MASK; 00507 iovCurPacket->TrackedIrp = NULL; 00508 } 00509 00510 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00511 } 00512 00513 // 00514 // We now remove any entries that will be leaving from the hash table. 00515 // Note that the ReferenceCount may be incremented outside the IRP lock 00516 // (but under the hash lock) but ReferenceCount can never be dropped 00517 // outside of the IRP lock. Therefore for performance we check once 00518 // and then take the lock to prevent anyone finding it and incrementing 00519 // it. 00520 // 00521 00522 if (iovCurPacket->ReferenceCount == 0) { 00523 00524 ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql ); 00525 00526 if (iovCurPacket->ReferenceCount ==0) { 00527 00528 ASSERT(iovCurPacket->PointerCount == 0); 00529 ASSERT((iovCurPacket->pIovSessionData == NULL) || 00530 (iovCurPacket != iovHeadPacket)); 00531 ASSERT((iovNextPacket->ReferenceCount == 0) || 00532 (iovNextPacket == iovHeadPacket)); 00533 00534 RemoveEntryList(&iovCurPacket->HashLink); 00535 00536 InitializeListHead(&iovCurPacket->HashLink); 00537 } 00538 ExReleaseSpinLock( &IovpIrpHashLock, oldIrql ); 00539 } 00540 00541 if (iovCurPacket == IovPacket) { 00542 00543 break; 00544 } 00545 00546 iovCurPacket = iovNextPacket; 00547 } 00548 00549 // 00550 // Pass two, drop locks and free neccessary data. 00551 // 00552 iovCurPacket = iovHeadPacket; 00553 while(1) { 00554 00555 freeTrackingData = IsListEmpty(&iovCurPacket->HashLink); 00556 00557 iovNextPacket = CONTAINING_RECORD( 00558 iovCurPacket->SurrogateLink.Flink, 00559 IOV_REQUEST_PACKET, 00560 SurrogateLink 00561 ); 00562 00563 ExReleaseSpinLock(&iovCurPacket->IrpLock, iovCurPacket->CallerIrql) ; 00564 00565 if (freeTrackingData) { 00566 00567 RemoveEntryList(&iovCurPacket->SurrogateLink); 00568 InitializeListHead(&iovCurPacket->SurrogateLink); 00569 00570 IovpTrackingDataFree(iovCurPacket) ; 00571 } 00572 00573 if (iovCurPacket == IovPacket) { 00574 00575 break; 00576 } 00577 00578 iovCurPacket = iovNextPacket; 00579 } 00580 }

VOID FASTCALL IovpWatermarkIrp IN PIRP  Irp,
IN ULONG  Flags
 

Definition at line 865 of file hashirp.c.

References _IOV_REQUEST_PACKET::Flags, IovpTrackingDataFindAndLock(), IovpTrackingDataReleaseLock(), Irp, IRP_BOGUS, IRP_SYSTEM_RESTRICTED, NULL, TRACKFLAG_BOGUS, and TRACKFLAG_WATERMARKED.

00869 { 00870 PIOV_REQUEST_PACKET iovPacket; 00871 00872 iovPacket = IovpTrackingDataFindAndLock(Irp); 00873 00874 if (iovPacket == NULL) { 00875 00876 return; 00877 } 00878 00879 if (Flags & IRP_SYSTEM_RESTRICTED) { 00880 00881 // 00882 // Note that calling this function is not in itself enough to get the 00883 // system to prevent drivers from sending restricted IRPs. Those IRPs to 00884 // be protected must also be added to IovpIsSystemRestrictedIrp in 00885 // flunkirp.c 00886 // 00887 iovPacket->Flags |= TRACKFLAG_WATERMARKED; 00888 } 00889 00890 if (Flags & IRP_BOGUS) { 00891 00892 iovPacket->Flags |= TRACKFLAG_BOGUS; 00893 } 00894 00895 IovpTrackingDataReleaseLock(iovPacket); 00896 }


Variable Documentation

ULONG IovpIrpTrackingSpewLevel
 

Definition at line 29 of file hashirp.h.


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