ReactOS 0.4.15-dev-5667-ged97270
FxIoQueue Class Reference

#include <fxioqueue.hpp>

Inheritance diagram for FxIoQueue:
Collaboration diagram for FxIoQueue:

Public Member Functions

 FxIoQueue (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxPkgIo *PkgIo)
 
virtual ~FxIoQueue ()
 
_Must_inspect_result_ NTSTATUS Initialize (__in PWDF_IO_QUEUE_CONFIG pConfig, __in_opt PWDF_OBJECT_ATTRIBUTES QueueAttributes, __in_opt FxDriver *Caller, __in BOOLEAN InitialPowerStateOn)
 
 _Releases_lock_ (this->m_SpinLock.m_Lock) VOID CancelForQueue(__in FxRequest *pRequest
 
 FX_DECLARE_VF_FUNCTION_P1 (VOID, VerifyCancelForDriver, _In_ FxRequest *)
 
VOID CancelForDriver (__in FxRequest *pRequest)
 
 FX_DECLARE_VF_FUNCTION_P1 (VOID, VerifyValidateCompletedRequest, _In_ FxRequest *)
 
__inline VOID RequestCompletedCallback (__in FxRequest *Request)
 
__inline VOID PreRequestCompletedCallback (__in FxRequest *Request)
 
__inline VOID PostRequestCompletedCallback (__in FxRequest *Request)
 
__inline FxDriverGetDriver (VOID)
 
__inline CfxDeviceGetDevice (VOID)
 
__inline FxPkgIoGetPackage (VOID)
 
WDFQUEUE __inline GetHandle (VOID)
 
__inline BOOLEAN IsPowerManaged ()
 
VOID StartPowerTransitionOn (VOID)
 
VOID StartPowerTransitionOff (VOID)
 
VOID StopProcessingForPower (__in FxIoStopProcessingForPowerAction Action)
 
VOID ResumeProcessingForPower (VOID)
 
VOID SetStateForShutdown (VOID)
 
VOID ResetStateForRestart (VOID)
 
WDF_IO_QUEUE_STATE GetState (__out_opt PULONG pQueueCount, __out_opt PULONG pDriverCount)
 
VOID SetState (__in FX_IO_QUEUE_SET_STATE NewStatus)
 
__inline BOOLEAN IsState (__in WDF_IO_QUEUE_STATE State)
 
__inline BOOLEAN IsState (__in FX_IO_QUEUE_STATE State)
 
 FX_DECLARE_VF_FUNCTION_P1 (NTSTATUS, VerifyGetRequestUpdateFlags, _In_ FxRequest *)
 
 FX_DECLARE_VF_FUNCTION_P1 (VOID, VerifyGetRequestRestoreFlags, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS GetRequest (__in_opt MdFileObject FileObject, __in_opt FxRequest *TagRequest, __deref_out FxRequest **pOutRequest)
 
 FX_DECLARE_VF_FUNCTION_P1 (NTSTATUS, VerifyPeekRequest, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS PeekRequest (__in_opt FxRequest *TagRequest, __in_opt MdFileObject FileObject, __out_opt PWDF_REQUEST_PARAMETERS Parameters, __deref_out FxRequest **pOutRequest)
 
 FX_DECLARE_VF_FUNCTION_P2 (NTSTATUS, VerifyForwardRequest, _In_ FxIoQueue *, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS ForwardRequest (__in FxIoQueue *pDestQueue, __in FxRequest *pRequest)
 
 FX_DECLARE_VF_FUNCTION_P2 (NTSTATUS, VerifyQueueDriverCreatedRequest, _In_ FxRequest *, _Inout_ SHORT *)
 
_Must_inspect_result_ NTSTATUS QueueDriverCreatedRequest (__in FxRequest *Request, __in BOOLEAN ParentQueue)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) VOID ProcessAcknowledgedRequests(__in FxRequest *Request
 
 FX_DECLARE_VF_FUNCTION_P1 (NTSTATUS, VerifyRequeue, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS Requeue (__in FxRequest *pRequest)
 
 FX_DECLARE_VF_FUNCTION_P2 (NTSTATUS, VerifyRequestCancelable, _In_ FxRequest *, _In_ BOOLEAN)
 
_Must_inspect_result_ NTSTATUS RequestCancelable (__in FxRequest *pRequest, __in BOOLEAN Cancelable, __in_opt PFN_WDF_REQUEST_CANCEL EvtRequestCancel, __in BOOLEAN FailIfIrpIsCancelled)
 
_Must_inspect_result_ NTSTATUS RequestCompleteEvent (__in FxRequest *Request)
 
_Must_inspect_result_ NTSTATUS QueueRequest (__in FxRequest *pRequest)
 
_Must_inspect_result_ NTSTATUS QueueRequestFromForward (__in FxRequest *pRequest)
 
_Must_inspect_result_ BOOLEAN CanThreadDispatchEventsLocked (__in KIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_SpinLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) BOOLEAN DispatchEvents(__in __drv_restoresIRQL KIRQL PreviousIrql
 
 _Releases_lock_ (this->m_SpinLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID DispatchInternalEvents(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
VOID DispatchRequestToDriver (__in FxRequest *pRequest)
 
virtual VOID GetConstraints (__out WDF_EXECUTION_LEVEL *ExecutionLevel, __out WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
 
virtual FxCallbackLockGetCallbackLockPtr (__deref_out FxObject **LockObject)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
virtual BOOLEAN Dispose (VOID)
 
VOID QueueStart (VOID)
 
_Must_inspect_result_ NTSTATUS QueueIdle (__in BOOLEAN CancelQueueRequests, __in_opt PFN_WDF_IO_QUEUE_STATE IdleComplete, __in_opt WDFCONTEXT Context)
 
_Must_inspect_result_ NTSTATUS QueueIdleSynchronously (__in BOOLEAN CancelRequests)
 
_Must_inspect_result_ NTSTATUS QueuePurge (__in BOOLEAN CancelQueueRequests, __in BOOLEAN CancelDriverRequests, __in_opt PFN_WDF_IO_QUEUE_STATE PurgeComplete, __in_opt WDFCONTEXT Context)
 
_Must_inspect_result_ NTSTATUS QueuePurgeSynchronously (VOID)
 
_Must_inspect_result_ NTSTATUS QueueDrain (__in_opt PFN_WDF_IO_QUEUE_STATE DrainComplete, __in_opt WDFCONTEXT Context)
 
_Must_inspect_result_ NTSTATUS QueueDrainSynchronously (VOID)
 
_Must_inspect_result_ NTSTATUS ReadyNotify (__in PFN_WDF_IO_QUEUE_STATE QueueReady, __in_opt WDFCONTEXT Context)
 
VOID FlushByFileObject (__in MdFileObject FileObject)
 
VOID GetRequestCount (__out_opt PULONG pQueuedRequests, __out_opt PULONG pDriverPendingRequests)
 
_Must_inspect_result_ NTSTATUS ConfigureConstraints (__in_opt PWDF_OBJECT_ATTRIBUTES ObjectAttributes, __in_opt FxDriver *Caller)
 
VOID DeferredDispatchRequestsFromDpc (VOID)
 
VOID DeferredDispatchRequestsFromWorkerThread (VOID)
 
DECLSPEC_NORETURN VOID FatalError (__in NTSTATUS Status)
 
BOOLEAN IsIoEventHandlerRegistered (__in WDF_REQUEST_TYPE RequestType)
 
__inline VOID SetPowerState (__in FXIOQUEUE_POWER_STATE PowerState)
 
_Must_inspect_result_ NTSTATUS GetReservedRequest (__in MdIrp Irp, __deref_out_opt FxRequest **ReservedRequest)
 
__inline BOOLEAN IsForwardProgressQueue (VOID)
 
__inline NTSTATUS InvokeAllocateResourcesCallback (__in FxRequest *Request)
 
VOID ReturnReservedRequest (__in FxRequest *ReservedRequest)
 
_Must_inspect_result_ NTSTATUS AllocateReservedRequest (__deref_out FxRequest **Request)
 
_Must_inspect_result_ NTSTATUS AssignForwardProgressPolicy (__in PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY Policy)
 
 FX_DECLARE_VF_FUNCTION_P1_EX (, SHORT, 0, VerifyForwardRequestUpdateFlags, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS ForwardRequestWorker (__in FxRequest *Request, __in FxIoQueue *DestQueue)
 
 FX_DECLARE_VF_FUNCTION_P2 (NTSTATUS, VerifyForwardRequestToParent, _In_ FxIoQueue *, _In_ FxRequest *)
 
_Must_inspect_result_ NTSTATUS ForwardRequestToParent (__in FxIoQueue *DestQueue, __in FxRequest *Request, __in PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions)
 
__inline VOID SetCxDeviceInfo (__in FxCxDeviceInfo *CxDeviceInfo)
 
__inline FxCxDeviceInfoGetCxDeviceInfo (VOID)
 
__inline VOID SetInterruptQueue (VOID)
 
VOID FlushQueuedDpcs (VOID)
 
VOID InsertQueueDpc (VOID)
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
virtual BOOLEAN Dispose (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Static Public Member Functions

static _Must_inspect_result_ NTSTATUS _Create (__in PFX_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_IO_QUEUE_CONFIG Config, __in_opt FxDriver *Caller, __in FxPkgIo *PkgIo, __in BOOLEAN InitialPowerStateOn, __deref_out FxIoQueue **Object)
 
static __inline FxIoQueue_FromIoPkgListEntry (__in PLIST_ENTRY Entry)
 
static __inline FxIoQueue_FromPowerSListEntry (__in PSINGLE_LIST_ENTRY Entry)
 
- Static Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Public Attributes

FxIoQueueNode m_IoPkgListNode
 
SINGLE_LIST_ENTRY m_PowerSListEntry
 
__in __drv_restoresIRQL KIRQL PreviousIrql
 
__out PKIRQL PreviousIrql
 
__in_opt FxRequestNewRequest
 

Static Protected Attributes

static EVT_IRP_QUEUE_CANCEL _IrpCancelForQueue
 
static EVT_IRP_QUEUE_CANCEL _IrpCancelForDriver
 
static EVT_SYSTEMWORKITEM _DeferredDispatchThreadThunk
 
static MdDeferredRoutineType _DeferredDispatchDpcThunk
 
static EVT_WDF_IO_QUEUE_STATE _PurgeComplete
 
static EVT_WDF_IO_QUEUE_STATE _IdleComplete
 
static MdCancelRoutineType _WdmCancelRoutineForReservedIrp
 

Private Member Functions

 __drv_requiresIRQL (DISPATCH_LEVEL) VOID ProcessIdleComplete(__out PKIRQL PreviousIrql)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) VOID ProcessPurgeComplete(__out PKIRQL PreviousIrql)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) VOID ProcessReadyNotify(__out PKIRQL PreviousIrql)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) BOOLEAN ProcessCancelledRequests(__out PKIRQL PreviousIrql)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) BOOLEAN ProcessCancelledRequestsOnQueue(__out PKIRQL PreviousIrql)
 
 __drv_requiresIRQL (DISPATCH_LEVEL) BOOLEAN ProcessPowerEvents(__out PKIRQL PreviousIrql)
 
__inline BOOLEAN IsPowerStateNotifyingDriver (VOID)
 
__inline VOID InsertInDriverOwnedList (__in FxRequest *Request)
 
__inline VOID RemoveFromDriverOwnedList (__in FxRequest *Request)
 
__inline VOID PreRemoveFromDriverOwnedList (__in FxRequest *Request)
 
__inline VOID PostRemoveFromDriverOwnedList (VOID)
 
__inline VOID CheckTransitionFromEmpty (VOID)
 
__inline VOID SetTransitionFromEmpty (VOID)
 
NTSTATUS InsertNewRequestLocked (__deref_in FxRequest **Request, __in KIRQL PreviousIrql)
 
__inline NTSTATUS InsertNewRequest (__in FxRequest **Request, __in KIRQL PreviousIrql)
 
VOID FreeAllReservedRequests (__in BOOLEAN Verify)
 
_Must_inspect_result_ NTSTATUS QueueForwardProgressIrpLocked (__in MdIrp Irp)
 
_Must_inspect_result_ MdIrp GetForwardProgressIrpLocked (__in_opt PFILE_OBJECT FileObject)
 
BOOLEAN IsPagingIo (__in MdIrp Irp)
 
VOID PutBackReservedRequest (__in FxRequest *ReservedRequest)
 
VOID GetForwardProgressIrps (__in PLIST_ENTRY IrpListHead, __in_opt MdFileObject FileObject)
 
VOID CancelIrps (__in PLIST_ENTRY IrpListHead)
 
VOID PurgeForwardProgressIrps (__in_opt MdFileObject FileObject)
 
VOID VerifierVerifyFwdProgListsLocked (VOID)
 
- Private Member Functions inherited from IFxHasCallbacks
virtual VOID GetConstraints (__out WDF_EXECUTION_LEVEL *ExecutionLevel, __out WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)=0
 
virtual _Must_inspect_result_ FxCallbackLockGetCallbackLockPtr (__out_opt FxObject **LockObject)=0
 

Private Attributes

PFXIO_FORWARD_PROGRESS_CONTEXT m_FwdProgContext
 
BOOLEAN m_SupportForwardProgress
 
BOOLEAN m_Configured
 
BOOLEAN m_PowerManaged
 
volatile BOOLEAN m_PowerReferenced
 
BOOLEAN m_AllowZeroLengthRequests
 
BOOLEAN m_PassiveLevel
 
volatile BOOLEAN m_Deleted
 
volatile BOOLEAN m_Disposing
 
MxEvent m_FinishDisposing
 
FXIOQUEUE_POWER_STATE m_PowerState
 
WDF_IO_QUEUE_DISPATCH_TYPE m_Type
 
ULONG m_MaxParallelQueuePresentedRequests
 
FX_IO_QUEUE_STATE m_QueueState
 
FxIrpQueue m_Queue
 
FxIrpQueue m_DriverCancelable
 
LIST_ENTRY m_Cancelled
 
LIST_ENTRY m_CanceledOnQueueList
 
LIST_ENTRY m_DriverOwned
 
LIST_ENTRY m_PowerNotify
 
LIST_ENTRY m_PowerDriverNotified
 
FxPkgIom_PkgIo
 
FxCxDeviceInfom_CxDeviceInfo
 
volatile ULONG m_Dispatching
 
volatile BOOLEAN m_TransitionFromEmpty
 
volatile BOOLEAN m_ForceTransitionFromEmptyWhenAddingNewRequest
 
volatile BOOLEAN m_CancelDispatchedRequests
 
BOOLEAN m_IsDevicePowerPolicyOwner
 
volatile LONG m_DriverIoCount
 
volatile LONG m_TwoPhaseCompletions
 
FxIoQueueIoDefault m_IoDefault
 
FxIoQueueIoStop m_IoStop
 
FxIoQueueIoResume m_IoResume
 
FxIoQueueIoRead m_IoRead
 
FxIoQueueIoWrite m_IoWrite
 
FxIoQueueIoDeviceControl m_IoDeviceControl
 
FxIoQueueIoInternalDeviceControl m_IoInternalDeviceControl
 
FxIoQueueIoCanceledOnQueue m_IoCanceledOnQueue
 
FxCallbackLockm_IoCancelCallbackLockPtr
 
FxIoQueueIoState m_IdleComplete
 
WDFCONTEXT m_IdleCompleteContext
 
FxIoQueueIoState m_PurgeComplete
 
WDFCONTEXT m_PurgeCompleteContext
 
FxIoQueueIoState m_ReadyNotify
 
WDFCONTEXT m_ReadyNotifyContext
 
WDF_EXECUTION_LEVEL m_ExecutionLevel
 
WDF_SYNCHRONIZATION_SCOPE m_SynchronizationScope
 
FxCallbackSpinLock m_CallbackSpinLock
 
FxCallbackMutexLock m_CallbackMutexLock
 
FxCallbackLockm_CallbackLockPtr
 
FxObjectm_CallbackLockObjectPtr
 
KDPC m_Dpc
 
FxSystemWorkItemm_SystemWorkItem
 
BOOLEAN m_DpcQueued
 
BOOLEAN m_WorkItemQueued
 
BOOLEAN m_RequeueDeferredDispatcher
 
MxEvent m_PowerIdle
 
MxEvent m_RequestWaitEventUm
 

Friends

VOID GetTriageInfo (VOID)
 

Additional Inherited Members

- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Detailed Description

Definition at line 232 of file fxioqueue.hpp.

Constructor & Destructor Documentation

◆ FxIoQueue()

FxIoQueue::FxIoQueue ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in FxPkgIo PkgIo 
)

Definition at line 37 of file fxioqueue.cpp.

40 :
41 FxNonPagedObject(FX_TYPE_QUEUE, sizeof(FxIoQueue), FxDriverGlobals),
42 m_CallbackSpinLock(FxDriverGlobals),
43 m_CallbackMutexLock(FxDriverGlobals),
45 {
54
55 // A newly created queue can not accept requests until initialized
57
58 //
59 // Set our Cancel callbacks
60 //
62
64
66
68
70
72
74
76
77 //
78 // We do not reference count the I/O package instance
79 // since it contains us. The fact we exist, the I/O
80 // package instance exists.
81 //
82 m_PkgIo = PkgIo;
84
85 m_Device = PkgIo->GetDevice();
86
89
91
94
97
99
102
105
108
111
112#if FX_IS_KERNEL_MODE
113
114 // Initialize the DPC used for deferrals
116 &m_Dpc,
118 this
119 );
120#endif
121
123
125
127
131
134
138
139 return;
140}
__inline BOOLEAN IsPnp(VOID)
Definition: fxdevice.hpp:1200
FxPkgPnp * m_PkgPnp
Definition: fxdevice.hpp:670
PFN_WDF_IO_QUEUE_STATE Method
BOOLEAN m_PassiveLevel
Definition: fxioqueue.hpp:280
FxObject * m_CallbackLockObjectPtr
Definition: fxioqueue.hpp:529
FxSystemWorkItem * m_SystemWorkItem
Definition: fxioqueue.hpp:557
FxIoQueueNode m_IoPkgListNode
Definition: fxioqueue.hpp:586
BOOLEAN m_PowerManaged
Definition: fxioqueue.hpp:261
WDFCONTEXT m_ReadyNotifyContext
Definition: fxioqueue.hpp:508
BOOLEAN m_RequeueDeferredDispatcher
Definition: fxioqueue.hpp:568
WDF_SYNCHRONIZATION_SCOPE m_SynchronizationScope
Definition: fxioqueue.hpp:515
BOOLEAN m_IsDevicePowerPolicyOwner
Definition: fxioqueue.hpp:463
PFXIO_FORWARD_PROGRESS_CONTEXT m_FwdProgContext
Definition: fxioqueue.hpp:241
FxCallbackSpinLock m_CallbackSpinLock
Definition: fxioqueue.hpp:520
volatile LONG m_TwoPhaseCompletions
Definition: fxioqueue.hpp:481
FxCallbackMutexLock m_CallbackMutexLock
Definition: fxioqueue.hpp:521
LIST_ENTRY m_DriverOwned
Definition: fxioqueue.hpp:397
WDF_EXECUTION_LEVEL m_ExecutionLevel
Definition: fxioqueue.hpp:514
FxIoQueueIoState m_PurgeComplete
Definition: fxioqueue.hpp:504
volatile LONG m_DriverIoCount
Definition: fxioqueue.hpp:475
volatile BOOLEAN m_Disposing
Definition: fxioqueue.hpp:296
volatile ULONG m_Dispatching
Definition: fxioqueue.hpp:435
static EVT_IRP_QUEUE_CANCEL _IrpCancelForDriver
Definition: fxioqueue.hpp:1683
FxIrpQueue m_DriverCancelable
Definition: fxioqueue.hpp:372
volatile BOOLEAN m_ForceTransitionFromEmptyWhenAddingNewRequest
Definition: fxioqueue.hpp:452
BOOLEAN m_Configured
Definition: fxioqueue.hpp:252
WDF_IO_QUEUE_DISPATCH_TYPE m_Type
Definition: fxioqueue.hpp:308
LIST_ENTRY m_PowerNotify
Definition: fxioqueue.hpp:405
BOOLEAN m_SupportForwardProgress
Definition: fxioqueue.hpp:246
FX_IO_QUEUE_STATE m_QueueState
Definition: fxioqueue.hpp:318
FxCxDeviceInfo * m_CxDeviceInfo
Definition: fxioqueue.hpp:425
ULONG m_MaxParallelQueuePresentedRequests
Definition: fxioqueue.hpp:313
FxIoQueueIoState m_ReadyNotify
Definition: fxioqueue.hpp:507
FxIrpQueue m_Queue
Definition: fxioqueue.hpp:366
WDFCONTEXT m_PurgeCompleteContext
Definition: fxioqueue.hpp:505
BOOLEAN m_WorkItemQueued
Definition: fxioqueue.hpp:563
SINGLE_LIST_ENTRY m_PowerSListEntry
Definition: fxioqueue.hpp:591
FxIoQueueIoState m_IdleComplete
Definition: fxioqueue.hpp:501
BOOLEAN m_DpcQueued
Definition: fxioqueue.hpp:562
LIST_ENTRY m_PowerDriverNotified
Definition: fxioqueue.hpp:414
BOOLEAN m_AllowZeroLengthRequests
Definition: fxioqueue.hpp:273
static MdDeferredRoutineType _DeferredDispatchDpcThunk
Definition: fxioqueue.hpp:1691
LIST_ENTRY m_CanceledOnQueueList
Definition: fxioqueue.hpp:387
KDPC m_Dpc
Definition: fxioqueue.hpp:554
volatile BOOLEAN m_TransitionFromEmpty
Definition: fxioqueue.hpp:442
WDFCONTEXT m_IdleCompleteContext
Definition: fxioqueue.hpp:502
volatile BOOLEAN m_Deleted
Definition: fxioqueue.hpp:288
FXIOQUEUE_POWER_STATE m_PowerState
Definition: fxioqueue.hpp:302
FxCallbackLock * m_CallbackLockPtr
Definition: fxioqueue.hpp:528
volatile BOOLEAN m_PowerReferenced
Definition: fxioqueue.hpp:267
FxPkgIo * m_PkgIo
Definition: fxioqueue.hpp:420
LIST_ENTRY m_Cancelled
Definition: fxioqueue.hpp:379
static EVT_IRP_QUEUE_CANCEL _IrpCancelForQueue
Definition: fxioqueue.hpp:1674
VOID Initialize(__in FxNonPagedObject *LockObject, __in PFN_IRP_QUEUE_CANCEL Callback)
Definition: fxirpqueue.cpp:61
VOID MarkPassiveDispose(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:944
CfxDevice * m_Device
Definition: fxobject.hpp:329
CfxDevice * GetDevice(VOID)
Definition: fxobject.hpp:781
BOOLEAN IsPowerPolicyOwner(VOID)
Definition: fxpkgpnp.hpp:3612
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ FxIoQueueNodeTypeQueue
Definition: fxioqueue.hpp:46
@ FxIoQueuePowerOn
Definition: fxioqueue.hpp:132
enum _FX_IO_QUEUE_STATE FX_IO_QUEUE_STATE
@ ObjectDoNotLock
Definition: fxobject.hpp:128
@ FX_TYPE_QUEUE
Definition: fxtypes.h:48
#define L(x)
Definition: ntvdm.h:50
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
uint32_t ULONG
Definition: typedefs.h:59
@ WdfIoQueueDispatchSequential
Definition: wdfio.h:78
@ WdfSynchronizationScopeInheritFromParent
Definition: wdfobject.h:63
@ WdfExecutionLevelInheritFromParent
Definition: wdfobject.h:53

◆ ~FxIoQueue()

FxIoQueue::~FxIoQueue ( )
virtual

Definition at line 142 of file fxioqueue.cpp.

Member Function Documentation

◆ __drv_requiresIRQL() [1/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ __drv_requiresIRQL() [2/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ __drv_requiresIRQL() [3/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ __drv_requiresIRQL() [4/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )

◆ __drv_requiresIRQL() [5/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ __drv_requiresIRQL() [6/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ __drv_requiresIRQL() [7/7]

FxIoQueue::__drv_requiresIRQL ( DISPATCH_LEVEL  )
private

◆ _Create()

_Must_inspect_result_ NTSTATUS FxIoQueue::_Create ( __in PFX_DRIVER_GLOBALS  DriverGlobals,
__in_opt PWDF_OBJECT_ATTRIBUTES  Attributes,
__in PWDF_IO_QUEUE_CONFIG  Config,
__in_opt FxDriver Caller,
__in FxPkgIo PkgIo,
__in BOOLEAN  InitialPowerStateOn,
__deref_out FxIoQueue **  Object 
)
static

Definition at line 164 of file fxioqueue.cpp.

173{
176
177 *Object = NULL;
178
180
181 if (pQueue == NULL) {
184 "Memory allocation failed: %!STATUS!", status);
185 return status;
186 }
187
188 //
189 // Initialize it, creating the handle to pass the driver
190 // and configuring its callbacks and queue type
191 //
194 Caller,
195 InitialPowerStateOn);
196 if (!NT_SUCCESS(status)) {
198 "Could not configure queue: %!STATUS!", status);
199 goto Done;
200 }
201Done:
202 if (NT_SUCCESS(status)) {
203 *Object = pQueue;
204 }
205 else {
206 //
207 // Release our newly allocated Queue object
208 //
210 }
211
212 return status;
213}
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS Initialize(__in PWDF_IO_QUEUE_CONFIG pConfig, __in_opt PWDF_OBJECT_ATTRIBUTES QueueAttributes, __in_opt FxDriver *Caller, __in BOOLEAN InitialPowerStateOn)
Definition: fxioqueue.cpp:217
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
#define TRACINGIO
Definition: dbgtrace.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxIoQueue * pQueue
DriverGlobals
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ps.c:97
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by FxPkgIo::CreateQueue().

◆ _FromIoPkgListEntry()

static __inline FxIoQueue * FxIoQueue::_FromIoPkgListEntry ( __in PLIST_ENTRY  Entry)
inlinestatic

Definition at line 1216 of file fxioqueue.hpp.

1219 {
1221 }
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY m_ListEntry
Definition: fxioqueue.hpp:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by FxPkgIo::AddIoQueue(), GetIoQueueList_ProcessQueueListEntry(), and FxPkgIo::GetNextIoQueueLocked().

◆ _FromPowerSListEntry()

static __inline FxIoQueue * FxIoQueue::_FromPowerSListEntry ( __in PSINGLE_LIST_ENTRY  Entry)
inlinestatic

◆ _Releases_lock_() [1/3]

FxIoQueue::_Releases_lock_ ( this->m_SpinLock.  m_Lock)
inline

Definition at line 1003 of file fxioqueue.hpp.

1024 {
1025 if(m_Dispatching == 0) {
1026 //
1027 // Nobody is dispatching events so we must
1028 // call the main DispatchEvents function because
1029 // the caller of this function might have affected the
1030 // state of the queue.
1031 //
1032 (VOID) DispatchEvents(PreviousIrql);
1033
1034 } else {
1035
1037 }
1038 }
#define VOID
Definition: acefi.h:82
__in __drv_restoresIRQL KIRQL PreviousIrql
Definition: fxioqueue.hpp:631
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474

◆ _Releases_lock_() [2/3]

FxIoQueue::_Releases_lock_ ( this->m_SpinLock.  m_Lock)

◆ _Releases_lock_() [3/3]

FxIoQueue::_Releases_lock_ ( this->m_SpinLock.  m_Lock)

◆ AllocateReservedRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::AllocateReservedRequest ( __deref_out FxRequest **  Request)

Definition at line 6359 of file fxioqueue.cpp.

6370{
6374 PWDF_OBJECT_ATTRIBUTES reqAttribs;
6375
6377 *Request = NULL;
6378 reqAttribs = NULL;
6379
6380 //
6381 // Get the right context for this request object.
6382 //
6383 if (GetCxDeviceInfo() != NULL) {
6384 reqAttribs = &GetCxDeviceInfo()->RequestAttributes;
6385 }
6386 else {
6387 reqAttribs = m_Device->GetRequestAttributes();
6388 }
6389
6390 //
6391 // FxRequest::_Create doesn't create a Request from the Device lookaside
6392 // hence we can't use that as the Request Context doesn't get associated
6393 // if the Request is not created from the lookaside.
6394 //
6396 if (!NT_SUCCESS(status)) {
6398 "Failure to allocate request %!STATUS!", status);
6399 return status;
6400 }
6401
6404
6405 //
6406 // This is used to return the request to the correct queue if it was
6407 // forwarded
6408 //
6411
6413
6415
6417 GetHandle(),
6418 pRequest->GetHandle());
6419 if (!NT_SUCCESS(status)) {
6421 "Failure from m_IoReservedResourcesAllocate callback %!STATUS!",
6422 status);
6424 }
6425 }
6426
6427 if (NT_SUCCESS(status)) {
6428 *Request = pRequest;
6429 }
6430
6431 return status;
6432}
__inline PWDF_OBJECT_ATTRIBUTES GetRequestAttributes(VOID)
Definition: fxdevice.hpp:1315
PFN_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request)
__inline FxCxDeviceInfo * GetCxDeviceInfo(VOID)
Definition: fxioqueue.hpp:1360
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__inline WDFREQUEST GetHandle(VOID)
__inline VOID SetCompleted(__in BOOLEAN Value)
VOID __inline SetPresented(VOID)
Definition: fxrequest.hpp:558
__inline VOID SetCurrentQueue(__in FxIoQueue *Queue)
Definition: fxrequest.hpp:649
__inline VOID SetReserved()
Definition: fxrequest.hpp:617
__inline VOID SetForwardProgressQueue(__in FxIoQueue *Queue)
Definition: fxrequest.hpp:625
static _Must_inspect_result_ NTSTATUS _CreateForPackage(__in CfxDevice *Device, __in PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in MdIrp Irp, __deref_out FxRequest **Request)
Definition: fxrequest.cpp:75
VOID FreeRequest(VOID)
Definition: fxrequest.cpp:1022
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxRequest * pRequest
WDF_OBJECT_ATTRIBUTES RequestAttributes
FxIoQueueForwardProgressAllocateResourcesReserved m_IoReservedResourcesAllocate
Definition: fxioqueue.hpp:156
#define GetHandle(h)
Definition: treelist.c:116
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

◆ AssignForwardProgressPolicy()

_Must_inspect_result_ NTSTATUS FxIoQueue::AssignForwardProgressPolicy ( __in PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY  Policy)

Definition at line 214 of file fxioqueueum.hpp.

223{
225
228}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
VOID UfxVerifierTrapNotImpl()
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:653

◆ CancelForDriver()

VOID FxIoQueue::CancelForDriver ( __in FxRequest pRequest)

Definition at line 4535 of file fxioqueue.cpp.

4555{
4556 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
4557 KIRQL irql;
4558
4559 // This is not an error, but want to make sure cancel testing works
4560 VerifyCancelForDriver(FxDriverGlobals, pRequest);
4561
4562 //
4563 // We are called with no locks held, but
4564 // can be in arbitrary thread context from
4565 // a cancel occuring from another driver within
4566 // a driver stack.
4567 //
4568
4569 //
4570 // The Csq has removed this request from the driver pending
4571 // queue, and it no longer has a cancel function if the
4572 // driver does not accept the cancel right now.
4573 //
4574 // When callside eventually goes to remove it from the queue
4575 // by CsqContext, the Csq's will return NULL.
4576 //
4577 // Irp and FxRequest is still valid until the driver calls
4578 // WdfRequestComplete either as a result of this cancel
4579 // callback, or at its leasure if it chooses to ignore it.
4580 //
4581 // The insert of FxRequest onto the FxIrpQueue took out a
4582 // reference, and when an IRP gets cancelled, we are responsible
4583 // for this final dereference after calling into the driver.
4584 //
4585
4586 //
4587 // Cancellations are dispatched as events to the device driver
4588 // using the standard DispatchEvents processing loop. In order
4589 // to support this, we must defer it by linking this request
4590 // into a list of cancelled requests.
4591 //
4592 // The requests will be removed from this list and cancel notified
4593 // to the device driver by the processing loop.
4594 //
4595
4597
4598 //
4599 // Queue it on the cancelled list
4600 //
4601 Lock(&irql);
4602
4604
4605 //
4606 // Visit the event dispatcher
4607 //
4608 DispatchInternalEvents(irql);
4609
4610 return;
4611}
__inline PLIST_ENTRY GetListEntry(__in FxListEntryNames Index)
Definition: fxrequest.hpp:475
__inline VOID MarkRemovedFromIrpQueue(VOID)
Definition: fxrequest.hpp:1100
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
@ FxListEntryQueueOwned
Definition: fxrequest.hpp:375
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

Referenced by QueueIdle(), QueuePurge(), and RequestCancelable().

◆ CancelIrps()

VOID FxIoQueue::CancelIrps ( __in PLIST_ENTRY  IrpListHead)
private

Definition at line 6436 of file fxioqueue.cpp.

6447{
6448 MdIrp irp;
6449 FxIrp fxIrp;
6451
6452 while(!IsListEmpty(IrpListHead)) {
6453
6454 entry = RemoveHeadList(IrpListHead);
6455
6457
6458 fxIrp.SetIrp(irp);
6459
6463 }
6464}
Definition: fxirp.hpp:28
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
static MdIrp GetIrpFromListEntry(__in PLIST_ENTRY Ple)
Definition: fxirpum.cpp:1190
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
FxIrp fxIrp(Irp)
FxIrp * irp
uint32_t entry
Definition: isohybrid.c:63
IWudfIrp * MdIrp
Definition: mxum.h:103
Definition: typedefs.h:120
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by PurgeForwardProgressIrps(), and QueueIdle().

◆ CanThreadDispatchEventsLocked()

_Must_inspect_result_ BOOLEAN FxIoQueue::CanThreadDispatchEventsLocked ( __in KIRQL  PreviousIrql)

Definition at line 2633 of file fxioqueue.cpp.

2653{
2654 //
2655 // If the current irql is not at passive-level and the queue is configured
2656 // to receive events only at passive-level then we should queue a
2657 // workitem to defer the processing.
2658 //
2662 "Current thread 0x%p is not at the passive-level"
2663 " %!irql!, posting to worker thread for WDFQUEUE"
2664 " 0x%p",
2667 GetObjectHandle());
2668 //
2669 // We only need to post this once
2670 //
2671 if (m_WorkItemQueued == FALSE) {
2672
2674
2676 ASSERT(FALSE);
2678 }
2679 }
2680
2681 return FALSE;
2682 }
2683
2684 //
2685 // If the current thread is holding the presentation lock, we
2686 // must defer to a DPC or work item.
2687 // This is the result of the device driver calling
2688 // WdfRequestForwardToIoQueue, or WdfIoQueueStart/Stop from
2689 // within I/O dispatch handler. This can also occur if a driver
2690 // attempts to forward a request among a circular series of Queues
2691 // that are configured to have locking constraints.
2692 //
2694
2696 "Presentation lock for WDFQUEUE 0x%p is "
2697 "already held, deferring to dpc or workitem",
2698 GetObjectHandle());
2699
2700 if (m_PassiveLevel) {
2701
2702 if(m_WorkItemQueued == FALSE) {
2703
2705
2707 ASSERT(FALSE);
2709 }
2710 }
2711 }
2712 else {
2713 //
2714 // We only need to post this once
2715 //
2716 if (m_DpcQueued == FALSE) {
2717
2718 m_DpcQueued = TRUE;
2719
2721 }
2722 }
2723
2724 return FALSE;
2725 }
2726
2727 return TRUE;
2728}
virtual _Must_inspect_result_ BOOLEAN IsOwner(VOID)=0
static EVT_SYSTEMWORKITEM _DeferredDispatchThreadThunk
Definition: fxioqueue.hpp:1687
VOID InsertQueueDpc(VOID)
__inline BOOLEAN Enqueue(__in PFN_WDF_SYSTEMWORKITEM CallbackFunc, __in PVOID Parameter)
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
#define TRUE
Definition: types.h:120
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
return pObject GetObjectHandle()
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28

◆ CheckTransitionFromEmpty()

__inline VOID FxIoQueue::CheckTransitionFromEmpty ( VOID  )
inlineprivate

Definition at line 1541 of file fxioqueue.hpp.

1544 {
1545 if (m_Queue.GetRequestCount() == 1L ||
1547
1549 }
1550 }
__inline VOID SetTransitionFromEmpty(VOID)
Definition: fxioqueue.hpp:1559
LONG GetRequestCount()
Definition: fxirpqueue.hpp:193

Referenced by InsertNewRequestLocked(), QueueRequestFromForward(), and Requeue().

◆ ConfigureConstraints()

_Must_inspect_result_ NTSTATUS FxIoQueue::ConfigureConstraints ( __in_opt PWDF_OBJECT_ATTRIBUTES  ObjectAttributes,
__in_opt FxDriver Caller 
)

Definition at line 571 of file fxioqueue.cpp.

592{
593 WDF_EXECUTION_LEVEL ParentLevel;
594 WDF_SYNCHRONIZATION_SCOPE ParentScope;
595 BOOLEAN AutomaticLockingRequired;
596
597 AutomaticLockingRequired = FALSE;
598 ASSERT(m_Device != NULL);
599
600 //
601 // Initialize both spin and mutex locks
602 //
605
606 //
607 // If WDF_OBJECT_ATTRIBUTES is specified, these override any
608 // default settings.
609 //
610 if (ObjectAttributes != NULL) {
611 m_ExecutionLevel = ObjectAttributes->ExecutionLevel;
612 m_SynchronizationScope = ObjectAttributes->SynchronizationScope;
613 }
614
615 //
616 // If no WDFQUEUE specific attributes are specified, we
617 // get them from WDFDEVICE, which allows WDFDEVICE to
618 // provide a default for all WDFQUEUE's created.
619 //
620 m_Device->GetConstraints(&ParentLevel, &ParentScope);
623
625 m_ExecutionLevel = ParentLevel;
626 }
627
629 m_SynchronizationScope = ParentScope;
630 }
631
632 //
633 // For backward compatibility purposes always have a lock associated with the
634 // object even for WdfSynchronizationScopeNone. This is so that we return a non-null
635 // presentation lock for the WDFQUEUE object.
636 //
638 //
639 // Mark FxObject as passive level to ensure that Dispose and Destroy
640 // callbacks are passive to the driver
641 //
644
645 //
646 // Passive Callbacks constraint has been set, we use a mutex for the
647 // callback lock.
648 //
651 }
652 else {
653 //
654 // If no passive level constraint is specified, then spinlocks
655 // are used for callbacks since they are lightweight and work with
656 // DPC's and Timer's
657 //
660 }
661
662 //
663 // Configure synchronization scope
664 //
667
668 //
669 // WDF extensions are not allowed to use this type of synchronization.
670 //
671 if (Caller != NULL && Caller != GetDriverGlobals()->Driver) {
674 "WDFQUEUE 0x%p Synchronization scope is set to "
675 "device; WDF extension drivers are not allowed "
676 "to use this type of synchronization, %!STATUS!",
678 return status;
679 }
680
681 //
682 // If we inherit the Sync. scope from parent or device
683 // and if the parent/device has Exec. Level different from Queue
684 // then disallow that case.
685 // FUTURE PROOF NOTE: Adding a new Execution Level will need reevaluation
686 // of the check below.
687 //
688 if (ParentLevel != m_ExecutionLevel) {
691 "WDFQUEUE 0x%p Synchronization scope is set to device"
692 " but the Device ExecutionLevel: 0x%x"
693 " doesn't match Queue ExecutionLevel: 0x%x, %!STATUS!",
694 GetObjectHandle(), ParentLevel,
696 return status;
697 }
698 //
699 // Per device automatic callback synchronization, so we update our
700 // callback lock ptr to point to the devices lock
701 //
702 AutomaticLockingRequired = TRUE;
703
704 //
705 // Get the callback lock and object from the device
706 //
708 }
710 //
711 // Per object automatic serialization
712 //
713 AutomaticLockingRequired = TRUE;
714
715 // m_CallbackLockPtr has been set above in execution level constraint
716 }
717
718
719 if (AutomaticLockingRequired) {
720 //
721 // If automatic locking has been configured, set the lock
722 // on the FxCallback object delegates
723 //
734
736 }
737 else {
738 //
739 // No automatic locking specified
740 //
751
753
754 }
755
756 return STATUS_SUCCESS;
757}
unsigned char BOOLEAN
virtual void Initialize(FxObject *ParentObject)
virtual void Initialize(FxObject *ParentObject)
FxCallbackLock * GetCallbackLockPtr(__out_opt FxObject **LockObject)
VOID GetConstraints(__out_opt WDF_EXECUTION_LEVEL *ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
FxIoQueueIoDefault m_IoDefault
Definition: fxioqueue.hpp:487
FxIoQueueIoDeviceControl m_IoDeviceControl
Definition: fxioqueue.hpp:492
FxIoQueueIoCanceledOnQueue m_IoCanceledOnQueue
Definition: fxioqueue.hpp:494
FxIoQueueIoInternalDeviceControl m_IoInternalDeviceControl
Definition: fxioqueue.hpp:493
FxIoQueueIoStop m_IoStop
Definition: fxioqueue.hpp:488
FxCallbackLock * m_IoCancelCallbackLockPtr
Definition: fxioqueue.hpp:496
FxIoQueueIoWrite m_IoWrite
Definition: fxioqueue.hpp:491
FxIoQueueIoResume m_IoResume
Definition: fxioqueue.hpp:489
FxIoQueueIoRead m_IoRead
Definition: fxioqueue.hpp:490
void SetCallbackLockPtr(FxCallbackLock *Lock)
Definition: fxcallback.hpp:105
VOID MarkPassiveCallbacks(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:972
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
@ WdfSynchronizationScopeQueue
Definition: wdfobject.h:65
@ WdfSynchronizationScopeDevice
Definition: wdfobject.h:64
@ WdfExecutionLevelPassive
Definition: wdfobject.h:54
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE

Referenced by Initialize().

◆ DeferredDispatchRequestsFromDpc()

VOID FxIoQueue::DeferredDispatchRequestsFromDpc ( VOID  )

Definition at line 2475 of file fxioqueue.cpp.

2491{
2492 KIRQL irql;
2493
2494 Lock(&irql);
2495
2497
2499
2500 DispatchEvents(irql);
2501
2502 //
2503 // DispatchEvents drops the lock before returning. So reacquire the lock.
2504 //
2505 Lock(&irql);
2506
2509 } else {
2512 }
2513
2514 Unlock(irql);
2515
2516 return;
2517}

◆ DeferredDispatchRequestsFromWorkerThread()

VOID FxIoQueue::DeferredDispatchRequestsFromWorkerThread ( VOID  )

Definition at line 2520 of file fxioqueue.cpp.

2536{
2537 KIRQL irql;
2538
2539 Lock(&irql);
2540
2542
2544
2545 DispatchEvents(irql);
2546
2547 //
2548 // DispatchEvents drops the lock before returning. So reacquire
2549 // the lock.
2550 //
2551 Lock(&irql);
2552
2553 if (m_Deleted == FALSE &&
2556 //
2557 // Workitem is queued.
2558 //
2559 DO_NOTHING();
2560 } else {
2563 }
2564
2565 Unlock(irql);
2566
2567 return;
2568}
#define DO_NOTHING()
Definition: mxgeneral.h:32

◆ DispatchRequestToDriver()

VOID FxIoQueue::DispatchRequestToDriver ( __in FxRequest pRequest)

Definition at line 3110 of file fxioqueue.cpp.

3133{
3134 PFX_DRIVER_GLOBALS FxDriverGlobals;
3136 FxRequestCompletionState oldState;
3137 WDFREQUEST hRequest;
3138 FxIrp* pIrp;
3139
3140 FxDriverGlobals = GetDriverGlobals();
3141
3142
3143
3144
3145
3147
3148 pIrp = pRequest->GetFxIrp();
3149
3150 // The Irp does not have a cancel function right now
3151#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
3153#endif
3154
3155 //
3156 // Set our completion callback on the request now before
3157 // calling the driver since the driver can complete the
3158 // request in the callback handler, and to avoid races with
3159 // the drivers completion thread.
3160 //
3161 // This takes a reference on the request object.
3162 //
3165 UNREFERENCED_PARAMETER(oldState);
3166
3167 if (FxDriverGlobals->FxVerifierOn) {
3168 //
3169 // If the verifier is on, we do not release the extra
3170 // reference so we can mark the request as no longer
3171 // being dispatched to the driver on return from the
3172 // event callback to the driver
3173 //
3174
3176
3177 // Mark the request as being "owned" by the driver
3180 }
3181 else {
3182
3183 //
3184 // Release our original reference. The FxRequest::Complete
3185 // will release the final one since we have registered a completion
3186 // callback handler
3187 //
3188 // We now have one reference count on the FxRequest object until
3189 // its completion routine runs since the completion event made
3190 // an extra reference, and will dereference it when it fires, or
3191 // its canceled.
3192 //
3193
3194 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3195 }
3196
3197 //
3198 // Attempt to dispatch it to the driver
3199 //
3200
3201 //
3202 // Note: A driver that changes its callback pointers at runtime
3203 // could run into a race here since we released the queue
3204 // lock. Currently, changing parameters on a processing
3205 // queue is undefined.
3206 //
3207 // The C DDI's force the callbacks to be registered at
3208 // queue creation time and avoid this race.
3209 //
3210
3211 hRequest = pRequest->GetHandle();
3212
3214
3216 ULONG readLength = pIrp->GetParameterReadLength();
3217
3218 //
3219 // Complete zero length reads with STATUS_SUCCESS unless the
3220 // driver specified it wants them delivered.
3221 //
3222 if ((readLength == 0) &&
3224
3226 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3227 "Zero length WDFREQUEST 0x%p completed automatically "
3228 "by WDFQUEUE 0x%p", hRequest, GetObjectHandle());
3229
3231 if (FxDriverGlobals->FxVerifierOn) {
3232 //
3233 // Release the reference taken in the call to SetCompletionState
3234 // at the top of the function.
3235 //
3236 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3237 }
3238 return;
3239 }
3240
3242
3244 "Calling driver EvtIoRead for WDFREQUEST 0x%p",
3245 hRequest);
3246
3248 GetHandle(),
3249 hRequest,
3250 readLength
3251 );
3252 }
3253 else if ((majorFunction == IRP_MJ_WRITE) && m_IoWrite.Method) {
3254 ULONG writeLength = pIrp->GetParameterWriteLength();
3255
3256 //
3257 // Complete zero length writes with STATUS_SUCCESS unless the
3258 // driver specified it wants them delivered.
3259 //
3260 if ((writeLength == 0) &&
3262
3264 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3265 "Zero length WDFREQUEST 0x%p completed automatically "
3266 "by WDFQUEUE 0x%p", hRequest, GetObjectHandle());
3267
3269
3270 if (FxDriverGlobals->FxVerifierOn) {
3271 //
3272 // Release the reference taken in the call to SetCompletionState
3273 // at the top of the function.
3274 //
3275 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3276 }
3277 return;
3278 }
3279
3281
3283 "Calling driver EvtIoWrite for WDFREQUEST 0x%p",
3285
3287 GetHandle(),
3288 hRequest,
3289 writeLength
3290 );
3291 }
3293
3295
3297 "Calling driver EvtIoDeviceControl for "
3298 "WDFREQUEST 0x%p", hRequest);
3299
3301 GetHandle(),
3302 hRequest,
3306 );
3307 }
3308
3310
3312
3314 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3315 "Calling driver EvtIoInternalDeviceControl for WDFREQUEST 0x%p",
3316 hRequest);
3317
3319 GetHandle(),
3320 hRequest,
3324 );
3325 }
3326 else {
3327
3328 //
3329 // If we have an IoStart registered, call it
3330 //
3331 if (m_IoDefault.Method) {
3332
3334 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3335 "Calling driver EvtIoDefault for WDFREQUEST 0x%p", hRequest);
3336
3337
3338 //
3339 // If we don't allow zero length requests, we must dig in whether
3340 // its a read or a write
3341 //
3343
3344 if (majorFunction == IRP_MJ_READ) {
3345
3346 if (pIrp->GetParameterReadLength() == 0) {
3347
3349 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3350 "Zero length WDFREQUEST 0x%p completed automatically "
3351 "by WDFQUEUE 0x%p", hRequest, GetObjectHandle());
3352
3354 if (FxDriverGlobals->FxVerifierOn) {
3355 //
3356 // Release the reference taken in the call to SetCompletionState
3357 // at the top of the function.
3358 //
3359 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3360 }
3361 return;
3362 }
3363 }
3364 else if (majorFunction == IRP_MJ_WRITE) {
3365
3366 if (pIrp->GetParameterWriteLength() == 0) {
3367
3369
3371 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO,
3372 "Zero length WDFREQUEST 0x%p completed automatically "
3373 "by WDFQUEUE 0x%p", hRequest, GetObjectHandle());
3374
3375 if (FxDriverGlobals->FxVerifierOn) {
3376 //
3377 // Release the reference taken in the call to SetCompletionState
3378 // at the top of the function.
3379 //
3380 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3381 }
3382 return;
3383 }
3384 }
3385 }
3386
3388
3389 m_IoDefault.Invoke(GetHandle(), hRequest);
3390 }
3391 else {
3393
3395 "Driver has no event callback "
3396 "for %!WDF_REQUEST_TYPE!, completing WDFREQUEST 0x%p with "
3397 "%!STATUS!",
3399 pRequest,
3400 Status);
3401
3403
3404 if (FxDriverGlobals->FxVerifierOn) {
3405 //
3406 // Release our extra verifier reference now
3407 //
3408 // Release the reference taken in the call to SetCompletionState
3409 // at the top of the function.
3410 //
3411 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3412 }
3413
3414 return;
3415 }
3416 }
3417
3418 // ******************************
3419 // Request may now be a freed object unless verifier is on. Only touch
3420 // request if verifier is on.
3421 // ******************************
3422
3423 if (FxDriverGlobals->FxVerifierOn) {
3424
3425 //
3426 // If the request has been forwarded, don't clear this
3427 // since the new queue may already be dispatching in a new thread or DPC
3428 //
3431 }
3432
3433 //
3434 // Release our extra verifier reference now
3435 //
3436 // Release the reference taken in the call to SetCompletionState
3437
3438 // at the top of the function.
3439 //
3440 pRequest->RELEASE(FXREQUEST_STATE_TAG);
3441 }
3442
3443 // Driver accepted a request
3444 return;
3445}
PFN_WDF_IO_QUEUE_IO_DEFAULT Method
void Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request)
PFN_WDF_IO_QUEUE_IO_DEVICE_CONTROL Method
void Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG OutputBufferLength, __in ULONG InputBufferLength, __in ULONG IoControlCode)
PFN_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL Method
void Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG OutputBufferLength, __in ULONG InputBufferLength, __in ULONG IoInternalControlCode)
void Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG Length)
PFN_WDF_IO_QUEUE_IO_READ Method
void Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG Length)
PFN_WDF_IO_QUEUE_IO_WRITE Method
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
ULONG GetParameterWriteLength(VOID)
Definition: fxirpum.cpp:1601
ULONG GetParameterIoctlCode(VOID)
Definition: fxirpum.cpp:1474
ULONG GetParameterIoctlOutputBufferLength(VOID)
Definition: fxirpum.cpp:1504
PIO_STACK_LOCATION GetCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:370
ULONG GetParameterIoctlInputBufferLength(VOID)
Definition: fxirpum.cpp:1518
ULONG GetParameterReadLength(VOID)
Definition: fxirpum.cpp:1589
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline VOID SetVerifierFlags(__in SHORT Flags)
__inline VOID ClearVerifierFlags(__in SHORT Flags)
__inline SHORT GetVerifierFlags(VOID)
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
FxRequestCompletionState SetCompletionState(__in FxRequestCompletionState NewState)
Definition: fxrequest.cpp:1760
__inline NTSTATUS Complete(__in NTSTATUS Status)
Definition: fxrequest.hpp:770
PIO_STACK_LOCATION GetCurrentIrpStackLocation(VOID)
Definition: fxrequest.hpp:1026
#define FXREQUEST_STATE_TAG
Definition: fxrequest.hpp:42
FxIrp * pIrp
UCHAR majorFunction
@ FXREQUEST_FLAG_FORWARDED
@ FXREQUEST_FLAG_DRIVER_DISPATCH
@ FXREQUEST_FLAG_DRIVER_OWNED
FxRequestCompletionState
@ FxRequestCompletionStateQueue
@ FxRequestCompletionStateNone
Status
Definition: gdiplustypes.h:25
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ Dispose()

BOOLEAN FxIoQueue::Dispose ( VOID  )
virtual

Reimplemented from FxObject.

Definition at line 448 of file fxioqueue.cpp.

464{
465 KIRQL irql;
466
467 if (IsCommitted() == FALSE) {
468 //
469 // We called DeleteFromFailedCreate because we couldn't commit the
470 // object.
471 //
472 goto End;
473 }
474
475 //
476 // If object is commited means we are added to the FxPkgIo queue list.
477 //
478 //
479 // Purge the queue asynchrnously without providing any callback. That way,
480 // we allow the driver to have an outstanding purge request while the delete
481 // is in progress.
482 //
484
485 Lock(&irql);
486
487 //
488 // Mark that this queue is disposing
489 //
490
492
494
495 //
496 // Just make sure the state hasn't changed after the purge.
497 //
499
500 //
501 // Call the FxPkgIo to remove its references to this queue
502 //
503 // Note: We are holding the queue lock to prevent races, and
504 // FxPkgIo never calls FxIoQueue methods while holding
505 // its lock.
506 //
508
509 DispatchEvents(irql);
510
511 //
512 // Wait for the finished event to be signalled. This event will
513 // be signalled when the queue is in a disposed state and there
514 // are no more pending events.
515 //
517 "waiting for the queue to be deleted, WDFQUEUE", GetHandle(),
518 GetDriverGlobals()->FxVerifierDbgWaitForSignalTimeoutInSec,
520
521
523
526
531 }
532
533 if (m_FwdProgContext != NULL) {
537 }
538
539 //
540 // Rundown the workitem.
541 //
542 if (m_SystemWorkItem != NULL) {
545 }
546
547 //
548 // Rundown the DPCs
549 //
550 if (m_DpcQueued) {
552 }
553
554 //
555 // All callbacks into the device driver acquire and release a
556 // reference on the queue. This ensures that the queue will
557 // not actually complete deleting until return from any
558 // outstanding event callbacks into the device driver.
559 //
560 // See DispatchRequestToDriver()
561 //
562End:
563
564 FxNonPagedObject::Dispose(); // __super call
565
566 return TRUE;
567}
__inline BOOLEAN IsForwardProgressQueue(VOID)
Definition: fxioqueue.hpp:1264
__inline BOOLEAN IsState(__in WDF_IO_QUEUE_STATE State)
Definition: fxioqueue.hpp:843
MxEvent m_FinishDisposing
Definition: fxioqueue.hpp:297
VOID FreeAllReservedRequests(__in BOOLEAN Verify)
Definition: fxioqueueum.hpp:81
_Must_inspect_result_ NTSTATUS QueuePurge(__in BOOLEAN CancelQueueRequests, __in BOOLEAN CancelDriverRequests, __in_opt PFN_WDF_IO_QUEUE_STATE PurgeComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:3894
VOID FlushQueuedDpcs(VOID)
virtual VOID DeleteObject(VOID)
virtual BOOLEAN Dispose(VOID)
BOOLEAN IsCommitted(VOID)
Definition: fxobject.hpp:1087
VOID RemoveQueueReferences(__inout FxIoQueue *pQueue)
Definition: fxpkgio.cpp:1091
MxEvent * GetSelfPointer(VOID)
Definition: mxevent.h:110
__inline VOID Uninitialize()
Definition: mxlockkm.h:104
@ WaitSignalBreakUnderVerifier
Definition: fxglobals.h:84
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
VOID WaitForSignal(__in MxEvent *Event, __in PCSTR ReasonForWaiting, __in PVOID Handle, __in ULONG WarningTimeoutInSec, __in ULONG WaitSignalFlags)
Definition: globals.cpp:1705
@ WdfIoQueueAcceptRequests
Definition: wdfio.h:125

◆ FatalError()

DECLSPEC_NORETURN VOID FxIoQueue::FatalError ( __in NTSTATUS  Status)

Definition at line 6339 of file fxioqueue.cpp.

6342{
6344
6345 RtlZeroMemory(&data, sizeof(data));
6346
6347 data.Queue = GetHandle();
6348 data.Request = NULL;
6349 data.Status = Status;
6350
6353 (ULONG_PTR) &data);
6354}
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
@ WDF_QUEUE_FATAL_ERROR
Definition: wdfbugcodes.h:67

◆ FlushByFileObject()

VOID FxIoQueue::FlushByFileObject ( __in MdFileObject  FileObject)

Definition at line 4256 of file fxioqueue.cpp.

4275{
4278 KIRQL irql;
4279
4280 if (IsForwardProgressQueue()) {
4282 }
4283
4284 Lock(&irql);
4285
4286 #pragma warning(disable:4127)
4287 while (TRUE) {
4288 #pragma warning(default:4127)
4289
4290 //
4291 // Get the next FxRequest from the cancel safe queue
4292 //
4295 break;
4296 }
4297 if(!NT_SUCCESS(status)) {
4298 ASSERTMSG("GetNextRequest failed\n", FALSE);
4299 break;
4300 }
4301
4302 //
4303 // We must add a reference since the CancelForQueue path
4304 // assumes we were on the FxIrpQueue with the extra reference
4305 //
4307
4308 //
4309 // Mark the request as cancelled, place it on the cancel list,
4310 // and schedule the cancel event to the driver
4311 //
4312 CancelForQueue(pRequest, irql);
4313
4314 //
4315 // Reacquire the lock because CancelForQueue visits the dispatch-loop
4316 // and releases the lock.
4317 //
4318 Lock(&irql);
4319 }
4320
4321 DispatchEvents(irql);
4322
4323 return;
4324
4325}
VOID PurgeForwardProgressIrps(__in_opt MdFileObject FileObject)
Definition: fxioqueue.cpp:6467
static _Must_inspect_result_ FxRequest * GetNextRequest(__in FxIrpQueue *IrpQueue)
Definition: fxrequest.cpp:2025
#define FXREQUEST_QUEUE_TAG
Definition: fxrequest.hpp:47
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

◆ FlushQueuedDpcs()

VOID FxIoQueue::FlushQueuedDpcs ( VOID  )

Definition at line 150 of file fxioqueueum.hpp.

164{
166}

Referenced by Dispose().

◆ ForwardRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::ForwardRequest ( __in FxIoQueue pDestQueue,
__in FxRequest pRequest 
)

Definition at line 1712 of file fxioqueue.cpp.

1746{
1748
1749 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
1750
1751 status = VerifyForwardRequest(FxDriverGlobals, pDestQueue, pRequest);
1752 if (!NT_SUCCESS(status)) {
1753 return status;
1754 }
1755
1757 return status;
1758}
_Must_inspect_result_ NTSTATUS ForwardRequestWorker(__in FxRequest *Request, __in FxIoQueue *DestQueue)
Definition: fxioqueue.cpp:1354
_Must_inspect_result_ NTSTATUS _In_ FxIoQueue * pDestQueue
Definition: fxioqueue.cpp:1667

Referenced by FxPkgGeneral::OnCreate().

◆ ForwardRequestToParent()

_Must_inspect_result_ NTSTATUS FxIoQueue::ForwardRequestToParent ( __in FxIoQueue DestQueue,
__in FxRequest Request,
__in PWDF_REQUEST_FORWARD_OPTIONS  ForwardOptions 
)

Definition at line 1569 of file fxioqueue.cpp.

1605{
1608 BOOLEAN forwardRequestToParent;
1609 FxIrp* pIrp;
1610
1612
1614
1615 forwardRequestToParent = Request->m_ForwardRequestToParent;
1616
1617 status = VerifyForwardRequestToParent(pFxDriverGlobals,
1618 DestQueue,
1619 Request);
1620 if(!NT_SUCCESS(status)){
1621 return status;
1622 }
1623
1624 pIrp = Request->GetFxIrp();
1625
1628
1629 //
1630 // Save a pointer to the device object for this request so that it can
1631 // be used later in completion.
1632 //
1634
1635 Request->SetDeviceBase((CfxDeviceBase *)m_Device->m_ParentDevice);
1636 Request->m_ForwardRequestToParent = TRUE;
1637
1639
1640 //
1641 // Undo the actions of changing the FxDevice and
1642 // changing the deviceObject and stack location in the IRP
1643 //
1644 if (!NT_SUCCESS(status)) {
1645 Request->SetDeviceBase((CfxDeviceBase *)m_Device);
1646 pIrp = Request->GetFxIrp();
1649
1650 //
1651 // Set the value of m_ForwardRequestToParent to the previous
1652 // value so that if the Request has been forwarded to Parent
1653 // successfully but fails to be forwarded to the grandparent
1654 // from the parent then we free it back using ExFreePool
1655 // instead of the Lookaside buffer .
1656 //
1657 Request->m_ForwardRequestToParent = forwardRequestToParent;
1658 }
1659
1660 return status;
1661}
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
CfxDevice * m_ParentDevice
Definition: fxdevice.hpp:569
MdDeviceObject GetDeviceObject(VOID)
Definition: fxirpum.cpp:1352
VOID SetNextIrpStackLocation(VOID)
Definition: fxirpum.cpp:1235
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
VOID CopyCurrentIrpStackLocationToNext(VOID)
Definition: fxirpum.cpp:209
VOID SetCurrentDeviceObject(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:1362
_Must_inspect_result_ NTSTATUS _In_ FxIoQueue * DestQueue
Definition: fxioqueue.cpp:1476
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE _In_ PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions
Definition: wdfrequest.h:1736

◆ ForwardRequestWorker()

_Must_inspect_result_ NTSTATUS FxIoQueue::ForwardRequestWorker ( __in FxRequest Request,
__in FxIoQueue DestQueue 
)

Definition at line 1354 of file fxioqueue.cpp.

1358{
1360 FxRequestCompletionState oldState;
1363 KIRQL irql;
1364
1365 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
1366
1367 OldFlags = 0;
1368
1369 //
1370 // The request has only one reference, held by the completion
1371 // callback function. We need to take another one before cancelling
1372 // this function, otherwise we will lose the request object
1373 //
1375
1376 //
1377 // Cancel its current completion event for this queue
1378 //
1379 oldState = Request->SetCompletionState(FxRequestCompletionStateNone);
1381
1382 OldFlags = VerifyForwardRequestUpdateFlags(FxDriverGlobals, Request);
1383
1384 //
1385 // Remove it from this queues driver owned list.
1386 //
1387 // This must be done before forward since new queue will
1388 // use the list entry in the FxRequest
1389 //
1390 // We can't use RemoveFromDriverOwnedList since we want the
1391 // m_DriverIoCount to be left alone in case the forward fails.
1392 // If we don't, another thread can run when we drop the lock, notice
1393 // that there are no more requests, and raise the purged and empty
1394 // events. But if the forward fails, the request will wind up back
1395 // on the queue! So m_DriverIoCount is used as a gate to prevent
1396 // these events from firing until we are really sure this queue
1397 // is done with the request.
1398 //
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410 Lock(&irql);
1411 ple = Request->GetListEntry(FxListEntryDriverOwned);
1414 Unlock(irql);
1415
1416 //
1417 // Attempt to pass the request onto the target queue
1418 //
1420 if (!NT_SUCCESS(status)) {
1421
1422 //
1423 // Target queue did not accept the request, so we
1424 // restore the original completion callback function
1425 // and flags
1426 //
1427 oldState = Request->SetCompletionState(oldState);
1429 UNREFERENCED_PARAMETER(oldState);
1430
1431 if (FxDriverGlobals->FxVerifierOn) {
1432 Request->SetVerifierFlags(OldFlags);
1433 }
1434
1435 // Release the extra reference we took
1436 Request->RELEASE(FXREQUEST_STATE_TAG);
1437
1438 Lock(&irql);
1439 // Place it back on the driver owned list
1441 Unlock(irql);
1442 }
1443 else {
1444
1445 Lock(&irql);
1446
1447 // Request is no longer part of the I/O count for this queue
1449
1450 ASSERT(m_DriverIoCount >= 0);
1451
1452 //
1453 // Don't run the event dispatcher if we are called from a
1454 // dispath routine in order to prevent stack recursion.
1455 // Since some other thread (possibly this thread higher on
1456 // the stack) is running the dispatcher, no events will get lost.
1457 //
1458 //
1459 // This returns with the IoQueue lock released
1460 //
1461 DispatchInternalEvents(irql);
1462
1463 //
1464 // We don't dereference the request object since the new IoQueue
1465 // will release it when it is done.
1466 //
1467 }
1468
1469 return status;
1470}
_Must_inspect_result_ NTSTATUS QueueRequestFromForward(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2351
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
PSINGLE_LIST_ENTRY ple
SHORT OldFlags
Definition: fxioqueue.cpp:1325
@ FxListEntryDriverOwned
Definition: fxrequest.hpp:378
short SHORT
Definition: pedump.c:59

Referenced by ForwardRequest(), and ForwardRequestToParent().

◆ FreeAllReservedRequests()

VOID FxIoQueue::FreeAllReservedRequests ( __in BOOLEAN  Verify)
private

Definition at line 81 of file fxioqueueum.hpp.

96{
98
100 return;
101
102}
@ Verify
Definition: msg.c:1065

Referenced by Dispose().

◆ FX_DECLARE_VF_FUNCTION_P1() [1/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( NTSTATUS  ,
VerifyGetRequestUpdateFlags  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1() [2/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( NTSTATUS  ,
VerifyPeekRequest  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1() [3/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( NTSTATUS  ,
VerifyRequeue  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1() [4/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( VOID  ,
VerifyCancelForDriver  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1() [5/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( VOID  ,
VerifyGetRequestRestoreFlags  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1() [6/6]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1 ( VOID  ,
VerifyValidateCompletedRequest  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P1_EX()

FxIoQueue::FX_DECLARE_VF_FUNCTION_P1_EX ( SHORT  ,
,
VerifyForwardRequestUpdateFlags  ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P2() [1/4]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P2 ( NTSTATUS  ,
VerifyForwardRequest  ,
_In_ FxIoQueue ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P2() [2/4]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P2 ( NTSTATUS  ,
VerifyForwardRequestToParent  ,
_In_ FxIoQueue ,
_In_ FxRequest  
)

◆ FX_DECLARE_VF_FUNCTION_P2() [3/4]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P2 ( NTSTATUS  ,
VerifyQueueDriverCreatedRequest  ,
_In_ FxRequest ,
_Inout_ SHORT  
)

◆ FX_DECLARE_VF_FUNCTION_P2() [4/4]

FxIoQueue::FX_DECLARE_VF_FUNCTION_P2 ( NTSTATUS  ,
VerifyRequestCancelable  ,
_In_ FxRequest ,
_In_  BOOLEAN 
)

◆ GetCallbackLockPtr()

virtual FxCallbackLock * FxIoQueue::GetCallbackLockPtr ( __deref_out FxObject **  LockObject)
inlinevirtual

Definition at line 1064 of file fxioqueue.hpp.

1067 {
1068 if (LockObject != NULL) {
1070 }
1071
1072 return m_CallbackLockPtr;
1073 }
#define LockObject(Object)
Definition: titypes.h:34

◆ GetConstraints()

virtual VOID FxIoQueue::GetConstraints ( __out WDF_EXECUTION_LEVEL ExecutionLevel,
__out WDF_SYNCHRONIZATION_SCOPE SynchronizationScope 
)
inlinevirtual

Implements IFxHasCallbacks.

Definition at line 1048 of file fxioqueue.hpp.

1051 {
1052
1053 if (ExecutionLevel != NULL) {
1054 *ExecutionLevel = m_ExecutionLevel;
1055 }
1056
1057 if (SynchronizationScope != NULL) {
1058 *SynchronizationScope = m_SynchronizationScope;
1059 }
1060 }

◆ GetCxDeviceInfo()

__inline FxCxDeviceInfo * FxIoQueue::GetCxDeviceInfo ( VOID  )
inline

Definition at line 1360 of file fxioqueue.hpp.

1363 {
1364 return m_CxDeviceInfo;
1365 }

Referenced by AllocateReservedRequest().

◆ GetDevice()

__inline CfxDevice * FxIoQueue::GetDevice ( VOID  )
inline

Definition at line 773 of file fxioqueue.hpp.

774 {
775 return m_Device;
776 }

Referenced by __drv_strictTypeMatch(), if(), PerfEvtIoStopStart(), PerfEvtIoStopStop(), PerfIoComplete(), and PerfIoStart().

◆ GetDriver()

__inline FxDriver * FxIoQueue::GetDriver ( VOID  )
inline

Definition at line 767 of file fxioqueue.hpp.

767 {
768 return m_PkgIo->GetDriver();
769 }
FxDriver * GetDriver(VOID)
Definition: fxpkgio.cpp:543

◆ GetForwardProgressIrpLocked()

_Must_inspect_result_ PIRP FxIoQueue::GetForwardProgressIrpLocked ( __in_opt PFILE_OBJECT  FileObject)
private

Definition at line 60 of file fxioqueueum.hpp.

71{
73
75 return NULL;
76
77}

◆ GetForwardProgressIrps()

VOID FxIoQueue::GetForwardProgressIrps ( __in PLIST_ENTRY  IrpListHead,
__in_opt MdFileObject  FileObject 
)
private

Definition at line 127 of file fxioqueueum.hpp.

139{
140 UNREFERENCED_PARAMETER(IrpListHead);
142
144 return;
145
146}

Referenced by PurgeForwardProgressIrps(), and QueueIdle().

◆ GetHandle()

WDFQUEUE __inline FxIoQueue::GetHandle ( VOID  )
inline

Definition at line 786 of file fxioqueue.hpp.

789 {
790 return (WDFQUEUE) GetObjectHandle();
791 }

◆ GetPackage()

__inline FxPkgIo * FxIoQueue::GetPackage ( VOID  )
inline

Definition at line 780 of file fxioqueue.hpp.

780 {
781 return m_PkgIo;
782 }

◆ GetRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::GetRequest ( __in_opt MdFileObject  FileObject,
__in_opt FxRequest TagRequest,
__deref_out FxRequest **  pOutRequest 
)

Definition at line 962 of file fxioqueue.cpp.

986{
991 KIRQL irql;
992
993 status = VerifyGetRequestUpdateFlags(pFxDriverGlobals, TagRequest);
994 if(!NT_SUCCESS(status)){
995 return status;
996 }
997
998 //
999 // Don't allow on parallel queues
1000 //
1005 "Cannot be called on a parallel WDFQUEUE 0x%p, %!STATUS!",
1007 return status;
1008 }
1009
1010 Lock(&irql);
1011
1012 //
1013 // Only if the queue state allows requests to be retrieved.
1014 // It's okay to retrieve requests while the queue is in a transitioning state.
1015 //
1019 "WDFQUEUE 0x%p is powered off, %!STATUS!",
1021 Unlock(irql);
1022 return status;
1023 }
1024
1025 //
1026 // See if the queue is (still) processing requests
1027 //
1031 "WDFQUEUE 0x%p is stopped, %!STATUS!",
1033 Unlock(irql);
1034 return status;
1035 }
1036
1037 #pragma warning(disable:4127)
1038 while (TRUE) {
1039
1040 #pragma warning(default:4127)
1041 //
1042 // Get the next FxRequest from the cancel safe queue
1043 //
1045 if (!NT_SUCCESS(status)) {
1046 //
1047 // This code address the following race condition:
1048 // 1) Queue has only one request (count 1).
1049 // 2) Request in queue is cancelled.
1050 // 3) Request's cancellation logic starts to run on thread 1.
1051 // 4) But before cancellation logic gets the queue's lock
1052 // thread 2 calls WdfIoQueueRetrieveNextRequest.
1053 // 5) WdfIoQueueRetrieveNextRequest returns no more requests.
1054 // Driver waits for the ReadyNotify callback. (count 1)
1055 // 6) Thread 3 adds a new request in queue. (count 1->2)
1056 // 7) Thread 1 finally runs. (count 2->1).
1057 // 8) At this point driver stops responding b/c it never receives ReadyNotify.
1058 //
1059 // This code below forces the queue logic to send a ReadyNotify
1060 // callback the next time a new request is added (in step 6 above).
1061 //
1063 NULL == FileObject && // WdfIoQueueRetrieveNextRequest
1064 NULL == TagRequest && // WdfIoQueueRetrieveNextRequest
1065 m_Queue.GetRequestCount() > 0L) {
1066
1068 }
1069
1070 Unlock(irql);
1071 return status;
1072 }
1073
1074 //
1075 // If we don't allow zero length read/write's to the driver,
1076 // complete it now with success and attempt to get another
1077 // request from the queue.
1078 //
1080
1081
1082
1083
1084
1086
1089
1090 if ((majorFunction == IRP_MJ_READ) &&
1091 (pIrp->GetParameterReadLength() == 0)) {
1092
1093 Unlock(irql);
1095 "Zero length WDFREQUEST 0x%p completed automatically by WDFQUEUE 0x%p",
1099
1100 Lock(&irql);
1101
1102 // Get another request from the queue
1103 continue;
1104 }
1105 else if ((majorFunction == IRP_MJ_WRITE) &&
1106 (pIrp->GetParameterWriteLength() == 0)) {
1107
1108 Unlock(irql);
1110 "Zero length WDFREQUEST 0x%p completed automatically by WDFQUEUE 0x%p",
1112
1115
1116 Lock(&irql);
1117
1118 // Get another request from the queue
1119 continue;
1120 }
1121 }
1122
1123 break;
1124 }
1125
1126 // Increase the driver owned request count
1128
1129 Unlock(irql);
1130
1131 //
1132 // We don't need to check for PurgeComplete since
1133 // we are giving the request to the driver
1134 //
1135
1136 // pRequest is not cancellable now
1137
1138 //
1139 // We are now going to return the request
1140 // to the driver, and it must complete it.
1141 //
1142
1143 //
1144 // Set a completion event, this takes a reference
1145 //
1148 UNREFERENCED_PARAMETER(oldState);
1149
1150 //
1151 // Track that we have given the request to the driver
1152 //
1153 VerifyGetRequestRestoreFlags(pFxDriverGlobals, pRequest);
1154
1156
1157 //
1158 // Release our original reference. The FxRequest::Complete
1159 // will release the final one since we have registered a completion
1160 // callback handler
1161 //
1162 // We now have one reference count on the FxRequest object until
1163 // its completion routine runs since the completion event made
1164 // an extra reference, and will dereference it when it fires, or
1165 // its canceled.
1166 //
1167
1168 pRequest->RELEASE(FXREQUEST_STATE_TAG);
1169
1170 // Return it to the driver
1171 *pOutRequest = pRequest;
1172
1173 return STATUS_SUCCESS;
1174}
__inline VOID InsertInDriverOwnedList(__in FxRequest *Request)
Definition: fxioqueue.hpp:1451
__inline NTSTATUS CompleteWithInformation(__in NTSTATUS Status, __in ULONG_PTR Information)
Definition: fxrequest.hpp:810
_Must_inspect_result_ NTSTATUS _In_ FxRequest * TagRequest
Definition: fxioqueue.cpp:885
@ FxIoQueuePowerOff
Definition: fxioqueue.hpp:133
#define FXREQUEST_COMPLETE_TAG
Definition: fxrequest.hpp:52
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
@ WdfIoQueueDispatchRequests
Definition: wdfio.h:126
@ WdfIoQueueDispatchManual
Definition: wdfio.h:80
#define STATUS_WDF_PAUSED
Definition: wdfstatus.h:117

Referenced by FxPkgGeneral::OnCreate().

◆ GetRequestCount()

VOID FxIoQueue::GetRequestCount ( __out_opt PULONG  pQueuedRequests,
__out_opt PULONG  pDriverPendingRequests 
)

Definition at line 4227 of file fxioqueue.cpp.

4243{
4244 if (pQueuedRequests != NULL) {
4245 *pQueuedRequests = m_Queue.GetRequestCount();
4246 }
4247
4248 if (pDriverPendingRequests != NULL) {
4249 *pDriverPendingRequests = m_DriverIoCount;
4250 }
4251
4252 return;
4253}

Referenced by GetState().

◆ GetReservedRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::GetReservedRequest ( __in MdIrp  Irp,
__deref_out_opt FxRequest **  ReservedRequest 
)

Definition at line 192 of file fxioqueueum.hpp.

203{
205 UNREFERENCED_PARAMETER(ReservedRequest);
206
209}
_In_ PIRP Irp
Definition: csq.h:116

◆ GetState()

WDF_IO_QUEUE_STATE FxIoQueue::GetState ( __out_opt PULONG  pQueueCount,
__out_opt PULONG  pDriverCount 
)

Definition at line 760 of file fxioqueue.cpp.

764{
765 int stat;
767
768 // Get request counts
770
771 if (pQueueCount ) *pQueueCount = QueueCount;
772
773 if (pDriverCount ) *pDriverCount = DriverCount;
774
775 //
776 // First fill in the values that are kept up to date at runtime
777 //
779
780 //
781 // Set additional information bits from information retrieved
782 // from other sources. It's cheaper to get this info at the infrequent
783 // GetStatus time, rather than keep the bits up to date at each
784 // request and queue transition.
785 //
786 if (QueueCount == 0) {
788 }
789
790 if (DriverCount == 0) {
792 }
793
794 if(m_PowerManaged) {
795
798 }
799 }
800
801 return (WDF_IO_QUEUE_STATE)stat;
802}
#define stat
Definition: acwin.h:99
VOID GetRequestCount(__out_opt PULONG pQueuedRequests, __out_opt PULONG pDriverPendingRequests)
Definition: fxioqueue.cpp:4227
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static LONG QueueCount
Definition: dispatch.c:34
__in WDFQUEUE __out_opt PULONG __out_opt PULONG DriverCount
Definition: stat.h:55
@ WdfIoQueueDriverNoRequests
Definition: wdfio.h:128
@ WdfIoQueueNoRequests
Definition: wdfio.h:127
@ WdfIoQueuePnpHeld
Definition: wdfio.h:129
enum _WDF_IO_QUEUE_STATE WDF_IO_QUEUE_STATE

◆ Initialize()

_Must_inspect_result_ NTSTATUS FxIoQueue::Initialize ( __in PWDF_IO_QUEUE_CONFIG  pConfig,
__in_opt PWDF_OBJECT_ATTRIBUTES  QueueAttributes,
__in_opt FxDriver Caller,
__in BOOLEAN  InitialPowerStateOn 
)

Definition at line 217 of file fxioqueue.cpp.

240{
242 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
243
245 if (!NT_SUCCESS(Status)) {
246 return Status;
247 }
248
250 if (!NT_SUCCESS(Status)) {
251 return Status;
252 }
253
254#if (FX_CORE_MODE==FX_CORE_USER_MODE)
256 if (!NT_SUCCESS(Status)) {
257 return Status;
258 }
259#endif
260
262
263 //
264 // Set the execution level and callback synchronization based on
265 // configuration
266 //
268 if (!NT_SUCCESS(Status)) {
269 return Status;
270 }
271
272 //
273 // Validate dispatch type.
274 //
275 if (pConfig->DispatchType <= WdfIoQueueDispatchInvalid ||
276 pConfig->DispatchType >= WdfIoQueueDispatchMax) {
278 "Invalid dispatch type "
279 "specified %d, Queue 0x%p %!STATUS!",
280 pConfig->DispatchType,
284 }
285
286 //
287 // If not a manual queue, must set at least IoStart, or one of
288 // read|write|devicecontrol
289 //
290 if ((pConfig->DispatchType != WdfIoQueueDispatchManual) &&
291 (pConfig->EvtIoDefault == NULL)) {
292
293 if ((pConfig->EvtIoDefault == NULL) &&
294 (pConfig->EvtIoRead == NULL) &&
295 (pConfig->EvtIoWrite == NULL) &&
296 (pConfig->EvtIoDeviceControl == NULL) &&
297 (pConfig->EvtIoInternalDeviceControl == NULL)) {
298
300 "At least one of EvtIoDefault|EvtIoRead|EvtIoWrite|"
301 "EvtIoDeviceControl|EvtIoInternalDeviceControl "
302 "must be set %!STATUS!", STATUS_WDF_NO_CALLBACK);
304 }
305 }
306
307 //
308 // A manual queue should not set any callback function
309 // pointers since they will not get invoked.
310 //
311 if (pConfig->DispatchType == WdfIoQueueDispatchManual) {
312
313 if ((pConfig->EvtIoDefault != NULL) ||
314 (pConfig->EvtIoRead != NULL) ||
315 (pConfig->EvtIoWrite != NULL) ||
316 (pConfig->EvtIoDeviceControl != NULL) ||
317 (pConfig->EvtIoInternalDeviceControl != NULL)) {
318
320 "Cannot set io callback events "
321 "on a manual WDFQUEUE 0x%p %!STATUS!",
325 }
326 }
327
328 //
329 // For version less than v1.9 m_MaxParallelQueuePresentedRequests is set to
330 // -1 by the FxIoQueue Constructor.
331 // By checking > below we mean v1.9 and above (public API already did the official
332 // validation).
333 //
334 if (pConfig->Size > sizeof(WDF_IO_QUEUE_CONFIG_V1_7)) {
335 if (pConfig->Settings.Parallel.NumberOfPresentedRequests != 0 &&
336 (pConfig->DispatchType == WdfIoQueueDispatchSequential ||
337 pConfig->DispatchType == WdfIoQueueDispatchManual)) {
340 "Cannot have NumberOfPresentedRequests other "
341 "than 0 on a Sequential or manual WDFQUEUE 0x%p."
342 "Make Sure you set NumberOfPresentedRequests"
343 " to 0, %!STATUS!",
345 Status
346 );
347 return Status;
348
349 }
350 else{
352 pConfig->Settings.Parallel.NumberOfPresentedRequests;
353 }
354 }
355
356 //
357 // Initialize our workitem if we have to support passive callbacks
358 //
359 if (m_PassiveLevel) {
360
361 Status = FxSystemWorkItem::_Create(FxDriverGlobals,
364 );
365
366 if (!NT_SUCCESS(Status)) {
368 "Could not allocate workitem: %!STATUS!", Status);
369 return Status;
370 }
371 }
372
373 m_Type = pConfig->DispatchType;
374
375 switch(pConfig->PowerManaged) {
376
377 case WdfUseDefault:
378 if(m_Device->IsFilter()){
380 } else {
382 }
383 break;
384
385 case WdfTrue:
387 break;
388
389 case WdfFalse:
391 break;
392 default:
393 ASSERTMSG("Invalid value in WDF_IO_QUEUE_CONFIG PowerManaged field\n", FALSE);
394 break;
395 }
396
397 //
398 // Queues for NonPnp devices can't be power managed.
399 //
400 if(m_Device->IsLegacy()) {
402 }
403
404 //
405 // If power managed queue, ensure its initial power state
406 // is same as the device.
407 //
408 if (m_PowerManaged) {
409 if (InitialPowerStateOn) {
411 }
412 else {
414 }
415 } else {
417 }
418
419 m_AllowZeroLengthRequests = pConfig->AllowZeroLengthRequests;
420
422 "EvtIoDefault 0x%p, EvtIoRead 0x%p, EvtIoWrite 0x%p, "
423 "EvtIoDeviceControl 0x%p for WDFQUEUE 0x%p",
424 pConfig->EvtIoDefault,
425 pConfig->EvtIoRead,
426 pConfig->EvtIoWrite,
427 pConfig->EvtIoDeviceControl, GetObjectHandle());
428
429 m_IoDefault.Method = pConfig->EvtIoDefault;
430 m_IoStop.Method = pConfig->EvtIoStop;
431 m_IoResume.Method = pConfig->EvtIoResume;
432 m_IoRead.Method = pConfig->EvtIoRead;
433 m_IoWrite.Method = pConfig->EvtIoWrite;
434 m_IoDeviceControl.Method = pConfig->EvtIoDeviceControl;
435 m_IoInternalDeviceControl.Method = pConfig->EvtIoInternalDeviceControl;
436 m_IoCanceledOnQueue.Method = pConfig->EvtIoCanceledOnQueue;
437
438
439 // A newly created queue can accept and dispatch requests once initialized
441
443
444 return STATUS_SUCCESS;
445}
__inline BOOLEAN IsLegacy(VOID)
Definition: fxdevice.hpp:1209
__inline BOOLEAN IsFilter()
Definition: fxdevice.hpp:1408
PFN_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE Method
PFN_WDF_IO_QUEUE_IO_RESUME Method
PFN_WDF_IO_QUEUE_IO_STOP Method
MxEvent m_RequestWaitEventUm
Definition: fxioqueue.hpp:578
MxEvent m_PowerIdle
Definition: fxioqueue.hpp:571
_Must_inspect_result_ NTSTATUS ConfigureConstraints(__in_opt PWDF_OBJECT_ATTRIBUTES ObjectAttributes, __in_opt FxDriver *Caller)
Definition: fxioqueue.cpp:571
VOID SetState(__in FX_IO_QUEUE_SET_STATE NewStatus)
Definition: fxioqueue.cpp:805
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
@ FxIoQueueSetAcceptRequests
Definition: fxioqueue.hpp:196
@ FxIoQueueSetDispatchRequests
Definition: fxioqueue.hpp:198
enum _FX_IO_QUEUE_SET_STATE FX_IO_QUEUE_SET_STATE
@ NotificationEvent
@ SynchronizationEvent
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_IO_QUEUE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES QueueAttributes
Definition: wdfio.h:617
@ WdfIoQueueDispatchMax
Definition: wdfio.h:81
@ WdfIoQueueDispatchInvalid
Definition: wdfio.h:77
#define STATUS_WDF_NO_CALLBACK
Definition: wdfstatus.h:189
@ WdfTrue
Definition: wdftypes.h:88
@ WdfUseDefault
Definition: wdftypes.h:89
@ WdfFalse
Definition: wdftypes.h:87

Referenced by _Create().

◆ InsertInDriverOwnedList()

__inline VOID FxIoQueue::InsertInDriverOwnedList ( __in FxRequest Request)
inlineprivate

Definition at line 1451 of file fxioqueue.hpp.

1454 {
1456
1458 return;
1459 }

Referenced by GetRequest().

◆ InsertNewRequest()

__inline NTSTATUS FxIoQueue::InsertNewRequest ( __in FxRequest **  Request,
__in KIRQL  PreviousIrql 
)
inlineprivate

Definition at line 1584 of file fxioqueue.hpp.

1588 {
1590
1591 if (*Request != NULL) {
1593 }
1594 else {
1595 status = STATUS_SUCCESS; // nothing to do.
1596 }
1597
1598 return status;
1599 }
NTSTATUS InsertNewRequestLocked(__deref_in FxRequest **Request, __in KIRQL PreviousIrql)
Definition: fxioqueue.cpp:2571

◆ InsertNewRequestLocked()

NTSTATUS FxIoQueue::InsertNewRequestLocked ( __deref_in FxRequest **  Request,
__in KIRQL  PreviousIrql 
)
private

Definition at line 2571 of file fxioqueue.cpp.

2594{
2596
2597 status = (*Request)->InsertTailIrpQueue(&m_Queue, NULL);
2598
2599 if (!NT_SUCCESS(status)) {
2600 //
2601 // Request was never presented to the driver
2602 // so there is no need to call CancelForQueue
2603 // in this case.
2604 //
2606
2608
2609 (*Request)->CompleteWithInformation(status, 0);
2610
2611 (*Request)->RELEASE(FXREQUEST_COMPLETE_TAG);
2612
2614 }
2615 else {
2616 (*Request)->SetCurrentQueue(this);
2617
2618 // Check if went from no requests to have requests
2620 }
2621
2622 //
2623 // Request is either inserted into the queue or completed. Clear
2624 // the field to prevent touching the request.
2625 //
2626 *Request = NULL;
2627
2628 return status;
2629}
__inline VOID CheckTransitionFromEmpty(VOID)
Definition: fxioqueue.hpp:1541

Referenced by InsertNewRequest(), and QueueRequest().

◆ InsertQueueDpc()

VOID FxIoQueue::InsertQueueDpc ( VOID  )

Definition at line 171 of file fxioqueueum.hpp.

185{
187}

Referenced by CanThreadDispatchEventsLocked(), and DeferredDispatchRequestsFromDpc().

◆ InvokeAllocateResourcesCallback()

__inline NTSTATUS FxIoQueue::InvokeAllocateResourcesCallback ( __in FxRequest Request)
inline

Definition at line 1273 of file fxioqueue.hpp.

1283 {
1285
1286 ASSERT(Request->IsReserved() == FALSE);
1287
1290 Request->SetPresented();
1292 GetHandle(), Request->GetHandle());
1293 }
1294
1295 return status;
1296 }
PFN_WDF_IO_ALLOCATE_REQUEST_RESOURCES Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFQUEUE Queue, __in WDFREQUEST Request)
FxIoQueueForwardProgressAllocateResources m_IoResourcesAllocate
Definition: fxioqueue.hpp:160

◆ IsForwardProgressQueue()

__inline BOOLEAN FxIoQueue::IsForwardProgressQueue ( VOID  )
inline

Definition at line 1264 of file fxioqueue.hpp.

1267 {
1269 }

Referenced by Dispose(), FlushByFileObject(), QueueIdle(), and QueuePurge().

◆ IsIoEventHandlerRegistered()

BOOLEAN FxIoQueue::IsIoEventHandlerRegistered ( __in WDF_REQUEST_TYPE  RequestType)

Definition at line 6178 of file fxioqueue.cpp.

6193{
6195 //
6196 // Manual queues wouldn't have any IoEvent callbacks registered.
6197 //
6198 return TRUE;
6199 }
6200
6201 //
6202 // Default handler is a catch all handler.
6203 //
6204 if(m_IoDefault.Method != NULL) {
6205 return TRUE;
6206 }
6207
6208 //
6209 // Default handle is not registered. So check to see if request specific
6210 // handler is registered.
6211 //
6212 switch(RequestType) {
6213 case WdfRequestTypeRead:
6214 if(m_IoRead.Method == NULL) {
6215 return FALSE;
6216 }
6217 break;
6219 if(m_IoWrite.Method == NULL) {
6220 return FALSE;
6221 }
6222 break;
6225 return FALSE;
6226 }
6227 break;
6230 return FALSE;
6231 }
6232 break;
6233 case WdfRequestTypeCreate: // Fall through. Must have default handler.
6234 default:
6235 return FALSE;
6236 }
6237
6238 return TRUE;
6239}
@ WdfRequestTypeDeviceControlInternal
Definition: wdfdevice.h:518
@ WdfRequestTypeCreate
Definition: wdfdevice.h:503
@ WdfRequestTypeWrite
Definition: wdfdevice.h:507
@ WdfRequestTypeRead
Definition: wdfdevice.h:506
@ WdfRequestTypeDeviceControl
Definition: wdfdevice.h:517
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4233

Referenced by FxPkgIo::EnqueueRequest().

◆ IsPagingIo()

__inline BOOLEAN FxIoQueue::IsPagingIo ( __in MdIrp  Irp)
private

Definition at line 30 of file fxioqueuekm.hpp.

39{
40 //
41 // NOTE: IRP_INPUT_OPERATION has the same value as IRP_SYNCHRONOUS_PAGING_IO
42 // and IRP_MOUNT_COMPLETION the same as IRP_PAGING_IO so how does one know if
43 // the IO is a paging IO ?
44 //
45
46 // One can assume that if IRP_PAGING_IO is set and the MJ code is not
47 // FILE_SYSTEM_CONTROL then it is a paging I/O.
48 //
49 if (Irp->Flags & IRP_PAGING_IO) {
52 return TRUE;
53 }
54 }
55
56 return FALSE;
57}
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_PAGING_IO

◆ IsPowerManaged()

__inline BOOLEAN FxIoQueue::IsPowerManaged ( )
inline

Definition at line 795 of file fxioqueue.hpp.

795 {
796 return m_PowerManaged;
797 }

◆ IsPowerStateNotifyingDriver()

__inline BOOLEAN FxIoQueue::IsPowerStateNotifyingDriver ( VOID  )
inlineprivate

Definition at line 1429 of file fxioqueue.hpp.

1432 {
1436 return TRUE;
1437 }
1438 else {
1439 return FALSE;
1440 }
1441 }
@ FxIoQueuePowerRestartingNotifyingDriver
Definition: fxioqueue.hpp:142
@ FxIoQueuePowerStoppingNotifyingDriver
Definition: fxioqueue.hpp:136
@ FxIoQueuePowerPurgeNotifyingDriver
Definition: fxioqueue.hpp:139

◆ IsState() [1/2]

__inline BOOLEAN FxIoQueue::IsState ( __in FX_IO_QUEUE_STATE  State)
inline

Definition at line 853 of file fxioqueue.hpp.

856 {
857 ASSERT(!(State & 0x80000000)); // Don't allow FX_IO_QUEUE_SET states
858 return (((int)m_QueueState & (int) (State)) != 0);
859 }

◆ IsState() [2/2]

__inline BOOLEAN FxIoQueue::IsState ( __in WDF_IO_QUEUE_STATE  State)
inline

Definition at line 843 of file fxioqueue.hpp.

846 {
847 ASSERT(!(State & 0x80000000)); // Don't allow FX_IO_QUEUE_SET states
848 return (((int)m_QueueState & (int) (State)) != 0);
849 }

Referenced by Dispose(), GetRequest(), QueueRequest(), QueueRequestFromForward(), ReadyNotify(), and SetState().

◆ PeekRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::PeekRequest ( __in_opt FxRequest TagRequest,
__in_opt MdFileObject  FileObject,
__out_opt PWDF_REQUEST_PARAMETERS  Parameters,
__deref_out FxRequest **  pOutRequest 
)

Definition at line 1197 of file fxioqueue.cpp.

1233{
1237 KIRQL irql;
1238
1239 //
1240 // FindRequest is allowed only on a manual queue.
1241 //
1245 "FindRequest is allowed only on a manaul queue 0x%p, %!STATUS!",
1246 GetHandle(), status);
1248 return status;
1249 }
1250
1251 if (TagRequest != NULL) {
1252 status = VerifyPeekRequest(pFxDriverGlobals, TagRequest);
1253 if (!NT_SUCCESS(status)) {
1254 return status;
1255 }
1256 }
1257
1258 //
1259 // Get the next FxRequest from the cancel safe queue
1260 //
1261 // If success, it will return a referenced FxRequest in
1262 // which the caller must release the reference.
1263 //
1264 Lock(&irql);
1265
1267 &m_Queue,
1268 TagRequest,
1269 FileObject,
1270 Parameters,
1271 &pRequest
1272 );
1273
1274 //
1275 // This code address the following potential race condition:
1276 // 1) Queue has only one request (count 1).
1277 // 2) Request in queue is cancelled.
1278 // 3) Request's cancellation logic starts to run on thread 1.
1279 // 4) But before cancellation logic gets the queue's lock
1280 // thread 2 calls WdfIoQueueFindRequest to find any request.
1281 // 5) WdfIoQueueFindRequest returns no more requests.
1282 // Driver waits for the ReadyNotify callback. (count 1)
1283 // 6) Thread 3 adds a new request in queue. (count 1->2)
1284 // 7) Thread 1 finally runs. (count 2->1).
1285 // 8) At this point driver stops responding b/c it never receives ReadyNotify.
1286 //
1287 // This code below forces the queue logic to send a ReadyNotify
1288 // callback the next time a new request is added (in step 6 above).
1289 //
1291 NULL == FileObject && // WdfIoQueueFindRequest(any request)
1292 NULL == TagRequest && // WdfIoQueueFindRequest(any request)
1293 m_Queue.GetRequestCount() > 0L) {
1294
1296 }
1297
1298 Unlock(irql);
1299
1300 if (!NT_SUCCESS(status)) {
1301 return status;
1302 }
1303
1304 //
1305 // Mark it as a tag request to detect abuse since its not
1306 // driver owned.
1307 //
1310 }
1311
1312 // Return it to the driver
1313 *pOutRequest = pRequest;
1314
1315 return status;
1316}
static _Must_inspect_result_ NTSTATUS PeekRequest(__in FxIrpQueue *IrpQueue, __in_opt FxRequest *TagRequest, __in_opt MdFileObject FileObject, __out_opt PWDF_REQUEST_PARAMETERS Parameters, __deref_out FxRequest **ppOutRequest)
Definition: fxrequest.cpp:2098
FxVerifierDbgBreakPoint(pFxDriverGlobals)
@ FXREQUEST_FLAG_TAG_REQUEST
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869

◆ PostRemoveFromDriverOwnedList()

__inline VOID FxIoQueue::PostRemoveFromDriverOwnedList ( VOID  )
inlineprivate

Definition at line 1522 of file fxioqueue.hpp.

1525 {
1528
1530 ASSERT(m_DriverIoCount >= 0);
1531 return;
1532 }

Referenced by PostRequestCompletedCallback().

◆ PostRequestCompletedCallback()

__inline VOID FxIoQueue::PostRequestCompletedCallback ( __in FxRequest Request)
inline

Definition at line 725 of file fxioqueue.hpp.

728 {
729 // Do not acccess Request, at this point the object may have already been
730 // deleted or reused.
731
732 //
733 // This is called when a queued-by-driver request (driver created) is
734 // completed or sent to a lower driver with 'send-and-forget' option.
735 // This callback allows the queue to schedule another request for delivery.
736 //
737
738 KIRQL irql;
739
740#if FX_VERBOSE_TRACE
742 "Enter: WDFQUEUE 0x%p, WDFREQUEST 0x%p",
744#else
746#endif
747
748 Lock(&irql);
749
750 //
751 // I/O has been completed by the driver
752 //
754
755 //
756 // Don't run the event dispatcher if we come from a Request
757 // complete callback in order to prevent stack recursion.
758 //
759 // Since some other thread (possibly this thread higher on
760 // the stack) is running the dispatcher, no events will get lost.
761 //
762 DispatchInternalEvents(irql);
763 }
__inline VOID PostRemoveFromDriverOwnedList(VOID)
Definition: fxioqueue.hpp:1522
static PVOID __inline _ToHandle(__in FxObject *Object)
Definition: fxobject.hpp:659

◆ PreRemoveFromDriverOwnedList()

__inline VOID FxIoQueue::PreRemoveFromDriverOwnedList ( __in FxRequest Request)
inlineprivate

Definition at line 1497 of file fxioqueue.hpp.

1500 {
1501 PLIST_ENTRY listEntry;
1502
1503 listEntry = Request->GetListEntry(FxListEntryDriverOwned);
1504
1505 RemoveEntryList(listEntry);
1506 InitializeListHead(listEntry);
1507
1510
1511 return;
1512 }

Referenced by PreRequestCompletedCallback().

◆ PreRequestCompletedCallback()

__inline VOID FxIoQueue::PreRequestCompletedCallback ( __in FxRequest Request)
inline

Definition at line 692 of file fxioqueue.hpp.

695 {
696 //
697 // This is called when a driver created request is about to be completed.
698 // This callback removes the FxRequest object from the internal queue linked
699 // lists. A call to PostRequestCompletedCallback must be made after irp is
700 // completed.
701 //
702
703 KIRQL irql;
704
705#if FX_VERBOSE_TRACE
707 "Enter: WDFQUEUE 0x%p, WDFREQUEST 0x%p",
708 GetObjectHandle(),Request->GetHandle());
709#endif
710
711 VerifyValidateCompletedRequest(GetDriverGlobals(), Request);
712
713 Lock(&irql);
714
715 //
716 // I/O has been completed by the driver
717 //
719
720 Unlock(irql);
721 }
__inline VOID PreRemoveFromDriverOwnedList(__in FxRequest *Request)
Definition: fxioqueue.hpp:1497

◆ PurgeForwardProgressIrps()

VOID FxIoQueue::PurgeForwardProgressIrps ( __in_opt MdFileObject  FileObject)
private

Definition at line 6467 of file fxioqueue.cpp.

6477{
6478 LIST_ENTRY cleanupList;
6479
6480 InitializeListHead(&cleanupList);
6481 GetForwardProgressIrps(&cleanupList, FileObject);
6482 CancelIrps(&cleanupList);
6483}
VOID CancelIrps(__in PLIST_ENTRY IrpListHead)
Definition: fxioqueue.cpp:6436
VOID GetForwardProgressIrps(__in PLIST_ENTRY IrpListHead, __in_opt MdFileObject FileObject)

Referenced by FlushByFileObject(), and QueuePurge().

◆ PutBackReservedRequest()

VOID FxIoQueue::PutBackReservedRequest ( __in FxRequest ReservedRequest)
inlineprivate

Definition at line 1624 of file fxioqueue.hpp.

1627 {
1628 KIRQL oldIrql;
1629 PLIST_ENTRY listEntry;
1630
1632
1633 listEntry = ReservedRequest->GetListEntry(FxListEntryForwardProgress);
1634
1635 m_FwdProgContext->m_PendedReserveLock.Acquire(&oldIrql);
1636
1637 RemoveEntryList(listEntry);
1638 InitializeListHead(listEntry);
1639
1641
1642 if (GetDriverGlobals()->FxVerifierIO) {
1644 }
1645
1646 m_FwdProgContext->m_PendedReserveLock.Release(oldIrql);
1647 }
VOID VerifierVerifyFwdProgListsLocked(VOID)
Definition: fxioqueue.cpp:6486
@ FxListEntryForwardProgress
Definition: fxrequest.hpp:381

◆ QueryInterface()

virtual _Must_inspect_result_ NTSTATUS FxIoQueue::QueryInterface ( __in FxQueryInterfaceParams Params)
inlinevirtual

Reimplemented from FxObject.

Definition at line 1078 of file fxioqueue.hpp.

1081 {
1082 switch (Params->Type) {
1083 case FX_TYPE_QUEUE:
1084 *Params->Object = (FxIoQueue*) this;
1085 break;
1086
1088 *Params->Object = (IFxHasCallbacks*) this;
1089 break;
1090
1091 default:
1092 return FxNonPagedObject::QueryInterface(Params); // __super call
1093 }
1094
1095 return STATUS_SUCCESS;
1096 }
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
@ FX_TYPE_IHASCALLBACKS
Definition: fxtypes.h:114
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

◆ QueueDrain()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueDrain ( __in_opt PFN_WDF_IO_QUEUE_STATE  DrainComplete,
__in_opt WDFCONTEXT  Context 
)

Definition at line 4158 of file fxioqueue.cpp.

4162{
4163 //
4164 // We drain the queue by calling QueuePurge with CancelQueueRequests
4165 // and CancelDriverRequests == FALSE. The Queue will reject new
4166 // requests, but allow the device driver to continue processing
4167 // requests currently on the Queue. The DrainComplete callback is
4168 // invoked when there are no requests in Queue or device driver.
4169 //
4170
4172
4173}
_In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE PurgeComplete
Definition: wdfio.h:1030

Referenced by QueueDrainSynchronously().

◆ QueueDrainSynchronously()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueDrainSynchronously ( VOID  )

Definition at line 4177 of file fxioqueue.cpp.

4188{
4190#if (FX_CORE_MODE==FX_CORE_USER_MODE)
4192#else
4193 MxEvent eventOnStack;
4194 //
4195 // Note that initialize always succeeds in KM so return is not checked.
4196 //
4197 eventOnStack.Initialize(NotificationEvent, FALSE);
4198 MxEvent* event = eventOnStack.GetSelfPointer();
4199#endif
4200
4201 status = QueueDrain(_PurgeComplete, event->GetSelfPointer());
4202
4203 if(NT_SUCCESS(status)) {
4204
4206 "Waiting for %d requests to complete "
4207 "on WDFQUEUE 0x%p",
4209 GetObjectHandle());
4210
4211 Mx::MxEnterCriticalRegion();
4212
4213 GetDriverGlobals()->WaitForSignal(event->GetSelfPointer(),
4214 "waiting for queue to drain, WDFQUEUE", GetHandle(),
4215 GetDriverGlobals()->FxVerifierDbgWaitForSignalTimeoutInSec,
4217
4218 Mx::MxLeaveCriticalRegion();
4219 }
4220
4221 return status;
4222
4223}
_Must_inspect_result_ NTSTATUS QueueDrain(__in_opt PFN_WDF_IO_QUEUE_STATE DrainComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:4158
static EVT_WDF_IO_QUEUE_STATE _PurgeComplete
Definition: fxioqueue.hpp:1695
struct _cl_event * event
Definition: glext.h:7739

◆ QueueDriverCreatedRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueDriverCreatedRequest ( __in FxRequest Request,
__in BOOLEAN  ParentQueue 
)

Definition at line 1791 of file fxioqueue.cpp.

1826{
1828 CfxDeviceBase * origDeviceBase;
1829 SHORT oldFlags = 0;
1830 FxIrp* fxIrp;
1831
1833 fxIrp = Request->GetFxIrp();
1834
1835 status = VerifyQueueDriverCreatedRequest(fxDriverGlobals, Request, &oldFlags);
1836 if(!NT_SUCCESS(status)) {
1837 return status;
1838 }
1839
1840 ASSERT(Request->SetCompletionState(FxRequestCompletionStateNone) ==
1842
1843 //
1844 // If this is the parent queue, we need to adjust the IRP's stack.
1845 //
1846 if (ParentQueue) {
1847
1848 //
1849 // IRP should not have a completion routine set yet.
1850 //
1851
1853
1856
1857 //
1858 // Save a pointer to the device object for this request so that it can
1859 // be used later in completion.
1860 //
1862 }
1863
1864 origDeviceBase = Request->GetDeviceBase();
1866
1867 //
1868 // Attempt to insert the request into the queue
1869 //
1871 if (!NT_SUCCESS(status)) {
1872 //
1873 // Request was not accepted, restore the original DeviceBase and flags.
1874 //
1875 ASSERT(Request->SetCompletionState(FxRequestCompletionStateNone) ==
1877
1878 //
1879 // Restore original device/info.
1880 //
1881 Request->SetDeviceBase(origDeviceBase);
1882
1884 Request->SetVerifierFlags(oldFlags);
1885 }
1886
1887 //
1888 // If this is the parent queue, we need to adjust the IRP's stack.
1889 //
1890 if (ParentQueue) {
1892 //
1893 // There is no completion routine. See above assert.
1894 //
1895 Request->m_Irp.ClearNextStack();
1896 }
1897 }
1898
1899 return status;
1900}
MdCompletionRoutine GetNextCompletionRoutine(VOID)
Definition: fxirpum.cpp:1206
VOID SetDeviceBase(__in CfxDeviceBase *DeviceBase)
Definition: fxobject.hpp:797
CfxDeviceBase * GetDeviceBase(VOID)
Definition: fxobject.hpp:789
PFX_DRIVER_GLOBALS fxDriverGlobals

◆ QueueForwardProgressIrpLocked()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueForwardProgressIrpLocked ( __in MdIrp  Irp)
private

Definition at line 46 of file fxioqueueum.hpp.

◆ QueueIdle()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueIdle ( __in BOOLEAN  CancelQueueRequests,
__in_opt PFN_WDF_IO_QUEUE_STATE  IdleComplete,
__in_opt WDFCONTEXT  Context 
)

Definition at line 3584 of file fxioqueue.cpp.

3609{
3611 KIRQL irql;
3613 LIST_ENTRY fwrIrpList = {0};
3615
3616
3617 Lock(&irql);
3618
3619 // If the queue is deleted, requests will not be serviced anymore
3620 if (m_Deleted) {
3623 "WDFQUEUE 0x%p is already deleted, %!STATUS!",
3625 Unlock(irql);
3626
3627 return status;
3628 }
3629
3630 //
3631 // If a IdleComplete callback is supplied, we must register it up
3632 // front since a transition empty could occur in another thread.
3633 //
3634 if (IdleComplete != NULL) {
3635
3636 //
3637 // Only one Idle or Purge Complete callback can be outstanding
3638 // at a time per Queue
3639 //
3640 if (m_IdleComplete.Method != NULL) {
3643 "WDFQUEUE 0x%p already has a "
3644 "IdleComplete callback registered 0x%p, "
3645 "%!STATUS!", GetObjectHandle(),
3647 status);
3648 Unlock(irql);
3649
3650 return status;
3651 }
3652
3653 m_IdleComplete.Method = IdleComplete;
3655 }
3656
3657 // Set Accept request and Clear dispatch requests
3659
3660 //
3661 // Get ready to cancel current queued requests. Note that we don't want to
3662 // prevent new requests from being queue, i.e., it is legal for an upper
3663 // driver can resend another request in its completion routine.
3664 //
3665 if (CancelRequests) {
3666 //
3667 // Driver wants to abort/complete all queued request and cancel or
3668 // wait for all requests the driver is currently handling. Thus we must
3669 // prevent the driver from requeuing stale requests.
3670 // The 'cancel driver requests' field gives us this ability.
3671 // It is set here, and cleared when:
3672 // (a) Driver doesn't own any more requests, or
3673 // (b) the driver calls WdfIoQueueStart again (dispatch gate is opened).
3674 // When set, the framework automatically deletes any request that the
3675 // driver requeues.
3676 //
3678
3679 request = NULL; // Initial tag used by PeekRequest.
3680 #pragma warning(disable:4127)
3681 while (TRUE) {
3682 #pragma warning(default:4127)
3683 status = FxRequest::PeekRequest(&m_Queue, // in:queue
3684 request, // in:tag.
3685 NULL, // in:file_obj
3686 NULL, // out:parameters
3687 &request); // out:request.
3688 if (status != STATUS_SUCCESS) {
3690 break;
3691 }
3692
3693 //
3694 // Tag this request and release the extra ref that Peek() takes.
3695 //
3696 request->m_Canceled = TRUE;
3697
3698#pragma prefast(suppress:__WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "This is the tag value used in the ADDREF of Peek()")
3699 request->RELEASE(NULL);
3700 }
3701
3702 //
3703 // Move forward progress IRPs to a temp list; we use this logic to
3704 // allow new IRPs to be pended to the original list.
3705 //
3706 if (IsForwardProgressQueue()) {
3707 InitializeListHead(&fwrIrpList);
3708 GetForwardProgressIrps(&fwrIrpList, NULL);
3709 }
3710 }
3711
3712 // Unlock queue lock
3713 Unlock(irql);
3714
3715 if (CancelRequests) {
3716 #pragma warning(disable:4127)
3717 while (TRUE) {
3718 #pragma warning(default:4127)
3719 //
3720 // Get the next FxRequest from the cancel safe queue
3721 //
3722 Lock(&irql);
3724 if (request == NULL) {
3727 "All WDFQUEUE 0x%p requests cancelled",
3728 GetObjectHandle());
3729 Unlock(irql);
3730 break;
3731 }
3732
3733 // Irp is not cancellable now
3734
3735 //
3736 // Make sure to purged requests only if:
3737 // (a) the request was present when we started this operation.
3738 // (b) any following request that is marked as cancelled.
3739 //
3740 if (request->IsCancelled() == FALSE) {
3741 status = request->InsertHeadIrpQueue(&m_Queue, NULL);
3742 if (NT_SUCCESS(status)) {
3743 Unlock(irql);
3744 break;
3745 }
3746
3748 }
3751 "Cancelling WDFREQUEST 0x%p, WDFQUEUE 0x%p",
3752 request->GetHandle(),GetObjectHandle());
3753
3754 //
3755 // We must add a reference since the CancelForQueue path
3756 // assumes we were on the FxIrpQueue with the extra reference
3757 //
3759
3760 //
3761 // Mark the request as cancelled, place it on the cancel list,
3762 // and schedule the cancel event to the driver
3763 //
3764 CancelForQueue(request, irql);
3765 }
3766
3767 //
3768 // Walk the driver cancelable list cancelling the requests.
3769 //
3770 #pragma warning(disable:4127)
3771 while (TRUE) {
3772 #pragma warning(default:4127)
3773 //
3774 // Get the next request of driver cancelable requests
3775 //
3776 Lock(&irql);
3778 if (request == NULL) {
3781 "All driver cancellable requests cancelled "
3782 " in WDFQUEUE 0x%p",
3783 GetObjectHandle());
3784 Unlock(irql);
3785 break;
3786 }
3787
3788 request->m_Canceled = TRUE;
3789
3790 Unlock(irql);
3791
3792 //
3793 // If the driver follows the pattern of removing cancel status
3794 // from the request before completion, then there is no race
3795 // with this routine since we will not be able to retrieve any
3796 // requests the driver has made non-cancellable in preparation
3797 // for completion.
3798 //
3800
3802
3803 // The request could have been completed and released by the driver
3804 }
3805
3806 //
3807 // Cleanup forward progress IRP list.
3808 //
3809 if (IsForwardProgressQueue()) {
3810 CancelIrps(&fwrIrpList);
3811 }
3812 }
3813
3814 //
3815 // Since we set that no new requests may be dispatched,
3816 // if both m_Queue.GetRequestCount(), m_DriverIoCount == 0, and
3817 // m_Dispatch == 0, right now the queue is completely idle.
3818 //
3819
3820 //
3821 // We check if our m_PurgeComplete callback is still set
3822 // since it may have been called by another thread when
3823 // we dropped the lock above
3824 //
3825 Lock(&irql);
3826 DispatchEvents(irql);
3827
3828 //
3829 // If the driver registered an IdleComplete callback, and it was
3830 // not idle in the above check, it will be called when the final
3831 // callback handler from the device driver returns.
3832 //
3833 return STATUS_SUCCESS;
3834}
volatile BOOLEAN m_CancelDispatchedRequests
Definition: fxioqueue.hpp:461
VOID CancelForDriver(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:4535
@ FxIoQueueClearDispatchRequests
Definition: fxioqueue.hpp:199
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
Definition: tftpd.h:86

Referenced by QueueIdleSynchronously().

◆ QueueIdleSynchronously()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueIdleSynchronously ( __in BOOLEAN  CancelRequests)

Definition at line 3838 of file fxioqueue.cpp.

3854{
3856#if (FX_CORE_MODE==FX_CORE_USER_MODE)
3858#else
3859 MxEvent eventOnStack;
3860 //
3861 // Note that initialize always succeeds in KM so return is not checked.
3862 //
3863 eventOnStack.Initialize(NotificationEvent, FALSE);
3864 MxEvent* event = eventOnStack.GetSelfPointer();
3865#endif
3866
3867 status = QueueIdle(CancelRequests, _IdleComplete, event->GetSelfPointer());
3868
3869 if(NT_SUCCESS(status)) {
3870
3872 "Waiting for %d requests to complete "
3873 "on WDFQUEUE 0x%p",
3875 GetObjectHandle());
3876
3877 Mx::MxEnterCriticalRegion();
3878
3879 GetDriverGlobals()->WaitForSignal(event->GetSelfPointer(),
3880 "waiting for queue to stop, WDFQUEUE", GetHandle(),
3881 GetDriverGlobals()->FxVerifierDbgWaitForSignalTimeoutInSec,
3883
3884
3885 Mx::MxLeaveCriticalRegion();
3886 }
3887
3888 return status;
3889
3890}
_Must_inspect_result_ NTSTATUS QueueIdle(__in BOOLEAN CancelQueueRequests, __in_opt PFN_WDF_IO_QUEUE_STATE IdleComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:3584
static EVT_WDF_IO_QUEUE_STATE _IdleComplete
Definition: fxioqueue.hpp:1699

◆ QueuePurge()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueuePurge ( __in BOOLEAN  CancelQueueRequests,
__in BOOLEAN  CancelDriverRequests,
__in_opt PFN_WDF_IO_QUEUE_STATE  PurgeComplete,
__in_opt WDFCONTEXT  Context 
)

Definition at line 3894 of file fxioqueue.cpp.

3919{
3921 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
3922 KIRQL irql;
3924
3925 Lock(&irql);
3926
3927 //
3928 // If the Queue is deleted, there can't be any requests
3929 // to purge, and the queue is no longer executing its
3930 // event dispatch loop, so we would stop responding if we
3931 // registered now.
3932 //
3933 // We could try and silently succeed this, but if we do, we
3934 // must invoke the PurgeComplete callback, and without our
3935 // queue state machine excuting, we can not ensure any
3936 // callback constraints are handled such as locking, queueing
3937 // to passive level, etc. So we just fail to indicate to the
3938 // driver we *will not* be invoking its PurgeComplete function.
3939 //
3940 if (m_Deleted) {
3943 "WDFQUEUE 0x%p is already deleted %!STATUS!",
3945 Unlock(irql);
3946
3947 return status;
3948 }
3949
3950 //
3951 // If a PurgeComplete callback is supplied, we must register it up
3952 // front since a transition empty could occur in another thread.
3953 //
3954 if (PurgeComplete != NULL) {
3955
3956 //
3957 // Only one PurgeComplete callback can be outstanding
3958 // at a time per Queue
3959 //
3960 if (m_PurgeComplete.Method != NULL) {
3963 "WDFQUEUE 0x%p already has a "
3964 "PurgeComplete callback registered 0x%p "
3965 "%!STATUS!", GetObjectHandle(),
3967 Unlock(irql);
3968
3969 return status;
3970 }
3971
3974 }
3975
3976 // Clear accept requests
3978
3979 if (CancelQueueRequests && CancelDriverRequests &&
3980 FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11)) {
3981 //
3982 // Driver wants to abort/complete all queued request and cancel or
3983 // wait for all requests the driver is currently handling. Thus we must
3984 // prevent the driver from requeuing stale requests.
3985 // This flag is set here, and cleared when:
3986 // (a) Driver doesn't own any more requests, or
3987 // (b) the driver calls WdfIoQueueStart again (dispatch gate is opened).
3988 // When set, the framework automatically deletes any request that the
3989 // driver requeues.
3990 // For compatibility we do this only for drivers v1.11 and above.
3991 //
3993 }
3994
3995 // Unlock queue lock
3996 Unlock(irql);
3997
3998 if (CancelQueueRequests) {
3999 #pragma warning(disable:4127)
4000 while (TRUE) {
4001 #pragma warning(default:4127)
4002 //
4003 // Get the next FxRequest from the cancel safe queue
4004 //
4005 Lock(&irql);
4007 if (pRequest == NULL) {
4009 "All WDFQUEUE 0x%p requests cancelled",
4010 GetObjectHandle());
4011 Unlock(irql);
4012 break;
4013 }
4014
4015 // Irp is not cancellable now
4016
4018 "Cancelling WDFREQUEST 0x%p, WDFQUEUE 0x%p",
4020
4021 //
4022 // We must add a reference since the CancelForQueue path
4023 // assumes we were on the FxIrpQueue with the extra reference
4025
4026 //
4027 // Mark the request as cancelled, place it on the cancel list,
4028 // and schedule the cancel event to the driver
4029 //
4030 CancelForQueue(pRequest, irql);
4031
4032 }
4033 }
4034
4035 if (CancelDriverRequests) {
4036
4037 //
4038 // Walk the driver cancelable list cancelling
4039 // the requests.
4040 //
4041 #pragma warning(disable:4127)
4042 while (TRUE) {
4043 #pragma warning(default:4127)
4044 //
4045 // Get the next request of driver cancelable requests
4046 //
4047 Lock(&irql);
4049 if (pRequest == NULL) {
4051 "All driver cancellable requests cancelled "
4052 " in WDFQUEUE 0x%p",
4053 GetObjectHandle());
4054 Unlock(irql);
4055 break;
4056 }
4057
4059
4060 Unlock(irql);
4061
4062 //
4063 // If the driver follows the pattern of removing cancel status
4064 // from the request before completion, then there is no race
4065 // with this routine since we will not be able to retrieve any
4066 // requests the driver has made non-cancellable in preparation
4067 // for completion.
4068 //
4070
4072
4073 // The request could have been completed and released by the driver
4074 }
4075 }
4076
4077 if (IsForwardProgressQueue()) {
4079 }
4080
4081 //
4082 // Since we set that no new requests may be enqueued,
4083 // if both m_Queue.GetRequestCount() and m_DriverIoCount == 0 right
4084 // now the queue is completely purged.
4085 //
4086
4087 //
4088 // We check if our m_PurgeComplete callback is still set
4089 // since it may have been called by another thread when
4090 // we dropped the lock above
4091 //
4092 Lock(&irql);
4093
4094 DispatchEvents(irql);
4095
4096 //
4097 // If the driver registered a PurgeComplete callback, and it was
4098 // not empty in the above check, it will be called when a
4099 // request complete from the device driver completes the
4100 // final request.
4101 //
4102 return STATUS_SUCCESS;
4103}
@ FxIoQueueClearAcceptRequests
Definition: fxioqueue.hpp:197
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92

Referenced by Dispose(), QueueDrain(), QueuePurgeSynchronously(), and StopProcessingForPower().

◆ QueuePurgeSynchronously()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueuePurgeSynchronously ( VOID  )

Definition at line 4107 of file fxioqueue.cpp.

4118{
4120
4121#if (FX_CORE_MODE==FX_CORE_USER_MODE)
4123#else
4124 MxEvent eventOnStack;
4125 //
4126 // Note that initialize always succeeds in KM so return is not checked.
4127 //
4128 eventOnStack.Initialize(NotificationEvent, FALSE);
4129 MxEvent* event = eventOnStack.GetSelfPointer();
4130#endif
4131
4132 status = QueuePurge(TRUE, TRUE, _PurgeComplete, event->GetSelfPointer());
4133
4134 if(NT_SUCCESS(status)) {
4135
4137 "Waiting for %d requests to complete "
4138 "on WDFQUEUE 0x%p",
4140 GetObjectHandle());
4141
4142 Mx::MxEnterCriticalRegion();
4143
4144 GetDriverGlobals()->WaitForSignal(event->GetSelfPointer(),
4145 "waiting for queue to purge, WDFQUEUE", GetHandle(),
4146 GetDriverGlobals()->FxVerifierDbgWaitForSignalTimeoutInSec,
4148
4149 Mx::MxLeaveCriticalRegion();
4150 }
4151
4152 return status;
4153
4154}

◆ QueueRequest()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueRequest ( __in FxRequest pRequest)

Definition at line 2245 of file fxioqueue.cpp.

2268{
2270 KIRQL irql;
2271 MdIrp pIrp;
2272 FxIrp* pFxIrp;
2273
2274 // Get IoQueue Object Lock
2275 Lock(&irql);
2276
2277 ASSERT(pRequest->GetRefCnt() == 1);
2278
2279 //
2280 // If the request is reserved, take an additional reference. This reference
2281 // will be released when the request is completed. This additional reference
2282 // enables us to detect 2 to 1 transition in the completion path so that
2283 // we can reclaim the reserved request for reuse.
2284 //
2285 if (pRequest->IsReserved()) {
2287 }
2288
2289 //
2290 // If queue is not taking new requests, fail now
2291 //
2293
2295 "WDFQUEUE 0x%p is not accepting requests, "
2296 "state is %!WDF_IO_QUEUE_STATE!, %s"
2297 "completing WDFREQUEST 0x%p %!STATUS!",
2300 "power stopping (Drain) in progress," : "",
2303
2304 // Must release IoQueue object Lock
2305 Unlock(irql);
2306
2308
2309 // Complete it with error
2311
2312 // Dereference request object
2314
2315 return Status;
2316 }
2317
2319 "Queuing WDFREQUEST 0x%p on WDFQUEUE 0x%p",
2321
2323
2324 pFxIrp = pRequest->GetFxIrp();
2325
2326 pFxIrp->MarkIrpPending();
2327
2328 //
2329 // If the request is reserved, we may be called to dispatch
2330 // a pending reserved IRP from within the context of the completion routine.
2331 // So to avoid recursion, we will insert the request in the queue and try
2332 // to dispatch in the return path. If the request is not reserved then we
2333 // will dispatch it directly because this path is meant for dispatching new
2334 // incoming I/O. There is no concern for running into recursion in that
2335 // scenario.
2336 //
2337 if (pRequest->IsReserved() && m_Dispatching != 0) {
2339 Unlock(irql);
2340 }
2341 else {
2342 DispatchEvents(irql, pRequest);
2343 }
2344
2345 // We always return status pending through the frameworks
2346 return STATUS_PENDING;
2347}
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
_Must_inspect_result_ NTSTATUS GetIrp(__deref_out MdIrp *ppIrp)
Definition: fxrequest.hpp:975
__inline BOOLEAN IsReserved()
Definition: fxrequest.hpp:609
@ FxIoQueueShutdown
Definition: fxioqueue.hpp:229
#define FXREQUEST_FWDPRG_TAG
Definition: fxrequest.hpp:63
#define STATUS_PENDING
Definition: ntstatus.h:82

Referenced by FxPkgGeneral::OnCreate().

◆ QueueRequestFromForward()

_Must_inspect_result_ NTSTATUS FxIoQueue::QueueRequestFromForward ( __in FxRequest pRequest)

Definition at line 2351 of file fxioqueue.cpp.

2373{
2375 KIRQL irql;
2376 BOOLEAN fromIo;
2377
2378 // Get IoQueue Object Lock
2379 Lock(&irql);
2380
2381 //
2382 // If queue is not taking new requests, fail now
2383 //
2385
2387
2389 "WDFQUEUE 0x%p is not accepting requests "
2390 "state is %!WDF_IO_QUEUE_STATE!, %s"
2391 "WDFREQUEST 0x%p %!STATUS!",
2394 "power stopping (Drain) in progress," : "",
2396
2397 Unlock(irql);
2398
2399 return status;
2400 }
2401#if FX_VERBOSE_TRACE
2403 "Queuing WDFREQUEST 0x%p on WDFQUEUE 0x%p",
2405#endif
2406 //
2407 // The Request has one reference count, and no completion
2408 // callback function. It has been completely removed from
2409 // its previous queue.
2410 //
2411
2412 //
2413 // Cache this info b/c the request can be delete and freed by the time we use it.
2414 //
2415 fromIo = pRequest->IsAllocatedFromIo();
2416
2417 //
2418 // Insert it in the Cancel Safe Queue
2419 //
2420 // This will mark the IRP pending
2421 //
2423
2424 if (!NT_SUCCESS(status)) {
2425
2427
2429
2430 //
2431 // We must add a reference since the CancelForQueue path
2432 // assumes we were on the FxIrpQueue with the extra reference
2433 //
2435
2436 //
2437 // Mark the request as cancelled, place it on the cancel list,
2438 // and schedule the cancel event to the driver
2439 //
2440 CancelForQueue(pRequest, irql);
2441
2442 Lock(&irql);
2443 }
2444 else {
2446
2447 // Check if went from no requests to have requests
2449 }
2450
2451 //
2452 // If the request is driver-created, we may be called to dispatch
2453 // a request from within the context of the completion routine.
2454 // So to avoid recursion, we will try to dispatch in the return path.
2455 // If the request is not driver-created then we will dispatch it directly because
2456 // this path is meant for dispatching new incoming I/O. There is no concern for
2457 // running into recursion in that scenario.
2458 //
2459 if (fromIo == FALSE && m_Dispatching != 0) {
2460 Unlock(irql);
2461 }
2462 else {
2463 //
2464 // Attempt to dispatch any new requests.
2465 //
2466 // This releases, and re-acquires the IoQueue lock
2467 //
2468 DispatchEvents(irql);
2469 }
2470
2471 return STATUS_SUCCESS;
2472}
BOOLEAN __inline IsAllocatedFromIo(VOID)
_Must_inspect_result_ NTSTATUS InsertTailIrpQueue(__in FxIrpQueue *IrpQueue, __out_opt ULONG *pRequestCount)
Definition: fxrequest.cpp:1858
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126

Referenced by FxPkgIo::EnqueueRequest(), ForwardRequestWorker(), and QueueDriverCreatedRequest().

◆ QueueStart()

VOID FxIoQueue::QueueStart ( VOID  )

Definition at line 3552 of file fxioqueue.cpp.

3554{
3555 KIRQL irql;
3556
3557 Lock(&irql);
3558
3560
3561 //
3562 // We should set the flag to notify the driver on queue start in case
3563 // the driver stops the queue while the ReadyNotify callback is executing.
3564 // If that happens, the request will be left in the manual queue with
3565 // m_TransitionFromEmpty cleared.
3566 //
3567 if (m_Queue.GetRequestCount() > 0L) {
3570 }
3571
3572 //
3573 // We may have transitioned to a status that resumes
3574 // processing, so call dispatch function.
3575 //
3576
3577 DispatchEvents(irql);
3578
3579 return;
3580}

◆ ReadyNotify()