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

trackirp.h File Reference

Go to the source code of this file.

Classes

struct  _IOFCALLDRIVER_STACKDATA
struct  _IOV_STACK_LOCATION
struct  _IOV_SESSION_DATA
struct  _IOV_REQUEST_PACKET
struct  _DEFERRAL_CONTEXT
struct  _IOFCOMPLETEREQUEST_STACKDATA

Defines

#define ASSERTFLAG_TRACKIRPS   0x00000001
#define ASSERTFLAG_MONITOR_ALLOCS   0x00000002
#define ASSERTFLAG_POLICEIRPS   0x00000004
#define ASSERTFLAG_MONITORMAJORS   0x00000008
#define ASSERTFLAG_SURROGATE   0x00000010
#define ASSERTFLAG_SMASH_SRBS   0x00000020
#define ASSERTFLAG_CONSUME_ALWAYS   0x00000040
#define ASSERTFLAG_FORCEPENDING   0x00000080
#define ASSERTFLAG_COMPLETEATDPC   0x00000100
#define ASSERTFLAG_COMPLETEATPASSIVE   0x00000200
#define ASSERTFLAG_DEFERCOMPLETION   0x00000800
#define ASSERTFLAG_ROTATE_STATUS   0x00001000
#define ASSERTMASK_COMPLETESTYLE   0x00000F80
#define ASSERTFLAG_SEEDSTACK   0x00010000
#define HACKHACKS_ENABLED
#define HACKFLAG_FOR_MUP   0x00000001
#define HACKFLAG_FOR_SCSIPORT   0x00000002
#define HACKFLAG_FOR_ACPI   0x00000004
#define HACKFLAG_FOR_BOGUSIRPS   0x00000008
#define IRPFLAG_EXAMINE_MASK   0xC0000000
#define IRPFLAG_EXAMINE_NOT_TRACKED   0x80000000
#define IRPFLAG_EXAMINE_TRACKED   0x40000000
#define IRPFLAG_EXAMINE_UNMARKED   0x00000000
#define IRP_DIAG_HAS_SURROGATE   0x02000000
#define IRP_DIAG_IS_SURROGATE   0x01000000
#define TRACKFLAG_ACTIVE   0x00000001
#define TRACKFLAG_SURROGATE   0x00000002
#define TRACKFLAG_HAS_SURROGATE   0x00000004
#define TRACKFLAG_PROTECTEDIRP   0x00000008
#define TRACKFLAG_QUEUED_INTERNALLY   0x00000010
#define TRACKFLAG_BOGUS   0x00000020
#define TRACKFLAG_RELEASED   0x00000040
#define TRACKFLAG_SRB_MUNGED   0x00000080
#define TRACKFLAG_SWAPPED_BACK   0x00000100
#define TRACKFLAG_WATERMARKED   0x00100000
#define TRACKFLAG_IO_ALLOCATED   0x00200000
#define TRACKFLAG_UNWOUND_BADLY   0x00400000
#define TRACKFLAG_PASSED_FAILURE   0x01000000
#define TRACKFLAG_PASSED_AT_BAD_IRQL   0x02000000
#define TRACKFLAG_IN_TRANSIT   0x40000000
#define TRACKFLAG_REMOVED_FROM_TABLE   0x80000000
#define DOE_DESIGNATED_FDO   0x80000000
#define DOE_BOTTOM_OF_FDO_STACK   0x40000000
#define DOE_RAW_FDO   0x20000000
#define DOE_EXAMINED   0x10000000
#define DOE_TRACKED   0x08000000
#define STACKFLAG_NO_HANDLER   0x80000000
#define STACKFLAG_REQUEST_COMPLETED   0x40000000
#define STACKFLAG_CHECK_FOR_REFERENCE   0x20000000
#define STACKFLAG_REACHED_PDO   0x10000000
#define STACKFLAG_FIRST_REQUEST   0x08000000
#define CALLFLAG_COMPLETED   0x80000000
#define CALLFLAG_IS_REMOVE_IRP   0x40000000
#define CALLFLAG_REMOVING_FDO_STACK_DO   0x20000000
#define CALLFLAG_OVERRIDE_STATUS   0x10000000
#define CALLFLAG_TOPMOST_IN_SLOT   0x08000000
#define ALLOCFLAG_PROTECTEDIRP   0x00000001
#define SESSIONFLAG_UNWOUND_INCONSISTANT   0x00000001
#define IRP_SYSTEM_RESTRICTED   0x00000001
#define IRP_BOGUS   0x00000002
#define SL_NOTCOPIED   0x10
#define IRP_ALLOCATION_MONITORED   0x80
#define STARTED_TOP_OF_STACK   1
#define FORWARDED_TO_NEXT_DO   2
#define SKIPPED_A_DO   3
#define STARTED_INSIDE_STACK   4
#define CHANGED_STACKS_AT_BOTTOM   5
#define CHANGED_STACKS_MID_STACK   6
#define IRP_ALLOC_COUNT   5
#define SPECIALIRP_MARK_NON_TRACKABLE(Irp)
#define SPECIALIRP_IOF_CALL_1(pIrp, DeviceObject, st1)
#define SPECIALIRP_IOF_CALL_2(Irp, DeviceObject, Routine, FinalStatus, st1)
#define SPECIALIRP_IOF_COMPLETE_1(Irp, PriorityBoost, CompletionPacket)
#define SPECIALIRP_IOF_COMPLETE_2(Irp, CompletionPacket)
#define SPECIALIRP_IOF_COMPLETE_3(Irp, Routine, CompletionPacket)
#define SPECIALIRP_IOF_COMPLETE_4(Irp, ReturnedStatus, CompletionPacket)
#define SPECIALIRP_IOF_COMPLETE_5(Irp, CompletionPacket)
#define SPECIALIRP_IO_CANCEL_IRP(Irp, CancelHandled, ReturnValue)
#define IOP_DIAG_THROW_CHAFF_AT_STARTED_PDO_STACK(DeviceObject)
#define SPECIALIRP_IO_FREE_IRP(Irp, FreeHandled)
#define SPECIALIRP_IO_ALLOCATE_IRP_1(StackSize, Quota, IrpPointer)
#define SPECIALIRP_IO_ALLOCATE_IRP_2(Irp)
#define SPECIALIRP_IO_INITIALIZE_IRP(Irp, PacketSize, StackSize, InitHandled)
#define SPECIALIRP_IO_DELETE_DEVICE(Device)
#define SPECIALIRP_IO_ATTACH_DEVICE_TO_DEVICE_STACK(NewDevice, ExistingDevice)
#define SPECIALIRP_IO_DETACH_DEVICE(TargetDevice)
#define SPECIALIRP_WATERMARK_IRP(Irp, Flags)
#define SPECIALIRP_IOP_COMPLETE_REQUEST(Irp, StackPointer)
#define TRACKIRP_DBGPRINT(txt, level)

Typedefs

typedef _IOFCALLDRIVER_STACKDATAPIOFCALLDRIVER_STACKDATA
typedef _IOV_STACK_LOCATIONPIOV_STACK_LOCATION
typedef _IOV_REQUEST_PACKETPIOV_REQUEST_PACKET
typedef _IOV_SESSION_DATAPIOV_SESSION_DATA
typedef _IOFCALLDRIVER_STACKDATA IOFCALLDRIVER_STACKDATA
typedef _IOV_STACK_LOCATION IOV_STACK_LOCATION
typedef _IOV_SESSION_DATA IOV_SESSION_DATA
typedef _IOV_REQUEST_PACKET IOV_REQUEST_PACKET
typedef _DEFERRAL_CONTEXT DEFERRAL_CONTEXT
typedef _DEFERRAL_CONTEXTPDEFERRAL_CONTEXT
typedef _IOFCOMPLETEREQUEST_STACKDATA IOFCOMPLETEREQUEST_STACKDATA
typedef _IOFCOMPLETEREQUEST_STACKDATAPIOFCOMPLETEREQUEST_STACKDATA

Enumerations

enum  DEFER_ACTION { DEFERACTION_QUEUE_WORKITEM, DEFERACTION_QUEUE_PASSIVE_TIMER, DEFERACTION_QUEUE_DISPATCH_TIMER, DEFERACTION_NORMAL }

Functions

BOOLEAN FASTCALL IovpInitIrpTracking (IN ULONG Level, IN ULONG Flags)
VOID FASTCALL IovpCallDriver1 (IN OUT PIRP *IrpPointer, IN PDEVICE_OBJECT DeviceObject, IN OUT PIOFCALLDRIVER_STACKDATA IofCallDriverStackData)
VOID FASTCALL IovpCallDriver2 (IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject, IN PVOID Routine, IN OUT NTSTATUS *FinalStatus, IN PIOFCALLDRIVER_STACKDATA IofCallDriverStackData)
VOID FASTCALL IovpCompleteRequest1 (IN PIRP Irp, IN CCHAR PriorityBoost, IN OUT PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket)
VOID FASTCALL IovpCompleteRequest2 (IN PIRP Irp, IN OUT PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket)
VOID FASTCALL IovpCompleteRequest3 (IN PIRP Irp, IN PVOID Routine, IN OUT PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket)
VOID FASTCALL IovpCompleteRequest4 (IN PIRP Irp, IN NTSTATUS ReturnedStatus, IN OUT PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket)
VOID FASTCALL IovpCompleteRequest5 (IN PIRP Irp, IN OUT PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket)
VOID FASTCALL IovpCompleteRequestApc (IN PIRP Irp, IN PVOID BestStackOffset)
VOID FASTCALL IovpCancelIrp (IN PIRP Irp, IN OUT PBOOLEAN CancelHandled, IN OUT PBOOLEAN ReturnValue)
VOID FASTCALL IovpFreeIrp (IN PIRP Irp, IN OUT PBOOLEAN FreeHandled)
VOID FASTCALL IovpAllocateIrp1 (IN CCHAR StackSize, IN BOOLEAN ChargeQuota, IN OUT PIRP *IrpPointer)
VOID FASTCALL IovpAllocateIrp2 (IN PIRP Irp)
VOID FASTCALL IovpInitializeIrp (IN OUT PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize, IN OUT PBOOLEAN InitializeHandled)
VOID IovpExamineIrpStackForwarding (IN OUT PIOV_REQUEST_PACKET IovPacket, IN BOOLEAN IsNewSession, IN ULONG ForwardMethod, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN OUT PIO_STACK_LOCATION *IoCurrentStackLocation, OUT PIO_STACK_LOCATION *IoLastStackLocation, OUT ULONG *StackLocationsAdvanced)
NTSTATUS IovpSwapSurrogateIrp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
VOID FASTCALL IovpExamineDevObjForwarding (IN PDEVICE_OBJECT DeviceBeingCalled, IN PDEVICE_OBJECT DeviceLastCalled, OUT PULONG ForwardingTechnique)
VOID FASTCALL IovpFinalizeIrpSettings (IN OUT PIOV_REQUEST_PACKET IrpTrackingData, IN BOOLEAN SurrogateIrpSwapped)
PDEVICE_OBJECT FASTCALL IovpGetDeviceAttachedTo (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IovpInternalCompletionTrap (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
NTSTATUS IovpInternalDeferredCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
PDEVICE_OBJECT FASTCALL IovpGetLowestDevice (IN PDEVICE_OBJECT DeviceObject)
VOID FASTCALL IovpAssertNonLegacyDevice (IN PDEVICE_OBJECT DeviceObject, IN ULONG StackFramesToSkip, IN PUCHAR FailureTxt)
BOOLEAN FASTCALL IovpIsInFdoStack (IN PDEVICE_OBJECT DeviceObject)
BOOLEAN FASTCALL IovpDoAssertIrps (VOID)
VOID FASTCALL IovpSeedStack (VOID)
VOID FASTCALL IovpSeedOnePage (VOID)
VOID FASTCALL IovpSeedTwoPages (VOID)
VOID FASTCALL IovpSeedThreePages (VOID)
VOID IovpInternalCompleteAfterWait (IN PVOID Context)
VOID IovpInternalCompleteAtDPC (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID IovpAttachDeviceToDeviceStack (IN PDEVICE_OBJECT NewDevice, IN PDEVICE_OBJECT ExistingDevice)
VOID IovpDetachDevice (IN PDEVICE_OBJECT LowerDevice)
VOID IovpDeleteDevice (IN PDEVICE_OBJECT Device)
BOOLEAN IovpIsInterestingStack (IN PDEVICE_OBJECT DeviceObject)
BOOLEAN IovpIsInterestingDriver (IN PDRIVER_OBJECT DriverObject)
VOID IovpReexamineAllStacks (VOID)
BOOLEAN IovpEnumDevObjCallback (IN PVOID Object, IN PUNICODE_STRING ObjectName, IN ULONG HandleCount, IN ULONG PointerCount, IN PVOID Context)
BOOLEAN IovpAdvanceStackDownwards (IN PIOV_STACK_LOCATION StackDataArray, IN CCHAR CurrentLocation, IN PIO_STACK_LOCATION IrpSp, IN PIO_STACK_LOCATION IrpLastSp OPTIONAL, IN ULONG LocationsAdvanced, IN BOOLEAN IsNewRequest, IN BOOLEAN MarkAsTaken, OUT PIOV_STACK_LOCATION *StackLocationInfo)

Variables

ULONG IovpHackFlags
ULONG IovpTrackingFlags


Define Documentation

#define ALLOCFLAG_PROTECTEDIRP   0x00000001
 

Definition at line 106 of file trackirp.h.

#define ASSERTFLAG_COMPLETEATDPC   0x00000100
 

Definition at line 35 of file trackirp.h.

Referenced by IovpCompleteRequest2(), IovpCompleteRequest5(), IovpInitIrpTracking(), and IovpInternalDeferredCompletion().

#define ASSERTFLAG_COMPLETEATPASSIVE   0x00000200
 

Definition at line 36 of file trackirp.h.

Referenced by IovpCompleteRequest3(), IovpInternalDeferredCompletion(), and IovpSessionDataCreate().

#define ASSERTFLAG_CONSUME_ALWAYS   0x00000040
 

Definition at line 33 of file trackirp.h.

Referenced by IovpExamineIrpStackForwarding(), and IovpInitIrpTracking().

#define ASSERTFLAG_DEFERCOMPLETION   0x00000800
 

Definition at line 37 of file trackirp.h.

Referenced by IovpCompleteRequest3(), IovpInitIrpTracking(), IovpInternalDeferredCompletion(), and IovpSessionDataCreate().

#define ASSERTFLAG_FORCEPENDING   0x00000080
 

Definition at line 34 of file trackirp.h.

Referenced by IovpCallDriver2(), IovpCompleteRequest1(), IovpCompleteRequest3(), IovpCompleteRequest4(), IovpInitIrpTracking(), IovpInternalDeferredCompletion(), and IovpSessionDataCreate().

#define ASSERTFLAG_MONITOR_ALLOCS   0x00000002
 

Definition at line 28 of file trackirp.h.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), and IovpInitIrpTracking().

#define ASSERTFLAG_MONITORMAJORS   0x00000008
 

Definition at line 30 of file trackirp.h.

Referenced by IovpCallDriver1(), IovpCompleteRequest2(), and IovpInitIrpTracking().

#define ASSERTFLAG_POLICEIRPS   0x00000004
 

Definition at line 29 of file trackirp.h.

Referenced by IovpAllocateIrp1(), IovpCallDriver1(), IovpCallDriver2(), IovpCancelIrp(), IovpCompleteRequest2(), IovpCompleteRequest3(), IovpExamineIrpStackForwarding(), IovpFreeIrp(), IovpInitializeIrp(), IovpInitIrpTracking(), IovpInternalDeferredCompletion(), IovpSessionDataDeterminePolicy(), and IovpSwapSurrogateIrp().

#define ASSERTFLAG_ROTATE_STATUS   0x00001000
 

Definition at line 38 of file trackirp.h.

Referenced by IovpCompleteRequest2(), and IovpInitIrpTracking().

#define ASSERTFLAG_SEEDSTACK   0x00010000
 

Definition at line 41 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpSeedStack().

#define ASSERTFLAG_SMASH_SRBS   0x00000020
 

Definition at line 32 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpSessionDataDeterminePolicy().

#define ASSERTFLAG_SURROGATE   0x00000010
 

Definition at line 31 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpSessionDataDeterminePolicy().

#define ASSERTFLAG_TRACKIRPS   0x00000001
 

Definition at line 27 of file trackirp.h.

Referenced by IovpCallDriver1(), IovpInitIrpTracking(), and IovpSessionDataDeterminePolicy().

#define ASSERTMASK_COMPLETESTYLE   0x00000F80
 

Definition at line 40 of file trackirp.h.

#define CALLFLAG_COMPLETED   0x80000000
 

Definition at line 100 of file trackirp.h.

Referenced by IovpCallDriver2(), and IovpCompleteRequest2().

#define CALLFLAG_IS_REMOVE_IRP   0x40000000
 

Definition at line 101 of file trackirp.h.

Referenced by IovpCallDriver1(), and IovpCallDriver2().

#define CALLFLAG_OVERRIDE_STATUS   0x10000000
 

Definition at line 103 of file trackirp.h.

Referenced by IovpCallDriver2(), and IovpCompleteRequest2().

#define CALLFLAG_REMOVING_FDO_STACK_DO   0x20000000
 

Definition at line 102 of file trackirp.h.

Referenced by IovpCallDriver1(), and IovpCallDriver2().

#define CALLFLAG_TOPMOST_IN_SLOT   0x08000000
 

Definition at line 104 of file trackirp.h.

Referenced by IovpCallDriver1().

#define CHANGED_STACKS_AT_BOTTOM   5
 

Definition at line 121 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpExamineDevObjForwarding().

#define CHANGED_STACKS_MID_STACK   6
 

Definition at line 122 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpExamineDevObjForwarding().

#define DOE_BOTTOM_OF_FDO_STACK   0x40000000
 

Definition at line 89 of file trackirp.h.

Referenced by IopCallDriverAddDevice(), and IovpIsInFdoStack().

#define DOE_DESIGNATED_FDO   0x80000000
 

Definition at line 88 of file trackirp.h.

Referenced by IopCallDriverAddDevice(), and IovpAssertIrpStackDownward().

#define DOE_EXAMINED   0x10000000
 

Definition at line 91 of file trackirp.h.

Referenced by IovpDetachDevice(), IovpEnumDevObjCallback(), and IovpIsInterestingStack().

#define DOE_RAW_FDO   0x20000000
 

Definition at line 90 of file trackirp.h.

Referenced by IopCallDriverAddDevice(), IovpAssertIrpStackDownward(), and IovpCallDriver1().

#define DOE_TRACKED   0x08000000
 

Definition at line 92 of file trackirp.h.

Referenced by IovpDetachDevice(), IovpEnumDevObjCallback(), and IovpIsInterestingStack().

#define FORWARDED_TO_NEXT_DO   2
 

Definition at line 118 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), IovpExamineDevObjForwarding(), and IovpExamineIrpStackForwarding().

#define HACKFLAG_FOR_ACPI   0x00000004
 

Definition at line 52 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpThrowChaffAtStartedPdoStack().

#define HACKFLAG_FOR_BOGUSIRPS   0x00000008
 

Definition at line 53 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpThrowChaffAtStartedPdoStack().

#define HACKFLAG_FOR_MUP   0x00000001
 

Definition at line 50 of file trackirp.h.

Referenced by IovpInitIrpTracking(), and IovpSessionDataDeterminePolicy().

#define HACKFLAG_FOR_SCSIPORT   0x00000002
 

Definition at line 51 of file trackirp.h.

Referenced by IovpExamineIrpStackForwarding(), and IovpInitIrpTracking().

#define HACKHACKS_ENABLED
 

Definition at line 49 of file trackirp.h.

#define IOP_DIAG_THROW_CHAFF_AT_STARTED_PDO_STACK DeviceObject   ) 
 

Value:

Definition at line 628 of file trackirp.h.

Referenced by IopEnumerateDevice().

#define IRP_ALLOC_COUNT   5
 

Definition at line 124 of file trackirp.h.

Referenced by IovpAllocateIrp1(), and IovpAllocateIrp2().

#define IRP_ALLOCATION_MONITORED   0x80
 

Definition at line 115 of file trackirp.h.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), and IovpFreeIrp().

#define IRP_BOGUS   0x00000002
 

Definition at line 111 of file trackirp.h.

Referenced by IovpThrowBogusSynchronousIrp(), and IovpWatermarkIrp().

#define IRP_DIAG_HAS_SURROGATE   0x02000000
 

Definition at line 66 of file trackirp.h.

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

#define IRP_DIAG_IS_SURROGATE   0x01000000
 

Definition at line 67 of file trackirp.h.

Referenced by IovpSessionDataAttachSurrogate(), and IovpSessionDataFinalizeSurrogate().

#define IRP_SYSTEM_RESTRICTED   0x00000001
 

Definition at line 110 of file trackirp.h.

Referenced by IopAsynchronousCall(), IopEjectDevice(), IopFilterResourceRequirementsCall(), IopSynchronousCall(), and IovpWatermarkIrp().

#define IRPFLAG_EXAMINE_MASK   0xC0000000
 

Definition at line 61 of file trackirp.h.

Referenced by IovpCallDriver1(), and IovpSessionDataFinalizeSurrogate().

#define IRPFLAG_EXAMINE_NOT_TRACKED   0x80000000
 

Definition at line 62 of file trackirp.h.

Referenced by IovpCallDriver1().

#define IRPFLAG_EXAMINE_TRACKED   0x40000000
 

Definition at line 63 of file trackirp.h.

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

#define IRPFLAG_EXAMINE_UNMARKED   0x00000000
 

Definition at line 64 of file trackirp.h.

Referenced by IovpCallDriver1().

#define SESSIONFLAG_UNWOUND_INCONSISTANT   0x00000001
 

Definition at line 108 of file trackirp.h.

Referenced by IovpCallDriver2().

#define SKIPPED_A_DO   3
 

Definition at line 119 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpExamineDevObjForwarding().

#define SL_NOTCOPIED   0x10
 

Definition at line 113 of file trackirp.h.

Referenced by IovpCallDriver1(), IovpExamineIrpStackForwarding(), and IovSpecialIrpCompleteRequest().

#define SPECIALIRP_IO_ALLOCATE_IRP_1 StackSize,
Quota,
IrpPointer   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpAllocateIrp1((StackSize), (Quota), (IrpPointer));\ } else { \ *(IrpPointer) = NULL ; \ } \ }

Definition at line 644 of file trackirp.h.

Referenced by IovAllocateIrp().

#define SPECIALIRP_IO_ALLOCATE_IRP_2 Irp   ) 
 

Value:

Definition at line 653 of file trackirp.h.

Referenced by IovAllocateIrp().

#define SPECIALIRP_IO_ATTACH_DEVICE_TO_DEVICE_STACK NewDevice,
ExistingDevice   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpAttachDeviceToDeviceStack(NewDevice, ExistingDevice);\ }\ }

Definition at line 676 of file trackirp.h.

Referenced by IovAttachDeviceToDeviceStack().

#define SPECIALIRP_IO_CANCEL_IRP Irp,
CancelHandled,
ReturnValue   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCancelIrp((Irp), (CancelHandled), (ReturnValue));\ } else { \ *(CancelHandled) = FALSE ; \ } \ }

Definition at line 619 of file trackirp.h.

Referenced by IovCancelIrp().

#define SPECIALIRP_IO_DELETE_DEVICE Device   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpDeleteDevice(Device);\ }\ }

Definition at line 669 of file trackirp.h.

Referenced by IovDeleteDevice().

#define SPECIALIRP_IO_DETACH_DEVICE TargetDevice   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpDetachDevice(TargetDevice);\ }\ }

Definition at line 683 of file trackirp.h.

Referenced by IovDetachDevice().

#define SPECIALIRP_IO_FREE_IRP Irp,
FreeHandled   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpFreeIrp((Irp), (FreeHandled));\ } else { \ *(FreeHandled) = FALSE ; \ } \ }

Definition at line 635 of file trackirp.h.

Referenced by IovFreeIrpPrivate().

#define SPECIALIRP_IO_INITIALIZE_IRP Irp,
PacketSize,
StackSize,
InitHandled   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpInitializeIrp((Irp), (PacketSize), (StackSize), (InitHandled));\ } else { \ *(InitHandled) = FALSE ; \ }\ }

Definition at line 660 of file trackirp.h.

Referenced by IovInitializeIrp().

#define SPECIALIRP_IOF_CALL_1 pIrp,
DeviceObject,
st1   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCallDriver1((pIrp), (DeviceObject), (st1));\ IovpSeedStack() ; \ } else { \ (st1)->IovSessionData = NULL ; \ SPECIALIRP_MARK_NON_TRACKABLE(*pIrp); \ } \ }

Definition at line 564 of file trackirp.h.

Referenced by IovSpecialIrpCallDriver().

#define SPECIALIRP_IOF_CALL_2 Irp,
DeviceObject,
Routine,
FinalStatus,
st1   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCallDriver2((Irp), (DeviceObject), (Routine), (FinalStatus), (st1));\ } \ }

Definition at line 575 of file trackirp.h.

Referenced by IovSpecialIrpCallDriver().

#define SPECIALIRP_IOF_COMPLETE_1 Irp,
PriorityBoost,
CompletionPacket   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequest1((Irp), (PriorityBoost), (CompletionPacket));\ } else { \ (CompletionPacket)->IovSessionData = NULL ; \ } \ }

Definition at line 582 of file trackirp.h.

#define SPECIALIRP_IOF_COMPLETE_2 Irp,
CompletionPacket   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequest2((Irp), (CompletionPacket));\ } \ }

Definition at line 591 of file trackirp.h.

#define SPECIALIRP_IOF_COMPLETE_3 Irp,
Routine,
CompletionPacket   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequest3((Irp), (Routine), (CompletionPacket));\ } \ }

Definition at line 598 of file trackirp.h.

#define SPECIALIRP_IOF_COMPLETE_4 Irp,
ReturnedStatus,
CompletionPacket   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequest4((Irp), (ReturnedStatus), (CompletionPacket));\ } \ }

Definition at line 605 of file trackirp.h.

#define SPECIALIRP_IOF_COMPLETE_5 Irp,
CompletionPacket   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequest5((Irp), (CompletionPacket));\ } \ }

Definition at line 612 of file trackirp.h.

#define SPECIALIRP_IOP_COMPLETE_REQUEST Irp,
StackPointer   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpCompleteRequestApc(Irp, StackPointer);\ }\ }

Definition at line 697 of file trackirp.h.

#define SPECIALIRP_MARK_NON_TRACKABLE Irp   ) 
 

Value:

{ \ (Irp)->Flags |= IRPFLAG_EXAMINE_NOT_TRACKED; \ }

Definition at line 560 of file trackirp.h.

#define SPECIALIRP_WATERMARK_IRP Irp,
Flags   ) 
 

Value:

{\ if (IovpTrackingFlags && IovpDoAssertIrps()) { \ IovpWatermarkIrp(Irp, Flags);\ }\ }

Definition at line 690 of file trackirp.h.

Referenced by IopAsynchronousCall(), IopEjectDevice(), IopFilterResourceRequirementsCall(), IopSynchronousCall(), and IovpThrowBogusSynchronousIrp().

#define STACKFLAG_CHECK_FOR_REFERENCE   0x20000000
 

Definition at line 96 of file trackirp.h.

Referenced by IovpAssertIrpStackUpward(), and IovpAssertNewRequest().

#define STACKFLAG_FIRST_REQUEST   0x08000000
 

Definition at line 98 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), IovpAssertNewRequest(), and IovpCallDriver1().

#define STACKFLAG_NO_HANDLER   0x80000000
 

Definition at line 94 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpAssertIrpStackUpward().

#define STACKFLAG_REACHED_PDO   0x10000000
 

Definition at line 97 of file trackirp.h.

Referenced by IovpAssertIrpStackUpward(), and IovpCallDriver1().

#define STACKFLAG_REQUEST_COMPLETED   0x40000000
 

Definition at line 95 of file trackirp.h.

Referenced by IovpCompleteRequest2().

#define STARTED_INSIDE_STACK   4
 

Definition at line 120 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpExamineDevObjForwarding().

#define STARTED_TOP_OF_STACK   1
 

Definition at line 117 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), and IovpExamineDevObjForwarding().

#define TRACKFLAG_ACTIVE   0x00000001
 

Definition at line 70 of file trackirp.h.

Referenced by IovpCallDriver1(), IovpCancelIrp(), IovpSessionDataAttachSurrogate(), IovpSessionDataCreate(), and IovpTrackingDataGetCurrentSessionData().

#define TRACKFLAG_BOGUS   0x00000020
 

Definition at line 76 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), IovpAssertIrpStackUpward(), and IovpWatermarkIrp().

#define TRACKFLAG_HAS_SURROGATE   0x00000004
 

Definition at line 72 of file trackirp.h.

Referenced by IovpCancelIrp(), and IovpSessionDataAttachSurrogate().

#define TRACKFLAG_IN_TRANSIT   0x40000000
 

Definition at line 85 of file trackirp.h.

#define TRACKFLAG_IO_ALLOCATED   0x00200000
 

Definition at line 81 of file trackirp.h.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), IovpAssertNewRequest(), IovpFreeIrp(), and IovpInitializeIrp().

#define TRACKFLAG_PASSED_AT_BAD_IRQL   0x02000000
 

Definition at line 84 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward().

#define TRACKFLAG_PASSED_FAILURE   0x01000000
 

Definition at line 83 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward(), IovpAssertNewRequest(), and IovpSessionDataCreate().

#define TRACKFLAG_PROTECTEDIRP   0x00000008
 

Definition at line 73 of file trackirp.h.

Referenced by IovpAllocateIrp1(), and IovpFreeIrp().

#define TRACKFLAG_QUEUED_INTERNALLY   0x00000010
 

Definition at line 75 of file trackirp.h.

Referenced by IovpCallDriver1(), IovpCancelIrp(), IovpCompleteRequest1(), IovpInternalCompleteAfterWait(), IovpInternalDeferredCompletion(), and IovpSessionDataCreate().

#define TRACKFLAG_RELEASED   0x00000040
 

Definition at line 77 of file trackirp.h.

Referenced by IovpSessionDataCreate().

#define TRACKFLAG_REMOVED_FROM_TABLE   0x80000000
 

Definition at line 86 of file trackirp.h.

Referenced by IovpTrackingDataFree().

#define TRACKFLAG_SRB_MUNGED   0x00000080
 

Definition at line 78 of file trackirp.h.

Referenced by IovpSessionDataAttachSurrogate(), and IovpSessionDataCreate().

#define TRACKFLAG_SURROGATE   0x00000002
 

Definition at line 71 of file trackirp.h.

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

#define TRACKFLAG_SWAPPED_BACK   0x00000100
 

Definition at line 79 of file trackirp.h.

Referenced by IovpSessionDataCreate(), and IovpSwapSurrogateIrp().

#define TRACKFLAG_UNWOUND_BADLY   0x00400000
 

Definition at line 82 of file trackirp.h.

Referenced by IovpCallDriver2(), and IovpFreeIrp().

#define TRACKFLAG_WATERMARKED   0x00100000
 

Definition at line 80 of file trackirp.h.

Referenced by IovpAssertNewRequest(), and IovpWatermarkIrp().

#define TRACKIRP_DBGPRINT txt,
level   ) 
 

Definition at line 712 of file trackirp.h.

Referenced by IovpAdvanceStackDownwards(), IovpCallDriver1(), IovpCallDriver2(), IovpCompleteRequest1(), IovpCompleteRequest2(), IovpSessionDataClose(), IovpSessionDataCreate(), IovpSessionDataDereference(), IovpSessionDataReference(), IovpSwapSurrogateIrp(), IovpTrackingDataCreateAndLock(), IovpTrackingDataDereference(), IovpTrackingDataFindAndLock(), IovpTrackingDataFree(), and IovpTrackingDataReference().


Typedef Documentation

typedef struct _DEFERRAL_CONTEXT DEFERRAL_CONTEXT
 

Referenced by IovpCompleteRequest3().

typedef struct _IOFCALLDRIVER_STACKDATA IOFCALLDRIVER_STACKDATA
 

Referenced by IovpCallDriver1(), and IovSpecialIrpCallDriver().

typedef struct _IOFCOMPLETEREQUEST_STACKDATA IOFCOMPLETEREQUEST_STACKDATA
 

typedef struct _IOV_REQUEST_PACKET IOV_REQUEST_PACKET
 

Referenced by IovpSessionDataAttachSurrogate(), and IovpTrackingDataCreateAndLock().

typedef struct _IOV_SESSION_DATA IOV_SESSION_DATA
 

Referenced by IovpSessionDataCreate().

typedef struct _IOV_STACK_LOCATION IOV_STACK_LOCATION
 

Referenced by IovpSessionDataCreate(), and IovpTrackingDataCreateAndLock().

typedef struct _DEFERRAL_CONTEXT * PDEFERRAL_CONTEXT
 

Referenced by IovpCompleteRequest3().

typedef struct _IOFCALLDRIVER_STACKDATA* PIOFCALLDRIVER_STACKDATA
 

Definition at line 139 of file trackirp.h.

Referenced by IovpCallDriver1().

typedef struct _IOFCOMPLETEREQUEST_STACKDATA * PIOFCOMPLETEREQUEST_STACKDATA
 

Referenced by IovpCompleteRequest1().

typedef struct _IOV_REQUEST_PACKET* PIOV_REQUEST_PACKET
 

Definition at line 141 of file trackirp.h.

Referenced by IovpAssertNewIrps(), and IovpSessionDataCreate().

typedef struct _IOV_SESSION_DATA* PIOV_SESSION_DATA
 

Definition at line 142 of file trackirp.h.

Referenced by IovpAssertIrpStackDownward().

typedef struct _IOV_STACK_LOCATION* PIOV_STACK_LOCATION
 

Definition at line 140 of file trackirp.h.

Referenced by IovpAssertNewIrps(), and IovpCallDriver1().


Enumeration Type Documentation

enum DEFER_ACTION
 

Enumeration values:
DEFERACTION_QUEUE_WORKITEM 
DEFERACTION_QUEUE_PASSIVE_TIMER 
DEFERACTION_QUEUE_DISPATCH_TIMER 
DEFERACTION_NORMAL 

Definition at line 126 of file trackirp.h.

Referenced by IovpInternalDeferredCompletion().


Function Documentation

BOOLEAN IovpAdvanceStackDownwards IN PIOV_STACK_LOCATION  StackDataArray,
IN CCHAR  CurrentLocation,
IN PIO_STACK_LOCATION  IrpSp,
IN PIO_STACK_LOCATION IrpLastSp  OPTIONAL,
IN ULONG  LocationsAdvanced,
IN BOOLEAN  IsNewRequest,
IN BOOLEAN  MarkAsTaken,
OUT PIOV_STACK_LOCATION StackLocationInfo
 

Definition at line 2023 of file trackirp.c.

References ASSERT, _IOV_STACK_LOCATION::CallStackData, _IOV_STACK_LOCATION::InUse, _IOV_STACK_LOCATION::IrpSp, _IOV_STACK_LOCATION::LastDispatch, NULL, _IOV_STACK_LOCATION::PerfDispatchStart, _IOV_STACK_LOCATION::PerfStackLocationStart, _IOV_STACK_LOCATION::RequestsFirstStackLocation, TRACKIRP_DBGPRINT, and TRUE.

Referenced by IovpCallDriver1(), and IovpCompleteRequest1().

02033 { 02034 PIOV_STACK_LOCATION iovCurrentStackLocation, advancedLocationData, requestOriginalSLD; 02035 PIO_STACK_LOCATION irpSpTemp; 02036 PLARGE_INTEGER dispatchTime, stackTime; 02037 BOOLEAN isNewSession, wasInUse; 02038 PVOID dispatchRoutine; 02039 02040 isNewSession = (IrpLastSp == NULL); 02041 ASSERT((!isNewSession) || (LocationsAdvanced == 1)); 02042 ASSERT(isNewSession || ((ULONG) (IrpLastSp - IrpSp) == LocationsAdvanced)); 02043 02044 // 02045 // The CurrentLocation will be decremented when we leave. If it hit's zero 02046 // we will bugcheck, therefore it should be at least two, and we'd need to 02047 // subtract two off it to make it an index into an array of slot locations 02048 // (our analog for stack locations). However we reserve an extra empty slot 02049 // at the head of the array to make our logic easier. Therefore we subtract 02050 // only one. 02051 // 02052 iovCurrentStackLocation = StackDataArray + CurrentLocation -1; 02053 02054 TRACKIRP_DBGPRINT(( 02055 " Smacking %lx (%lx) to valid in SD\n", 02056 CurrentLocation -1, iovCurrentStackLocation 02057 ), 2); 02058 02059 // 02060 // Note that we do set the InUse field. That's for the caller to do. 02061 // 02062 if (iovCurrentStackLocation->InUse) { 02063 02064 // 02065 // The only way the stack slot could be in use is if we skipped before 02066 // 02067 ASSERT(!LocationsAdvanced); // && (!isNewSession) 02068 ASSERT(IrpSp == iovCurrentStackLocation->IrpSp); 02069 02070 } else if (MarkAsTaken) { 02071 02072 // 02073 // ADRIAO BUGBUG 01/02/1999 - 02074 // Is the below assertion is not true in the case of an internally 02075 // forwarded, completed, and then externally forwarded IRP? 02076 // 02077 ASSERT(LocationsAdvanced); // || isNewSession 02078 RtlZeroMemory(iovCurrentStackLocation, sizeof(IOV_STACK_LOCATION)); 02079 InitializeListHead(&iovCurrentStackLocation->CallStackData); 02080 iovCurrentStackLocation->IrpSp = IrpSp; 02081 } 02082 02083 // 02084 // Determine the last original request. A "Request" is block of data in a 02085 // stack location that is progressively copied downwards as the IRP is 02086 // forwarded (ie, a forwarded START IRP, a forwarded IOCTL, etc). A clever 02087 // driver writer could use his own stack location to send down a quick 02088 // query before forwarding along the original request. We correctly 02089 // differentiate between those two unique requests within the IRP below. 02090 // 02091 if (isNewSession) { 02092 02093 // 02094 // *We* are the original request. None of these fields below should 02095 // be used. 02096 // 02097 dispatchRoutine = NULL; 02098 requestOriginalSLD = NULL; 02099 stackTime = NULL; 02100 dispatchTime = NULL; 02101 02102 } else if (LocationsAdvanced) { 02103 02104 // 02105 // To get the original request (the pointer to the Irp slot that 02106 // represents where we *first* saw this request), we go backwards to get 02107 // the most recent previous irp slot data (set up when the device above 02108 // forwarded this Irp to us), and we read what it's original request was. 02109 // We also get the dispatch routine for that slot, which we will use to 02110 // backfill skipped slots if we advanced more than one Irp stack 02111 // location this time (ie, someone called IoSetNextIrpStackLocation). 02112 // 02113 dispatchTime = &iovCurrentStackLocation[LocationsAdvanced].PerfDispatchStart; 02114 stackTime = &iovCurrentStackLocation[LocationsAdvanced].PerfStackLocationStart; 02115 dispatchRoutine = iovCurrentStackLocation[LocationsAdvanced].LastDispatch; 02116 requestOriginalSLD = iovCurrentStackLocation[LocationsAdvanced].RequestsFirstStackLocation; 02117 02118 ASSERT(dispatchRoutine); 02119 ASSERT(iovCurrentStackLocation[LocationsAdvanced].InUse); 02120 ASSERT(requestOriginalSLD->RequestsFirstStackLocation == requestOriginalSLD); 02121 iovCurrentStackLocation->RequestsFirstStackLocation = requestOriginalSLD; 02122 02123 } else { 02124 02125 // 02126 // We skipped. The slot should already be filled. 02127 // 02128 dispatchRoutine = NULL; 02129 dispatchTime = NULL; 02130 stackTime = NULL; 02131 requestOriginalSLD = iovCurrentStackLocation->RequestsFirstStackLocation; 02132 ASSERT(requestOriginalSLD); 02133 ASSERT(requestOriginalSLD->RequestsFirstStackLocation == requestOriginalSLD); 02134 } 02135 02136 // 02137 // The previous request seen is in requestOriginalSLD (NULL if none). If 02138 // we advanced more than one stack location (ie, someone called 02139 // IoSetNextIrpStackLocation), we need to update the slots we never saw get 02140 // consumed. Note that the dispatch routine we set in the slot is for the 02141 // driver that owned the last slot - we do not use the device object at 02142 // that IrpSp because it might be stale (or perhaps even NULL). 02143 // 02144 advancedLocationData = iovCurrentStackLocation; 02145 irpSpTemp = IrpSp; 02146 while(LocationsAdvanced>1) { 02147 advancedLocationData++ ; 02148 LocationsAdvanced-- ; 02149 irpSpTemp++ ; 02150 TRACKIRP_DBGPRINT(( 02151 " Late smacking %lx to valid in CD1\n", 02152 advancedLocationData - StackDataArray 02153 ), 3) ; 02154 02155 ASSERT(!advancedLocationData->InUse) ; 02156 RtlZeroMemory(advancedLocationData, sizeof(IOV_STACK_LOCATION)) ; 02157 InitializeListHead(&advancedLocationData->CallStackData) ; 02158 advancedLocationData->InUse = TRUE ; 02159 advancedLocationData->IrpSp = irpSpTemp ; 02160 02161 advancedLocationData->RequestsFirstStackLocation = requestOriginalSLD ; 02162 advancedLocationData->PerfDispatchStart = *dispatchTime; 02163 advancedLocationData->PerfStackLocationStart = *stackTime; 02164 advancedLocationData->LastDispatch = dispatchRoutine ; 02165 } 02166 02167 // 02168 // For the assertion below... 02169 // 02170 if (LocationsAdvanced) { 02171 irpSpTemp++ ; 02172 } 02173 ASSERT((irpSpTemp == IrpLastSp)||(IrpLastSp == NULL)) ; 02174 02175 // 02176 // Write out the slot we're using. 02177 // 02178 *StackLocationInfo = iovCurrentStackLocation; 02179 02180 if (!MarkAsTaken) { 02181 return iovCurrentStackLocation->InUse; 02182 } 02183 02184 // 02185 // Record a pointer in this slot to the requests originating slot as 02186 // appropriate. 02187 // 02188 if (IsNewRequest) { 02189 02190 TRACKIRP_DBGPRINT(( 02191 " CD1: %lx is a new request\n", 02192 advancedLocationData-StackDataArray 02193 ), 3) ; 02194 02195 ASSERT(LocationsAdvanced == 1) ; 02196 // 02197 // ADRIAO BUGBUG 01/02/1999 - 02198 // 02199 // Why the **ll did I have this there? If this were correct then the 02200 // backfill logic above would need fixing. I think what I have now is 02201 // correct, not this: 02202 // 02203 // advancedLocationData->RequestsFirstStackLocation = advancedLocationData ; 02204 // 02205 iovCurrentStackLocation->RequestsFirstStackLocation = iovCurrentStackLocation; 02206 02207 } else if (LocationsAdvanced) { 02208 02209 ASSERT(!isNewSession) ; 02210 // 02211 // ADRIAO BUGBUG 01/02/1999 - 02212 // As per above, this should already have been handled. 02213 // 02214 //advancedLocationData->RequestsFirstStackLocation = requestOriginalSLD ; 02215 TRACKIRP_DBGPRINT(( 02216 " CD1: %lx is a request for %lx\n", 02217 advancedLocationData-StackDataArray, 02218 requestOriginalSLD-StackDataArray 02219 ), 3) ; 02220 02221 } else { 02222 02223 // 02224 // As we skipped, the request should not have changed. If it did, 02225 // either guy we called trashed the stack given to him (giving none 02226 // to the dude under him), or we incorrectly saw a new request when 02227 // we shouldn't have (see previous comment). 02228 // 02229 ASSERT(!isNewSession) ; 02230 ASSERT(advancedLocationData->RequestsFirstStackLocation == requestOriginalSLD) ; 02231 } 02232 02233 wasInUse = iovCurrentStackLocation->InUse; 02234 iovCurrentStackLocation->InUse = TRUE; 02235 return wasInUse; 02236 }

VOID FASTCALL IovpAllocateIrp1 IN CCHAR  StackSize,
IN BOOLEAN  ChargeQuota,
IN OUT PIRP IrpPointer
 

Definition at line 3132 of file trackirp.c.

References _IOV_REQUEST_PACKET::AllocatorStack, ASSERTFLAG_MONITOR_ALLOCS, ASSERTFLAG_POLICEIRPS, _IOV_REQUEST_PACKET::Flags, IopInitializeIrp, IoSizeOfIrp, IovpProtectedIrpAllocate(), IovpTrackingDataCreateAndLock(), IovpTrackingDataReference(), IovpTrackingDataReleaseLock(), IovpTrackingFlags, IOVREFTYPE_POINTER, IRP_ALLOC_COUNT, IRP_ALLOCATION_MONITORED, IRPFLAG_EXAMINE_TRACKED, NULL, PsGetCurrentThread, RtlCaptureStackBackTrace(), TRACKFLAG_IO_ALLOCATED, and TRACKFLAG_PROTECTEDIRP.

03139 : 03140 03141 This routine is called by IoAllocateIrp and returns an IRP iff 03142 we are handled the allocations ourselves. 03143 03144 We may need to do this internally so we can turn off IRP lookaside lists 03145 and use the special pool to catch people reusing free'd IRPs. 03146 03147 Arguments: 03148 03149 StackSize - Count of stack locations to allocate for this IRP. 03150 03151 ChargeQuote - TRUE if quote should be charged against the current 03152 thread. 03153 03154 IrpPointer - Pointer to IRP if one was allocated. This will 03155 point to NULL after the call iff IoAllocateIrp 03156 should use it's normal lookaside list code. 03157 03158 Return Value: 03159 03160 None. 03161 03162 --*/ 03163 { 03164 PIOV_REQUEST_PACKET iovPacket; 03165 PVOID returnAddress[1]; 03166 ULONG stackHash; 03167 PIRP irp; 03168 03169 *IrpPointer = NULL ; 03170 if (!(IovpTrackingFlags&ASSERTFLAG_MONITOR_ALLOCS)) { 03171 03172 return ; 03173 } 03174 03175 if (!(IovpTrackingFlags&ASSERTFLAG_POLICEIRPS)) { 03176 03177 return ; 03178 } 03179 03180 irp = IovpProtectedIrpAllocate( 03181 StackSize, 03182 ChargeQuota, 03183 PsGetCurrentThread() 03184 ) ; 03185 03186 if (irp == NULL) { 03187 03188 return; 03189 } 03190 03191 IopInitializeIrp(irp, IoSizeOfIrp(StackSize), StackSize); 03192 *IrpPointer = irp; 03193 03194 iovPacket = IovpTrackingDataCreateAndLock(irp); 03195 03196 if (iovPacket == NULL) { 03197 03198 return; 03199 } 03200 03201 IovpTrackingDataReference(iovPacket, IOVREFTYPE_POINTER); 03202 iovPacket->Flags |= TRACKFLAG_PROTECTEDIRP | TRACKFLAG_IO_ALLOCATED; 03203 irp->AllocationFlags |= IRP_ALLOCATION_MONITORED ; 03204 irp->Flags |= IRPFLAG_EXAMINE_TRACKED; 03205 03206 // 03207 // Record he who allocated this IRP (if we can get it) 03208 // 03209 RtlCaptureStackBackTrace(3, IRP_ALLOC_COUNT, iovPacket->AllocatorStack, &stackHash) ; 03210 03211 IovpTrackingDataReleaseLock(iovPacket) ; 03212 }

VOID FASTCALL IovpAllocateIrp2 IN PIRP  Irp  ) 
 

Definition at line 3216 of file trackirp.c.

References _IRP::AllocationFlags, _IOV_REQUEST_PACKET::AllocatorStack, ASSERTFLAG_MONITOR_ALLOCS, _IRP::Flags, _IOV_REQUEST_PACKET::Flags, IovpTrackingDataCreateAndLock(), IovpTrackingDataReference(), IovpTrackingDataReleaseLock(), IovpTrackingFlags, IOVREFTYPE_POINTER, Irp, IRP_ALLOC_COUNT, IRP_ALLOCATION_MONITORED, IRPFLAG_EXAMINE_TRACKED, NULL, RtlCaptureStackBackTrace(), and TRACKFLAG_IO_ALLOCATED.

03221 : 03222 03223 This routine is called by IoAllocateIrp and captures information if 03224 the IRP was allocated by the OS. 03225 03226 Arguments: 03227 03228 Irp - Pointer to IRP 03229 03230 Return Value: 03231 03232 None. 03233 03234 --*/ 03235 { 03236 PIOV_REQUEST_PACKET iovPacket; 03237 PVOID returnAddress[1]; 03238 ULONG stackHash; 03239 03240 if (!(IovpTrackingFlags&ASSERTFLAG_MONITOR_ALLOCS)) { 03241 03242 return; 03243 } 03244 03245 // ASSERT(!(IovpTrackingFlags&ASSERTFLAG_POLICEIRPS)); 03246 03247 iovPacket = IovpTrackingDataCreateAndLock(Irp); 03248 if (iovPacket == NULL) { 03249 03250 return; 03251 } 03252 03253 IovpTrackingDataReference(iovPacket, IOVREFTYPE_POINTER); 03254 iovPacket->Flags |= TRACKFLAG_IO_ALLOCATED; 03255 Irp->AllocationFlags |= IRP_ALLOCATION_MONITORED; 03256 Irp->Flags |= IRPFLAG_EXAMINE_TRACKED; 03257 03258 // 03259 // Record he who allocated this IRP (if we can get it) 03260 // 03261 RtlCaptureStackBackTrace(2, IRP_ALLOC_COUNT, iovPacket->AllocatorStack, &stackHash) ; 03262 03263 IovpTrackingDataReleaseLock(iovPacket) ; 03264 }

VOID FASTCALL IovpAssertNonLegacyDevice IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  StackFramesToSkip,
IN PUCHAR  FailureTxt
 

Definition at line 3680 of file trackirp.c.

References ASSERT, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_LEGACY_DRIVER, _DEVICE_NODE::Flags, IovpGetLowestDevice(), and ObDereferenceObject.

03688 { 03689 PDEVICE_OBJECT pdoDeviceObject ; 03690 PDEVICE_NODE pDevNode ; 03691 03692 pdoDeviceObject = IovpGetLowestDevice(DeviceObject) ; 03693 03694 if (pdoDeviceObject) { 03695 03696 pDevNode = pdoDeviceObject->DeviceObjectExtension->DeviceNode ; 03697 if (pDevNode&&(!(pDevNode->Flags&DNF_LEGACY_DRIVER))) { 03698 03699 // 03700 // ADRIAO BUGBUG 12/30/98 - More stuff to fix... 03701 // 03702 ASSERT(0); 03703 /* 03704 WDM_FAIL_CALLER( 03705 (FailureTxt), 03706 StackFramesToSkip+1, 03707 NULL 03708 ); 03709 */ 03710 } 03711 ObDereferenceObject(pdoDeviceObject) ; 03712 } 03713 }

VOID IovpAttachDeviceToDeviceStack IN PDEVICE_OBJECT  NewDevice,
IN PDEVICE_OBJECT  ExistingDevice
 

Definition at line 3346 of file trackirp.c.

03350 { 03351 }

VOID FASTCALL IovpCallDriver1 IN OUT PIRP IrpPointer,
IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIOFCALLDRIVER_STACKDATA  IofCallDriverStackData
 

Definition at line 493 of file trackirp.c.

References ASSERT, ASSERTFLAG_MONITORMAJORS, ASSERTFLAG_POLICEIRPS, ASSERTFLAG_TRACKIRPS, _IOV_REQUEST_PACKET::AssertFlags, CALLFLAG_IS_REMOVE_IRP, CALLFLAG_REMOVING_FDO_STACK_DO, CALLFLAG_TOPMOST_IN_SLOT, _IOV_STACK_LOCATION::CallStackData, _IRP::Cancel, _IRP::CancelRoutine, _IO_STACK_LOCATION::Control, _IRP::CurrentLocation, DCERROR_CANCELROUTINE_FORWARDED, DCERROR_NULL_DEVOBJ_FORWARDED, DCERROR_QUEUED_IRP_FORWARDED, DCPARAM_IRP, _IOV_SESSION_DATA::DeviceLastCalled, DOE_RAW_FDO, FAIL_CALLER_OF_IOFCALLDRIVER, FALSE, _IOV_STACK_LOCATION::Flags, _IOV_REQUEST_PACKET::Flags, _IRP::Flags, _IOV_SESSION_DATA::ForwardMethod, _IOV_STACK_LOCATION::InitialStatusBlock, IOFCALLDRIVER_STACKDATA, IoGetNextIrpStackLocation, IoSetNextIrpStackLocation, IoSkipCurrentIrpStackLocation, _IRP::IoStatus, IOVERIFIERINIT_RANDOMLY_CANCEL_IRPS, IovpAdvanceStackDownwards(), IovpAssertIrpStackDownward(), IovpAssertIsNewRequest(), IovpAssertNewIrps(), IovpAssertNewRequest(), IovpCancelCount, IovpExamineDevObjForwarding(), IovpExamineIrpStackForwarding(), IovpGetDeviceAttachedTo(), IovpGetLowestDevice(), IovpInitFlags, IovpIsInFdoStack(), IovpSessionDataAdvance(), IovpSessionDataCreate(), IovpSessionDataReference(), IovpTrackingDataCreateAndLock(), IovpTrackingDataFindAndLock(), IovpTrackingDataGetCurrentSessionData(), IovpTrackingDataReference(), IovpTrackingDataReleaseLock(), IovpTrackingFlags, IOVREFTYPE_POINTER, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, IRP_PAGING_IO, IRPFLAG_EXAMINE_MASK, IRPFLAG_EXAMINE_NOT_TRACKED, IRPFLAG_EXAMINE_TRACKED, IRPFLAG_EXAMINE_UNMARKED, KeQuerySystemTime(), _IOV_STACK_LOCATION::LastDispatch, _IOV_REQUEST_PACKET::LastLocation, _IOV_STACK_LOCATION::LastStatusBlock, _IO_STACK_LOCATION::MajorFunction, _DRIVER_OBJECT::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NULL, ObDereferenceObject, _IOV_STACK_LOCATION::PerfDispatchStart, _IOV_STACK_LOCATION::PerfStackLocationStart, PIOFCALLDRIVER_STACKDATA, PIOV_STACK_LOCATION, PsGetCurrentThread, _IOV_STACK_LOCATION::RequestsFirstStackLocation, SL_NOTCOPIED, _IOV_SESSION_DATA::StackData, STACKFLAG_FIRST_REQUEST, STACKFLAG_REACHED_PDO, _IOV_STACK_LOCATION::ThreadDispatchedTo, _IOV_REQUEST_PACKET::TrackedIrp, TRACKFLAG_ACTIVE, TRACKFLAG_QUEUED_INTERNALLY, TRACKIRP_DBGPRINT, and TRUE.

00500 : 00501 00502 This routine is called by IofCallDriver just before adjusting 00503 the IRP stack and calling the driver's dispatch routine. 00504 00505 Arguments: 00506 00507 IrpPointer - a pointer* to the IRP passed in to 00508 IofCallDriver. This routine may 00509 change the pointer if a surrogate 00510 IRP is allocated. 00511 00512 DeviceObject - Device object passed into IofCallDriver. 00513 00514 IofCallDriverStackData - Pointer to a local variable on 00515 IofCallDriver's stack to store data. 00516 The stored information will be picked 00517 up by IovpCallDriver2, and 00518 may be adjusted at other times. 00519 00520 00521 Return Value: 00522 00523 None. 00524 00525 --*/ 00526 { 00527 PIOV_REQUEST_PACKET iovPacket; 00528 PIOV_SESSION_DATA iovSessionData; 00529 PIOV_STACK_LOCATION iovCurrentStackLocation; 00530 PIRP irp, replacementIrp; 00531 PIO_STACK_LOCATION irpSp, irpLastSp; 00532 BOOLEAN isNewSession, isNewRequest, previouslyInUse, surrogateSpawned; 00533 ULONG isSameStack; 00534 ULONG locationsAdvanced, completeStyle; 00535 PDEVICE_OBJECT pdo, lowerDeviceObject; 00536 PDRIVER_OBJECT driverObject; 00537 PVOID dispatchRoutine; 00538 00539 irp = *IrpPointer; 00540 irpSp = IoGetNextIrpStackLocation( irp ); 00541 00542 // 00543 // Preinitialize the CallStackData. 00544 // 00545 RtlZeroMemory(IofCallDriverStackData, sizeof(IOFCALLDRIVER_STACKDATA)); 00546 00547 // 00548 // If we are going to die shortly, kindly say so. 00549 // 00550 if (DeviceObject == NULL) { 00551 00552 FAIL_CALLER_OF_IOFCALLDRIVER( 00553 (DCERROR_NULL_DEVOBJ_FORWARDED, DCPARAM_IRP, irp), 00554 irpSp 00555 ); 00556 } 00557 00558 // 00559 // The examined flag is set on any IRP that has come through 00560 // IofCallDriver. We use the flag to detect whether we have seen the IRP 00561 // before. 00562 // 00563 switch(irp->Flags&IRPFLAG_EXAMINE_MASK) { 00564 00565 case IRPFLAG_EXAMINE_NOT_TRACKED: 00566 00567 // 00568 // This packet is marked do not touch. So we ignore it. 00569 // 00570 iovPacket = NULL; 00571 break; 00572 00573 case IRPFLAG_EXAMINE_TRACKED: 00574 00575 // 00576 // This packet has been marked. We should find it. 00577 // 00578 iovPacket = IovpTrackingDataFindAndLock(irp); 00579 ASSERT(iovPacket != NULL); 00580 break; 00581 00582 case IRPFLAG_EXAMINE_UNMARKED: 00583 00584 iovPacket = IovpTrackingDataFindAndLock(irp); 00585 if (iovPacket) { 00586 00587 // 00588 // Was tracked but cache flag got wiped. Replace. 00589 // 00590 irp->Flags |= IRPFLAG_EXAMINE_TRACKED; 00591 00592 } else if (IovpTrackingFlags&ASSERTFLAG_TRACKIRPS) { 00593 00594 // 00595 // Create the packet 00596 // 00597 iovPacket = IovpTrackingDataCreateAndLock(irp); 00598 if (iovPacket) { 00599 00600 // 00601 // Mark it 00602 // 00603 irp->Flags |= IRPFLAG_EXAMINE_TRACKED; 00604 } else { 00605 00606 // 00607 // No memory, try to keep it out of the IRP assert though. 00608 // 00609 irp->Flags |= IRPFLAG_EXAMINE_NOT_TRACKED; 00610 } 00611 } else { 00612 00613 // 00614 // Do as told, don't track through IofCallDriver. 00615 // 00616 irp->Flags |= IRPFLAG_EXAMINE_NOT_TRACKED; 00617 } 00618 break; 00619 00620 default: 00621 ASSERT(0); 00622 break; 00623 } 00624 00625 if (iovPacket == NULL) { 00626 00627 // 00628 // Nothing to track, get out. 00629 // 00630 return; 00631 } 00632 00633 // 00634 // Find the current session. The session terminates when the final top-level 00635 // completion routine gets called. 00636 // 00637 iovSessionData = IovpTrackingDataGetCurrentSessionData(iovPacket); 00638 00639 if (iovSessionData) { 00640 00641 ASSERT(iovPacket->Flags&TRACKFLAG_ACTIVE); 00642 isNewSession = FALSE; 00643 00644 IovpSessionDataAdvance( 00645 DeviceObject, 00646 iovSessionData, // This param is optional. 00647 &iovPacket, 00648 &surrogateSpawned 00649 ); 00650 00651 } else if (!(iovPacket->Flags&TRACKFLAG_ACTIVE)){ 00652 00653 iovPacket->Flags |= TRACKFLAG_ACTIVE; 00654 isNewSession = TRUE; 00655 00656 iovSessionData = IovpSessionDataCreate( 00657 DeviceObject, 00658 &iovPacket, 00659 &surrogateSpawned 00660 ); 00661 00662 } else { 00663 00664 // 00665 // Might hit this path under low memory, or we are tracking allocations 00666 // but not the IRP sessions themselves. 00667 // 00668 } 00669 00670 // 00671 // Let IovpCallDriver2 know what it's tracking... 00672 // 00673 IofCallDriverStackData->IovSessionData = iovSessionData; 00674 00675 if (iovSessionData == NULL) { 00676 00677 IovpTrackingDataReleaseLock(iovPacket) ; 00678 return; 00679 } 00680 00681 if (surrogateSpawned) { 00682 00683 // 00684 // iovPacket was changed to cover the surrogate IRP. Update our own 00685 // local variable and IofCallDriver's local variable appropriately. 00686 // 00687 irp = iovPacket->TrackedIrp; 00688 irpSp = IoGetNextIrpStackLocation(irp); 00689 *IrpPointer = irp; 00690 } 00691 00692 if (isNewSession) { 00693 00694 IovpTrackingDataReference(iovPacket, IOVREFTYPE_POINTER); 00695 IovpSessionDataReference(iovSessionData); 00696 } 00697 00698 if (iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) { 00699 00700 // 00701 // If someone has given us an IRP with a cancel routine, beat them. Drivers 00702 // set cancel routines when they are going to be pending IRPs *themselves* 00703 // and should remove them before passing the IRP below. This is also true 00704 // as the driver will *not* call your cancel routine if he writes in his 00705 // own (which it may). Nor is the lower driver expected to put yours back 00706 // either... 00707 // 00708 if (irp->CancelRoutine) { 00709 00710 FAIL_CALLER_OF_IOFCALLDRIVER( 00711 (DCERROR_CANCELROUTINE_FORWARDED, DCPARAM_IRP, irp), 00712 irpSp 00713 ); 00714 00715 irp->CancelRoutine = NULL; 00716 } 00717 } 00718 00719 // 00720 // Now do any checking that requires tracking data. 00721 // 00722 if (iovPacket->Flags&TRACKFLAG_QUEUED_INTERNALLY) { 00723 00724 // 00725 // We internally queue irps to catch bugs. When we are doing this, we 00726 // force the stack returned status to STATUS_PENDING, and we queue the 00727 // irp and release it on a timer. We also may make the IRP non-touchable. 00728 // This particular caller is trying to forward an IRP he doesn't own, 00729 // and we didn't actually end up with an untouchable irp. 00730 // 00731 FAIL_CALLER_OF_IOFCALLDRIVER( 00732 (DCERROR_QUEUED_IRP_FORWARDED, DCPARAM_IRP, irp), 00733 irpSp 00734 ); 00735 } 00736 00737 // 00738 // Figure out how many stack locations we've moved up since we've last seen 00739 // this IRP, and determine if the stack locations were copied appropriately. 00740 // We also need to see exactly how the IRP was forwarded (down the stack, 00741 // to another stack, straight to the PDO, etc). 00742 // 00743 // ADRIAO BUGBUG #07 05/11/98 - The only way to truely detect this is to 00744 // attach a filter at every layer in stack. 00745 // This is left as an exercise for later. 00746 // 00747 IovpExamineDevObjForwarding( 00748 DeviceObject, 00749 iovSessionData->DeviceLastCalled, 00750 &iovSessionData->ForwardMethod 00751 ) ; 00752 00753 IovpExamineIrpStackForwarding( 00754 iovPacket, 00755 isNewSession, 00756 iovSessionData->ForwardMethod, 00757 DeviceObject, 00758 irp, 00759 &irpSp, 00760 &irpLastSp, 00761 &locationsAdvanced 00762 ); 00763 00764 TRACKIRP_DBGPRINT(( 00765 " CD1: Current, Last = (%x, %x)\n", 00766 irp->CurrentLocation, 00767 iovPacket->LastLocation 00768 ), 3) ; 00769 00770 // 00771 // Figure out whether this is a new request or not, and record a 00772 // pointer in this slot to the requests originating slot as appropriate. 00773 // 00774 isNewRequest = IovpAssertIsNewRequest(irpLastSp, irpSp); 00775 00776 // 00777 // Record information in our private stack locations and 00778 // write that back into the "stack" data itself... 00779 // 00780 previouslyInUse = IovpAdvanceStackDownwards( 00781 iovSessionData->StackData, 00782 irp->CurrentLocation, 00783 irpSp, 00784 irpLastSp, 00785 locationsAdvanced, 00786 isNewRequest, 00787 TRUE, 00788 &iovCurrentStackLocation 00789 ); 00790 00791 ASSERT(iovCurrentStackLocation); 00792 00793 if (previouslyInUse) { 00794 00795 ASSERT(!isNewRequest); 00796 ASSERT(!isNewSession); 00797 KeQuerySystemTime(&iovCurrentStackLocation->PerfDispatchStart) ; 00798 00799 } else { 00800 00801 IofCallDriverStackData->Flags = CALLFLAG_TOPMOST_IN_SLOT ; 00802 InitializeListHead(&IofCallDriverStackData->SharedLocationList) ; 00803 00804 KeQuerySystemTime(&iovCurrentStackLocation->PerfDispatchStart) ; 00805 KeQuerySystemTime(&iovCurrentStackLocation->PerfStackLocationStart) ; 00806 00807 // 00808 // Record the first thread this IRP slot was dispatched to. 00809 // 00810 iovCurrentStackLocation->ThreadDispatchedTo = PsGetCurrentThread(); 00811 if (isNewRequest) { 00812 00813 iovCurrentStackLocation->InitialStatusBlock = irp->IoStatus; 00814 iovCurrentStackLocation->LastStatusBlock = irp->IoStatus; 00815 if (isNewSession) { 00816 00817 iovCurrentStackLocation->Flags |= STACKFLAG_FIRST_REQUEST; 00818 } 00819 } 00820 } 00821 00822 // 00823 // Record whether this is the last device object for this IRP... 00824 // PDO's have devnodes filled out, so look for that field. 00825 // Actually, we can't quite do that trick as during Bus 00826 // enumeration a bus filter might be sending down Irps before 00827 // the OS has ever seen the node. So we assume a devobj is a 00828 // PDO if he has never attached to anyone. 00829 // 00830 lowerDeviceObject = IovpGetDeviceAttachedTo(DeviceObject) ; 00831 if (lowerDeviceObject) { 00832 ObDereferenceObject(lowerDeviceObject) ; 00833 } else { 00834 iovCurrentStackLocation->Flags |= STACKFLAG_REACHED_PDO ; 00835 } 00836 00837 // 00838 // Record who is getting this IRP (we will blame any mistakes on him 00839 // if this request gets completed.) Note that we've already asserted 00840 // DeviceObject is non-NULL... 00841 // 00842 driverObject = DeviceObject->DriverObject ; 00843 dispatchRoutine = driverObject->MajorFunction[irpSp->MajorFunction] ; 00844 iovCurrentStackLocation->LastDispatch = dispatchRoutine ; 00845 00846 // 00847 // Uncomplete the request if we are heading back down with it... 00848 // 00849 iovCurrentStackLocation->Flags &=~ STACKFLAG_REQUEST_COMPLETED ; 00850 00851 // 00852 // This IofCallDriver2 dude will need to be told what his status should 00853 // be later. Add him to the linked list of addresses to scribble away 00854 // stati when the appropriate level is completed. 00855 // 00856 InsertHeadList( 00857 &iovCurrentStackLocation->CallStackData, 00858 &IofCallDriverStackData->SharedLocationList 00859 ) ; 00860 00861 // 00862 // More IofCallDriver2 stuff, tell him the stack location. 00863 // 00864 IofCallDriverStackData->IovStackLocation = iovCurrentStackLocation ; 00865 00866 // If it's a remove IRP, mark everyone appropriately 00867 if ((irpSp->MajorFunction == IRP_MJ_PNP)&& 00868 (irpSp->MinorFunction == IRP_MN_REMOVE_DEVICE)) { 00869 00870 IofCallDriverStackData->Flags |= CALLFLAG_IS_REMOVE_IRP ; 00871 00872 pdo = IovpGetLowestDevice(DeviceObject) ; 00873 ASSERT(pdo) ; 00874 IofCallDriverStackData->RemovePdo = pdo ; 00875 ObDereferenceObject(pdo) ; 00876 if (IovpIsInFdoStack(DeviceObject) && 00877 (!(DeviceObject->DeviceObjectExtension->ExtensionFlags&DOE_RAW_FDO))) { 00878 IofCallDriverStackData->Flags |= CALLFLAG_REMOVING_FDO_STACK_DO ; 00879 } 00880 } 00881 00882 if ((iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) && 00883 (iovPacket->AssertFlags&ASSERTFLAG_MONITORMAJORS)) { 00884 00885 // 00886 // Do IRP-major specific assertions as appropriate 00887 // 00888 if (isNewSession) { 00889 00890 IovpAssertNewIrps(iovPacket, irpSp, iovCurrentStackLocation) ; 00891 } 00892 00893 if (isNewRequest) { 00894 00895 IovpAssertNewRequest(iovPacket, DeviceObject, irpLastSp, irpSp, iovCurrentStackLocation) ; 00896 } 00897 00898 IovpAssertIrpStackDownward(iovPacket, DeviceObject, irpLastSp, irpSp, iovCurrentStackLocation) ; 00899 } 00900 00901 // 00902 // Update our fields 00903 // 00904 iovSessionData->DeviceLastCalled = DeviceObject ; 00905 iovPacket->LastLocation = irp->CurrentLocation ; 00906 iovCurrentStackLocation->RequestsFirstStackLocation->LastStatusBlock = irp->IoStatus; 00907 00908 // 00909 // Dope the next stack location so we can detect usage of 00910 // IoCopyCurrentIrpStackLocationToNext or IoSetCompletionRoutine. 00911 // 00912 if (irp->CurrentLocation>1) { 00913 IoSetNextIrpStackLocation( irp ) ; 00914 irpSp = IoGetNextIrpStackLocation( irp ); 00915 irpSp->Control |= SL_NOTCOPIED ; 00916 IoSkipCurrentIrpStackLocation( irp ) ; 00917 } 00918 00919 // 00920 // Randomly set the cancel flag on a percentage of forwarded IRPs. Many 00921 // drivers queue first and after dequeue assume the cancel routine they 00922 // set must have been cleared if Cancel = TRUE. They don't handle the case 00923 // were the Irp was cancelled in flight. 00924 // 00925 // ADRIAO BUGBUG 07/16/1999 - 00926 // Do better spontaneous cancel logic later. 00927 // 00928 if ((IovpInitFlags & IOVERIFIERINIT_RANDOMLY_CANCEL_IRPS) && 00929 (!(irp->Flags & IRP_PAGING_IO))) { 00930 00931 if (((++IovpCancelCount) % 4000) == 0) { 00932 00933 irp->Cancel = TRUE; 00934 } 00935 } 00936 00937 // 00938 // Assert LastLocation is consistent with an IRP that may be completed. 00939 // 00940 ASSERT(iovSessionData->StackData[iovPacket->LastLocation-1].InUse) ; 00941 00942 IovpSessionDataReference(iovSessionData); 00943 IovpTrackingDataReleaseLock(iovPacket) ; 00944 }

VOID FASTCALL IovpCallDriver2 IN PIRP  Irp,
IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Routine,
IN OUT NTSTATUS *  FinalStatus,
IN PIOFCALLDRIVER_STACKDATA  IofCallDriverStackData
 

Definition at line 948 of file trackirp.c.

References ASSERT, ASSERTFLAG_FORCEPENDING, ASSERTFLAG_POLICEIRPS, _IOV_SESSION_DATA::AssertFlags, _IOV_SESSION_DATA::BestVisibleIrp, CALLFLAG_COMPLETED, CALLFLAG_IS_REMOVE_IRP, CALLFLAG_OVERRIDE_STATUS, CALLFLAG_REMOVING_FDO_STACK_DO, _IOV_STACK_LOCATION::CallStackData, DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED, DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED, DCERROR_DELETED_PRESENT_PDO, DCERROR_INCONSISTANT_STATUS, DCERROR_IRP_RETURNED_WITHOUT_COMPLETION, DCERROR_SHOULDVE_DELETED, DCERROR_SHOULDVE_DETACHED, DCERROR_UNINITIALIZED_STATUS, DCPARAM_DEVOBJ, DCPARAM_IRP, DCPARAM_ROUTINE, DCPARAM_STATUS, DNF_DEVICE_GONE, DOE_DELETE_PENDING, FALSE, _IOV_REQUEST_PACKET::Flags, _DEVICE_NODE::Flags, _IOV_STACK_LOCATION::InUse, IovpGetDeviceAttachedTo(), IovpSessionDataDereference(), IovpTrackingDataAcquireLock(), IovpTrackingDataReleaseLock(), _IOV_SESSION_DATA::IovRequestPacket, NTSTATUS(), NULL, ObDereferenceObject, PsGetCurrentThread, SESSIONFLAG_UNWOUND_INCONSISTANT, _IOV_SESSION_DATA::SessionFlags, _IOV_STACK_LOCATION::ThreadDispatchedTo, TRACKFLAG_UNWOUND_BADLY, TRACKIRP_DBGPRINT, TRUE, and WDM_FAIL_ROUTINE.

00957 : 00958 00959 This routine is called by IofCallDriver just after the driver's dispatch 00960 routine has been called. The IRP may not be touchable at this time. 00961 00962 Arguments: 00963 00964 Irp - A pointer to the IRP passed into IofCallDriver. 00965 The IRP may not be touchable right now. 00966 00967 DispatchRoutine - Dispatch routine that was called by IofCallDriver. 00968 00969 FinalStatus - A pointer to the status returned by the dispatch 00970 routine. This may be changed if all IRPs are being 00971 forced "pending". 00972 00973 IofCallDriverStackData - Pointer to a local variable on IofCallDriver's 00974 stack to retreive data stored by 00975 IovpCallDriver1. 00976 00977 Return Value: 00978 00979 None. 00980 00981 --*/ 00982 { 00983 NTSTATUS status, lastStatus; 00984 PIOV_REQUEST_PACKET iovPacket; 00985 PIOV_SESSION_DATA iovSessionData; 00986 ULONG refCount; 00987 PIOV_STACK_LOCATION iovCurrentStackLocation; 00988 BOOLEAN mustDetachAndDelete; 00989 PDEVICE_NODE devNode; 00990 PDEVICE_OBJECT lowerDevObj; 00991 00992 iovSessionData = IofCallDriverStackData->IovSessionData; 00993 if (iovSessionData == NULL) { 00994 00995 return; 00996 } 00997 00998 iovPacket = iovSessionData->IovRequestPacket; 00999 ASSERT(iovPacket); 01000 IovpTrackingDataAcquireLock(iovPacket); 01001 01002 // 01003 // ADRIAO BUGBUG 08/10/1999 - 01004 // This needs to be reenabled once the DNF_ flags are used in a 01005 // consistant manner. 01006 // 01007 #if 0 01008 if (iovSessionData->AssertFlags&ASSERTFLAG_POLICEIRPS) { 01009 01010 if (IofCallDriverStackData->Flags&CALLFLAG_IS_REMOVE_IRP) { 01011 01012 if ((*FinalStatus != STATUS_PENDING) && 01013 (iovCurrentStackLocation->ThreadDispatchedTo == PsGetCurrentThread())) { 01014 01015 lowerDevObj = IovpGetDeviceAttachedTo(DeviceObject) ; 01016 01017 // 01018 // We can look at this because the caller has committed to this being 01019 // completed now, and we are on the original thread. 01020 // 01021 // N.B. This works because all the objects in the stack have been 01022 // referenced during a remove. If we decide to only reference the 01023 // top object, this logic would break... 01024 // 01025 if (IofCallDriverStackData->Flags&CALLFLAG_REMOVING_FDO_STACK_DO) { 01026 01027 // 01028 // FDO, Upper, & Lower filters *must* go. Note that lowerDevObj 01029 // should be null as we should have detached. 01030 // 01031 mustDetachAndDelete = TRUE ; 01032 01033 } else { 01034 01035 devNode = IofCallDriverStackData->RemovePdo->DeviceObjectExtension->DeviceNode ; 01036 ASSERT(devNode) ; 01037 01038 if (devNode->Flags & DNF_DEVICE_GONE) { 01039 01040 // 01041 // It's been reported as missing. It *must* go! 01042 // 01043 mustDetachAndDelete = TRUE ; 01044 01045 } else { 01046 01047 // 01048 // It must stay! 01049 // 01050 mustDetachAndDelete = FALSE ; 01051 } 01052 } 01053 01054 if (mustDetachAndDelete) { 01055 01056 // 01057 // IoDetachDevice and IoDeleteDevice should have been called. 01058 // First verify IoDetachDevice... 01059 // 01060 if (lowerDevObj) { 01061 01062 WDM_FAIL_ROUTINE(( 01063 DCERROR_SHOULDVE_DETACHED, 01064 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, 01065 iovSessionData->BestVisibleIrp, 01066 DispatchRoutine, 01067 DeviceObject 01068 )); 01069 } 01070 01071 // 01072 // Now verify IoDeleteDevice 01073 // 01074 if (!(DeviceObject->DeviceObjectExtension->ExtensionFlags&DOE_DELETE_PENDING)) { 01075 01076 WDM_FAIL_ROUTINE(( 01077 DCERROR_SHOULDVE_DELETED, 01078 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, 01079 iovSessionData->BestVisibleIrp, 01080 DispatchRoutine, 01081 DeviceObject 01082 )); 01083 } 01084 01085 } else { 01086 01087 // 01088 // Did we mistakenly leave? Verify we aren't a bus filter that 01089 // has been fooled. In that case, no checking can be done... 01090 // 01091 ASSERT(!(IofCallDriverStackData->Flags&CALLFLAG_REMOVING_FDO_STACK_DO)) ; 01092 01093 if (DeviceObject == IofCallDriverStackData->RemovePdo) { 01094 01095 // 01096 // Check PDO's - did we mistakenly delete ourselves? 01097 // 01098 if (DeviceObject->DeviceObjectExtension->ExtensionFlags&DOE_DELETE_PENDING) { 01099 01100 WDM_FAIL_ROUTINE(( 01101 DCERROR_DELETED_PRESENT_PDO, 01102 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, 01103 iovSessionData->BestVisibleIrp, 01104 DispatchRoutine, 01105 DeviceObject 01106 )); 01107 } 01108 01109 } else if (!(IofCallDriverStackData->RemovePdo->DeviceObjectExtension->ExtensionFlags&DOE_DELETE_PENDING)) { 01110 01111 // 01112 // Check bus filters. Bus filters better not have detached 01113 // or deleted themselves, as the PDO is still present! 01114 // 01115 if (lowerDevObj == NULL) { 01116 01117 // 01118 // Oops, it detached. Baad bus filter... 01119 // 01120 WDM_FAIL_ROUTINE(( 01121 DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED, 01122 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, 01123 iovSessionData->BestVisibleIrp, 01124 DispatchRoutine, 01125 DeviceObject 01126 )); 01127 } 01128 01129 if (DeviceObject->DeviceObjectExtension->ExtensionFlags&DOE_DELETE_PENDING) { 01130 01131 // 01132 // It deleted itself. Also very bad... 01133 // 01134 WDM_FAIL_ROUTINE(( 01135 DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED, 01136 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, 01137 iovSessionData->BestVisibleIrp, 01138 DispatchRoutine, 01139 DeviceObject 01140 )); 01141 } 01142 } 01143 } 01144 01145 if (lowerDevObj) { 01146 01147 ObDereferenceObject(lowerDevObj) ; 01148 } 01149 } 01150 } 01151 } 01152 #endif 01153 if (IofCallDriverStackData->Flags&CALLFLAG_COMPLETED) { 01154 01155 TRACKIRP_DBGPRINT(( 01156 " Verifying status in CD2\n" 01157 ),2) ; 01158 01159 if ((*FinalStatus != IofCallDriverStackData->ExpectedStatus)&& 01160 (*FinalStatus != STATUS_PENDING)) { 01161 01162 if ((iovSessionData->AssertFlags&ASSERTFLAG_POLICEIRPS) && 01163 (!(iovSessionData->SessionFlags&SESSIONFLAG_UNWOUND_INCONSISTANT))) { 01164 01165 01166 // 01167 // The completion routine and the return value don't match. Hey! 01168 // 01169 WDM_FAIL_ROUTINE(( 01170 DCERROR_INCONSISTANT_STATUS, 01171 DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_STATUS*2, 01172 iovSessionData->BestVisibleIrp, 01173 DispatchRoutine, 01174 IofCallDriverStackData->ExpectedStatus, 01175 *FinalStatus 01176 )); 01177 } 01178 01179 iovSessionData->SessionFlags |= SESSIONFLAG_UNWOUND_INCONSISTANT; 01180 01181 } else if (*FinalStatus == 0xFFFFFFFF) { 01182 01183 if (iovSessionData->AssertFlags&ASSERTFLAG_POLICEIRPS) { 01184 01185 01186 // 01187 // This status value is illegal. If we see it, we probably have 01188 // an uninitialized variable... 01189 // 01190 WDM_FAIL_ROUTINE(( 01191 DCERROR_UNINITIALIZED_STATUS, 01192 DCPARAM_IRP + DCPARAM_ROUTINE, 01193 iovSessionData->BestVisibleIrp, 01194 DispatchRoutine 01195 )); 01196 } 01197 } 01198 01199 // 01200 // We do not need to remove ourselves from the list because 01201 // we will not be completed twice (InUse is NULL makes sure). 01202 // 01203 01204 } else { 01205 01206 // 01207 // OK, we haven't completed yet. Status better 01208 // be pending... 01209 // 01210 TRACKIRP_DBGPRINT(( 01211 " Verifying status is STATUS_PENDING in CR2\n" 01212 ), 2) ; 01213 01214 if (*FinalStatus != STATUS_PENDING) { 01215 01216 if ((iovSessionData->AssertFlags&ASSERTFLAG_POLICEIRPS) && 01217 (!(iovPacket->Flags&TRACKFLAG_UNWOUND_BADLY))) { 01218 01219 // 01220 // We got control before this slot was completed. This is 01221 // legal as long as STATUS_PENDING was returned (it was not), 01222 // so it's bug time. Note that the IRP may not be safe to touch. 01223 // 01224 WDM_FAIL_ROUTINE(( 01225 DCERROR_IRP_RETURNED_WITHOUT_COMPLETION, 01226 DCPARAM_IRP + DCPARAM_ROUTINE, 01227 iovSessionData->BestVisibleIrp, 01228 DispatchRoutine 01229 )); 01230 } 01231 01232 iovPacket->Flags |= TRACKFLAG_UNWOUND_BADLY; 01233 } 01234 01235 iovCurrentStackLocation = (PIOV_STACK_LOCATION)(IofCallDriverStackData->IovStackLocation) ; 01236 ASSERT(iovCurrentStackLocation->InUse) ; 01237 ASSERT(!IsListEmpty(&iovCurrentStackLocation->CallStackData)) ; 01238 01239 // 01240 // We now extricate ourselves from the list. 01241 // 01242 RemoveEntryList(&IofCallDriverStackData->SharedLocationList) ; 01243 } 01244 01245 if ((IofCallDriverStackData->Flags&CALLFLAG_OVERRIDE_STATUS)&& 01246 (*FinalStatus != STATUS_PENDING)) { 01247 01248 *FinalStatus = IofCallDriverStackData->NewStatus ; 01249 } 01250 01251 if ((iovSessionData->AssertFlags&ASSERTFLAG_FORCEPENDING) && 01252 (!(IofCallDriverStackData->Flags&CALLFLAG_IS_REMOVE_IRP))) { 01253 01254 // 01255 // We also have the option of causing trouble by making every Irp 01256 // look as if were pending. 01257 // 01258 *FinalStatus = STATUS_PENDING ; 01259 } 01260 01261 IovpSessionDataDereference(iovSessionData); 01262 IovpTrackingDataReleaseLock(iovPacket); 01263 }

VOID FASTCALL IovpCancelIrp IN PIRP  Irp,
IN OUT PBOOLEAN  CancelHandled,
IN OUT PBOOLEAN  ReturnValue
 

VOID FASTCALL IovpCompleteRequest1 IN PIRP  Irp,
IN CCHAR  PriorityBoost,
IN OUT PIOFCOMPLETEREQUEST_STACKDATA  CompletionPacket
 

Definition at line 1267 of file trackirp.c.

References ASSERT, ASSERTFLAG_FORCEPENDING, _IOV_SESSION_DATA::AssertFlags, _IRP::CurrentLocation, DCERROR_QUEUED_IRP_COMPLETED, DCERROR_UNFORWARDED_IRP_COMPLETED, DCPARAM_IRP, _IOV_SESSION_DATA::DeviceLastCalled, FALSE, _IRP::Flags, _IOV_REQUEST_PACKET::Flags, IoGetCurrentIrpStackLocation, IoMarkIrpPending, IovpAdvanceStackDownwards(), IovpTrackingDataFindAndLock(), IovpTrackingDataGetCurrentSessionData(), IovpTrackingDataReleaseLock(), _IOV_SESSION_DATA::IovRequestPacket, Irp, IRP_DIAG_HAS_SURROGATE, _IOV_REQUEST_PACKET::LastLocation, NULL, PIOFCOMPLETEREQUEST_STACKDATA, _IOV_REQUEST_PACKET::PriorityBoost, PriorityBoost, _IRP::StackCount, _IOV_SESSION_DATA::StackData, TRACKFLAG_QUEUED_INTERNALLY, TRACKIRP_DBGPRINT, WDM_CHASTISE_CALLER3, and WDM_FAIL_CALLER3.

01280 : 01281 01282 Irp - A pointer to the IRP passed into 01283 IofCompleteRequest. 01284 01285 PriorityBoost - The priority boost passed into 01286 IofCompleteRequest. 01287 01288 CompletionPacket - A pointer to a local variable on the stack of 01289 IofCompleteRequest. The information stored in 01290 this local variable will be picked up by 01291 IovpCompleteRequest2-5. 01292 Return Value: 01293 01294 None. 01295 --*/ 01296 { 01297 PIOV_REQUEST_PACKET iovPacket; 01298 PIOV_SESSION_DATA iovSessionData; 01299 BOOLEAN slotIsInUse; 01300 PIOV_STACK_LOCATION iovCurrentStackLocation; 01301 ULONG locationsAdvanced; 01302 PIO_STACK_LOCATION irpSp; 01303 PDEVICE_OBJECT lowerDevobj; 01304 01305 iovPacket = IovpTrackingDataFindAndLock(Irp); 01306 01307 CompletionPacket->RaisedCount = 0; 01308 01309 if (iovPacket == NULL) { 01310 01311 CompletionPacket->IovSessionData = NULL; 01312 return; 01313 } 01314 01315 iovSessionData = IovpTrackingDataGetCurrentSessionData(iovPacket); 01316 01317 CompletionPacket->IovSessionData = iovSessionData; 01318 CompletionPacket->IovRequestPacket = iovPacket; 01319 01320 if (iovSessionData == NULL) { 01321 01322 // 01323 // We just got a look at the allocation, not the session itself. 01324 // This can happen if a driver calls IofCompleteRequest on an internally 01325 // generated IRP before calling IofCallDriver. NPFS does this. 01326 // 01327 IovpTrackingDataReleaseLock(iovPacket); 01328 return; 01329 } 01330 01331 TRACKIRP_DBGPRINT(( 01332 " CR1: Current, Last = (%x, %x)\n", 01333 Irp->CurrentLocation, iovPacket->LastLocation 01334 ), 3); 01335 01336 irpSp = IoGetCurrentIrpStackLocation(Irp); 01337 01338 if (iovPacket->Flags&TRACKFLAG_QUEUED_INTERNALLY) { 01339 01340 // 01341 // We are probably going to die now. Anyway, it was a good life... 01342 // 01343 WDM_FAIL_CALLER3((DCERROR_QUEUED_IRP_COMPLETED, DCPARAM_IRP, Irp)); 01344 } 01345 01346 // 01347 // This would be *very* bad - someone is completing an IRP that is 01348 // currently in progress... 01349 // 01350 ASSERT(!(Irp->Flags&IRP_DIAG_HAS_SURROGATE)); 01351 01352 // 01353 // Hmmm, someone is completing an IRP that IoCallDriver never called. These 01354 // is possible but rather gross, so we warn. 01355 // 01356 if (Irp->CurrentLocation == ((CCHAR) Irp->StackCount + 1)) { 01357 01358 WDM_CHASTISE_CALLER3((DCERROR_UNFORWARDED_IRP_COMPLETED, DCPARAM_IRP, Irp)); 01359 } 01360 01361 // 01362 // Record priority for our own later recompletion... 01363 // 01364 iovPacket->PriorityBoost = PriorityBoost; 01365 01366 // 01367 // We have the option of causing trouble by making every Irp look 01368 // as if were pending. It is best to do it here, as this also takes 01369 // care of anybody who has synchronized the IRP and thus does not need 01370 // to mark it pending in his completion routine. 01371 // 01372 if (iovSessionData->AssertFlags&ASSERTFLAG_FORCEPENDING) { 01373 01374 IoMarkIrpPending(Irp); 01375 } 01376 01377 // 01378 // Do this so that if the IRP comes down again, it looks like a new one 01379 // to the "forward them correctly" code. 01380 // 01381 iovSessionData->DeviceLastCalled = NULL; 01382 01383 locationsAdvanced = iovPacket->LastLocation - Irp->CurrentLocation; 01384 01385 // 01386 // Remember this so that we can detect the case where someone is completing 01387 // to themselves. 01388 // 01389 CompletionPacket->LocationsAdvanced = locationsAdvanced; 01390 01391 // 01392 // If this failed, somebody skipped then completed. 01393 // 01394 ASSERT(locationsAdvanced); 01395 01396 // 01397 // If somebody called IoSetNextIrpStackLocation, and then completed, 01398 // update our internal stack locations (slots) as appropriate. 01399 // 01400 slotIsInUse = IovpAdvanceStackDownwards( 01401 iovSessionData->StackData, 01402 Irp->CurrentLocation, 01403 irpSp, 01404 irpSp + locationsAdvanced, 01405 locationsAdvanced, 01406 FALSE, 01407 FALSE, 01408 &iovCurrentStackLocation 01409 ); 01410 01411 IovpTrackingDataReleaseLock(iovPacket); 01412 }

VOID FASTCALL IovpCompleteRequest2 IN PIRP  Irp,
IN OUT PIOFCOMPLETEREQUEST_STACKDATA  CompletionPacket
 

Definition at line 1416 of file trackirp.c.

References ASSERT, ASSERTFLAG_COMPLETEATDPC, ASSERTFLAG_MONITORMAJORS, ASSERTFLAG_POLICEIRPS, ASSERTFLAG_ROTATE_STATUS, _IOV_SESSION_DATA::AssertFlags, CALLFLAG_COMPLETED, CALLFLAG_OVERRIDE_STATUS, _IRP::CancelRoutine, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, _IO_STACK_LOCATION::Control, _IRP::CurrentLocation, DISPATCH_LEVEL, _IOFCALLDRIVER_STACKDATA::ExpectedStatus, FALSE, _IOFCALLDRIVER_STACKDATA::Flags, _IOV_STACK_LOCATION::Flags, _IOV_STACK_LOCATION::InUse, IoGetNextIrpStackLocation, IoSetCompletionRoutine, _IRP::IoStatus, IovpAssertDoAdvanceStatus(), IovpAssertFinalIrpStack(), IovpAssertIrpStackUpward(), IovpSessionDataClose(), IovpSessionDataDereference(), IovpSessionDataReference(), IovpSwapSurrogateIrp(), IovpTrackingDataAcquireLock(), IovpTrackingDataDereference(), IovpTrackingDataGetCurrentSessionData(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, Irp, KeRaiseIrql(), _IOFCALLDRIVER_STACKDATA::NewStatus, NTSTATUS(), NULL, _IOV_STACK_LOCATION::RequestsFirstStackLocation, _IOV_SESSION_DATA::StackData, STACKFLAG_REQUEST_COMPLETED, TRACKFLAG_SURROGATE, TRACKIRP_DBGPRINT, and TRUE.

01422 : 01423 01424 This routine is called for each stack location that might have a completion 01425 routine. 01426 01427 Arguments: 01428 01429 Irp - A pointer to the IRP passed into 01430 IofCompleteRequest. 01431 01432 CompletionPacket - A pointer to a local variable on the stack of 01433 IofCompleteRequest. The information stored in 01434 this local variable will be picked up by 01435 IovpCompleteRequest4&5. 01436 01437 Return Value: 01438 01439 None. 01440 --*/ 01441 { 01442 PIOV_REQUEST_PACKET iovPacket; 01443 PIOV_SESSION_DATA iovSessionData; 01444 BOOLEAN raiseToDPC, newlyCompleted, requestFinalized ; 01445 KIRQL oldIrql ; 01446 PIOV_STACK_LOCATION iovCurrentStackLocation, requestsFirstStackLocation ; 01447 NTSTATUS status, entranceStatus ; 01448 PIOFCALLDRIVER_STACKDATA IofCallDriverStackData ; 01449 PIO_STACK_LOCATION irpSp ; 01450 ULONG refAction ; 01451 PLIST_ENTRY listEntry ; 01452 01453 iovSessionData = CompletionPacket->IovSessionData; 01454 if (iovSessionData == NULL) { 01455 01456 return; 01457 } 01458 01459 iovPacket = CompletionPacket->IovRequestPacket; 01460 ASSERT(iovPacket); 01461 IovpTrackingDataAcquireLock(iovPacket); 01462 01463 ASSERT(iovSessionData == IovpTrackingDataGetCurrentSessionData(iovPacket)); 01464 01465 ASSERT(!Irp->CancelRoutine) ; 01466 01467 status = Irp->IoStatus.Status ; 01468 01469 TRACKIRP_DBGPRINT(( 01470 " CR2: Current, Last = (%x, %x)\n", 01471 Irp->CurrentLocation, iovPacket->LastLocation 01472 ), 3) ; 01473 01474 iovCurrentStackLocation = iovSessionData->StackData + Irp->CurrentLocation -1 ; 01475 TRACKIRP_DBGPRINT(( 01476 " Smacking %lx in CR2\n", 01477 iovCurrentStackLocation-iovSessionData->StackData 01478 ), 2) ; 01479 01480 if (Irp->CurrentLocation <= iovPacket->TopStackLocation) { 01481 01482 // 01483 // Might this be false if the completion routine is to an 01484 // internal stack loc as set up by IoSetNextIrpStackLocation? 01485 // 01486 ASSERT(iovCurrentStackLocation->InUse) ; 01487 01488 // 01489 // Determine if a request was newly completed. Note that 01490 // several requests may exist within an IRP if it is being 01491 // "reused". For instance, in response to a IRP_MJ_READ, a 01492 // driver might convert it into a IRP_MJ_PNP request for the 01493 // rest of the stack. The two are treated as seperate requests. 01494 // 01495 requestsFirstStackLocation = iovCurrentStackLocation->RequestsFirstStackLocation ; 01496 TRACKIRP_DBGPRINT(( 01497 " CR2: original request for %lx is %lx\n", 01498 iovCurrentStackLocation-iovSessionData->StackData, 01499 requestsFirstStackLocation-iovSessionData->StackData 01500 ), 3) ; 01501 01502 ASSERT(requestsFirstStackLocation) ; 01503 if (requestsFirstStackLocation->Flags&STACKFLAG_REQUEST_COMPLETED) { 01504 newlyCompleted = FALSE ; 01505 } else { 01506 requestsFirstStackLocation->Flags|=STACKFLAG_REQUEST_COMPLETED ; 01507 newlyCompleted = TRUE ; 01508 TRACKIRP_DBGPRINT(( 01509 " CR2: Request %lx newly completed by %lx\n", 01510 requestsFirstStackLocation-iovSessionData->StackData, 01511 iovCurrentStackLocation-iovSessionData->StackData 01512 ), 3) ; 01513 } 01514 requestFinalized = (iovCurrentStackLocation == requestsFirstStackLocation) ; 01515 if (requestFinalized) { 01516 01517 TRACKIRP_DBGPRINT(( 01518 " CR2: Request %lx finalized\n", 01519 iovCurrentStackLocation-iovSessionData->StackData 01520 ), 3) ; 01521 } 01522 01523 // 01524 // OK - 01525 // If we haven't unwound yet, then IofCallDriverStackData will 01526 // start out non-NULL, in which case we will scribble away the final 01527 // completion routine status to everybody asking (could be multiple 01528 // if they IoSkip'd). 01529 // On the other hand, everybody might have unwound, in which 01530 // case IofCallDriver(...) will start out NULL, and we will already have 01531 // asserted if STATUS_PENDING wasn't returned much much earlier... 01532 // Finally, this slot may not have been "prepared" if an 01533 // internal stack location called IoSetNextIrpStackLocation, thus 01534 // consuming a stack location. In this case, IofCallDriverStackData 01535 // will come from a zero'd slot, and we will do nothing, which is 01536 // also fine. 01537 // 01538 irpSp = IoGetNextIrpStackLocation(Irp) ; 01539 01540 if ((iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) && 01541 (iovPacket->AssertFlags&ASSERTFLAG_MONITORMAJORS)) { 01542 01543 IovpAssertIrpStackUpward( 01544 iovPacket, 01545 irpSp, 01546 iovCurrentStackLocation, 01547 newlyCompleted, 01548 requestFinalized 01549 ); 01550 } 01551 01552 entranceStatus = status ; 01553 01554 while(!IsListEmpty(&iovCurrentStackLocation->CallStackData)) { 01555 01556 // 01557 // Pop off the list head. 01558 // 01559 listEntry = RemoveHeadList(&iovCurrentStackLocation->CallStackData) ; 01560 IofCallDriverStackData = CONTAINING_RECORD( 01561 listEntry, 01562 IOFCALLDRIVER_STACKDATA, 01563 SharedLocationList) ; 01564 01565 ASSERT(!(IofCallDriverStackData->Flags&CALLFLAG_COMPLETED)) ; 01566 01567 IofCallDriverStackData->Flags |= CALLFLAG_COMPLETED ; 01568 IofCallDriverStackData->ExpectedStatus = status ; 01569 01570 if ((iovSessionData->AssertFlags&ASSERTFLAG_ROTATE_STATUS)&& 01571 IovpAssertDoAdvanceStatus(irpSp, entranceStatus, &status)) { 01572 01573 // 01574 // Purposely munge the returned status for everyone at this 01575 // layer to flush more bugs. We are specifically trolling for 01576 // this buggy sequence: 01577 // Irp->IoStatus.Status = STATUS_SUCCESS ; 01578 // IoSkipCurrentIrpStackLocation(Irp); 01579 // IoCallDriver(DeviceBelow, Irp) ; 01580 // return STATUS_SUCCESS ; 01581 // 01582 IofCallDriverStackData->Flags |= CALLFLAG_OVERRIDE_STATUS ; 01583 IofCallDriverStackData->NewStatus = status ; 01584 } 01585 } 01586 Irp->IoStatus.Status = status ; 01587 01588 // 01589 // Set InUse = FALSE and CallStackData = NULL 01590 // 01591 RtlZeroMemory(iovCurrentStackLocation, sizeof(IOV_STACK_LOCATION)) ; 01592 InitializeListHead(&iovCurrentStackLocation->CallStackData) ; 01593 } else { 01594 01595 ASSERT(0) ; 01596 } 01597 01598 // 01599 // Once we return, we may be completed again before IofCompleteRequest3 01600 // get's called, so we make sure we are at DPC level throughout. 01601 // 01602 raiseToDPC = FALSE ; 01603 01604 if (iovSessionData->AssertFlags&ASSERTFLAG_COMPLETEATDPC) { 01605 01606 if (!CompletionPacket->RaisedCount) { 01607 01608 // 01609 // Copy away the callers IRQL 01610 // 01611 CompletionPacket->PreviousIrql = iovPacket->CallerIrql; 01612 raiseToDPC = TRUE ; 01613 } 01614 CompletionPacket->RaisedCount++ ; 01615 } 01616 01617 iovPacket->LastLocation = Irp->CurrentLocation+1 ; 01618 01619 if (iovPacket->TopStackLocation == Irp->CurrentLocation) { 01620 01621 CompletionPacket->IovSessionData = NULL; 01622 01623 if (iovPacket->Flags&TRACKFLAG_SURROGATE) { 01624 01625 // 01626 // Scribble away the real completion routine and corrosponding control 01627 // 01628 irpSp = IoGetNextIrpStackLocation(Irp) ; 01629 iovPacket->RealIrpCompletionRoutine = irpSp->CompletionRoutine ; 01630 iovPacket->RealIrpControl = irpSp->Control ; 01631 iovPacket->RealIrpContext = irpSp->Context ; 01632 01633 // 01634 // We want to peek at the Irp prior to completion. This is why we 01635 // have expanded the initial number of stack locations with the 01636 // driver verifier enabled. 01637 // 01638 IoSetCompletionRoutine( 01639 Irp, 01640 IovpSwapSurrogateIrp, 01641 Irp, 01642 TRUE, 01643 TRUE, 01644 TRUE 01645 ) ; 01646 01647 } else { 01648 01649 // 01650 // Close this session as the IRP has entirely completed. We drop 01651 // the pointer count we added to the tracking data here for the 01652 // same reason. 01653 // 01654 irpSp = IoGetNextIrpStackLocation(Irp) ; 01655 if (iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) { 01656 01657 IovpAssertFinalIrpStack(iovPacket, irpSp) ; 01658 } 01659 01660 ASSERT(iovPacket->TopStackLocation == Irp->CurrentLocation); 01661 IovpSessionDataClose(iovSessionData); 01662 IovpSessionDataDereference(iovSessionData); 01663 IovpTrackingDataDereference(iovPacket, IOVREFTYPE_POINTER); 01664 } 01665 01666 } else { 01667 01668 // 01669 // We will be seeing this IRP again. Hold a session count against it. 01670 // 01671 IovpSessionDataReference(iovSessionData); 01672 } 01673 01674 // 01675 // Assert LastLocation is consistent with an IRP that may be completed. 01676 // 01677 if (iovPacket->LastLocation < iovPacket->TopStackLocation) { 01678 01679 ASSERT(iovSessionData->StackData[iovPacket->LastLocation-1].InUse) ; 01680 } 01681 01682 IovpTrackingDataReleaseLock(iovPacket); 01683 01684 if (raiseToDPC) { 01685 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); 01686 } 01687 01688 CompletionPacket->LocationsAdvanced --; 01689 }

VOID FASTCALL IovpCompleteRequest3 IN PIRP  Irp,
IN PVOID  Routine,
IN OUT PIOFCOMPLETEREQUEST_STACKDATA  CompletionPacket
 

Definition at line 1693 of file trackirp.c.

References ASSERT, ASSERTFLAG_COMPLETEATPASSIVE, ASSERTFLAG_DEFERCOMPLETION, ASSERTFLAG_FORCEPENDING, ASSERTFLAG_POLICEIRPS, _IOV_SESSION_DATA::AssertFlags, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, _IRP::CurrentLocation, DbgPrint, DCERROR_COMPLETION_ROUTINE_PAGABLE, DCPARAM_IRP, DCPARAM_ROUTINE, DEFERRAL_CONTEXT, ExAllocatePoolWithTag, FALSE, IoGetCurrentIrpStackLocation, IoGetNextIrpStackLocation, IovpInternalDeferredCompletion(), IovpTrackingDataAcquireLock(), IovpTrackingDataReference(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, _DEFERRAL_CONTEXT::IovRequestPacket, _IOV_SESSION_DATA::IovRequestPacket, Irp, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, _DEFERRAL_CONTEXT::IrpSpNext, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, MmIsSystemAddressLocked(), NonPagedPool, NULL, _DEFERRAL_CONTEXT::OriginalCompletionRoutine, _DEFERRAL_CONTEXT::OriginalContext, _DEFERRAL_CONTEXT::OriginalIrp, _DEFERRAL_CONTEXT::OriginalPriorityBoost, PDEFERRAL_CONTEXT, POOL_TAG_DEFERRED_CONTEXT, _IOV_REQUEST_PACKET::PriorityBoost, _IRP::StackCount, and WDM_FAIL_ROUTINE.

01700 : 01701 01702 This routine is called just before each completion routine is invoked. 01703 01704 Arguments: 01705 01706 Irp - A pointer to the IRP passed into 01707 IofCompleteRequest. 01708 01709 Routine - The completion routine about to be called. 01710 01711 CompletionPacket - A pointer to data on the callers stack. This will 01712 be picked up IovpCompleteRequest4 and 01713 IovpCompleteRequest5. 01714 01715 Return Value: 01716 01717 None. 01718 --*/ 01719 { 01720 PIOV_REQUEST_PACKET iovPacket; 01721 PIOV_SESSION_DATA iovSessionData; 01722 PIO_STACK_LOCATION irpSpCur, irpSpNext ; 01723 PDEFERRAL_CONTEXT deferralContext ; 01724 01725 iovSessionData = CompletionPacket->IovSessionData; 01726 if (iovSessionData == NULL) { 01727 01728 return; 01729 } 01730 01731 iovPacket = iovSessionData->IovRequestPacket; 01732 ASSERT(iovPacket); 01733 IovpTrackingDataAcquireLock(iovPacket); 01734 01735 // 01736 // Verify all completion routines are in nonpaged code, exempting one 01737 // special case - when a driver completes the IRP to itself by calling 01738 // IoSetNextStackLocation before calling IoCompleteRequest. 01739 // 01740 if (iovSessionData->AssertFlags&ASSERTFLAG_POLICEIRPS) { 01741 01742 if ((CompletionPacket->LocationsAdvanced <= 0) && 01743 (MmIsSystemAddressLocked(Routine) == FALSE)) { 01744 01745 DbgPrint( 01746 "Verifier Notes: LocationsAdvanced %d\n", 01747 CompletionPacket->LocationsAdvanced 01748 ); 01749 01750 WDM_FAIL_ROUTINE(( 01751 DCERROR_COMPLETION_ROUTINE_PAGABLE, 01752 DCPARAM_IRP + DCPARAM_ROUTINE, 01753 Irp, 01754 Routine 01755 )); 01756 } 01757 } 01758 01759 // 01760 // Setup fields for those assertion functions that will be called *after* 01761 // the completion routine has been called. 01762 // 01763 irpSpCur = IoGetCurrentIrpStackLocation(Irp) ; 01764 CompletionPacket->IsRemoveIrp = 01765 ((Irp->CurrentLocation <= (CCHAR) Irp->StackCount) && 01766 (irpSpCur->MajorFunction == IRP_MJ_PNP) && 01767 (irpSpCur->MinorFunction == IRP_MN_REMOVE_DEVICE)) ; 01768 01769 CompletionPacket->CompletionRoutine = Routine ; 01770 01771 // 01772 // Is this a completion routine that should be called later? Note that this 01773 // is only legal if we are pending the IRPs (because to the upper driver, 01774 // IofCallDriver is returning before it's completion routine has been called) 01775 // 01776 if ((!CompletionPacket->IsRemoveIrp)&& 01777 ((iovSessionData->AssertFlags&ASSERTFLAG_DEFERCOMPLETION)|| 01778 (iovSessionData->AssertFlags&ASSERTFLAG_COMPLETEATPASSIVE))) { 01779 01780 ASSERT(iovSessionData->AssertFlags&ASSERTFLAG_FORCEPENDING) ; 01781 01782 irpSpNext = IoGetNextIrpStackLocation(Irp) ; 01783 01784 deferralContext = ExAllocatePoolWithTag( 01785 NonPagedPool, 01786 sizeof(DEFERRAL_CONTEXT), 01787 POOL_TAG_DEFERRED_CONTEXT 01788 ) ; 01789 01790 if (deferralContext) { 01791 01792 // 01793 // Swap the original completion and context for our own. 01794 // 01795 deferralContext->IovRequestPacket = iovPacket; 01796 deferralContext->IrpSpNext = irpSpNext; 01797 deferralContext->OriginalCompletionRoutine = irpSpNext->CompletionRoutine; 01798 deferralContext->OriginalContext = irpSpNext->Context; 01799 deferralContext->OriginalIrp = Irp; 01800 deferralContext->OriginalPriorityBoost = iovPacket->PriorityBoost; 01801 01802 irpSpNext->CompletionRoutine = IovpInternalDeferredCompletion; 01803 irpSpNext->Context = deferralContext; 01804 IovpTrackingDataReference(iovPacket, IOVREFTYPE_POINTER); 01805 } 01806 } 01807 01808 IovpTrackingDataReleaseLock(iovPacket) ; 01809 }

VOID FASTCALL IovpCompleteRequest4 IN PIRP  Irp,
IN NTSTATUS  ReturnedStatus,
IN OUT PIOFCOMPLETEREQUEST_STACKDATA  CompletionPacket
 

Definition at line 1813 of file trackirp.c.

References ASSERT, ASSERTFLAG_FORCEPENDING, _IOV_SESSION_DATA::AssertFlags, _IO_STACK_LOCATION::Control, DCERROR_PENDING_BIT_NOT_MIGRATED, DCPARAM_IRP, DCPARAM_ROUTINE, IoGetCurrentIrpStackLocation, IoMarkIrpPending, IovpTrackingDataAcquireLock(), IovpTrackingDataReleaseLock(), _IOV_SESSION_DATA::IovRequestPacket, Irp, NULL, _IOV_REQUEST_PACKET::pIovSessionData, SL_PENDING_RETURNED, and WDM_FAIL_ROUTINE.

01820 : 01821 01822 This assert routine is called just after each completion routine is 01823 invoked (but not if STATUS_MORE_PROCESSING is returned) 01824 01825 Arguments: 01826 01827 Irp - A pointer to the IRP passed into 01828 IofCompleteRequest. 01829 01830 Routine - The completion routine called. 01831 01832 ReturnedStatus - The status value returned. 01833 01834 CompletionPacket - A pointer to data on the callers stack. This was 01835 filled in by IovpCompleteRequest3. 01836 01837 Return Value: 01838 01839 None. 01840 --*/ 01841 { 01842 PIOV_REQUEST_PACKET iovPacket; 01843 PIOV_SESSION_DATA iovSessionData; 01844 PIO_STACK_LOCATION irpSp; 01845 PVOID routine; 01846 01847 routine = CompletionPacket->CompletionRoutine; 01848 iovSessionData = CompletionPacket->IovSessionData; 01849 01850 if (iovSessionData == NULL) { 01851 01852 return; 01853 } 01854 01855 iovPacket = iovSessionData->IovRequestPacket; 01856 ASSERT(iovPacket); 01857 IovpTrackingDataAcquireLock(iovPacket); 01858 01859 // 01860 // ADRIAO BUGBUG 01/06/1999 - 01861 // Check for leaked Cancel routines here. 01862 // 01863 if (iovSessionData->AssertFlags&ASSERTFLAG_FORCEPENDING) { 01864 01865 // 01866 // ADRIAO BUGBUG #05 05/12/98 - Find a way to do this in the non-pend 01867 // everything path... 01868 // 01869 if ((ReturnedStatus != STATUS_MORE_PROCESSING_REQUIRED)&& 01870 (iovPacket->pIovSessionData == iovSessionData)) { 01871 01872 // 01873 // At this point, we know the completion routine is required to have 01874 // set the IRP pending bit, because we've hardwired everyone below 01875 // him to return pending, and we've marked the pending returned bit. 01876 // Verify he did his part 01877 // 01878 irpSp = IoGetCurrentIrpStackLocation(Irp) ; 01879 if (!(irpSp->Control & SL_PENDING_RETURNED )) { 01880 01881 WDM_FAIL_ROUTINE(( 01882 DCERROR_PENDING_BIT_NOT_MIGRATED, 01883 DCPARAM_IRP + DCPARAM_ROUTINE, 01884 Irp, 01885 routine 01886 )); 01887 01888 // 01889 // This will keep the IRP above from erroneously asserting (and 01890 // correctly hanging). 01891 // 01892 IoMarkIrpPending(Irp); 01893 } 01894 } 01895 } 01896 IovpTrackingDataReleaseLock(iovPacket); 01897 }

VOID FASTCALL IovpCompleteRequest5 IN PIRP  Irp,
IN OUT PIOFCOMPLETEREQUEST_STACKDATA  CompletionPacket
 

Definition at line 1901 of file trackirp.c.

References ASSERT, ASSERTFLAG_COMPLETEATDPC, _IOV_SESSION_DATA::AssertFlags, IovpSessionDataDereference(), IovpTrackingDataAcquireLock(), IovpTrackingDataReleaseLock(), _IOV_SESSION_DATA::IovRequestPacket, KeLowerIrql(), and NTSTATUS().

01907 : 01908 01909 This routine is called for each stack location that could have had a 01910 completion routine, after any possible completion routine has been 01911 called. 01912 01913 Arguments: 01914 01915 Irp - A pointer to the IRP passed into 01916 IofCompleteRequest. 01917 01918 CompletionPacket - A pointer to a local variable on the stack of 01919 IofCompleteRequest. This information was stored 01920 by IovpCompleteRequest2 and 3. 01921 01922 Return Value: 01923 01924 None. 01925 --*/ 01926 { 01927 PIOV_REQUEST_PACKET iovPacket; 01928 PIOV_SESSION_DATA iovSessionData; 01929 PIOV_STACK_LOCATION iovCurrentStackLocation ; 01930 NTSTATUS status ; 01931 01932 iovSessionData = CompletionPacket->IovSessionData; 01933 01934 if (iovSessionData) { 01935 01936 iovPacket = iovSessionData->IovRequestPacket; 01937 ASSERT(iovPacket); 01938 IovpTrackingDataAcquireLock(iovPacket); 01939 01940 ASSERT((!CompletionPacket->RaisedCount) || 01941 (iovSessionData->AssertFlags&ASSERTFLAG_COMPLETEATDPC)) ; 01942 01943 IovpSessionDataDereference(iovSessionData); 01944 IovpTrackingDataReleaseLock(iovPacket); 01945 } 01946 01947 // 01948 // When this count is at zero, we have unnested out of every 01949 // completion routine, so it is OK to return back to our original IRQL 01950 // 01951 if (CompletionPacket->RaisedCount) { 01952 01953 if (!(--CompletionPacket->RaisedCount)) { 01954 // 01955 // Undo IRQL madness (wouldn't want to return to 01956 // the caller at DPC, would we now?) 01957 // 01958 KeLowerIrql(CompletionPacket->PreviousIrql); 01959 } 01960 } 01961 }

VOID FASTCALL IovpCompleteRequestApc IN PIRP  Irp,
IN PVOID  BestStackOffset
 

Definition at line 1965 of file trackirp.c.

References IovpTrackingDataFindAndLock(), IovpTrackingDataReleaseLock(), Irp, KeGetCurrentThread, RtlAssert(), _IRP::UserEvent, and _IRP::UserIosb.

01971 : 01972 01973 This routine is after the APC for completing IRPs and fired. 01974 01975 Arguments: 01976 01977 Irp - A pointer to the IRP passed into retrieved from 01978 the APC in IopCompleteRequest. 01979 01980 BestStackOffset - A pointer to a last parameter passed on the stack. 01981 We use this to detect the case where a driver has 01982 ignored STATUS_PENDING and left the UserIosb on 01983 it's stack. 01984 01985 Return Value: 01986 01987 None. 01988 --*/ 01989 { 01990 #if DBG 01991 #if defined(_X86_) 01992 PUCHAR addr; 01993 PIOV_REQUEST_PACKET iovPacket; 01994 01995 addr = (PUCHAR)Irp->UserIosb; 01996 if ((addr > (PUCHAR)KeGetCurrentThread()->StackLimit) && 01997 (addr <= (PUCHAR)BestStackOffset)) { 01998 01999 iovPacket = IovpTrackingDataFindAndLock(Irp) ; 02000 02001 RtlAssert("UserIosb below stack pointer", __FILE__, (ULONG) iovPacket, 02002 "Call AdriaO"); 02003 02004 IovpTrackingDataReleaseLock(iovPacket) ; 02005 } 02006 02007 addr = (PUCHAR)Irp->UserEvent; 02008 if ((addr > (PUCHAR)KeGetCurrentThread()->StackLimit) && 02009 (addr <= (PUCHAR)BestStackOffset)) { 02010 02011 iovPacket = IovpTrackingDataFindAndLock(Irp) ; 02012 02013 RtlAssert("UserEvent below stack pointer", __FILE__, (ULONG) iovPacket, 02014 "Call AdriaO"); 02015 02016 IovpTrackingDataReleaseLock(iovPacket) ; 02017 } 02018 #endif 02019 #endif 02020 }

VOID IovpDeleteDevice IN PDEVICE_OBJECT  Device  ) 
 

Definition at line 3379 of file trackirp.c.

References DCERROR_DELETE_WHILE_ATTACHED, IovpGetDeviceAttachedTo(), ObDereferenceObject, and WDM_FAIL_CALLER1.

03382 { 03383 PDEVICE_OBJECT deviceBelow; 03384 03385 // 03386 // ADRIAO BUGBUG 03/03/1999 - 03387 // Complain if the dude already deleted himself. 03388 // 03389 03390 deviceBelow = IovpGetDeviceAttachedTo(DeviceObject); 03391 if (deviceBelow) { 03392 03393 WDM_FAIL_CALLER1((DCERROR_DELETE_WHILE_ATTACHED, 0)); 03394 ObDereferenceObject(deviceBelow); 03395 } 03396 }

VOID IovpDetachDevice IN PDEVICE_OBJECT  LowerDevice  ) 
 

Definition at line 3354 of file trackirp.c.

References DCERROR_DETACH_NOT_ATTACHED, DCPARAM_DEVOBJ, DOE_EXAMINED, DOE_TRACKED, _DEVOBJ_EXTENSION::ExtensionFlags, NULL, and WDM_FAIL_CALLER2.

03357 { 03358 PDEVOBJ_EXTENSION deviceExtension; 03359 03360 if (LowerDevice->AttachedDevice == NULL) { 03361 03362 WDM_FAIL_CALLER2((DCERROR_DETACH_NOT_ATTACHED, DCPARAM_DEVOBJ, LowerDevice)); 03363 } else { 03364 03365 // 03366 // ADRIAO BUGBUG 01/07/1999 - 03367 // As the stack can be torn apart simulatenously from above and 03368 // below during a remove IRP, we cannot assert the below, and moreover 03369 // changes to the ExtensionFlags will have to involve walking the tree. 03370 // 03371 // ASSERT(LowerDevice->AttachedDevice->AttachedDevice == NULL); 03372 // 03373 deviceExtension = LowerDevice->AttachedDevice->DeviceObjectExtension; 03374 deviceExtension->ExtensionFlags &=~ (DOE_EXAMINED | DOE_TRACKED); 03375 } 03376 }

BOOLEAN FASTCALL IovpDoAssertIrps VOID   ) 
 

Definition at line 404 of file trackirp.c.

References ASSERT, DISPATCH_LEVEL, IoVerifierInit(), IOVERIFIERINIT_ASYNCHRONOUSINIT, IOVERIFIERINIT_EVERYTHING_TRACKED, IOVERIFIERINIT_NO_REINIT, IovpIrpTrackingEnabled, and IovpTrackingFlags.

00409 : 00410 00411 This routine is called to ensure we can do IRP assertions. When called we 00412 lock the neccessary data structures and code if we haven't been initialized. 00413 00414 Arguments: None 00415 00416 Return Value: 00417 00418 TRUE if assertions can be done, FALSE otherwise (e.g., 00419 called at DPC time and we weren't already enabled) 00420 00421 --*/ 00422 { 00423 ASSERT(IovpTrackingFlags); 00424 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL) ; 00425 00426 // 00427 // If we aren't enabled, call the enabling function. This is harmless to 00428 // call repeatedly. We are not gaurenteed to be enabled when this function 00429 // returns (it can't block anyway, as paging might need to occur, and we'd 00430 // be sitting on file system IRPs). The IOVERIFIERINIT_EVERYTHING_TRACKED is 00431 // used to let us know we caught all IRPs, ie none are outstanding that 00432 // haven't been tracked/marked in some manner. We can set this here as 00433 // SPECIALIRP_MARK_NON_TRACKABLE() is called in the normal IofCallDriver 00434 // code paths if SPECIAL_IRP's are enabled. 00435 // 00436 if (!IovpIrpTrackingEnabled) { 00437 00438 #if 0 00439 IoVerifierInit( 00440 DRIVER_VERIFIER_IO_CHECKING, 00441 IOVERIFIERINIT_EVERYTHING_TRACKED | 00442 IOVERIFIERINIT_ASYNCHRONOUSINIT | 00443 IOVERIFIERINIT_NO_REINIT 00444 ); 00445 #endif 00446 } 00447 00448 // 00449 // If enabled, return so. 00450 // 00451 return IovpIrpTrackingEnabled; 00452 }

BOOLEAN IovpEnumDevObjCallback IN PVOID  Object,
IN PUNICODE_STRING  ObjectName,
IN ULONG  HandleCount,
IN ULONG  PointerCount,
IN PVOID  Context
 

Definition at line 3413 of file trackirp.c.

References _DEVICE_OBJECT::DeviceObjectExtension, DOE_EXAMINED, DOE_TRACKED, _DEVOBJ_EXTENSION::ExtensionFlags, and TRUE.

Referenced by IovpReexamineAllStacks().

03420 { 03421 PDEVICE_OBJECT deviceObject; 03422 PDEVOBJ_EXTENSION deviceExtension; 03423 03424 deviceObject = (PDEVICE_OBJECT) Object; 03425 deviceExtension = deviceObject->DeviceObjectExtension; 03426 03427 if (PointerCount || HandleCount) { 03428 03429 deviceExtension->ExtensionFlags &=~ (DOE_EXAMINED | DOE_TRACKED); 03430 } 03431 03432 return TRUE; 03433 }

VOID FASTCALL IovpExamineDevObjForwarding IN PDEVICE_OBJECT  DeviceBeingCalled,
IN PDEVICE_OBJECT  DeviceLastCalled,
OUT PULONG  ForwardingTechnique
 

Definition at line 3537 of file trackirp.c.

References ASSERT, _DEVICE_OBJECT::AttachedDevice, CHANGED_STACKS_AT_BOTTOM, CHANGED_STACKS_MID_STACK, FORWARDED_TO_NEXT_DO, IopDatabaseLock, IovpGetDeviceAttachedTo(), NULL, ObDereferenceObject, SKIPPED_A_DO, STARTED_INSIDE_STACK, and STARTED_TOP_OF_STACK.

Referenced by IovpCallDriver1().

03544 : 03545 03546 STARTED_TOP_OF_STACK 03547 FORWARDED_TO_NEXT_DO 03548 SKIPPED_A_DO 03549 STARTED_INSIDE_STACK 03550 CHANGED_STACKS_AT_BOTTOM 03551 CHANGED_STACKS_MID_STACK 03552 03553 --*/ 03554 03555 { 03556 PDEVICE_OBJECT upperDevobj, lowerObject ; 03557 ULONG result ; 03558 KIRQL irql; 03559 03560 lowerObject = IovpGetDeviceAttachedTo(DeviceLastCalled) ; 03561 03562 ExAcquireFastLock( &IopDatabaseLock, &irql ); 03563 03564 // 03565 // Nice and simple. Walk the device being called 03566 // upwards and find either NULL or the last device 03567 // we called. 03568 // 03569 upperDevobj = DeviceBeingCalled->AttachedDevice ; 03570 while(upperDevobj && (upperDevobj != DeviceLastCalled)) { 03571 03572 upperDevobj = upperDevobj->AttachedDevice ; 03573 } 03574 03575 if (DeviceLastCalled == NULL) { 03576 03577 // 03578 // This is a newly started IRP, was it targetted 03579 // at the top of a stack or at the middle/bottom? 03580 // 03581 result = (DeviceBeingCalled->AttachedDevice) ? STARTED_INSIDE_STACK : 03582 STARTED_TOP_OF_STACK ; 03583 03584 } else if (upperDevobj == NULL) { 03585 03586 // 03587 // We were forwarded the Irp beyond our own stack 03588 // 03589 result = (lowerObject) ? CHANGED_STACKS_MID_STACK : 03590 CHANGED_STACKS_AT_BOTTOM ; 03591 03592 } else if (DeviceBeingCalled->AttachedDevice == upperDevobj) { 03593 03594 result = FORWARDED_TO_NEXT_DO ; 03595 03596 // 03597 // Quick assertion, if LastDevice was non-NULL, the 03598 // device under him should be the one we are calling... 03599 // 03600 ASSERT(lowerObject == DeviceBeingCalled) ; 03601 03602 } else { 03603 03604 // 03605 // DeviceLastCalled was found higher in the stack, but wasn't 03606 // directly above DeviceBeingCalled 03607 // 03608 result = SKIPPED_A_DO ; 03609 } 03610 03611 ExReleaseFastLock( &IopDatabaseLock, irql ); 03612 if (lowerObject) { 03613 ObDereferenceObject(lowerObject) ; 03614 } 03615 *ForwardTechnique = result ; 03616 }

VOID IovpExamineIrpStackForwarding IN OUT PIOV_REQUEST_PACKET  IovPacket,
IN BOOLEAN  IsNewSession,
IN ULONG  ForwardMethod,
IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN OUT PIO_STACK_LOCATION IoCurrentStackLocation,
OUT PIO_STACK_LOCATION IoLastStackLocation,
OUT ULONG *  StackLocationsAdvanced
 

Definition at line 2239 of file trackirp.c.

References ASSERT, ASSERTFLAG_CONSUME_ALWAYS, ASSERTFLAG_POLICEIRPS, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, _IO_STACK_LOCATION::Control, _IRP::CurrentLocation, DCERROR_INSUFFICIENT_STACK_LOCATIONS, DCERROR_IRPSP_COPIED, DCERROR_NEXTIRPSP_DIRTY, DCERROR_UNNECCESSARY_COPY, DCPARAM_IRP, _IO_STACK_LOCATION::DeviceObject, _DEVICE_OBJECT::DriverObject, FAIL_CALLER_OF_IOFCALLDRIVER2, _IO_STACK_LOCATION::FileObject, FORWARDED_TO_NEXT_DO, HACKFLAG_FOR_SCSIPORT, IoCopyCurrentIrpStackLocationToNext, IoGetCurrentIrpStackLocation, IoGetNextIrpStackLocation, IoSetCompletionRoutine, IoSetNextIrpStackLocation, IovpHackFlags, IovpInternalCompletionTrap(), IovpSwapSurrogateIrp(), Irp, IRP_MJ_POWER, _IO_STACK_LOCATION::MajorFunction, NULL, _IO_STACK_LOCATION::Parameters, SL_NOTCOPIED, _IRP::Tail, TRUE, WDM_CHASTISE_CALLER3, and WDM_CHASTISE_CALLER5.

Referenced by IovpCallDriver1().

02249 { 02250 PIRP irp; 02251 PIO_STACK_LOCATION irpSp, irpLastSp; 02252 BOOLEAN isSameStack; 02253 ULONG locationsAdvanced; 02254 02255 irpSp = *IoCurrentStackLocation; 02256 02257 if (!IsNewSession) { 02258 02259 // 02260 // We are sitting on current next being one back (-1) from 02261 // CurrentStackLocation. 02262 // 02263 locationsAdvanced = IovPacket->LastLocation-Irp->CurrentLocation ; 02264 irpLastSp = Irp->Tail.Overlay.CurrentStackLocation+(locationsAdvanced-1) ; 02265 02266 } else { 02267 02268 // 02269 // New IRP, so no last SP and we always advance "1" 02270 // 02271 locationsAdvanced = 1 ; 02272 irpLastSp = NULL ; 02273 } 02274 02275 if ((!IsNewSession) && (IovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS)) { 02276 02277 // 02278 // As the control field is zeroed by IoCopyCurrentStackLocation, we 02279 // dope each stack location with the value SL_NOTCOPIED. If it is 02280 // zeroed or the IRP stack location has stayed the same, the one of 02281 // the two API's was called. Otherwise the next stack location wasn't 02282 // set up properly (I have yet to find a case otherwise)... 02283 // 02284 if ((irpSp->Control&SL_NOTCOPIED)&& 02285 IovPacket->LastLocation != Irp->CurrentLocation) { 02286 02287 #if 0 02288 FAIL_CALLER_OF_IOFCALLDRIVER2( 02289 (DCERROR_NEXTIRPSP_DIRTY, DCPARAM_IRP, Irp), 02290 irpSp 02291 ); 02292 #endif 02293 } 02294 02295 // 02296 // Now check for people who copy the stack locations and forget to 02297 // wipe out previous completion routines. 02298 // 02299 if (locationsAdvanced) { 02300 02301 // 02302 // IoCopyCurrentStackLocation copies everything but Completion, 02303 // Context, and Control 02304 // 02305 isSameStack = RtlEqualMemory(irpSp, irpLastSp, 02306 FIELD_OFFSET(IO_STACK_LOCATION, Control)) ; 02307 02308 isSameStack &= RtlEqualMemory(&irpSp->Parameters, &irpLastSp->Parameters, 02309 FIELD_OFFSET(IO_STACK_LOCATION, DeviceObject)- 02310 FIELD_OFFSET(IO_STACK_LOCATION, Parameters)) ; 02311 02312 isSameStack &= (irpSp->FileObject == irpLastSp->FileObject) ; 02313 02314 // 02315 // We should *never* see this on the stack! If we do, something 02316 // quite bizarre has happened... 02317 // 02318 ASSERT(irpSp->CompletionRoutine != IovpSwapSurrogateIrp) ; 02319 02320 if (isSameStack) { 02321 02322 // 02323 // We caught them doing something either very bad or quite 02324 // inefficient. We can tell which based on whether there is 02325 // a completion routine. 02326 // 02327 if ((irpSp->CompletionRoutine == irpLastSp->CompletionRoutine)&& 02328 (irpSp->Context == irpLastSp->Context) && 02329 (irpSp->Control == irpLastSp->Control) && 02330 (irpSp->CompletionRoutine != NULL) && 02331 (DeviceObject->DriverObject != irpLastSp->DeviceObject->DriverObject) 02332 ) { 02333 02334 // 02335 // Duplication of both the completion and the context 02336 // while not properly zeroing the control field is enough 02337 // to make me believe the caller has made a vexing mistake. 02338 // 02339 FAIL_CALLER_OF_IOFCALLDRIVER2( 02340 (DCERROR_IRPSP_COPIED, DCPARAM_IRP, Irp), 02341 irpSp 02342 ) ; 02343 02344 // 02345 // Repair the stack 02346 // 02347 irpSp->CompletionRoutine = NULL ; 02348 irpSp->Control = 0 ; 02349 02350 } else if (!irpSp->CompletionRoutine) { 02351 02352 if (!(irpSp->Control&SL_NOTCOPIED) 02353 #ifdef HACKHACKS_ENABLED 02354 && (!(IovpHackFlags&HACKFLAG_FOR_SCSIPORT)) 02355 #endif 02356 ) { 02357 02358 // 02359 // ADRIAO HACKHACK 06/12/98 #10 - PeterWie does this for 02360 // two reasons: 02361 // 1) It's easier to debug 02362 // 2) The space is not really recovered anyway. 02363 // 02364 // This will be an ongoing argument it seems, but #2 can 02365 // be cleverly solved if one decrements their stack 02366 // count, and #1 I've solved in Debug... 02367 // 02368 if (irpSp->MajorFunction == IRP_MJ_POWER) { 02369 02370 // 02371 // Unwind back past PoCallDriver... 02372 // 02373 WDM_CHASTISE_CALLER5( 02374 (DCERROR_UNNECCESSARY_COPY, DCPARAM_IRP, Irp) 02375 ); 02376 02377 } else { 02378 02379 WDM_CHASTISE_CALLER3( 02380 (DCERROR_UNNECCESSARY_COPY, DCPARAM_IRP, Irp) 02381 ); 02382 } 02383 } 02384 02385 IoSetCompletionRoutine( 02386 Irp, 02387 IovpInternalCompletionTrap, 02388 IoGetCurrentIrpStackLocation( Irp ), 02389 TRUE, 02390 TRUE, 02391 TRUE 02392 ) ; 02393 } 02394 } 02395 02396 } else if (IovPacket->AssertFlags&ASSERTFLAG_CONSUME_ALWAYS) { 02397 02398 if (ForwardMethod == FORWARDED_TO_NEXT_DO) { 02399 02400 if (Irp->CurrentLocation<2) { 02401 02402 FAIL_CALLER_OF_IOFCALLDRIVER2( 02403 (DCERROR_INSUFFICIENT_STACK_LOCATIONS, DCPARAM_IRP, Irp), 02404 irpSp 02405 ) ; 02406 02407 } else { 02408 02409 // 02410 // Back up the skip, then copy. Add a completion routine with 02411 // unique and assertable context to catch people who clumsily 02412 // Rtl-copy stack locations (we can't catch them if the caller 02413 // above used an empty stack with no completion routine)... 02414 // 02415 IoSetNextIrpStackLocation( Irp ) ; 02416 02417 // 02418 // Set the trap... 02419 // 02420 IoCopyCurrentIrpStackLocationToNext( Irp ) ; 02421 IoSetCompletionRoutine( 02422 Irp, 02423 IovpInternalCompletionTrap, 02424 IoGetCurrentIrpStackLocation( Irp ), 02425 TRUE, 02426 TRUE, 02427 TRUE 02428 ) ; 02429 02430 // 02431 // This is our new reality... 02432 // 02433 locationsAdvanced = 1 ; 02434 irpSp = IoGetNextIrpStackLocation( Irp ); 02435 } 02436 } 02437 } 02438 } 02439 02440 *IoCurrentStackLocation = irpSp; 02441 *IoLastStackLocation = irpLastSp; 02442 *StackLocationsAdvanced = locationsAdvanced; 02443 }

VOID FASTCALL IovpFinalizeIrpSettings IN OUT PIOV_REQUEST_PACKET  IrpTrackingData,
IN BOOLEAN  SurrogateIrpSwapped
 

VOID FASTCALL IovpFreeIrp IN PIRP  Irp,
IN OUT PBOOLEAN  FreeHandled
 

Definition at line 2990 of file trackirp.c.

References _IRP::AllocationFlags, ASSERT, ASSERTFLAG_POLICEIRPS, _IOV_REQUEST_PACKET::AssertFlags, DCERROR_FREE_OF_INUSE_IRP, DCERROR_FREE_OF_THREADED_IRP, DCPARAM_IRP, FALSE, _IOV_REQUEST_PACKET::Flags, IovpProtectedIrpFree(), IovpProtectedIrpMakeUntouchable(), IovpTrackingDataDereference(), IovpTrackingDataFindAndLock(), IovpTrackingDataGetCurrentSessionData(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, Irp, IRP_ALLOCATION_MONITORED, NULL, _IOV_REQUEST_PACKET::PointerCount, _IRP::ThreadListEntry, TRACKFLAG_IO_ALLOCATED, TRACKFLAG_PROTECTEDIRP, TRACKFLAG_UNWOUND_BADLY, TRUE, _IRP::Type, and WDM_FAIL_CALLER2.

02996 : 02997 02998 This routine is called by IoFreeIrp and returns TRUE iff 02999 the free was handled internally here (in which case IoFreeIrp 03000 should do nothing). 03001 03002 We need to handle the call internally because we may turn off lookaside 03003 list cacheing to catch people reusing IRPs after they are freed. 03004 03005 Arguments: 03006 03007 Irp - A pointer to the IRP passed into 03008 IoCancelIrp. 03009 03010 FreeHandled - Indicates whether the free operation was 03011 handled entirely by this routine. 03012 03013 Return Value: 03014 03015 None. 03016 03017 --*/ 03018 { 03019 PIOV_REQUEST_PACKET iovPacket; 03020 PVOID restoreHandle ; 03021 03022 iovPacket = IovpTrackingDataFindAndLock(Irp); 03023 03024 if (iovPacket == NULL) { 03025 03026 // 03027 // ADRIAO BUGBUG 01/06/1999 - 03028 // Below assertion might fire if an IRP allocated then freed twice. 03029 // 03030 ASSERT(!(Irp->AllocationFlags&IRP_ALLOCATION_MONITORED)); 03031 *FreeHandled = FALSE ; 03032 return; 03033 } 03034 03035 if (!IsListEmpty(&Irp->ThreadListEntry)) { 03036 03037 if (iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) { 03038 03039 WDM_FAIL_CALLER2( 03040 (DCERROR_FREE_OF_THREADED_IRP, DCPARAM_IRP, Irp) 03041 ); 03042 } 03043 03044 // 03045 // <Grumble> keep us alive by not actually freeing the IRP if someone did 03046 // this to us. We leak for life... 03047 // 03048 *FreeHandled = TRUE ; 03049 return ; 03050 } 03051 03052 if (IovpTrackingDataGetCurrentSessionData(iovPacket)) { 03053 03054 // 03055 // If there's a current session, that means someone is freeing an IRP 03056 // that they don't own. Of course, if the stack unwound badly because 03057 // someone forgot to return PENDING or complete the IRP, then we don't 03058 // assert here (we'd probably end up blaiming kernel). 03059 // 03060 if ((iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) && 03061 (!(iovPacket->Flags&TRACKFLAG_UNWOUND_BADLY))) { 03062 03063 WDM_FAIL_CALLER2( 03064 (DCERROR_FREE_OF_INUSE_IRP, DCPARAM_IRP, Irp) 03065 ); 03066 } 03067 03068 // 03069 // <Grumble> keep us alive by not actually freeing the IRP if someone did 03070 // this to us. We leak for life... 03071 // 03072 IovpTrackingDataReleaseLock(iovPacket) ; 03073 *FreeHandled = TRUE ; 03074 return ; 03075 } 03076 03077 if (!(iovPacket->Flags&TRACKFLAG_IO_ALLOCATED)) { 03078 03079 // 03080 // We weren't tracking this at allocation time. We shouldn't got our 03081 // packet unless the IRP had a pointer count still, meaning it's has 03082 // a session. And that should've been caught above. 03083 // 03084 ASSERT(0); 03085 IovpTrackingDataReleaseLock(iovPacket) ; 03086 *FreeHandled = FALSE ; 03087 return; 03088 } 03089 03090 // 03091 // The IRP may have been reinitialized, possibly losing it's allocation 03092 // flags. We catch this bug in the IoInitializeIrp hook. 03093 // 03094 //ASSERT(Irp->AllocationFlags&IRP_ALLOCATION_MONITORED) ; 03095 // 03096 03097 if (!(iovPacket->Flags&TRACKFLAG_PROTECTEDIRP)) { 03098 03099 // 03100 // We're just tagging along this IRP. Drop our pointer count but bail. 03101 // 03102 IovpTrackingDataDereference(iovPacket, IOVREFTYPE_POINTER); 03103 IovpTrackingDataReleaseLock(iovPacket); 03104 *FreeHandled = FALSE; 03105 return; 03106 } 03107 03108 // 03109 // Set up a nice bugcheck for those who free their IRPs twice. This is done 03110 // because the special pool may have been exhausted, in which case the IRP 03111 // can be touched after it has been freed. 03112 // 03113 Irp->Type = 0; 03114 03115 ASSERT(iovPacket) ; 03116 ASSERT(iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS); 03117 IovpTrackingDataDereference(iovPacket, IOVREFTYPE_POINTER); 03118 ASSERT(iovPacket->PointerCount == 0); 03119 IovpTrackingDataReleaseLock(iovPacket) ; 03120 restoreHandle = IovpProtectedIrpMakeUntouchable(Irp, TRUE) ; 03121 IovpProtectedIrpFree(Irp, &restoreHandle) ; 03122 03123 // 03124 // We handled allocation and initialization. There is nothing much more to 03125 // do. 03126 // 03127 *FreeHandled = TRUE ; 03128 }

PDEVICE_OBJECT FASTCALL IovpGetDeviceAttachedTo IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 3620 of file trackirp.c.

References _DEVOBJ_EXTENSION::AttachedTo, IopDatabaseLock, NULL, and ObReferenceObject.

Referenced by IovpCallDriver1(), IovpCallDriver2(), IovpDeleteDevice(), and IovpExamineDevObjForwarding().

03623 { 03624 PDEVOBJ_EXTENSION deviceExtension; 03625 PDEVICE_OBJECT deviceAttachedTo ; 03626 KIRQL irql ; 03627 03628 if (DeviceObject == NULL) { 03629 03630 return NULL ; 03631 } 03632 03633 ExAcquireFastLock( &IopDatabaseLock, &irql ); 03634 03635 deviceExtension = DeviceObject->DeviceObjectExtension; 03636 deviceAttachedTo = deviceExtension->AttachedTo ; 03637 03638 if (deviceAttachedTo) { 03639 ObReferenceObject(deviceAttachedTo) ; 03640 } 03641 03642 ExReleaseFastLock( &IopDatabaseLock, irql ); 03643 return deviceAttachedTo ; 03644 }

PDEVICE_OBJECT FASTCALL IovpGetLowestDevice IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 3648 of file trackirp.c.

References _DEVOBJ_EXTENSION::AttachedTo, _DEVICE_OBJECT::DeviceObjectExtension, IopDatabaseLock, and ObReferenceObject.

Referenced by IovpAssertNewRequest(), IovpAssertNonLegacyDevice(), IovpCallDriver1(), and IovpThrowChaffAtStartedPdoStack().

03656 { 03657 PDEVOBJ_EXTENSION deviceExtension; 03658 PDEVICE_OBJECT lowerDevobj, deviceAttachedTo ; 03659 KIRQL irql ; 03660 03661 deviceAttachedTo = DeviceObject ; 03662 03663 ExAcquireFastLock( &IopDatabaseLock, &irql ); 03664 03665 do { 03666 lowerDevobj = deviceAttachedTo ; 03667 deviceExtension = lowerDevobj->DeviceObjectExtension; 03668 deviceAttachedTo = deviceExtension->AttachedTo ; 03669 03670 } while ( deviceAttachedTo ); 03671 03672 ObReferenceObject(lowerDevobj) ; 03673 03674 ExReleaseFastLock( &IopDatabaseLock, irql ); 03675 return lowerDevobj ; 03676 }

VOID FASTCALL IovpInitializeIrp IN OUT PIRP  Irp,
IN USHORT  PacketSize,
IN CCHAR  StackSize,
IN OUT PBOOLEAN  InitializeHandled
 

Definition at line 3268 of file trackirp.c.

References _IRP::AllocationFlags, ASSERTFLAG_POLICEIRPS, _IOV_REQUEST_PACKET::AssertFlags, DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA, DCPARAM_IRP, FALSE, _IOV_REQUEST_PACKET::Flags, IovpTrackingDataFindAndLock(), IovpTrackingDataReleaseLock(), Irp, IRP_QUOTA_CHARGED, NULL, TRACKFLAG_IO_ALLOCATED, and WDM_FAIL_CALLER2.

03276 : 03277 03278 This routine is called by IoInitializeIrp and sets InitializeHandled to 03279 TRUE if the entire initialization was handled internally. 03280 03281 While here we verify the caller is not Initializing an IRP allocated 03282 through IoAllocateIrp, as doing so means we may leak quota/etc. 03283 03284 Arguments: 03285 03286 Irp - Irp to initialize 03287 03288 PacketSize - Size of the IRP in bytes. 03289 03290 StackSize - Count of stack locations for this IRP. 03291 03292 InitializeHandled - Pointer to a BOOLEAN that will be set to true iff 03293 the initialization of the IRP was handled entirely 03294 within this routine. If FALSE, IoInitializeIrp 03295 should initialize the IRP as normal. 03296 03297 Return Value: 03298 03299 None. 03300 03301 --*/ 03302 { 03303 PIOV_REQUEST_PACKET iovPacket ; 03304 03305 iovPacket = IovpTrackingDataFindAndLock(Irp); 03306 if (iovPacket == NULL) { 03307 03308 *InitializeHandled = FALSE ; 03309 return; 03310 } 03311 03312 if ((iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) && 03313 (iovPacket->Flags&TRACKFLAG_IO_ALLOCATED)) { 03314 03315 if (Irp->AllocationFlags&IRP_QUOTA_CHARGED) { 03316 03317 // 03318 // Don't let us leak quota now! 03319 // 03320 WDM_FAIL_CALLER2( 03321 (DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA, DCPARAM_IRP, Irp) 03322 ); 03323 03324 } else { 03325 03326 // 03327 // In this case we are draining our lookaside lists erroneously. 03328 // 03329 // WDM_CHASTISE_CALLER2( 03330 // (DCERROR_REINIT_OF_ALLOCATED_IRP_WITHOUT_QUOTA, DCPARAM_IRP, Irp) 03331 // ); 03332 } 03333 } 03334 03335 *InitializeHandled = FALSE ; 03336 IovpTrackingDataReleaseLock(iovPacket) ; 03337 }

BOOLEAN FASTCALL IovpInitIrpTracking IN ULONG  Level,
IN ULONG  Flags
 

Definition at line 257 of file trackirp.c.

References ASSERTFLAG_COMPLETEATDPC, ASSERTFLAG_CONSUME_ALWAYS, ASSERTFLAG_DEFERCOMPLETION, ASSERTFLAG_FORCEPENDING, ASSERTFLAG_MONITOR_ALLOCS, ASSERTFLAG_MONITORMAJORS, ASSERTFLAG_POLICEIRPS, ASSERTFLAG_ROTATE_STATUS, ASSERTFLAG_SEEDSTACK, ASSERTFLAG_SMASH_SRBS, ASSERTFLAG_SURROGATE, ASSERTFLAG_TRACKIRPS, HACKFLAG_FOR_ACPI, HACKFLAG_FOR_BOGUSIRPS, HACKFLAG_FOR_MUP, HACKFLAG_FOR_SCSIPORT, IOVERIFIERINIT_EVERYTHING_TRACKED, IOVERIFIERINIT_NO_REINIT, IovpHackFlags, IovpInitFlags, IovpIrpTrackingEnabled, IovpTrackingDataInit(), IovpTrackingFlags, PAGED_CODE, and TRUE.

Referenced by IoVerifierInit().

00263 : 00264 00265 Initialize that which needs to be initialized. 00266 00267 Arguments: 00268 00269 Level - Level of testing to apply 00270 0 - No checks 00271 1 - Tracking with surrogate irp allocation 00272 2 - Monitors basic IRP mistakes 00273 3 - Monitors mistakes based on the irp major 00274 Surrogate IRPs used, status values rotated, 00275 and various other checks. 00276 4 - IRPs always completed at DPC. 00277 5 - All IRPs pended with completion defered via timer. 00278 6 - Any hacks turned off. 00279 00280 Return Value: 00281 00282 Returns TRUE iff settings were successfully applied. 00283 00284 --*/ 00285 { 00286 PVOID sectionHeaderHandle; 00287 ULONG newTrackingFlags; 00288 00289 PAGED_CODE(); 00290 00291 if (IovpIrpTrackingEnabled) { 00292 00293 IovpInitFlags = (Flags | (IovpInitFlags&IOVERIFIERINIT_EVERYTHING_TRACKED)); 00294 00295 } else { 00296 00297 IovpTrackingDataInit(); 00298 00299 IovpInitFlags = Flags; 00300 IovpIrpTrackingEnabled = TRUE; 00301 } 00302 00303 newTrackingFlags = 0; 00304 switch(Level) { 00305 00306 default: 00307 case 7: 00308 IovpHackFlags = 0; 00309 00310 case 6: 00311 newTrackingFlags |= ASSERTFLAG_FORCEPENDING | 00312 ASSERTFLAG_DEFERCOMPLETION; 00313 // 00314 // Fall through 00315 // 00316 00317 case 5: 00318 newTrackingFlags |= ASSERTFLAG_COMPLETEATDPC; 00319 // 00320 // Fall through 00321 // 00322 00323 case 4: 00324 newTrackingFlags |= ASSERTFLAG_SURROGATE | 00325 ASSERTFLAG_SMASH_SRBS | 00326 ASSERTFLAG_CONSUME_ALWAYS | 00327 ASSERTFLAG_ROTATE_STATUS | 00328 ASSERTFLAG_SEEDSTACK; 00329 // 00330 // Fall through 00331 // 00332 00333 case 3: 00334 newTrackingFlags |= ASSERTFLAG_MONITORMAJORS; 00335 // 00336 // Fall through 00337 // 00338 00339 case 2: 00340 newTrackingFlags |= ASSERTFLAG_POLICEIRPS; 00341 // 00342 // Fall through 00343 // 00344 00345 case 1: 00346 newTrackingFlags |= ASSERTFLAG_TRACKIRPS | 00347 ASSERTFLAG_MONITOR_ALLOCS; 00348 // 00349 // Fall through 00350 // 00351 00352 case 0: 00353 break; 00354 } 00355 00356 if ((Level == 0) && (Flags&IOVERIFIERINIT_NO_REINIT)) { 00357 00358 // 00359 // Preinit flags 00360 // 00361 newTrackingFlags = IovpTrackingFlags; 00362 } 00363 00364 if (IovpHackFlags == (ULONG) -1) { 00365 00366 IovpHackFlags = 00367 #ifdef HACKHACKS_ENABLED 00368 #ifdef HACKHACK_FOR_MUP 00369 HACKFLAG_FOR_MUP | 00370 #endif 00371 #ifdef HACKHACK_FOR_SCSIPORT 00372 HACKFLAG_FOR_SCSIPORT | 00373 #endif 00374 #ifdef HACKHACK_FOR_ACPI 00375 HACKFLAG_FOR_ACPI | 00376 #endif 00377 #ifdef HACKHACK_FOR_BOGUSIRPS 00378 HACKFLAG_FOR_BOGUSIRPS | 00379 #endif 00380 #endif // HACKHACKS_ENABLED 00381 0; 00382 } 00383 00384 if (!(IovpInitFlags & IOVERIFIERINIT_EVERYTHING_TRACKED)) { 00385 00386 // 00387 // These options aren't available unless we were marking IRPs since 00388 // boot. 00389 // 00390 newTrackingFlags &=~ ( 00391 ASSERTFLAG_MONITORMAJORS | 00392 ASSERTFLAG_SURROGATE | 00393 ASSERTFLAG_SMASH_SRBS | 00394 ASSERTFLAG_CONSUME_ALWAYS 00395 ); 00396 } 00397 00398 IovpTrackingFlags = newTrackingFlags; 00399 return TRUE; 00400 }

VOID IovpInternalCompleteAfterWait IN PVOID  Context  ) 
 

Definition at line 2499 of file trackirp.c.

References ASSERT, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, _DEFERRAL_CONTEXT::DeferAction, DEFERACTION_QUEUE_PASSIVE_TIMER, _DEFERRAL_CONTEXT::DeferralTimer, _DEFERRAL_CONTEXT::DeviceObject, Executive, ExFreePool(), FALSE, _IOV_REQUEST_PACKET::Flags, IoCompleteRequest, IoGetNextIrpStackLocation, IovpProtectedIrpMakeTouchable(), IovpTrackingDataAcquireLock(), IovpTrackingDataDereference(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, _DEFERRAL_CONTEXT::IovRequestPacket, _DEFERRAL_CONTEXT::IrpSpNext, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, _DEFERRAL_CONTEXT::OriginalCompletionRoutine, _DEFERRAL_CONTEXT::OriginalContext, _DEFERRAL_CONTEXT::OriginalIrp, _DEFERRAL_CONTEXT::OriginalPriorityBoost, PASSIVE_LEVEL, _IOV_REQUEST_PACKET::RestoreHandle, and TRACKFLAG_QUEUED_INTERNALLY.

Referenced by IovpInternalCompleteAtDPC(), and IovpInternalDeferredCompletion().

02502 { 02503 PDEFERRAL_CONTEXT deferralContext = (PDEFERRAL_CONTEXT) Context ; 02504 PIO_STACK_LOCATION irpSpNext ; 02505 NTSTATUS status ; 02506 02507 if (deferralContext->DeferAction == DEFERACTION_QUEUE_PASSIVE_TIMER) { 02508 02509 // 02510 // Wait the appropriate amount of time if so ordered... 02511 // 02512 ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL) ; 02513 KeWaitForSingleObject( 02514 &deferralContext->DeferralTimer, 02515 Executive, 02516 KernelMode, 02517 FALSE, 02518 NULL 02519 ) ; 02520 } 02521 02522 IovpTrackingDataAcquireLock(deferralContext->IovRequestPacket) ; 02523 02524 IovpProtectedIrpMakeTouchable( 02525 deferralContext->OriginalIrp, 02526 &deferralContext->IovRequestPacket->RestoreHandle 02527 ); 02528 02529 irpSpNext = IoGetNextIrpStackLocation( deferralContext->OriginalIrp ) ; 02530 02531 ASSERT(irpSpNext == deferralContext->IrpSpNext) ; 02532 ASSERT(irpSpNext->CompletionRoutine == deferralContext->OriginalCompletionRoutine) ; 02533 ASSERT(irpSpNext->Context == deferralContext->OriginalContext) ; 02534 02535 ASSERT(deferralContext->IovRequestPacket->Flags & TRACKFLAG_QUEUED_INTERNALLY) ; 02536 deferralContext->IovRequestPacket->Flags &=~ TRACKFLAG_QUEUED_INTERNALLY ; 02537 02538 IovpTrackingDataDereference(deferralContext->IovRequestPacket, IOVREFTYPE_POINTER) ; 02539 IovpTrackingDataReleaseLock(deferralContext->IovRequestPacket) ; 02540 02541 status = irpSpNext->CompletionRoutine( 02542 deferralContext->DeviceObject, 02543 deferralContext->OriginalIrp, 02544 irpSpNext->Context 02545 ) ; 02546 02547 if (status!=STATUS_MORE_PROCESSING_REQUIRED) { 02548 02549 IoCompleteRequest(deferralContext->OriginalIrp, deferralContext->OriginalPriorityBoost) ; 02550 } 02551 ExFreePool(deferralContext) ; 02552 }

VOID IovpInternalCompleteAtDPC IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 2488 of file trackirp.c.

References IovpInternalCompleteAfterWait().

Referenced by IovpInternalDeferredCompletion().

02494 { 02495 IovpInternalCompleteAfterWait(DeferredContext) ; 02496 }

NTSTATUS IovpInternalCompletionTrap IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 2446 of file trackirp.c.

References ASSERT, IoGetCurrentIrpStackLocation, IoMarkIrpPending, Irp, and _IRP::PendingReturned.

Referenced by IovpExamineIrpStackForwarding().

02453 : 02454 02455 This routine does nothing but act as a trap for people 02456 incorrectly copying stack locations... 02457 02458 Arguments: 02459 02460 DeviceObject - Device object set at this level of the completion 02461 routine - ignored. 02462 02463 Irp - A pointer to the IRP. 02464 02465 Context - Context should equal the Irp's stack location - 02466 this is asserted. 02467 02468 Return Value: 02469 02470 STATUS_SUCCESS 02471 02472 --*/ 02473 { 02474 PIO_STACK_LOCATION irpSp ; 02475 02476 if (Irp->PendingReturned) { 02477 02478 IoMarkIrpPending( Irp ) ; 02479 } 02480 irpSp = IoGetCurrentIrpStackLocation( Irp ) ; 02481 02482 ASSERT((PVOID) irpSp == Context) ; 02483 02484 return STATUS_SUCCESS ; 02485 }

NTSTATUS IovpInternalDeferredCompletion IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 2555 of file trackirp.c.

References ASSERT, ASSERTFLAG_COMPLETEATDPC, ASSERTFLAG_COMPLETEATPASSIVE, ASSERTFLAG_DEFERCOMPLETION, ASSERTFLAG_FORCEPENDING, ASSERTFLAG_POLICEIRPS, _IOV_REQUEST_PACKET::AssertFlags, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, DCERROR_COMPLETION_ROUTINE_PAGABLE, DCPARAM_IRP, DCPARAM_ROUTINE, DEFER_ACTION, _DEFERRAL_CONTEXT::DeferAction, DEFERACTION_NORMAL, DEFERACTION_QUEUE_DISPATCH_TIMER, DEFERACTION_QUEUE_PASSIVE_TIMER, DEFERACTION_QUEUE_WORKITEM, _DEFERRAL_CONTEXT::DeferralTimer, DelayedWorkQueue, _DEFERRAL_CONTEXT::DeviceObject, DISPATCH_LEVEL, _DEFERRAL_CONTEXT::DpcItem, ExFreePool(), ExInitializeWorkItem, ExQueueWorkItem(), FALSE, _IOV_REQUEST_PACKET::Flags, IoGetNextIrpStackLocation, IovpInternalCompleteAfterWait(), IovpInternalCompleteAtDPC(), IovpInternalDeferredCompletion(), IovpIrpDeferralTime, IovpProtectedIrpMakeUntouchable(), IovpTrackingDataAcquireLock(), IovpTrackingDataDereference(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, _DEFERRAL_CONTEXT::IovRequestPacket, Irp, KDASSERT, KeInitializeDpc(), KeInitializeTimerEx(), KeSetTimerEx(), MmIsSystemAddressLocked(), NULL, _DEFERRAL_CONTEXT::OriginalCompletionRoutine, _DEFERRAL_CONTEXT::OriginalContext, PASSIVE_LEVEL, _IOV_REQUEST_PACKET::RestoreHandle, TRACKFLAG_QUEUED_INTERNALLY, WDM_FAIL_ROUTINE, and _DEFERRAL_CONTEXT::WorkQueueItem.

Referenced by IovpCompleteRequest3(), and IovpInternalDeferredCompletion().

02562 : 02563 02564 This function is slipped in as a completion routine when we are 02565 "deferring" completion via work item, etc. 02566 02567 Arguments: 02568 02569 DeviceObject - Device object set at this level of the completion 02570 routine - passed on. 02571 02572 Irp - A pointer to the IRP. 02573 02574 Context - Context block that includes original completion 02575 routine. 02576 02577 Return Value: 02578 02579 NTSTATUS 02580 02581 --*/ 02582 { 02583 PDEFERRAL_CONTEXT deferralContext = (PDEFERRAL_CONTEXT) Context; 02584 PIO_STACK_LOCATION irpSpNext; 02585 BOOLEAN passiveCompletionOK; 02586 DEFER_ACTION deferAction; 02587 ULONG refAction; 02588 ULONG trackingFlags; 02589 LARGE_INTEGER deltaTime; 02590 02591 // 02592 // Do delta time conversion. 02593 // 02594 deltaTime.QuadPart = - IovpIrpDeferralTime ; 02595 02596 // 02597 // The *next* stack location holds our completion and context. The current 02598 // stack location has already been wiped. 02599 // 02600 irpSpNext = IoGetNextIrpStackLocation( Irp ) ; 02601 02602 ASSERT((PVOID) irpSpNext->CompletionRoutine == IovpInternalDeferredCompletion) ; 02603 02604 // 02605 // Put everything back in case someone is looking... 02606 // 02607 irpSpNext->CompletionRoutine = deferralContext->OriginalCompletionRoutine ; 02608 irpSpNext->Context = deferralContext->OriginalContext ; 02609 02610 // 02611 // Some IRP dispatch routines cannot be called at passive. Two examples are 02612 // paging IRPs (cause we could switch) and Power IRPs. As we don't check yet, 02613 // if we "were" completed passive, continue to do so, but elsewhere... 02614 // 02615 passiveCompletionOK = (KeGetCurrentIrql()==PASSIVE_LEVEL) ; 02616 02617 IovpTrackingDataAcquireLock(deferralContext->IovRequestPacket) ; 02618 02619 // 02620 // Verify all completion routines are in nonpaged code. 02621 // 02622 if (deferralContext->IovRequestPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) { 02623 02624 if (MmIsSystemAddressLocked(irpSpNext->CompletionRoutine) == FALSE) { 02625 02626 WDM_FAIL_ROUTINE(( 02627 DCERROR_COMPLETION_ROUTINE_PAGABLE, 02628 DCPARAM_IRP + DCPARAM_ROUTINE, 02629 Irp, 02630 irpSpNext->CompletionRoutine 02631 )) ; 02632 } 02633 } 02634 02635 trackingFlags = deferralContext->IovRequestPacket->AssertFlags; 02636 02637 ASSERT(trackingFlags&ASSERTFLAG_FORCEPENDING) ; 02638 02639 switch(trackingFlags&(ASSERTFLAG_DEFERCOMPLETION| 02640 ASSERTFLAG_COMPLETEATPASSIVE| 02641 ASSERTFLAG_COMPLETEATDPC)) { 02642 02643 case ASSERTFLAG_COMPLETEATPASSIVE: 02644 deferAction = passiveCompletionOK ? DEFERACTION_QUEUE_WORKITEM : 02645 DEFERACTION_NORMAL ; 02646 break; 02647 02648 case ASSERTFLAG_DEFERCOMPLETION | ASSERTFLAG_COMPLETEATPASSIVE: 02649 deferAction = passiveCompletionOK ? DEFERACTION_QUEUE_PASSIVE_TIMER : 02650 DEFERACTION_NORMAL ; 02651 break; 02652 02653 case ASSERTFLAG_DEFERCOMPLETION | ASSERTFLAG_COMPLETEATDPC: 02654 deferAction = DEFERACTION_QUEUE_DISPATCH_TIMER ; 02655 break; 02656 02657 case ASSERTFLAG_DEFERCOMPLETION: 02658 deferAction = (KeGetCurrentIrql()==DISPATCH_LEVEL) ? 02659 DEFERACTION_QUEUE_DISPATCH_TIMER : 02660 DEFERACTION_QUEUE_PASSIVE_TIMER ; 02661 break; 02662 02663 default: 02664 deferAction = DEFERACTION_NORMAL ; 02665 KDASSERT(0) ; 02666 } 02667 02668 if (deferAction != DEFERACTION_NORMAL) { 02669 02670 // 02671 // Set this flag. If anybody uses this IRP while this flag is on, complain 02672 // immediately! 02673 // 02674 ASSERT(!(trackingFlags&TRACKFLAG_QUEUED_INTERNALLY)) ; 02675 deferralContext->IovRequestPacket->Flags |= TRACKFLAG_QUEUED_INTERNALLY ; 02676 deferralContext->DeviceObject = DeviceObject ; 02677 02678 deferralContext->IovRequestPacket->RestoreHandle = 02679 IovpProtectedIrpMakeUntouchable( 02680 Irp, 02681 FALSE 02682 ) ; 02683 } else { 02684 02685 IovpTrackingDataDereference(deferralContext->IovRequestPacket, IOVREFTYPE_POINTER); 02686 } 02687 02688 IovpTrackingDataReleaseLock(deferralContext->IovRequestPacket) ; 02689 02690 deferralContext->DeferAction = deferAction ; 02691 02692 switch(deferAction) { 02693 02694 case DEFERACTION_QUEUE_PASSIVE_TIMER: 02695 KeInitializeTimerEx(&deferralContext->DeferralTimer, SynchronizationTimer) ; 02696 KeSetTimerEx( 02697 &deferralContext->DeferralTimer, 02698 deltaTime, 02699 0, 02700 NULL 02701 ) ; 02702 02703 // 02704 // Fall through... 02705 // 02706 02707 case DEFERACTION_QUEUE_WORKITEM: 02708 02709 // 02710 // Queue this up so we can complete this passively. 02711 // 02712 ExInitializeWorkItem( 02713 (PWORK_QUEUE_ITEM)&deferralContext->WorkQueueItem, 02714 IovpInternalCompleteAfterWait, 02715 deferralContext 02716 ); 02717 02718 ExQueueWorkItem( 02719 (PWORK_QUEUE_ITEM)&deferralContext->WorkQueueItem, 02720 DelayedWorkQueue 02721 ); 02722 02723 return STATUS_MORE_PROCESSING_REQUIRED ; 02724 02725 case DEFERACTION_QUEUE_DISPATCH_TIMER: 02726 02727 KeInitializeDpc( 02728 &deferralContext->DpcItem, 02729 IovpInternalCompleteAtDPC, 02730 deferralContext 02731 ); 02732 02733 KeInitializeTimerEx(&deferralContext->DeferralTimer, SynchronizationTimer) ; 02734 KeSetTimerEx( 02735 &deferralContext->DeferralTimer, 02736 deltaTime, 02737 0, 02738 &deferralContext->DpcItem 02739 ) ; 02740 return STATUS_MORE_PROCESSING_REQUIRED ; 02741 02742 case DEFERACTION_NORMAL: 02743 default: 02744 02745 ExFreePool(deferralContext) ; 02746 return irpSpNext->CompletionRoutine(DeviceObject, Irp, irpSpNext->Context) ; 02747 } 02748 }

BOOLEAN FASTCALL IovpIsInFdoStack IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 3717 of file trackirp.c.

References _DEVOBJ_EXTENSION::AttachedTo, _DEVICE_OBJECT::DeviceObjectExtension, DOE_BOTTOM_OF_FDO_STACK, _DEVOBJ_EXTENSION::ExtensionFlags, IopDatabaseLock, and NULL.

Referenced by IovpCallDriver1().

03720 { 03721 PDEVOBJ_EXTENSION deviceExtension; 03722 PDEVICE_OBJECT deviceAttachedTo, lowerDevobj ; 03723 KIRQL irql ; 03724 03725 deviceAttachedTo = DeviceObject ; 03726 03727 ExAcquireFastLock( &IopDatabaseLock, &irql ); 03728 03729 do { 03730 if (deviceAttachedTo->DeviceObjectExtension->ExtensionFlags&DOE_BOTTOM_OF_FDO_STACK) { 03731 break; 03732 } 03733 deviceAttachedTo = deviceAttachedTo->DeviceObjectExtension->AttachedTo ; 03734 03735 } while ( deviceAttachedTo ); 03736 03737 ExReleaseFastLock( &IopDatabaseLock, irql ); 03738 return (deviceAttachedTo != NULL) ; 03739 }

BOOLEAN IovpIsInterestingDriver IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 3521 of file trackirp.c.

References IOVERIFIERINIT_VERIFIER_DRIVER_LIST, IovpInitFlags, MmIsDriverVerifying(), and TRUE.

Referenced by IovpIsInterestingStack().

03524 { 03525 if (IovpInitFlags&IOVERIFIERINIT_VERIFIER_DRIVER_LIST) { 03526 03527 return (BOOLEAN) MmIsDriverVerifying(DriverObject); 03528 03529 } else { 03530 03531 return TRUE; 03532 } 03533 }

BOOLEAN IovpIsInterestingStack IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 3436 of file trackirp.c.

References _DEVICE_OBJECT::AttachedDevice, _DEVOBJ_EXTENSION::AttachedTo, _DEVICE_OBJECT::DeviceObjectExtension, DOE_EXAMINED, DOE_TRACKED, _DEVICE_OBJECT::DriverObject, _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, IopDatabaseLock, IovpIsInterestingDriver(), and TRUE.

Referenced by IovpSessionDataDeterminePolicy().

03439 { 03440 PDEVOBJ_EXTENSION deviceExtension; 03441 PDEVICE_OBJECT currentDevObj, deviceAttachedTo; 03442 BOOLEAN stackIsInteresting; 03443 KIRQL irql; 03444 03445 // 03446 // Walk downward until we find the PDO or an examined device object. 03447 // 03448 ExAcquireFastLock( &IopDatabaseLock, &irql ); 03449 03450 // 03451 // Quickly check the top of the stack... 03452 // 03453 if (DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_EXAMINED) { 03454 03455 stackIsInteresting = 03456 ((DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_TRACKED) != 0); 03457 03458 ExReleaseFastLock( &IopDatabaseLock, irql ); 03459 return stackIsInteresting; 03460 } 03461 03462 // 03463 // OK, if the top hasn't been examined, odds are devices below it haven't 03464 // either. Walk downwards until we can determine whether the stack as a 03465 // whole should be tracked. 03466 // 03467 stackIsInteresting = FALSE; 03468 deviceAttachedTo = DeviceObject; 03469 do { 03470 currentDevObj = deviceAttachedTo; 03471 deviceExtension = currentDevObj->DeviceObjectExtension; 03472 deviceAttachedTo = deviceExtension->AttachedTo; 03473 03474 // 03475 // Remember this... 03476 // 03477 if (IovpIsInterestingDriver(currentDevObj->DriverObject)) { 03478 03479 stackIsInteresting = TRUE; 03480 } 03481 03482 } while (deviceAttachedTo && 03483 (deviceAttachedTo->DeviceObjectExtension->ExtensionFlags & DOE_EXAMINED) 03484 ); 03485 03486 if (deviceAttachedTo && 03487 (deviceAttachedTo->DeviceObjectExtension->ExtensionFlags & DOE_TRACKED)) { 03488 03489 // 03490 // Propogate upwards the "interesting-ness" of the last examined device 03491 // in the stack... 03492 // 03493 stackIsInteresting = TRUE; 03494 } 03495 03496 // 03497 // Walk upwards, marking everything examined and appropriately tracked. 03498 // 03499 do { 03500 deviceExtension = currentDevObj->DeviceObjectExtension; 03501 03502 if (stackIsInteresting) { 03503 03504 deviceExtension->ExtensionFlags |= DOE_TRACKED; 03505 } else { 03506 03507 deviceExtension->ExtensionFlags &=~ DOE_TRACKED; 03508 } 03509 03510 deviceExtension->ExtensionFlags |= DOE_EXAMINED; 03511 03512 currentDevObj = currentDevObj->AttachedDevice; 03513 03514 } while (currentDevObj); 03515 03516 ExReleaseFastLock( &IopDatabaseLock, irql ); 03517 return stackIsInteresting; 03518 }

VOID IovpReexamineAllStacks VOID   ) 
 

Definition at line 3399 of file trackirp.c.

References IoDeviceObjectType, IovpEnumDevObjCallback(), NULL, ObEnumerateObjectsByType(), and PAGED_CODE.

03402 { 03403 PAGED_CODE(); 03404 03405 ObEnumerateObjectsByType( 03406 IoDeviceObjectType, 03407 IovpEnumDevObjCallback, 03408 NULL 03409 ); 03410 }

VOID FASTCALL IovpSeedOnePage VOID   ) 
 

Definition at line 3743 of file trackirp.c.

References PAGE_SIZE.

Referenced by IovpSeedStack().

03746 { 03747 ULONG StackSeed[(PAGE_SIZE/sizeof(ULONG))] ; 03748 ULONG register i ; 03749 03750 // 03751 // We use the return value 0xFFFFFFFF, as it is an illegal return value. We 03752 // are trying to catch people who don't initialize NTSTATUS, and it's also 03753 // a good pointer trap too. 03754 // 03755 for(i=0; i<(PAGE_SIZE/sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ; 03756 }

VOID FASTCALL IovpSeedStack VOID   ) 
 

Definition at line 3784 of file trackirp.c.

References ASSERTFLAG_SEEDSTACK, IovpSeedOnePage(), IovpSeedThreePages(), IovpSeedTwoPages(), IovpTrackingFlags, MmIsAddressValid(), and PAGE_SIZE.

03789 : 03790 03791 This routine "seeds" the stack so that uninitialized variables are 03792 more easily ferreted out. 03793 03794 ADRIAO BUGBUG 08/17/98 - This is a really neat idea that runs into a 03795 memory manager optimization. While I do find 03796 the appropriate guard page, the memory manager 03797 throws out the above touched pages on a thread 03798 switch and bring in new (and probably zero'd) 03799 ones. 03800 03801 Arguments: None 03802 03803 Return Value: None 03804 03805 --*/ 03806 { 03807 int i, interruptReservedOverhead ; 03808 03809 if (!(IovpTrackingFlags&ASSERTFLAG_SEEDSTACK)) { 03810 return ; 03811 } 03812 03813 // 03814 // Is there room to try this before we run out of stack? We will reserve 03815 // half a page for interrupt overhead... 03816 // 03817 interruptReservedOverhead = PAGE_SIZE/2 ; 03818 03819 // 03820 // There must be a guard page somewhere. Find it... 03821 // 03822 for(i=0; i<4; i++) { 03823 if (!MmIsAddressValid(((PUCHAR)&i)-i*PAGE_SIZE-interruptReservedOverhead)) { 03824 break; 03825 } 03826 } 03827 03828 switch(i) { 03829 case 4: IovpSeedThreePages() ; break ; 03830 case 3: IovpSeedTwoPages() ; break ; 03831 case 2: IovpSeedOnePage() ; break ; 03832 case 1: break ; // Minimum is overhead 03833 case 0: break ; // Umm, we don't even have overhead! 03834 default: break ; 03835 } 03836 }

VOID FASTCALL IovpSeedThreePages VOID   ) 
 

Definition at line 3772 of file trackirp.c.

References PAGE_SIZE.

Referenced by IovpSeedStack().

03775 { 03776 ULONG register i ; 03777 ULONG StackSeed[(PAGE_SIZE*3/sizeof(ULONG))] ; 03778 03779 for(i=0; i<(PAGE_SIZE*3/sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ; 03780 }

VOID FASTCALL IovpSeedTwoPages VOID   ) 
 

Definition at line 3760 of file trackirp.c.

References PAGE_SIZE.

Referenced by IovpSeedStack().

03763 { 03764 ULONG StackSeed[(PAGE_SIZE*2/sizeof(ULONG))] ; 03765 ULONG register i ; 03766 03767 for(i=0; i<(PAGE_SIZE*2/sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ; 03768 }

NTSTATUS IovpSwapSurrogateIrp IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 2751 of file trackirp.c.

References ASSERT, ASSERTFLAG_POLICEIRPS, _IOV_REQUEST_PACKET::AssertFlags, _IO_STACK_LOCATION::CompletionRoutine, _IO_STACK_LOCATION::Context, _IO_STACK_LOCATION::Control, _IRP::CurrentLocation, _IOV_REQUEST_PACKET::Flags, _IOV_REQUEST_PACKET::HeadPacket, IoCompleteRequest, IoGetCurrentIrpStackLocation, IoGetNextIrpStackLocation, IoSetNextIrpStackLocation, IoSizeOfIrp, IovpAssertFinalIrpStack(), IovpSessionDataClose(), IovpSessionDataDereference(), IovpSessionDataFinalizeSurrogate(), IovpTrackingDataDereference(), IovpTrackingDataFindAndLock(), IovpTrackingDataGetCurrentSessionData(), IovpTrackingDataReleaseLock(), IOVREFTYPE_POINTER, Irp, NTSTATUS(), NULL, _IOV_REQUEST_PACKET::PriorityBoost, _IOV_REQUEST_PACKET::RealIrpCompletionRoutine, _IOV_REQUEST_PACKET::RealIrpContext, _IOV_REQUEST_PACKET::RealIrpControl, _IRP::StackCount, _IOV_REQUEST_PACKET::SurrogateLink, _IOV_REQUEST_PACKET::TopStackLocation, _IOV_REQUEST_PACKET::TrackedIrp, TRACKFLAG_SWAPPED_BACK, and TRACKIRP_DBGPRINT.

Referenced by IovpCompleteRequest2(), and IovpExamineIrpStackForwarding().

02758 : 02759 02760 This completion routine will copy back the surrogate IRP 02761 to the original and complete the original IRP. 02762 02763 Arguments: 02764 02765 DeviceObject - Device object set at this level 02766 of the completion routine - ignored. 02767 02768 Irp - A pointer to the IRP. 02769 02770 Context - Context should equal the IRP - this is 02771 asserted. 02772 02773 Return Value: 02774 02775 STATUS_MORE_PROCESSING_REQUIRED... 02776 02777 --*/ 02778 { 02779 PIOV_REQUEST_PACKET iovPacket, iovPrevPacket; 02780 PIOV_SESSION_DATA iovSessionData; 02781 ULONG irpSize ; 02782 PIRP realIrp ; 02783 BOOLEAN freeTrackingData ; 02784 NTSTATUS status, lockedStatus ; 02785 CCHAR priorityBoost ; 02786 PVOID completionRoutine ; 02787 PIO_STACK_LOCATION irpSp ; 02788 BOOLEAN locked ; 02789 02790 // 02791 // If this one fails, somebody has probably copied the stack 02792 // inclusive with our completion routine. We should already 02793 // have caught this... 02794 // 02795 ASSERT(Irp == Context) ; 02796 02797 iovPacket = IovpTrackingDataFindAndLock(Irp) ; 02798 ASSERT(iovPacket) ; 02799 02800 if (iovPacket == NULL) { 02801 02802 return STATUS_SUCCESS ; 02803 } 02804 02805 ASSERT(iovPacket->TopStackLocation == Irp->CurrentLocation) ; 02806 02807 iovSessionData = IovpTrackingDataGetCurrentSessionData(iovPacket); 02808 ASSERT(iovSessionData); 02809 02810 // 02811 // Put everything back 02812 // 02813 ASSERT(iovPacket->HeadPacket != iovPacket); 02814 02815 iovPrevPacket = CONTAINING_RECORD( 02816 iovPacket->SurrogateLink.Blink, 02817 IOV_REQUEST_PACKET, 02818 SurrogateLink 02819 ); 02820 02821 realIrp = iovPrevPacket->TrackedIrp ; 02822 irpSize = IoSizeOfIrp( Irp->StackCount ) ; 02823 02824 // 02825 // Back the IRP stack up so that the original completion routine 02826 // is called if appropriate 02827 // 02828 IoSetNextIrpStackLocation(Irp); 02829 IoSetNextIrpStackLocation(realIrp); 02830 02831 irpSp = IoGetCurrentIrpStackLocation(Irp) ; 02832 irpSp->CompletionRoutine = iovPacket->RealIrpCompletionRoutine ; 02833 irpSp->Control = iovPacket->RealIrpControl ; 02834 irpSp->Context = iovPacket->RealIrpContext ; 02835 02836 // 02837 // Record final data and make any accesses to the surrogate IRP 02838 // crash. 02839 // 02840 irpSp = IoGetNextIrpStackLocation(Irp) ; 02841 if (iovPacket->AssertFlags&ASSERTFLAG_POLICEIRPS) { 02842 02843 IovpAssertFinalIrpStack(iovPacket, irpSp) ; 02844 } 02845 02846 priorityBoost = iovPacket->PriorityBoost ; 02847 IovpTrackingDataDereference(iovPacket, IOVREFTYPE_POINTER); 02848 IovpSessionDataFinalizeSurrogate(iovSessionData, iovPacket, Irp); 02849 IovpSessionDataClose(iovSessionData); 02850 IovpSessionDataDereference(iovSessionData); 02851 02852 TRACKIRP_DBGPRINT(( 02853 " Swapping surrogate IRP %lx back to %lx (Tracking data %lx)\n", 02854 Irp, 02855 realIrp, 02856 iovPacket 02857 ), 1) ; 02858 02859 iovPacket->Flags |= TRACKFLAG_SWAPPED_BACK ; 02860 IovpTrackingDataReleaseLock(iovPacket) ; 02861 02862 // 02863 // Send the IRP onwards and upwards. 02864 // 02865 IoCompleteRequest(realIrp, priorityBoost) ; 02866 02867 return STATUS_MORE_PROCESSING_REQUIRED ; 02868 }


Variable Documentation

ULONG IovpHackFlags
 

Definition at line 55 of file trackirp.h.

Referenced by IovpExamineIrpStackForwarding(), IovpInitIrpTracking(), IovpSessionDataDeterminePolicy(), and IovpThrowChaffAtStartedPdoStack().

ULONG IovpTrackingFlags
 

Definition at line 56 of file trackirp.h.

Referenced by IovpAllocateIrp1(), IovpAllocateIrp2(), IovpCallDriver1(), IovpDoAssertIrps(), IovpInitIrpTracking(), IovpSeedStack(), IovpSessionDataCreate(), IovpSessionDataDeterminePolicy(), and IovpTrackingDataCreateAndLock().


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