test: trackirp.h File Reference

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_STACKDATA * | PIOFCALLDRIVER_STACKDATA
typedef _IOV_STACK_LOCATION * | PIOV_STACK_LOCATION
typedef _IOV_REQUEST_PACKET * | PIOV_REQUEST_PACKET
typedef _IOV_SESSION_DATA * | PIOV_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_CONTEXT * | PDEFERRAL_CONTEXT
typedef _IOFCOMPLETEREQUEST_STACKDATA | IOFCOMPLETEREQUEST_STACKDATA
typedef _IOFCOMPLETEREQUEST_STACKDATA * | PIOFCOMPLETEREQUEST_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:

    {\
        if (IovpTrackingFlags && IovpDoAssertIrps()) { \
            IovpThrowChaffAtStartedPdoStack(DeviceObject);\
        }\
    }

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:

    {\
        if (IovpTrackingFlags && IovpDoAssertIrps()) { \
            IovpAllocateIrp2(Irp);\
        }\
    }

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().

    00126              {
    00127
    00128     DEFERACTION_QUEUE_WORKITEM,
    00129     DEFERACTION_QUEUE_PASSIVE_TIMER,
    00130     DEFERACTION_QUEUE_DISPATCH_TIMER,
    00131     DEFERACTION_NORMAL
    00132
    00133 } DEFER_ACTION;

## 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().