ReactOS 0.4.16-dev-329-g9223134
FxIoTarget Class Reference

#include <fxiotarget.hpp>

Inheritance diagram for FxIoTarget:
Collaboration diagram for FxIoTarget:

Public Member Functions

 FxIoTarget (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize)
 
 FxIoTarget (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in WDFTYPE WdfType)
 
virtual _Must_inspect_result_ NTSTATUS Start (VOID)
 
virtual VOID Stop (__in WDF_IO_TARGET_SENT_IO_ACTION Action)
 
virtual VOID Purge (__in WDF_IO_TARGET_PURGE_IO_ACTION Action)
 
virtual VOID Remove (VOID)
 
NTSTATUS _Must_inspect_result_ QueryInterface (__inout FxQueryInterfaceParams *Params)
 
__inline WDF_IO_TARGET_STATE GetState (VOID)
 
__inline MdDeviceObject GetTargetDevice (VOID)
 
__inline MdDeviceObject GetTargetPDO (VOID)
 
__inline MdFileObject GetTargetFileObject (VOID)
 
__inline WDFDEVICE GetDeviceHandle (VOID)
 
WDFIOTARGET GetHandle (VOID)
 
__inline FxDriverGetDriver (VOID)
 
virtual _Must_inspect_result_ MdDeviceObject GetTargetDeviceObject (_In_ CfxDeviceBase *Device)
 
_Must_inspect_result_ NTSTATUS Init (__in CfxDeviceBase *Device)
 
ULONG Submit (__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in_opt ULONG Flags)
 
 FX_DECLARE_VF_FUNCTION_P1 (NTSTATUS, VerifySubmitLocked, _In_ FxRequestBase *)
 
ULONG SubmitLocked (__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in ULONG Flags)
 
_Must_inspect_result_ NTSTATUS SubmitSync (__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
 
VOID TimerCallback (__in FxRequestBase *Request)
 
VOID CompleteCanceledRequest (__in FxRequestBase *Request)
 
VOID SubmitPendedRequest (__in FxRequestBase *Request)
 
VOID CompletePendedRequest (__in FxRequestBase *Request)
 
BOOLEAN __inline HasEnoughStackLocations (__in FxIrp *Irp)
 
_Must_inspect_result_ NTSTATUS FormatIoRequest (__inout FxRequestBase *Request, __in UCHAR MajorCode, __in FxRequestBuffer *IoBuffer, __in_opt PLONGLONG StartingOffset, __in_opt FxFileObject *FileObject=NULL)
 
_Must_inspect_result_ NTSTATUS FormatIoctlRequest (__in FxRequestBase *Request, __in ULONG Ioctl, __in BOOLEAN Internal, __in FxRequestBuffer *InputBuffer, __in FxRequestBuffer *OutputBuffer, __in_opt FxFileObject *FileObject=NULL)
 
_Must_inspect_result_ NTSTATUS FormatInternalIoctlOthersRequest (__in FxRequestBase *Request, __in ULONG Ioctl, __in FxRequestBuffer *Buffers)
 
VOID CancelSentIo (VOID)
 
_Must_inspect_result_ NTSTATUS SubmitSyncRequestIgnoreTargetState (__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions)
 
VOID UpdateTargetIoType (VOID)
 
BOOLEAN HasValidStackSize (VOID)
 
virtual VOID Send (_In_ MdIrp Irp)
 
- 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 VOID _CancelSentRequest (__in FxRequestBase *Request)
 
static FxIoTarget_FromEntry (__in FxTransactionedEntry *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

FxTransactionedEntry m_TransactionedEntry
 
BOOLEAN m_InStack
 
BOOLEAN m_AddedToDeviceList
 

Static Public Attributes

static const PVOID m_SentRequestTag = (PVOID) 'lcnC'
 

Protected Member Functions

 ~FxIoTarget ()
 
_Must_inspect_result_ NTSTATUS InitModeSpecific (__in CfxDeviceBase *Device)
 
virtual BOOLEAN Dispose (VOID)
 
VOID FailPendedRequest (__in FxRequestBase *Request, __in NTSTATUS Status)
 
VOID DrainPendedRequestsLocked (__in PLIST_ENTRY RequestListHead, __in BOOLEAN RequestWillBeResent)
 
VOID CompletePendedRequestList (__in PLIST_ENTRY RequestListHead)
 
VOID SubmitPendedRequests (__in PLIST_ENTRY RequestListHeadHead)
 
VOID GetSentRequestsListLocked (__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
 
virtual _Must_inspect_result_ NTSTATUS GotoStartState (__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
 
virtual VOID GotoStopState (__in WDF_IO_TARGET_SENT_IO_ACTION Action, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
 
virtual VOID GotoPurgeState (__in WDF_IO_TARGET_PURGE_IO_ACTION Action, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
 
_Must_inspect_result_ NTSTATUS PendRequestLocked (__in FxRequestBase *Request)
 
__inline VOID CompleteRequest (__in FxRequestBase *Request)
 
VOID HandleFailedResubmit (__in FxRequestBase *Request)
 
VOID RequestCompletionRoutine (__in FxRequestBase *Request)
 
BOOLEAN RemoveCompletedRequestLocked (__in FxRequestBase *Request)
 
virtual VOID ClearTargetPointers (VOID)
 
UCHAR GetTargetIoType (VOID)
 
virtual VOID GotoRemoveState (__in WDF_IO_TARGET_STATE NewState, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __in BOOLEAN Lock, __out PBOOLEAN Wait)
 
virtual VOID WaitForSentIoToComplete (VOID)
 
virtual VOID WaitForDisposeEvent (VOID)
 
virtual VOID Forward (__in MdIrp Irp)
 
__inline VOID CopyFileObjectAndFlags (__in FxRequestBase *Request)
 
__inline VOID IncrementIoCount (VOID)
 
__inline VOID DecrementIoCount (VOID)
 
VOID PrintDisposeMessage (VOID)
 
- 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

static VOID _CancelSentRequests (__in PSINGLE_LIST_ENTRY RequestListHead)
 
static VOID _RequestCancelled (__in FxIrpQueue *Queue, __in MdIrp Irp, __in PMdIoCsqIrpContext pCsqContext, __in KIRQL CallerIrql)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 

Protected Attributes

LIST_ENTRY m_SentIoListHead
 
LIST_ENTRY m_IgnoredIoListHead
 
FxCREvent m_SentIoEvent
 
FxCREventm_DisposeEvent
 
FxCREvent m_DisposeEventUm
 
FxIrpQueue m_PendedQueue
 
FxDriverm_Driver
 
MdDeviceObject m_InStackDevice
 
MdDeviceObject m_TargetDevice
 
MdDeviceObject m_TargetPdo
 
MdFileObject m_TargetFileObject
 
WDF_IO_TARGET_STATE m_State
 
LONG m_IoCount
 
CCHAR m_TargetStackSize
 
UCHAR m_TargetIoType
 
BOOLEAN m_WaitingForSentIo
 
BOOLEAN m_Removing
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Static Protected Attributes

static MdCompletionRoutineType _RequestCompletionRoutine
 
static EVT_WDF_REQUEST_COMPLETION_ROUTINE _SyncCompletionRoutine
 

Private Member Functions

VOID Construct (VOID)
 
VOID ClearCompletedRequestVerifierFlags (__in FxRequestBase *Request)
 
VOID SetCompletionRoutine (__in FxRequestBase *Request)
 

Private Attributes

friend FxRequestBase
 

Detailed Description

Definition at line 210 of file fxiotarget.hpp.

Constructor & Destructor Documentation

◆ FxIoTarget() [1/2]

FxIoTarget::FxIoTarget ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in USHORT  ObjectSize 
)

Definition at line 34 of file fxiotarget.cpp.

37 :
38 FxNonPagedObject(FX_TYPE_IO_TARGET, ObjectSize, FxDriverGlobals)
39{
40 Construct();
41}
VOID Construct(VOID)
Definition: fxiotarget.cpp:54
@ FX_TYPE_IO_TARGET
Definition: fxtypes.h:100

◆ FxIoTarget() [2/2]

FxIoTarget::FxIoTarget ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in USHORT  ObjectSize,
__in WDFTYPE  WdfType 
)

Definition at line 43 of file fxiotarget.cpp.

47 :
48 FxNonPagedObject(WdfType, ObjectSize, FxDriverGlobals)
49{
50 Construct();
51}

◆ ~FxIoTarget()

FxIoTarget::~FxIoTarget ( )
protected

Definition at line 91 of file fxiotarget.cpp.

92{
95 ASSERT(m_IoCount == 0);
96}
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
LONG m_IoCount
Definition: fxiotarget.hpp:935
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ASSERT(a)
Definition: mode.c:44

Member Function Documentation

◆ _CancelSentRequest()

VOID FxIoTarget::_CancelSentRequest ( __in FxRequestBase Request)
static

Definition at line 534 of file fxiotarget.cpp.

537{
538 //
539 // Attempt to cancel the request
540 //
541 Request->Cancel();
542
543 //
544 // Release the reference taken by GetSentRequestsListLocked
545 //
546 Request->RELEASE(m_SentRequestTag);
547}
static const PVOID m_SentRequestTag
Definition: fxiotarget.hpp:862
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

Referenced by _CancelSentRequests().

◆ _CancelSentRequests()

VOID FxIoTarget::_CancelSentRequests ( __in PSINGLE_LIST_ENTRY  RequestListHead)
staticprotected

Definition at line 550 of file fxiotarget.cpp.

565{
567
568 while (RequestListHead->Next != NULL) {
569 ple = PopEntryList(RequestListHead);
570
571 //
572 // Set the Next pointer back to NULL so that if it is reinserted into a
573 // cancel list, it will not point to unknown pool.
574 //
575 ple->Next = NULL;
576
578 }
579}
static VOID _CancelSentRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:534
static __inline FxRequestBase * _FromDrainEntry(__in PSINGLE_LIST_ENTRY Entry)
#define NULL
Definition: types.h:112
PSINGLE_LIST_ENTRY ple
Definition: ntbasedef.h:636
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:637
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:243

Referenced by FxUsbDevice::_CleanupPipesRequests(), CancelSentIo(), FxIoTargetRemote::Close(), Purge(), FxUsbDevice::Purge(), Remove(), Stop(), and FxUsbDevice::Stop().

◆ _FromEntry()

static FxIoTarget * FxIoTarget::_FromEntry ( __in FxTransactionedEntry Entry)
inlinestatic

Definition at line 455 of file fxiotarget.hpp.

458 {
460 }
FxTransactionedEntry m_TransactionedEntry
Definition: fxiotarget.hpp:853
base of all file and directory entries
Definition: entries.h:83
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ _RequestCancelled()

VOID FxIoTarget::_RequestCancelled ( __in FxIrpQueue Queue,
__in MdIrp  Irp,
__in PMdIoCsqIrpContext  pCsqContext,
__in KIRQL  CallerIrql 
)
staticprotected

Definition at line 2532 of file fxiotarget.cpp.

2538{
2539 FxIoTarget* pThis;
2541 KIRQL irql;
2542 FxIrp pFxIrp;
2543
2545
2546 pThis->Unlock(CallerIrql);
2547
2548 //
2549 // Grab the request out of the irp. After this call we are done with the
2550 // m_CsqContext field.
2551 //
2553
2556 "Pended WDFREQUEST %p canceled", pRequest->GetTraceObjectHandle());
2557
2558 //
2559 // m_ListEntry is union'ed with m_CsqContext. m_CsqContext was in use up
2560 // until this function was called. From this point on, we are going to
2561 // process the request as if it has been completed. The completed code path
2562 // assumes m_ListEntry is on a list head. To have a valid m_ListEntry when
2563 // we call RemoveEntryList, initialize it now. Since we have an outstanding
2564 // irp completion reference count (which is decremented in the call to
2565 // FailPendedRequest later), we can safely initialize this field without
2566 // holding any locks.
2567 //
2569
2570 //
2571 // Undo the affects of the IoSetNextIrpStackLocation made when we
2572 // enqueued the request.
2573 //
2574 pFxIrp.SetIrp(Irp);
2576
2577 //
2578 // Request is no longer pended
2579 //
2580 pThis->Lock(&irql);
2583 pThis->Unlock(irql);
2584
2585 //
2586 // Call the driver's completion routine
2587 //
2589}
VOID FailPendedRequest(__in FxRequestBase *Request, __in NTSTATUS Status)
FxIrpQueue m_PendedQueue
Definition: fxiotarget.hpp:895
Definition: fxirp.hpp:28
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
__inline PVOID GetTraceObjectHandle(VOID)
__inline ULONG ClearTargetFlags(__in UCHAR Flags)
LIST_ENTRY m_ListEntry
static __inline FxRequestBase * _FromCsqContext(__in PMdIoCsqIrpContext Context)
__inline UCHAR GetTargetFlags(VOID)
_In_ PIRP Irp
Definition: csq.h:116
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxRequest * pRequest
__in MdIrp __in PMdIoCsqIrpContext __in KIRQL CallerIrql
Definition: fxirpqueue.hpp:77
@ FX_REQUEST_PENDED
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225

Referenced by Construct().

◆ CancelSentIo()

VOID FxIoTarget::CancelSentIo ( VOID  )

Definition at line 2618 of file fxiotarget.cpp.

2630{
2631 SINGLE_LIST_ENTRY sentRequestListHead;
2632 BOOLEAN sentAdded;
2633 KIRQL irql;
2635
2636
2638 sentRequestListHead.Next = NULL;
2639 Lock(&irql);
2640
2641 GetSentRequestsListLocked(&sentRequestListHead,
2643 &sentAdded);
2644
2645 Unlock(irql);
2646
2649 "Cancelling pending I/O on WDFIOTARGET %p ",
2650 GetHandle());
2651
2652 if (sentAdded) {
2653 _CancelSentRequests(&sentRequestListHead);
2654 }
2655}
unsigned char BOOLEAN
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
VOID GetSentRequestsListLocked(__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
Definition: fxiotarget.cpp:582
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define GetHandle(h)
Definition: treelist.c:116
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

Referenced by FxUsbDevice::CancelSentIo(), and FxUsbPipe::Reset().

◆ ClearCompletedRequestVerifierFlags()

VOID FxIoTarget::ClearCompletedRequestVerifierFlags ( __in FxRequestBase Request)
inlineprivate

Definition at line 814 of file fxiotarget.hpp.

817 {
818 if (GetDriverGlobals()->FxVerifierOn &&
819 GetDriverGlobals()->FxVerifierIO) {
820 KIRQL irql;
821
822 Request->Lock(&irql);
823 //
824 // IF we are completing a request that was pended in the target,
825 // this flag was not set.
826 //
827 // ASSERT(Request->GetVerifierFlagsLocked() & FXREQUEST_FLAG_SENT_TO_TARGET);
828 Request->ClearVerifierFlagsLocked(FXREQUEST_FLAG_SENT_TO_TARGET);
829 Request->Unlock(irql);
830 }
831 }
@ FXREQUEST_FLAG_SENT_TO_TARGET

Referenced by DrainPendedRequestsLocked(), and RemoveCompletedRequestLocked().

◆ ClearTargetPointers()

virtual VOID FxIoTarget::ClearTargetPointers ( VOID  )
inlineprotectedvirtual

Reimplemented in FxIoTargetRemote.

Definition at line 618 of file fxiotarget.hpp.

621 {
625
628 }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
MdDeviceObject m_TargetPdo
Definition: fxiotarget.hpp:918
UCHAR m_TargetIoType
Definition: fxiotarget.hpp:947
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941
MdFileObject m_TargetFileObject
Definition: fxiotarget.hpp:923
@ WdfDeviceIoUndefined
Definition: wdfdevice.h:450

Referenced by FxIoTargetRemote::ClearTargetPointers(), GotoRemoveState(), and RemoveCompletedRequestLocked().

◆ CompleteCanceledRequest()

VOID FxIoTarget::CompleteCanceledRequest ( __in FxRequestBase Request)

Definition at line 2183 of file fxiotarget.cpp.

2186{
2187 KIRQL irql;
2188 BOOLEAN setStopEvent;
2189
2190 Lock(&irql);
2191
2192 //
2193 // RemoveCompletedRequestLocked clears Request->m_TargetFlags, so we must
2194 // do this check before that call.
2195 //
2196 if ((Request->GetTargetFlags() & FX_REQUEST_CANCELLED_FROM_TIMER) &&
2197 Request->m_Irp.GetStatus() == STATUS_CANCELLED) {
2198 //
2199 // We cancelled the request from the timer and it has completed with
2200 // cancelled. Morph the status code into a timeout status.
2201 //
2202 // Don't muck with the IoStatus.Information field.
2203 //
2204 Request->m_Irp.SetStatus(STATUS_IO_TIMEOUT);
2205 }
2206
2207 setStopEvent = RemoveCompletedRequestLocked(Request);
2208 Unlock(irql);
2210 "WDFREQUEST %p completed in from cancel",
2211 Request->GetTraceObjectHandle());
2213
2214 if (setStopEvent) {
2216 "WDFIOTARGET %p, setting stop event %p",
2218
2220 }
2221
2223}
__inline VOID CompleteRequest(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:580
__inline VOID DecrementIoCount(VOID)
Definition: fxiotarget.hpp:785
BOOLEAN RemoveCompletedRequestLocked(__in FxRequestBase *Request)
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
return pObject GetObjectHandle()
@ FX_REQUEST_CANCELLED_FROM_TIMER
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID GetEvent(VOID)
Definition: fxwaitlock.hpp:172
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163

Referenced by FxRequestBase::Cancel().

◆ CompletePendedRequest()

VOID FxIoTarget::CompletePendedRequest ( __in FxRequestBase Request)

Definition at line 508 of file fxiotarget.cpp.

511{
512 //
513 // This will attempt to claim cancelation ownership and call the
514 // request's completion routine.
515 //
517}
#define STATUS_WDF_DEVICE_REMOVED_NOT_SENT
Definition: wdfstatus.h:144

Referenced by FxUsbDevice::_CleanupPipesRequests(), and CompletePendedRequestList().

◆ CompletePendedRequestList()

VOID FxIoTarget::CompletePendedRequestList ( __in PLIST_ENTRY  RequestListHead)
protected

Definition at line 520 of file fxiotarget.cpp.

523{
525
526 while (!IsListEmpty(RequestListHead)) {
527 ple = RemoveHeadList(RequestListHead);
530 }
531}
VOID CompletePendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:508
static __inline FxRequestBase * _FromListEntry(__in PLIST_ENTRY Entry)
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
Definition: typedefs.h:120

Referenced by FxIoTargetRemote::Close(), Purge(), FxUsbDevice::Purge(), and Remove().

◆ CompleteRequest()

__inline VOID FxIoTarget::CompleteRequest ( __in FxRequestBase Request)
inlineprotected

Definition at line 580 of file fxiotarget.hpp.

583 {
584 //
585 // This will remove the reference taken by this object on the request
586 //
587 Request->CompleteSubmitted();
588 }

Referenced by CompleteCanceledRequest(), HandleFailedResubmit(), RequestCompletionRoutine(), and TimerCallback().

◆ Construct()

VOID FxIoTarget::Construct ( VOID  )
private

Definition at line 54 of file fxiotarget.cpp.

57{
60
62
64
68
69 m_Driver = NULL;
76 m_IoCount = 1;
79
81
82 //
83 // We want to guarantee that the cleanup callback is called at passive level
84 // so the driver writer can override the automatic behavior the target uses
85 // when shutting down with i/o in progress.
86 //
89}
BOOLEAN m_AddedToDeviceList
Definition: fxiotarget.hpp:860
BOOLEAN m_InStack
Definition: fxiotarget.hpp:855
MdDeviceObject m_InStackDevice
Definition: fxiotarget.hpp:905
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
FxDriver * m_Driver
Definition: fxiotarget.hpp:900
static VOID _RequestCancelled(__in FxIrpQueue *Queue, __in MdIrp Irp, __in PMdIoCsqIrpContext pCsqContext, __in KIRQL CallerIrql)
FxCREvent * m_DisposeEvent
Definition: fxiotarget.hpp:885
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
BOOLEAN m_Removing
Definition: fxiotarget.hpp:955
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
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ ObjectDoNotLock
Definition: fxobject.hpp:128
VOID SetTransactionedObject(__in FxObject *Object)
@ WdfIoTargetStarted
Definition: wdfiotarget.h:53

Referenced by FxIoTarget().

◆ CopyFileObjectAndFlags()

__inline VOID FxIoTarget::CopyFileObjectAndFlags ( __in FxRequestBase Request)
inlineprotected

Definition at line 743 of file fxiotarget.hpp.

746 {
747 FxIrp* irp = Request->GetSubmitFxIrp();
748
749 if (Request->IsAllocatedFromIo()) {
752 }
753
754 //
755 // Use the target's fileobject if present, otherwise use the current
756 // stack location's fileobject (if there is a current stack location).
757 //
758 if (m_InStack == FALSE) {
760 }
761 }
UCHAR GetCurrentStackFlags(VOID)
Definition: fxirpum.cpp:1243
MdFileObject GetCurrentStackFileObject(VOID)
Definition: fxirpum.cpp:1258
VOID SetNextStackFlags(__in UCHAR Flags)
Definition: fxirpum.cpp:1556
VOID SetNextStackFileObject(_In_ MdFileObject FileObject)
Definition: fxirpum.cpp:1573
FxIrp * irp

Referenced by FormatInternalIoctlOthersRequest(), FormatIoctlRequest(), and FormatIoRequest().

◆ DecrementIoCount()

__inline VOID FxIoTarget::DecrementIoCount ( VOID  )
inlineprotected

Definition at line 785 of file fxiotarget.hpp.

788 {
789 LONG ret;
790
792 ASSERT(ret >= 0);
793
794 if (ret == 0) {
798 }
799 }
#define InterlockedDecrement
Definition: armddk.h:52
VOID PrintDisposeMessage(VOID)
Definition: fxiotarget.cpp:99
long LONG
Definition: pedump.c:60
int ret

Referenced by CompleteCanceledRequest(), HandleFailedResubmit(), RequestCompletionRoutine(), SubmitLocked(), SubmitPendedRequest(), and TimerCallback().

◆ Dispose()

BOOLEAN FxIoTarget::Dispose ( VOID  )
protectedvirtual

Reimplemented from FxObject.

Reimplemented in FxUsbDevice, and FxUsbPipe.

Definition at line 154 of file fxiotarget.cpp.

175{
177
179 //
180 // Remove the target from the list of targets that the device keeps track
181 // of.
182 //
185 }
186
187 //
188 //
189 // Call all of the cleanup callbacks first
190 //
191 CallCleanup();
192
193 //
194 // Now cancel all sent i/o and shut the target down
195 //
196 Remove();
197
198 //
199 // By returning FALSE, the object state machine will not attempt to call
200 // cleanup again.
201 //
202 return FALSE;
203}
virtual VOID RemoveIoTarget(__inout FxIoTarget *IoTarget)
Definition: fxdevice.hpp:261
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
__inline VOID CallCleanup(VOID)
Definition: fxobject.hpp:815
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_In_ BOOLEAN Remove
Definition: psfuncs.h:110

Referenced by FxUsbDevice::Dispose(), and FxUsbPipe::Dispose().

◆ DrainPendedRequestsLocked()

VOID FxIoTarget::DrainPendedRequestsLocked ( __in PLIST_ENTRY  RequestListHead,
__in BOOLEAN  RequestWillBeResent 
)
protected

Definition at line 395 of file fxiotarget.cpp.

399{
400 PMdIoCsqIrpContext pContext;
401 MdIrp pIrp;
402 FxIrp* pFxIrp = NULL;
403 pContext = NULL;
404
405 while ((pIrp = m_PendedQueue.GetNextRequest(&pContext)) != NULL) {
407 BOOLEAN enqueue;
408
409 enqueue = FALSE;
410
411 //
412 // Each FxRequestBase on the pending list has a reference taken against
413 // it already. We will release the reference after we call Submit.
414 //
415 // After this call we are done with the m_CsqContext field.
416 //
418
419 //
420 // m_ListEntry and m_CsqContext are a union. Now that we are done with
421 // m_CsqContext, initialize it to be a valid list entry.
422 //
424
425 //
426 // Undo the affects of the IoSetNextIrpStackLocation made when we
427 // enqueued the request. We want to do this no matter if we can claim
428 // cancellation ownership of the request or not.
429 //
430 pFxIrp = pRequest->GetSubmitFxIrp();
432
433 //
434 // Request is not longer pended.
435 //
438
439 if (RequestWillBeResent) {
440 //
441 // Make sure timer callback is not about to run. After the call
442 // below the timer was successfully canceled or the timer callback
443 // already run.
444 //
445 if (pRequest->CancelTimer()) {
446 //
447 // Try to claim cancellation (*) ownership of the request.
448 // CanComplete() decrements the irp completion ref count and
449 // whomever decrements to zero owns the request. Ownership in
450 // this case is resubmission as well as completion (as the name
451 // of the function implies).
452 //
453 // (*) - cancellation as defined by WDF and the myriad of
454 // functions which are calling FxRequestBase::Cancel().
455 // By this point we have already removed the cancellation
456 // routine by calling m_PendedQueue.GetNextRequest()
457 //
458 if (pRequest->CanComplete()) {
459
460 enqueue = TRUE;
461 }
462 }
463
464 if (FALSE == enqueue) {
465 //
466 // Some other thread is responsible for canceling this request.
467 // We are assuming here that the other thread will complete it
468 // in that thread because we are no longer tracking this request
469 // in any of our lists.
470 //
472
473 //
474 // Mark that the request has been completed so that if the other
475 // thread is the timer DPC, it will handle the case properly and
476 // complete the request.
477 //
480
483 "WDFIOTARGET %p, WDFREQUEST %p is being canceled on another thread,"
484 " allowing other thread to complete request, not resending",
486 }
487 }
488 else {
489 //
490 // The caller is going to attempt to complete the requests. To make
491 // the caller's life easier and let it reuse RequestCompletionRoutine,
492 // to handle the completion semantics, keep the completion reference
493 // count != 0 and return the request back to the caller.
494 //
495 enqueue = TRUE;
496 }
497
498 if (enqueue) {
500 InsertTailList(RequestListHead, &pRequest->m_ListEntry);
501 }
502
503 pContext = NULL;
504 }
505}
VOID ClearCompletedRequestVerifierFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:814
MdIrp GetNextRequest(__out PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:219
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
__inline FxIrp * GetSubmitFxIrp(VOID)
__inline VOID SetTargetFlags(__in UCHAR Flags)
__inline BOOLEAN CanComplete(VOID)
_Must_inspect_result_ BOOLEAN CancelTimer(VOID)
#define InsertTailList(ListHead, Entry)
FxIrp * pIrp
@ FX_REQUEST_COMPLETED
IWudfIrp * MdIrp
Definition: mxum.h:103

Referenced by GotoPurgeState(), GotoRemoveState(), and GotoStartState().

◆ FailPendedRequest()

VOID FxIoTarget::FailPendedRequest ( __in FxRequestBase Request,
__in NTSTATUS  Status 
)
protected

Definition at line 1877 of file fxiotarget.cpp.

1901{
1902 FxIrp* irp;
1903
1904 irp = Request->GetSubmitFxIrp();
1905
1906 //
1907 // Simulate failure in the IRP
1908 //
1910 irp->SetInformation(0);
1911
1912 //
1913 // Manaully process the irp as if it has completed back from the target.
1914 //
1916}
VOID RequestCompletionRoutine(__in FxRequestBase *Request)
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
Status
Definition: gdiplustypes.h:25

Referenced by _RequestCancelled(), and CompletePendedRequest().

◆ FormatInternalIoctlOthersRequest()

_Must_inspect_result_ NTSTATUS FxIoTarget::FormatInternalIoctlOthersRequest ( __in FxRequestBase Request,
__in ULONG  Ioctl,
__in FxRequestBuffer Buffers 
)

Definition at line 2454 of file fxiotarget.cpp.

2459{
2463 ULONG i;
2464 FxIrp* irp;
2465
2466 status = Request->ValidateTarget(this);
2467 if (!NT_SUCCESS(status)) {
2468 return status;
2469 }
2470
2471 if (Request->HasContextType(FX_RCT_INTERNAL_IOCTL_OTHERS)) {
2472 pContext = (FxInternalIoctlOthersContext*) Request->GetContext();
2473 }
2474 else {
2476
2477 if (pContext == NULL) {
2480 "Could not allocate context for request");
2481
2483 }
2484
2485 Request->SetContext(pContext);
2486 }
2487
2488 //
2489 // Save away any references to IFxMemory pointers that are passed.
2490 // (StoreAndReferenceMemory can only store one buffer, so it doesn't help).
2491 //
2493 &Buffers[1],
2494 &Buffers[2]);
2495
2496
2497 irp = Request->GetSubmitFxIrp();
2499
2502
2504
2505 i = 0;
2509
2510 for (i = 0; i < FX_REQUEST_NUM_OTHER_PARAMS; i++) {
2511 status = Buffers[i].GetBuffer(bufs[i]);
2512
2513 if (!NT_SUCCESS(status)) {
2516 "Could not retrieve buffer %d, status %!STATUS!", i+1, status);
2517
2518 Request->ContextReleaseAndRestore();
2519
2520 return status;
2521 }
2522 }
2523
2524 if (NT_SUCCESS(status)) {
2525 Request->VerifierSetFormatted();
2526 }
2527
2528 return status;
2529}
PVOID Buffers[0x100]
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID CopyFileObjectAndFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:743
PVOID * GetNextStackParameterOthersArgument2Pointer()
Definition: fxirpum.cpp:1434
PVOID * GetNextStackParameterOthersArgument4Pointer()
Definition: fxirpum.cpp:1447
VOID SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
VOID SetParameterIoctlCode(__in ULONG DeviceIoControlCode)
Definition: fxirpum.cpp:1157
PVOID * GetNextStackParameterOthersArgument1Pointer()
Definition: fxirpum.cpp:1421
VOID ClearNextStackLocation(VOID)
Definition: fxirpum.cpp:1581
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_Must_inspect_result_ __in WDFIOTARGET __in_opt WDFREQUEST __in ULONG Ioctl
#define FX_REQUEST_NUM_OTHER_PARAMS
@ FX_RCT_INTERNAL_IOCTL_OTHERS
const GLenum * bufs
Definition: glext.h:6026
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
VOID StoreAndReferenceOtherMemories(__in FxRequestBuffer *Buffer1, __in FxRequestBuffer *Buffer2, __in FxRequestBuffer *Buffer4)
Definition: fxiotarget.hpp:129
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MJ_INTERNAL_DEVICE_CONTROL

Referenced by FxUsbDevice::GetPortStatus().

◆ FormatIoctlRequest()

_Must_inspect_result_ NTSTATUS FxIoTarget::FormatIoctlRequest ( __in FxRequestBase Request,
__in ULONG  Ioctl,
__in BOOLEAN  Internal,
__in FxRequestBuffer InputBuffer,
__in FxRequestBuffer OutputBuffer,
__in_opt FxFileObject FileObject = NULL 
)

Definition at line 280 of file fxiotargetkm.cpp.

288{
289 FxIoContext* pContext;
292 ULONG inLength, outLength;
293 BOOLEAN freeSysBuf;
294 BOOLEAN setBufferAndLength;
295 FxIrp* irp;
296
298
299 irp = Request->GetSubmitFxIrp();
300 freeSysBuf = FALSE;
301
302 status = Request->ValidateTarget(this);
303 if (!NT_SUCCESS(status)) {
304 return status;
305 }
306
307 if (Request->HasContextType(FX_RCT_IO)) {
308 pContext = (FxIoContext*) Request->GetContext();
309 }
310 else {
311 pContext = new(GetDriverGlobals()) FxIoContext();
312 if (pContext == NULL) {
315 "Could not allocate context for request");
316
318 }
319
320 Request->SetContext(pContext);
321 }
322
323 pContext->CaptureState(irp);
324
326
327 //
328 // Save away any references to IFxMemory pointers that are passed
329 //
332
334 if (Internal) {
336 }
337 else {
339 }
340
342
343 pContext->m_MajorFunction = majorFunction;
344
346
347 inLength = InputBuffer->GetBufferLength();
348 outLength = OutputBuffer->GetBufferLength();
349
353
354
355 //
356 // Anytime we return here and we allocated the context above, the context
357 // will be freed when the FxRequest is freed or reformatted.
358 //
359 switch (METHOD_FROM_CTL_CODE(Ioctl)) {
360 case METHOD_BUFFERED:
361
362 if (inLength != 0 || outLength != 0) {
363 ULONG allocationLength;
364
365 allocationLength = (inLength > outLength ? inLength : outLength);
366
367 if ((pContext->m_BufferToFreeLength >= allocationLength) &&
368 (pContext->m_BufferToFree != NULL)) {
370 setBufferAndLength = FALSE;
371 }
372 else {
373 irp->SetSystemBuffer(FxPoolAllocate(GetDriverGlobals(),
375 allocationLength));
376 if (irp->GetSystemBuffer() == NULL) {
379 "Could not allocate common buffer");
381 break;
382 }
383 setBufferAndLength = TRUE;
384 freeSysBuf = TRUE;
385 }
386
387 status = InputBuffer->GetBuffer(&pBuffer);
388 if (!NT_SUCCESS(status)) {
391 "Could not retrieve input buffer, %!STATUS!",
392 status);
393 break;
394 }
395
396 if (pBuffer != NULL) {
398 pBuffer,
399 inLength);
400 }
401
402 status = OutputBuffer->GetBuffer(&pBuffer);
403 if (!NT_SUCCESS(status)) {
406 "Could not retrieve output buffer, %!STATUS!",
407 status);
408 break;
409 }
410
412 if (setBufferAndLength) {
414 allocationLength,
415 outLength > 0 ? TRUE : FALSE);
416 freeSysBuf = FALSE; // FxIoContext will free the buffer.
417 } else {
418 pContext->m_CopyBackToBuffer = outLength > 0 ? TRUE : FALSE;
419 }
420
421 }
422 else {
423 //
424 // These fields were captured and will be restored by the context
425 // later.
426 //
429 }
430
431 break;
432
433 case METHOD_DIRECT_TO_HARDWARE: // METHOD_IN_DIRECT
434 case METHOD_DIRECT_FROM_HARDWARE: // METHOD_OUT_DIRECT
435 {
436 BOOLEAN reuseMdl;
437
438 reuseMdl = FALSE;
439
440 status = InputBuffer->GetBuffer(&pBuffer);
441 if (!NT_SUCCESS(status)) {
444 "Could not retrieve input buffer as a PVOID, %!STATUS!",
445 status);
446 break;
447 }
448
450
451 //
452 // NOTE: There is no need to compare the operation type since that
453 // applies only to the Pages locked in memory and not the MDL data
454 // structure itself per se.
455 // Also, note that if the size of the Outbuf need not be equal to the
456 // size of the MdlToFree as long as the number of page entries match.
457 //
458 if (pContext->m_MdlToFree != NULL) {
459 reuseMdl = TRUE;
460 }
461
462 status = OutputBuffer->GetOrAllocateMdl(
465 &pContext->m_MdlToFree,
466 &pContext->m_UnlockPages,
468 reuseMdl,
469 &pContext->m_MdlToFreeSize
470 );
471
472 if (!NT_SUCCESS(status)) {
475 "Could not retrieve output buffer as a PMDL, %!STATUS!",
476 status);
477 break;
478 }
479 break;
480 }
481
482 case METHOD_NEITHER:
483 status = OutputBuffer->GetBuffer(&pBuffer);
484
485 if (!NT_SUCCESS(status)) {
488 "Could not retrieve output buffer as a PVOID, %!STATUS!",
489 status);
490 break;
491 }
492
494
495 status = InputBuffer->GetBuffer(&pBuffer);
496
497 if (!NT_SUCCESS(status)) {
500 "Could not retrieve input buffer as a PVOID, %!STATUS!",
501 status);
502
503 break;
504 }
505
507 break;
508 }
509
510 if (NT_SUCCESS(status)) {
511 Request->VerifierSetFormatted();
512 }
513 else {
514 if (freeSysBuf) {
517 }
518
519 Request->ContextReleaseAndRestore();
520 }
521
522 return status;
523}
PMDL * GetMdlAddressPointer()
Definition: fxirpum.cpp:1323
VOID SetSystemBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1313
PVOID GetSystemBuffer()
Definition: fxirpum.cpp:543
VOID SetParameterIoctlInputBufferLength(__in ULONG InputBufferLength)
Definition: fxirpum.cpp:1166
VOID SetParameterIoctlType3InputBuffer(__in PVOID Type3InputBuffer)
Definition: fxirpum.cpp:1175
VOID SetUserBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1341
VOID SetParameterIoctlOutputBufferLength(__in ULONG OutputBufferLength)
Definition: fxirpum.cpp:1532
#define NonPagedPool
Definition: env_spec_w32.h:307
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
UCHAR majorFunction
@ Internal
Definition: hwresource.cpp:137
#define METHOD_NEITHER
Definition: nt_native.h:597
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
PVOID pBuffer
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
PVOID m_BufferToFree
Definition: fxiotarget.hpp:91
VOID StoreAndReferenceOtherMemory(__in FxRequestBuffer *Buffer)
Definition: fxiotarget.hpp:44
UCHAR m_MajorFunction
Definition: fxiotarget.hpp:114
PMDL m_MdlToFree
Definition: fxiotarget.hpp:94
BOOLEAN m_UnlockPages
Definition: fxiotarget.hpp:105
BOOLEAN m_CopyBackToBuffer
Definition: fxiotarget.hpp:104
size_t m_MdlToFreeSize
Definition: fxiotarget.hpp:103
VOID SetBufferAndLength(__in PVOID Buffer, __in size_t BufferLength, __in BOOLEAN CopyBackToBuffer)
size_t m_BufferToFreeLength
Definition: fxiotarget.hpp:102
VOID CaptureState(__in FxIrp *Irp)
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
#define METHOD_DIRECT_FROM_HARDWARE
#define METHOD_FROM_CTL_CODE(ctrlCode)
#define METHOD_DIRECT_TO_HARDWARE
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by FxUsbDevice::FormatCycleRequest(), FxIoTargetFormatIoctl(), FxIoTargetSendIoctl(), and FxUsbDevice::Reset().

◆ FormatIoRequest()

_Must_inspect_result_ NTSTATUS FxIoTarget::FormatIoRequest ( __inout FxRequestBase Request,
__in UCHAR  MajorCode,
__in FxRequestBuffer IoBuffer,
__in_opt PLONGLONG  StartingOffset,
__in_opt FxFileObject FileObject = NULL 
)

Definition at line 34 of file fxiotargetkm.cpp.

41{
42 FxIoContext* pContext;
45 ULONG ioLength;
46 BOOLEAN freeSysBuf;
47 BOOLEAN setBufferAndLength;
48 FxIrp* irp;
49
51
52 ASSERT(MajorCode == IRP_MJ_WRITE || MajorCode == IRP_MJ_READ);
53
54 freeSysBuf = FALSE;
55 pBuffer = NULL;
56
57 status = Request->ValidateTarget(this);
58 if (!NT_SUCCESS(status)) {
59 return status;
60 }
61
62 if (Request->HasContextType(FX_RCT_IO)) {
63 pContext = (FxIoContext*) Request->GetContext();
64 }
65 else {
66 pContext = new(GetDriverGlobals()) FxIoContext();
67 if (pContext == NULL) {
69 "could not allocate context for request");
70
72 }
73
74 //
75 // Since we can error out and return, remember the allocation before
76 // we do anything so we can free it later.
77 //
78 Request->SetContext(pContext);
79 }
80
81 //
82 // Save away any references to IFxMemory pointers that are passed
83 //
84 pContext->StoreAndReferenceMemory(IoBuffer);
85
86 irp = Request->GetSubmitFxIrp();
88
90
91 //
92 // Note that by convention "Set" methods of FxIrp apply to next stack
93 // location unless specified otherwise in the name.
94 //
95 irp->SetMajorFunction(MajorCode);
96 pContext->m_MajorFunction = MajorCode;
97
98 //
99 // Anytime we return here and we allocated the context above, the context
100 // will be freed when the FxRequest is freed or reformatted.
101 //
102
103 ioLength = IoBuffer->GetBufferLength();
104
105 pContext->CaptureState(irp);
106
107 switch (m_TargetIoType) {
110
111 if (ioLength != 0) {
112
113
114 if ((pContext->m_BufferToFreeLength >= ioLength) &&
115 (pContext->m_BufferToFree != NULL)) {
117 setBufferAndLength = FALSE;
118 }
119 else {
120 irp->SetSystemBuffer(FxPoolAllocate(GetDriverGlobals(),
122 ioLength));
123 if (irp->GetSystemBuffer() == NULL) {
126 "Could not allocate common buffer");
127
129 break;
130 }
131
132 setBufferAndLength = TRUE;
133 freeSysBuf = TRUE;
134 }
135
136 status = IoBuffer->GetBuffer(&pBuffer);
137
138 if (!NT_SUCCESS(status)) {
141 "Could not retrieve io buffer, %!STATUS!", status);
142 break;
143 }
144
145 //
146 // If its a write, copy into the double buffer now, otherwise,
147 // no copy into the buffer is needed for a read.
148 //
149 if (MajorCode == IRP_MJ_WRITE) {
150 if (pBuffer != NULL) {
152 pBuffer,
153 ioLength);
154 }
155 }
156 else {
158 }
159
160 //
161 // On reads, copy back to the double buffer after the read has
162 // completed.
163 //
164 if (setBufferAndLength) {
166 ioLength,
167 (MajorCode == IRP_MJ_READ) ? TRUE : FALSE);
168
169 freeSysBuf = FALSE; // FxIoContext will free the buffer.
170 }
171 else {
172 pContext->m_CopyBackToBuffer = MajorCode == IRP_MJ_READ ?
173 TRUE : FALSE;
174 }
175 }
176 else {
177 //
178 // This field was captured and will be restored by the context
179 // later.
180 //
182 }
183 break;
185 {
186 BOOLEAN reuseMdl;
187
188 reuseMdl = FALSE;
189
190 if (pContext->m_MdlToFree != NULL) {
191 reuseMdl = TRUE;
192 }
193
194 status = IoBuffer->GetOrAllocateMdl(
197 &pContext->m_MdlToFree,
198 &pContext->m_UnlockPages,
199 (MajorCode == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess,
200 reuseMdl,
201 &pContext->m_MdlToFreeSize
202 );
203
204 if (!NT_SUCCESS(status)) {
207 "Could not retrieve io buffer as a PMDL, %!STATUS!",
208 status);
209 break;
210 }
211 break;
212 }
214 //
215 // Neither MDL nor buffered
216 //
217 status = IoBuffer->GetBuffer(&pBuffer);
218
219 if (NT_SUCCESS(status)) {
221 }
222 else {
225 "Could not retrieve io buffer as a PVOID, %!STATUS!",
226 status);
227 }
228 break;
229
231 default:
235 "Trying to format closed WDFIOTARGET %p, %!STATUS!",
236 GetHandle(), status);
237 break;
238 }
239
240 //
241 // We are assuming the read and write parts of the Parameters union
242 // are at the same offset. If this is FALSE, WDFCASSERT will not allow
243 // this file to compile, so keep these WDFCASSERTs here as long as the
244 // assumption is being made.
245 //
247 ==
249
251 ==
253
254 if (NT_SUCCESS(status)) {
255
257 if (DeviceOffset != NULL) {
259 }
260 else {
262 }
263
264 Request->VerifierSetFormatted();
265 }
266 else {
267 if (freeSysBuf) {
270 }
271
272 Request->ContextReleaseAndRestore();
273 }
274
275 return status;
276}
VOID SetNextParameterWriteLength(__in ULONG IoLength)
Definition: fxirpum.cpp:1398
VOID SetNextParameterWriteByteOffsetQuadPart(__in LONGLONG DeviceOffset)
Definition: fxirpum.cpp:1385
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct _IO_STACK_LOCATION::@3980::@3985 Write
struct _IO_STACK_LOCATION::@3980::@3984 Read
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define WDFCASSERT(c)
Definition: wdfassert.h:93
@ WdfDeviceIoNeither
Definition: wdfdevice.h:451
@ WdfDeviceIoBuffered
Definition: wdfdevice.h:452
@ WdfDeviceIoDirect
Definition: wdfdevice.h:453
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG DeviceOffset
Definition: wdfiotarget.h:865

Referenced by FxIoTargetFormatIo(), and FxIoTargetSendIo().

◆ Forward()

virtual VOID FxIoTarget::Forward ( __in MdIrp  Irp)
inlineprotectedvirtual

Definition at line 699 of file fxiotarget.hpp.

702 {
703 //
704 // Ignore the return value because once we have sent the request, we
705 // want all processing to be done in the completion routine.
706 //
707 (void) Irp->Forward();
708 }

◆ FX_DECLARE_VF_FUNCTION_P1()

FxIoTarget::FX_DECLARE_VF_FUNCTION_P1 ( NTSTATUS  ,
VerifySubmitLocked  ,
_In_ FxRequestBase  
)

◆ GetDeviceHandle()

__inline WDFDEVICE FxIoTarget::GetDeviceHandle ( VOID  )
inline

Definition at line 299 of file fxiotarget.hpp.

302 {
303 return m_Device->GetHandle();
304 }
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
CfxDevice * m_Device
Definition: fxobject.hpp:329

◆ GetDriver()

__inline FxDriver * FxIoTarget::GetDriver ( VOID  )
inline

Definition at line 316 of file fxiotarget.hpp.

319 {
320 return m_Driver;
321 }

◆ GetHandle()

WDFIOTARGET FxIoTarget::GetHandle ( VOID  )
inline

Definition at line 307 of file fxiotarget.hpp.

310 {
311 return (WDFIOTARGET) GetObjectHandle();
312 }

Referenced by FxRequestBase::CompleteSubmitted(), FxRequestBase::CompleteSubmittedNoContext(), and if().

◆ GetSentRequestsListLocked()

VOID FxIoTarget::GetSentRequestsListLocked ( __in PSINGLE_LIST_ENTRY  RequestListHead,
__in PLIST_ENTRY  SendList,
__out PBOOLEAN  AddedToList 
)
protected

Definition at line 582 of file fxiotarget.cpp.

587{
589
590 *AddedToList = IsListEmpty(SendList) ? FALSE : TRUE;
591
592 //
593 // Since we are inserting into the head of the single list head, if we walked
594 // over the list from first to last, we would reverse the entries. By walking
595 // the list backwards, we build the single list head in the order of SendList.
596 //
597 for (ple = SendList->Blink; ple != SendList; ple = ple->Blink) {
599
601
602 //
603 // Add a reference since the request will be touched outside of the
604 // lock being held.
605 //
606 pRequest->ADDREF(m_SentRequestTag);
607
608 //
609 // Add the request at the head of the list.
610 //
611 pRequest->m_DrainSingleEntry.Next = RequestListHead->Next;
612 RequestListHead->Next = &pRequest->m_DrainSingleEntry;
613 }
614}
SINGLE_LIST_ENTRY m_DrainSingleEntry
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)

Referenced by CancelSentIo(), GotoPurgeState(), GotoRemoveState(), and GotoStopState().

◆ GetState()

__inline WDF_IO_TARGET_STATE FxIoTarget::GetState ( VOID  )
inline

Definition at line 263 of file fxiotarget.hpp.

266 {
267 return m_State;
268 }

◆ GetTargetDevice()

__inline MdDeviceObject FxIoTarget::GetTargetDevice ( VOID  )
inline

Definition at line 272 of file fxiotarget.hpp.

275 {
276 return m_TargetDevice;
277 }

Referenced by FxUsbPipeContinuousReader::FxUsbPipeContinuousReader().

◆ GetTargetDeviceObject()

virtual _Must_inspect_result_ MdDeviceObject FxIoTarget::GetTargetDeviceObject ( _In_ CfxDeviceBase Device)
inlinevirtual

Reimplemented in FxIoTargetSelf.

Definition at line 326 of file fxiotarget.hpp.

329 {
330 return Device->GetAttachedDevice();
331 }
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474

Referenced by Init().

◆ GetTargetFileObject()

__inline MdFileObject FxIoTarget::GetTargetFileObject ( VOID  )
inline

Definition at line 290 of file fxiotarget.hpp.

293 {
294 return m_TargetFileObject;
295 }

◆ GetTargetIoType()

UCHAR FxIoTarget::GetTargetIoType ( VOID  )
inlineprotected

Definition at line 631 of file fxiotarget.hpp.

634 {
635 ULONG flags;
637
639
640 if (flags & DO_BUFFERED_IO) {
641 return WdfDeviceIoBuffered;
642 }
643 else if (flags & DO_DIRECT_IO) {
644 return WdfDeviceIoDirect;
645 }
646 else {
647 return WdfDeviceIoNeither;
648 }
649 }
ULONG GetFlags(VOID)
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
MxDeviceObject deviceObject
GLbitfield flags
Definition: glext.h:7161

Referenced by Init(), FxIoTargetRemote::Open(), and UpdateTargetIoType().

◆ GetTargetPDO()

__inline MdDeviceObject FxIoTarget::GetTargetPDO ( VOID  )
inline

Definition at line 281 of file fxiotarget.hpp.

284 {
285 return m_TargetPdo;
286 }

Referenced by __deref_out_range(), and FxDevice::SetFilterIoType().

◆ GotoPurgeState()

VOID FxIoTarget::GotoPurgeState ( __in WDF_IO_TARGET_PURGE_IO_ACTION  Action,
__in PLIST_ENTRY  PendedRequestListHead,
__in PSINGLE_LIST_ENTRY  SentRequestListHead,
__out PBOOLEAN  Wait,
__in BOOLEAN  LockSelf 
)
protectedvirtual

Reimplemented in FxUsbPipe.

Definition at line 790 of file fxiotarget.cpp.

810{
811 KIRQL irql;
812 BOOLEAN wait, added;
813
814 wait = FALSE;
816
817 if (LockSelf) {
818 Lock(&irql);
819 }
820
821 //
822 // The following transitions are allowed:
823 // (1) Started -> Purged
824 // (2) Stop -> Purged
825 // (3) Purged -> Purged
826 //
827 // A Purged -> Purged transition is feasible if the previous purge didn't
828 // wait for pending i/o to complete and the current purge wants to wait
829 // for them.
830 //
833 }
834 else if (m_State != WdfIoTargetPurged) {
835 //
836 // Purging in any state other then purged or started is not fatal,
837 // but should be logged.
838 //
839
840 //
843 "WDFIOTARGET %p purged, but it is currently in the "
844 "%!WDF_IO_TARGET_STATE! state, not started, stopped or purged",
845 GetHandle(), m_State);
846 }
847
848 //
849 // FALSE - requests will not be resent to the target. As such,
850 // cancellation ownership will not be claimed b/c the request
851 // will subsequently be passed to FailPendedRequest.
852 //
853 DrainPendedRequestsLocked(PendedRequestListHead, FALSE);
854
855 GetSentRequestsListLocked(SentRequestListHead,
857 &added);
858
859 switch (Action) {
861 if (added == FALSE) {
862 //
863 // By using m_WaitingForSentIo as value for wait, we can handle the
864 // case where GotoPurgeState is called when we are already in the
865 // purging case (in which case we would have drained
866 // m_SendIoListHead already).
867 //
868 wait = m_WaitingForSentIo;
869
870 if (m_WaitingForSentIo) {
873 "WDFIOTARGET %p is already in the process of being purged "
874 "or stopped from another thread. Driver must wait for the "
875 "first WdfIoTargetPurge or WdfIoTargetStop to complete "
876 "before calling it again.",
878
880 }
881 }
882 else {
883 wait = TRUE;
884 }
885 break;
886
888 wait = FALSE;
889 break;
890 }
891
892 m_WaitingForSentIo = wait;
893 *Wait = wait;
894
895 if (wait) {
896 //
897 // If Stop/Purge(don't wait) was previously called, m_SentIoEvent
898 // will be in the signalled state. We need to wait for sent i/o to be
899 // completed, so make sure it is not signalled while holding the lock
900 //
902 }
903 else {
904 //
905 // Even though *Wait is set to FALSE, the caller may wait anyways
906 // if it is aggregating targets to move into the purged state and
907 // wait on them all.
908 //
910 }
911
912 if (LockSelf) {
913 Unlock(irql);
914 }
915}
VOID DrainPendedRequestsLocked(__in PLIST_ENTRY RequestListHead, __in BOOLEAN RequestWillBeResent)
Definition: fxiotarget.cpp:395
FxVerifierDbgBreakPoint(pFxDriverGlobals)
VOID Clear(VOID)
Definition: fxwaitlock.hpp:152
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
@ WdfIoTargetPurged
Definition: wdfiotarget.h:58
@ WdfIoTargetStopped
Definition: wdfiotarget.h:54
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
@ WdfIoTargetPurgeIo
Definition: wdfiotarget.h:79
@ WdfIoTargetPurgeIoAndWait
Definition: wdfiotarget.h:78

Referenced by FxUsbPipe::GotoPurgeState(), and Purge().

◆ GotoRemoveState()

VOID FxIoTarget::GotoRemoveState ( __in WDF_IO_TARGET_STATE  NewState,
__in PLIST_ENTRY  PendedRequestListHead,
__in PSINGLE_LIST_ENTRY  SentRequestListHead,
__in BOOLEAN  Lock,
__out PBOOLEAN  Wait 
)
protectedvirtual

Reimplemented in FxUsbPipe.

Definition at line 964 of file fxiotarget.cpp.

971{
972 KIRQL irql;
973 BOOLEAN sentAdded, ignoredAdded;
974
976
977 if (Lock) {
978 this->Lock(&irql);
979 }
980
981 if (m_WaitingForSentIo) {
984 "WDFIOTARGET %p is being deleted while it is being stopped/purged "
985 "by another thread. Driver must wait for WdfIoTargetStop or "
986 "WdfIoTargetPurge to complete before deleting the object.",
988
989 ASSERT(Lock);
990
991 Unlock(irql);
993 this->Lock(&irql);
994
996 }
997
998 *Wait = FALSE;
999 m_State = NewState;
1000
1001 //
1002 // FALSE - requests will not be resent to the target. As such,
1003 // cancellation ownership will not be claimed b/c the request
1004 // will subsequently be passed to FailPendedRequest.
1005 //
1006 DrainPendedRequestsLocked(PendedRequestListHead, FALSE);
1007
1008 //
1009 // Now cancel all of the sent I/O since we are being removed for good.
1010 //
1011 if (NewState == WdfIoTargetDeleted || NewState == WdfIoTargetClosed ||
1012 NewState == WdfIoTargetClosedForQueryRemove) {
1013 //
1014 // If the caller is aggregating calls to GotoRemoveState among many
1015 // targets (for instance, WDFUSBDEVICE will do this over its WDFUSBPIPEs
1016 // on remove), we cannot use the state of SentRequestListHead after these
1017 // two calls as a test to see if any requests are being canceled (and the
1018 // diff between removing and removed). Instead, we rely on the added
1019 // state returned by each call.
1020 //
1021 GetSentRequestsListLocked(SentRequestListHead,
1023 &sentAdded);
1024 GetSentRequestsListLocked(SentRequestListHead,
1026 &ignoredAdded);
1027
1028 if (sentAdded || ignoredAdded) {
1029 //
1030 // We will have to wait for the i/o to come back. As such, we are
1031 // in the transition state and must wait for it to complete. In this
1032 // transitionary stage, I/O can still be sent if they are marked to
1033 // ignore the target state.
1034 //
1035 m_Removing = TRUE;
1036 *Wait = TRUE;
1037
1038 //
1039 // If Stop(leave sent io pending) or Purge(do-not-wait) was
1040 // previously called, m_SentIoEvent will be in the signalled state.
1041 // We need to wait for sent i/o to be completed, so make sure it
1042 // is not signalled while hodling the lock
1043 //
1045 }
1046 else {
1048
1049 //
1050 // Even though *Wait is set to FALSE, the caller may wait anyways
1051 // if it is aggregating targets to move into the remove state and
1052 // wait on all of them.
1053 //
1055 }
1056 }
1057
1058 if (Lock) {
1059 Unlock(irql);
1060 }
1061
1062 return;
1063}
virtual VOID ClearTargetPointers(VOID)
Definition: fxiotarget.hpp:618
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
@ WdfIoTargetClosed
Definition: wdfiotarget.h:56
@ WdfIoTargetClosedForQueryRemove
Definition: wdfiotarget.h:55
@ WdfIoTargetDeleted
Definition: wdfiotarget.h:57

Referenced by FxIoTargetRemote::Close(), FxUsbPipe::GotoRemoveState(), and Remove().

◆ GotoStartState()

_Must_inspect_result_ NTSTATUS FxIoTarget::GotoStartState ( __in PLIST_ENTRY  RequestListHead,
__in BOOLEAN  Lock = TRUE 
)
protectedvirtual

Reimplemented in FxUsbPipe.

Definition at line 306 of file fxiotarget.cpp.

310{
312 KIRQL irql;
313
315
317
318 if (Lock) {
319 FxIoTarget::Lock(&irql);
320 }
321
325 }
326 else if (m_WaitingForSentIo) {
327
329
332 "WDFIOTARGET %p is being started while it is being stopped or "
333 "purged by another thread. WdfIoTargetStart and "
334 "WdfIoTargetStop/WdfIoTargetPurge must be called synchronously. "
335 "After the driver calls one of these functions, it must not call "
336 "the other function before the first one returns.",
338
340 (irql > PASSIVE_LEVEL)) {
341
342 //
343 // We cannont wait for a previous stop to complete if we are at
344 // dispatch level
345 //
347 }
348
349 //
350 // Wait for the stop code to complete
351 //
353
354 ASSERT(Lock);
355 Unlock(irql);
356
358
359 //
360 // Go back and check our state again since we dropped the lock.
361 //
362 FxIoTarget::Lock(&irql);
363 goto CheckState;
364 }
365 else {
367 }
368
369 //
370 // Restart all of the pended i/o.
371 //
372 if (NT_SUCCESS(status)) {
374
377
378 //
379 // TRUE - requests will be resent to the target, so attempt to claim
380 // cancelation ownership
381 //
382 DrainPendedRequestsLocked(RequestListHead, TRUE);
383 }
384
385 if (Lock) {
386 Unlock(irql);
387 }
388
390
391 return status;
392}
#define CheckState(OldState, NewState)
@ OkForDownLevel
Definition: fxglobals.h:80
#define START_TAG
Definition: fxiotarget.cpp:302
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define RELEASE(_tag)
Definition: fxobject.hpp:50
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286

Referenced by FxUsbPipe::GotoStartState(), FxIoTargetRemote::Open(), and Start().

◆ GotoStopState()

VOID FxIoTarget::GotoStopState ( __in WDF_IO_TARGET_SENT_IO_ACTION  Action,
__in PSINGLE_LIST_ENTRY  SentRequestListHead,
__out PBOOLEAN  Wait,
__in BOOLEAN  LockSelf 
)
protectedvirtual

Reimplemented in FxUsbPipe.

Definition at line 617 of file fxiotarget.cpp.

636{
637 KIRQL irql;
638 BOOLEAN getSentList, wait, added;
639
640 getSentList = FALSE;
641 wait = FALSE;
643
644 if (LockSelf) {
645 Lock(&irql);
646 }
647
648 //
649 // The following transitions are allowed:
650 // (1) Started -> Stopped
651 // (2) Purged -> Stopped
652 // (3) Stopped -> Stopped
653 //
654 // A Stopped -> Stopped transition
655 // is feasible if the previous stop left all pending i/o and the current
656 // stop wants to cancel all i/o.
657 //
660 }
661 else if (m_State != WdfIoTargetStopped) {
662 //
663 // Stopping in any state other then stopped or started is not fatal,
664 // but should be logged.
665 //
666
667 //
670 "WDFIOTARGET %p stopped, but it is currently in the "
671 "%!WDF_IO_TARGET_STATE! state, not started or stopped",
672 GetHandle(), m_State);
673 }
674
675 switch (Action) {
677 getSentList = TRUE;
678 // || || Drop through || ||
679 // \/ \/ \/ \/
680
683 //
684 // By using m_WaitingForSentIo as value for wait, we can handle the
685 // case where GotoStopState is called when we are already in the
686 // stopping case (in which case we would have drained
687 // m_SendIoListHead already).
688 //
689 wait = m_WaitingForSentIo;
690
691 if (m_WaitingForSentIo) {
694 "WDFIOTARGET %p is already in the process of being stopped "
695 "or purged from another thread. Driver must wait for the "
696 "first WdfIoTargetStop or WdfIoTargetPurge to complete "
697 "before calling it again.",
699 }
700 }
701 else {
702 wait = TRUE;
703
704 if (getSentList) {
705 //
706 // Ignore the assignment to added since we have already computed
707 // if we need to wait or not.
708 //
709 GetSentRequestsListLocked(SentRequestListHead,
711 &added);
712 }
713 }
714
715 break;
716
718 wait = FALSE;
719 break;
720 }
721
722 m_WaitingForSentIo = wait;
723 *Wait = wait;
724
725 if (wait) {
726 //
727 // If Stop(leave sent io pending) was previously called, m_SentIoEvent
728 // will be in the signalled state. We need to wait for sent i/o to be
729 // completed, so make sure it is not signalled while holding the lock
730 //
732 }
733 else {
734 //
735 // Even though *Wait is set to FALSE, the caller may wait anyways
736 // if it is aggregating targets to move into the stopped state and
737 // wait on them all.
738 //
740 }
741
742 if (LockSelf) {
743 Unlock(irql);
744 }
745}
@ WdfIoTargetCancelSentIo
Definition: wdfiotarget.h:71
@ WdfIoTargetWaitForSentIoToComplete
Definition: wdfiotarget.h:72
@ WdfIoTargetLeaveSentIoPending
Definition: wdfiotarget.h:73

Referenced by FxUsbPipe::GotoStopState(), and Stop().

◆ HandleFailedResubmit()

VOID FxIoTarget::HandleFailedResubmit ( __in FxRequestBase Request)
protected

Definition at line 2226 of file fxiotarget.cpp.

2243{
2244 KIRQL irql;
2245 BOOLEAN setStopEvent;
2246
2248 "WDFREQUEST %p", Request->GetTraceObjectHandle());
2249
2250 setStopEvent = FALSE;
2251
2252 Lock(&irql);
2253
2254 //
2255 // Flag should be clear until we set it below
2256 //
2257 ASSERT((Request->GetTargetFlags() & FX_REQUEST_COMPLETED) == 0);
2258
2259 //
2260 // Mark that the request has been completed
2261 //
2262 Request->SetTargetFlags(FX_REQUEST_COMPLETED);
2263
2264 //
2265 // Timer should not have been started.
2266 //
2267 ASSERT((Request->GetTargetFlags() & FX_REQUEST_TIMER_SET) == 0);
2268
2269 //
2270 // RemoveCompletedRequestLocked clears Request->m_TargetFlags, so we must
2271 // do this check before that call.
2272 //
2273 if ((Request->GetTargetFlags() & FX_REQUEST_CANCELLED_FROM_TIMER) &&
2274 Request->m_Irp.GetStatus() == STATUS_CANCELLED) {
2275 //
2276 // We cancelled the request from the timer and it has completed with
2277 // cancelled. Morph the status code into a timeout status.
2278 //
2279 // Don't muck with the IoStatus.Information field.
2280 //
2281 Request->m_Irp.SetStatus(STATUS_IO_TIMEOUT);
2282 }
2283
2284 setStopEvent = RemoveCompletedRequestLocked(Request);
2285
2286 Unlock(irql);
2287
2289 "WDFREQUEST %p completed in completion routine",
2290 Request->GetTraceObjectHandle());
2292
2293 if (setStopEvent) {
2295 "WDFIOTARGET %p, setting stop event %p",
2298 }
2299
2301}
@ FX_REQUEST_TIMER_SET

Referenced by SubmitPendedRequest().

◆ HasEnoughStackLocations()

BOOLEAN __inline FxIoTarget::HasEnoughStackLocations ( __in FxIrp Irp)
inline

Definition at line 396 of file fxiotarget.hpp.

399 {
400#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
401 //
402 // Check to make sure there are enough current stack locations available.
403 // When a IRP is initially created, Irp->CurrentLocation is set to
404 // StackSize + 1. When comparing against the target device, subtract
405 // off the extra space to see how many locations are left.
406 //
407 // Say Target->m_TargetStackSize == 1, then:
408 // irp = IoAllocateIrp(Target->m_TargetStackSize, FALSE);
409 // ASSERT(irp->CurrentLocation == 2);
410 //
411 return (Irp->GetCurrentIrpStackLocationIndex() - 1 >= m_TargetStackSize) ? TRUE : FALSE;
412#else // FX_CORE_USER_MODE
413 //
414 // For UMDF, host does the necessary checks to ensure there are enough
415 // stack locations. In addition, UMDF drivers can't create WDM IRPs
416 // so they don't get to dictate the number of stack locations in the irp
417 // so this kind of check in framework for UMDF is redundant. Return TRUE
418 // always.
419 //
420 return TRUE;
421#endif
422 }

◆ HasValidStackSize()

__inline BOOLEAN FxIoTarget::HasValidStackSize ( VOID  )

Definition at line 250 of file fxiotargetkm.hpp.

253{
254 return (m_TargetStackSize == 0 ? FALSE : TRUE);
255}

◆ IncrementIoCount()

__inline VOID FxIoTarget::IncrementIoCount ( VOID  )
inlineprotected

Definition at line 767 of file fxiotarget.hpp.

770 {
771 LONG ret;
772
774
775#if DBG
776 ASSERT(ret > 1);
777#else
779#endif
780 }
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by FxUsbPipe::GotoStartState(), and SubmitLocked().

◆ Init()

_Must_inspect_result_ NTSTATUS FxIoTarget::Init ( __in CfxDeviceBase Device)

Definition at line 1119 of file fxiotarget.cpp.

1122{
1124
1126 if (!NT_SUCCESS(status)) {
1127 return status;
1128 }
1129
1132
1133 m_InStackDevice = Device->GetDeviceObject();
1134
1135 //
1136 // Note that AttachedDevice can be NULL for UMDF for
1137 // example when there is only one device in the stack.
1138 //
1140 m_TargetPdo = Device->GetPhysicalDevice();
1141
1142 m_Driver = Device->GetDriver();
1143
1144#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1145 if (m_InStackDevice == NULL || m_Driver == NULL ||
1149 "Init WDFIOTARGET %p, unexpected NULL, m_InStackDevice %p, "
1150 "m_TargetDevice %p, m_TargetPdo %p, m_Driver %p",
1152 m_Driver);
1153
1154 return STATUS_UNSUCCESSFUL;
1155 }
1156#else
1157 if (m_InStackDevice == NULL || m_Driver == NULL) {
1160 "Init WDFIOTARGET %p, unexpected NULL, m_InStackDevice %p, "
1161 "m_Driver %p",
1163
1164 return STATUS_UNSUCCESSFUL;
1165 }
1166#endif
1167
1168 //
1169 // For UMDF the target device can be NULL if there is only one driver in the
1170 // stack. In that case m_TargetStackSize retains its initial value (0).
1171 //
1172 if (m_TargetDevice != NULL) {
1174
1176
1178 }
1179
1180 return STATUS_SUCCESS;
1181}
UCHAR GetTargetIoType(VOID)
Definition: fxiotarget.hpp:631
virtual _Must_inspect_result_ MdDeviceObject GetTargetDeviceObject(_In_ CfxDeviceBase *Device)
Definition: fxiotarget.hpp:326
_Must_inspect_result_ NTSTATUS InitModeSpecific(__in CfxDeviceBase *Device)
VOID SetDeviceBase(__in CfxDeviceBase *DeviceBase)
Definition: fxobject.hpp:797
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
CCHAR GetStackSize(VOID)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by CTipbarWnd::_CreateThread(), FxDeviceBase::AllocateTarget(), FxUsbInterface::MakeAndConfigurePipes(), FxUsbDevice::SelectConfig(), and FxUsbInterface::SelectSetting().

◆ InitModeSpecific()

_Must_inspect_result_ NTSTATUS FxIoTarget::InitModeSpecific ( __in CfxDeviceBase Device)
protected

Definition at line 237 of file fxiotargetkm.hpp.

240{
242
243 DO_NOTHING();
244
245 return STATUS_SUCCESS;
246}
#define DO_NOTHING()
Definition: mxgeneral.h:32

Referenced by Init(), and FxIoTargetRemote::InitRemote().

◆ PendRequestLocked()

_Must_inspect_result_ NTSTATUS FxIoTarget::PendRequestLocked ( __in FxRequestBase Request)
protected

Definition at line 2017 of file fxiotarget.cpp.

2020{
2022 FxIrp* irp;
2023
2024 //
2025 // Assumes this object's lock is being held
2026 //
2027 Request->SetTargetFlags(FX_REQUEST_PENDED);
2028
2029 irp = Request->GetSubmitFxIrp();
2030
2031 //
2032 // Make sure there is a valid current stack location in the irp. If we
2033 // allocated the irp ourself, then the current stack location is not valid.
2034 // Even if we didn't allocate the irp ourself, this will do no harm. In
2035 // every spot where we remove the request, we undo this call with a call to
2036 // IoSkipCurrentIrpStackLocation
2037 //
2039
2041
2043
2044 if (!NT_SUCCESS(status)) {
2045 //
2046 // Undo the affects of the IoSetNextIrpStackLocation made when we
2047 // enqueued the request.
2048 //
2050
2051 //
2052 // Request was not pended.
2053 //
2054 Request->ClearTargetFlags(FX_REQUEST_PENDED);
2055 }
2056
2057 return status;
2058}
_Must_inspect_result_ NTSTATUS InsertTailRequest(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext CsqContext, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:115
VOID SetNextIrpStackLocation(VOID)
Definition: fxirpum.cpp:1235
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
BOOLEAN IsCurrentIrpStackLocationValid(VOID)
Definition: fxirpum.cpp:1761

Referenced by SubmitLocked().

◆ PrintDisposeMessage()

VOID FxIoTarget::PrintDisposeMessage ( VOID  )
protected

Definition at line 99 of file fxiotarget.cpp.

117{
119 "WDFIOTARGET %p, setting Dispose event %p",
121}

Referenced by DecrementIoCount().

◆ Purge()

VOID FxIoTarget::Purge ( __in WDF_IO_TARGET_PURGE_IO_ACTION  Action)
virtual

Reimplemented in FxUsbDevice.

Definition at line 918 of file fxiotarget.cpp.

921{
922 LIST_ENTRY pendedHead;
923 SINGLE_LIST_ENTRY sentHead;
924 BOOLEAN wait;
925
926 InitializeListHead(&pendedHead);
927 sentHead.Next = NULL;
928 wait = FALSE;
929
930 GotoPurgeState(Action, &pendedHead, &sentHead, &wait, TRUE);
931
932 //
933 // Complete any requests we might have pulled off of our lists
934 //
935 CompletePendedRequestList(&pendedHead);
936 _CancelSentRequests(&sentHead);
937
938 if (wait) {
939 KIRQL irql;
940
941 //
942 // Under the lock, if wait is set, m_WaitingForSentIo is true, but once
943 // we drop the lock, all pended i/o could have already been canceled
944 // and m_WaitingForSentIo is FALSE at this point.
945 //
946 // ASSERT(m_WaitingForSentIo);
947
949
950 //
951 // Mark that we are no longer purging and waiting for i/o to complete.
952 //
953 Lock(&irql);
955 Unlock(irql);
956 }
957
960 "WDFIOTARGET %p purged ",GetHandle());
961}
VOID CompletePendedRequestList(__in PLIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:520
virtual VOID GotoPurgeState(__in WDF_IO_TARGET_PURGE_IO_ACTION Action, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxiotarget.cpp:790

Referenced by __drv_strictTypeMatch(), and FxUsbDevice::Purge().

◆ QueryInterface()

_Must_inspect_result_ NTSTATUS FxIoTarget::QueryInterface ( __inout FxQueryInterfaceParams Params)

Definition at line 1102 of file fxiotarget.cpp.

1105{
1106 switch (Params->Type) {
1107 case FX_TYPE_IO_TARGET:
1108 *Params->Object = (FxIoTarget*) this;
1109 break;
1110 default:
1111 return FxNonPagedObject::QueryInterface(Params); // __super call
1112 }
1113
1114 return STATUS_SUCCESS;
1115}
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

Referenced by FxIoTargetRemote::QueryInterface().

◆ Remove()

VOID FxIoTarget::Remove ( VOID  )
virtual

Reimplemented in FxIoTargetRemote.

Definition at line 1066 of file fxiotarget.cpp.

1069{
1070 SINGLE_LIST_ENTRY sentHead;
1071 LIST_ENTRY pendedHead;
1072 BOOLEAN wait;
1073
1074 sentHead.Next = NULL;
1075 InitializeListHead(&pendedHead);
1076
1078 &pendedHead,
1079 &sentHead,
1080 TRUE,
1081 &wait);
1082
1083 //
1084 // Complete any requests we might have pulled off of our lists
1085 //
1086 CompletePendedRequestList(&pendedHead);
1087 _CancelSentRequests(&sentHead);
1088
1089 if (wait) {
1091
1093 }
1094
1096
1097 return;
1098}
virtual VOID WaitForDisposeEvent(VOID)
Definition: fxiotarget.cpp:124
virtual VOID GotoRemoveState(__in WDF_IO_TARGET_STATE NewState, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __in BOOLEAN Lock, __out PBOOLEAN Wait)
Definition: fxiotarget.cpp:964

◆ RemoveCompletedRequestLocked()

BOOLEAN FxIoTarget::RemoveCompletedRequestLocked ( __in FxRequestBase Request)
protected

Definition at line 1919 of file fxiotarget.cpp.

1938{
1939 ULONG oldFlags;
1940
1941 //
1942 // We will decrement the pending io count associated with this completed
1943 // request in FxIoTarget::CompleteRequest
1944 //
1945 // DecrementPendingIoCount();
1946
1948 "WDFIOTARGET %p, WDFREQUEST %p", GetObjectHandle(),
1949 Request->GetTraceObjectHandle());
1950
1951 RemoveEntryList(&Request->m_ListEntry);
1952
1953 //
1954 // The request expects not to be on a list when it is destroyed.
1955 //
1956 InitializeListHead(&Request->m_ListEntry);
1957
1958 //
1959 // By the time we get here, there should never ever be a timer set for the
1960 // request.
1961 //
1962 ASSERT((Request->GetTargetFlags() & FX_REQUEST_TIMER_SET) == 0);
1963
1964 //
1965 // Clear flags that may have been set previously.
1966 //
1967 oldFlags = Request->ClearTargetFlags(FX_REQUEST_COMPLETED |
1971
1973
1974 //
1975 // If we are removing, we must wait for *ALL* requests that were sent down
1976 // the stack.
1977 //
1978 // If we are stopping, we only wait for i/o which do not ignore state
1979 //
1980 // NOTE: if we are completing a request which was inserted onto a list
1981 // Cancel()'ed before SubmitLocked was called and the Cancel()
1982 // thread already had a completion reference taken we are going to
1983 // evaluate a state transition even though the request is not a part
1984 // in that transition. I think this is OK b/c the transition would
1985 // have already occurred if the request(s) holding up the transition
1986 // have completed and will not occur here if they are still pending.
1987 //
1988 if (m_Removing) {
1990 //
1991 // We are no longer transitioning, do not allow new I/O of any kind
1992 // to come in.
1993 //
1994 m_Removing = FALSE;
1995
1996 //
1997 // Now that all i/o has ceased, clear out our pointers with relation
1998 // to the target itself.
1999 //
2001
2002 return TRUE;
2003 }
2004 }
2005 else if (m_WaitingForSentIo &&
2006 (oldFlags & FX_REQUEST_IGNORE_STATE) == 0 &&
2009 return TRUE;
2010 }
2011
2012 return FALSE;
2013}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
@ FX_REQUEST_IGNORE_STATE

Referenced by CompleteCanceledRequest(), HandleFailedResubmit(), RequestCompletionRoutine(), and TimerCallback().

◆ RequestCompletionRoutine()

VOID FxIoTarget::RequestCompletionRoutine ( __in FxRequestBase Request)
protected

Definition at line 2304 of file fxiotarget.cpp.

2322{
2323 KIRQL irql;
2324 BOOLEAN completeRequest, setStopEvent;
2325
2327 "WDFREQUEST %p", Request->GetTraceObjectHandle());
2328
2329
2330 setStopEvent = FALSE;
2331 completeRequest = FALSE;
2332
2333 Lock(&irql);
2334
2335 //
2336 // Flag should be clear until we set it below
2337 //
2338 ASSERT((Request->GetTargetFlags() & FX_REQUEST_COMPLETED) == 0);
2339
2340 //
2341 // Mark that the request has been completed so that the potential timer
2342 // DPC will handle the case properly
2343 //
2344 Request->SetTargetFlags(FX_REQUEST_COMPLETED);
2345
2346 //
2347 // CancelTimer() returns TRUE if the timer was successfully canceled (if
2348 // queued) or if no timer was queued.
2349 //
2350 if (Request->CancelTimer()) {
2351 //
2352 // Sync with Request->Cancel() to make sure we can delete the request.
2353 //
2354 completeRequest = Request->CanComplete();
2355 }
2356
2357 if (completeRequest) {
2358 //
2359 // RemoveCompletedRequestLocked clears Request->m_TargetFlags, so we must
2360 // do this check before that call.
2361 //
2362 if ((Request->GetTargetFlags() & FX_REQUEST_CANCELLED_FROM_TIMER) &&
2363 Request->m_Irp.GetStatus() == STATUS_CANCELLED) {
2364 //
2365 // We cancelled the request from the timer and it has completed with
2366 // cancelled. Morph the status code into a timeout status.
2367 //
2368 // Don't muck with the IoStatus.Information field.
2369 //
2370 Request->m_Irp.SetStatus(STATUS_IO_TIMEOUT);
2371 }
2372
2373 setStopEvent = RemoveCompletedRequestLocked(Request);
2374 }
2375 else {
2378 "WDFREQUEST %p deferring completion due to outstanding completion "
2379 "references", Request->GetTraceObjectHandle());
2380 }
2381
2382 Unlock(irql);
2383
2384 if (completeRequest) {
2386 "WDFREQUEST %p completed in completion routine",
2387 Request->GetTraceObjectHandle());
2389 }
2390
2391 if (setStopEvent) {
2393 "WDFIOTARGET %p, setting stop event %p",
2396 }
2397
2398 if (completeRequest) {
2400 }
2401}

Referenced by FailPendedRequest().

◆ Send()

__inline VOID FxIoTarget::Send ( _In_ MdIrp  Irp)
virtual

Reimplemented in FxIoTargetSelf.

Definition at line 259 of file fxiotargetkm.hpp.

262{
263 //
264 // Ignore the return value because once we have sent the request, we
265 // want all processing to be done in the completion routine.
266 //
268}
#define IoCallDriver
Definition: irp.c:1225

Referenced by SubmitPendedRequest(), and SubmitSync().

◆ SetCompletionRoutine()

VOID FxIoTarget::SetCompletionRoutine ( __in FxRequestBase Request)
inlineprivate

Definition at line 834 of file fxiotarget.hpp.

837 {
838 FxIrp* irp = Request->GetSubmitFxIrp();
839
843 Request,
844 TRUE,
845 TRUE,
846 TRUE);
847 }
static MdCompletionRoutineType _RequestCompletionRoutine
Definition: fxiotarget.hpp:609
VOID SetCompletionRoutineEx(__in MdDeviceObject DeviceObject, __in MdCompletionRoutine CompletionRoutine, __in PVOID Context, __in BOOLEAN InvokeOnSuccess=TRUE, __in BOOLEAN InvokeOnError=TRUE, __in BOOLEAN InvokeOnCancel=TRUE)
Definition: fxirpum.cpp:104

Referenced by SubmitLocked().

◆ Start()

_Must_inspect_result_ NTSTATUS FxIoTarget::Start ( VOID  )
virtual

Reimplemented in FxUsbDevice.

Definition at line 282 of file fxiotarget.cpp.

285{
288
290
292
294
297 "WDFIOTARGET %p started status %!STATUS!",
298 GetHandle(),status);
299 return status;
300}
struct outqueuenode * head
Definition: adnsresfilter.c:66
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxiotarget.cpp:306
VOID SubmitPendedRequests(__in PLIST_ENTRY RequestListHeadHead)
Definition: fxiotarget.cpp:268

Referenced by FxUsbDevice::Start().

◆ Stop()

VOID FxIoTarget::Stop ( __in WDF_IO_TARGET_SENT_IO_ACTION  Action)
virtual

Reimplemented in FxUsbDevice.

Definition at line 748 of file fxiotarget.cpp.

751{
753 BOOLEAN wait;
754
755 head.Next = NULL;
756 wait = FALSE;
757
758 GotoStopState(Action, &head, &wait, TRUE);
759
760 if (head.Next != NULL) {
762 }
763
764 if (wait) {
765 KIRQL irql;
766
767 //
768 // Under the lock, if wait is set, m_WaitingForSentIo is true, but once
769 // we drop the lock, all pended i/o could have already been canceled
770 // and m_WaitingForSentIo is FALSE at this point.
771 //
772 // ASSERT(m_WaitingForSentIo);
773
775
776 //
777 // Mark that we are no longer stopping and waiting for i/o to complete.
778 //
779 Lock(&irql);
781 Unlock(irql);
782 }
783
786 "WDFIOTARGET %p stopped ",GetHandle());
787}
virtual VOID GotoStopState(__in WDF_IO_TARGET_SENT_IO_ACTION Action, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxiotarget.cpp:617

Referenced by __drv_strictTypeMatch(), and FxUsbDevice::Stop().

◆ Submit()

ULONG FxIoTarget::Submit ( __in FxRequestBase Request,
__in_opt PWDF_REQUEST_SEND_OPTIONS  Options,
__in_opt ULONG  Flags 
)

Definition at line 1636 of file fxiotarget.cpp.

1641{
1642 ULONG result;
1643 KIRQL irql;
1644
1645 Lock(&irql);
1647 Unlock(irql);
1648
1649 return result;
1650}
ULONG SubmitLocked(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in ULONG Flags)
GLuint64EXT * result
Definition: glext.h:11304
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by SubmitPendedRequest(), and SubmitSync().

◆ SubmitLocked()

ULONG FxIoTarget::SubmitLocked ( __in FxRequestBase Request,
__in_opt PWDF_REQUEST_SEND_OPTIONS  Options,
__in ULONG  Flags 
)

Definition at line 1244 of file fxiotarget.cpp.

1284{
1287 ULONG action;
1288 BOOLEAN startTimer, stateIgnored, verify;
1289 BOOLEAN addedRef;
1290 FxIrp* irp;
1291
1293
1294 action = 0;
1295 startTimer = FALSE;
1296 stateIgnored = FALSE;
1297 addedRef = FALSE;
1298
1299 //
1300 // If the reference count is not zero, the irp has not completed and the
1301 // driver is reusing it before it has returned to the driver. Not good!
1302 //
1303 ASSERT(Request->m_IrpCompletionReferenceCount == 0);
1304 if (Request->m_IrpCompletionReferenceCount != 0) {
1307 "WDFREQUEST %p already sent to a target",
1308 Request->GetTraceObjectHandle());
1309
1310 //
1311 // Last ditch assert
1312 //
1313 ASSERT((Request->GetTargetFlags() & FX_REQUEST_PENDED) == 0);
1314
1315 // no return
1319 (ULONG_PTR) Request->GetHandle());
1320 }
1321
1322 irp = Request->GetSubmitFxIrp();
1323
1326
1327 verify = TRUE;
1328 status = VerifySubmitLocked(pFxDriverGlobals, Request);
1329 if (!NT_SUCCESS(status)){
1330 goto Done;
1331 }
1332 }
1333 else {
1334 verify = FALSE;
1335 }
1336
1337 //
1338 // if WDF_REQUEST_SEND_OPTION_TIMEOUT is set, Options != NULL
1339 //
1340 if ((Flags & WDF_REQUEST_SEND_OPTION_TIMEOUT) && Options->Timeout != 0) {
1341 //
1342 // Create the timer under the lock
1343 //
1344 status = Request->CreateTimer();
1345
1346 if (!NT_SUCCESS(status)) {
1349 "WDFREQUEST %p, could not create timer, %!STATUS!",
1350 Request->GetTraceObjectHandle(), status);
1351
1352 goto Done;
1353 }
1354
1355 startTimer = TRUE;
1356 }
1357
1359 //
1360 // If we are in the deleted or closed state, we must be in the transitioning
1361 // state to allow I/O at this time. For any other state, always allow
1362 // the i/o to go through.
1363 //
1364 if ((m_State == WdfIoTargetDeleted ||
1367 m_Removing == FALSE) {
1368 //
1369 // The target is truly closed or removed, it is not in the
1370 // transitionary state. We don't allow I/O anymore.
1371 //
1373
1376 "WDFIOTARGET %p state %!WDF_IO_TARGET_STATE!, sending "
1377 "WDFREQUEST %p cannot ignore current state, %!STATUS!",
1378 GetObjectHandle(), m_State, Request->GetTraceObjectHandle(),
1379 status);
1380
1381 goto Done;
1382 }
1383 else {
1384 action |= SubmitSend;
1385
1388 "ignoring WDFIOTARGET %p state, sending WDFREQUEST %p, state "
1389 "%!WDF_IO_TARGET_STATE!",
1390 GetObjectHandle(), Request->GetTraceObjectHandle(), m_State);
1391
1392 Request->SetTargetFlags(FX_REQUEST_IGNORE_STATE);
1393
1395 stateIgnored = TRUE;
1396 }
1397 }
1398 else {
1399 switch (m_State) {
1400 case WdfIoTargetStarted:
1402 action |= SubmitSend;
1403 break;
1404
1405 case WdfIoTargetStopped:
1408 goto Done;
1409 }
1410 else {
1413 }
1414 break;
1415
1417 case WdfIoTargetClosed:
1418 case WdfIoTargetDeleted:
1419 case WdfIoTargetPurged:
1420 default:
1423 "failing WDFREQUEST %p, WDFIOTARGET %p not accepting requests, "
1424 "state %!WDF_IO_TARGET_STATE!", Request->GetTraceObjectHandle(),
1426
1428 goto Done;
1429 }
1430 }
1431
1432 //
1433 // Make sure the list entry is initialized so if we call RemoveEntryList
1434 // later, we don't corrupt whatever Flink and Blink point to.
1435 //
1436 InitializeListHead(&Request->m_ListEntry);
1437
1439
1440Done:
1441 if (NT_SUCCESS(status)) {
1442 //
1443 // Request should not be pended
1444 //
1445 ASSERT((Request->GetTargetFlags() & FX_REQUEST_PENDED) == 0);
1446
1447 //
1448 // Set m_Target before setting the reference count to one because as soon
1449 // as it is set to 1, it can be decremented to zero and then it will
1450 // assume that m_Target is valid.
1451 //
1452 Request->SetTarget(this);
1453
1454 //
1455 // Assume we are successful, we will adjust this value in case of error.
1456 //
1458
1459 //
1460 // All paths which are pulling the request off of the list must use this
1461 // specific tag. This would include the cancel, timer, and completion
1462 // routines.
1463 //
1464 // We don't add a reference in the error case because the caller
1465 // will just complete the request back to the caller (for a queue
1466 // presented request) or free it (for a driver created request).
1467 //
1468 // This released at the end of FxRequestBase::CompleteSubmitted
1469 //
1470 Request->ADDREF(this);
1471
1472 //
1473 // In case of error, we use this flag to know if the IoCount and
1474 // RequestRef need to be rolled back.
1475 //
1476 addedRef = TRUE;
1477
1478 //
1479 // Set the reference count to one. This reference count guards prevents
1480 // Request::Cancel from touching an invalid PIRP outside of any lock.
1481 //
1482 Request->m_IrpCompletionReferenceCount = 1;
1483
1484 if (Request->m_Canceled) {
1485 //
1486 // CanComplete() decrements the count that was set above. If the
1487 // count goes to zero, CanComplete() returns TRUE and
1488 // FxRequestBase::Cancel will not touch the irp. If it returns
1489 // FALSE, we indicate that the request was sent, in actuality we
1490 // don't send the request b/c FxRequestBase::Cancel will call
1491 // CompleteCanceledRequest, where the irp will complete.
1492 //
1493 if (Request->CanComplete()) {
1494 //
1495 // This thread owns the irp. Set the status to !NT_SUCCESS and
1496 // clear any actions we indicate to the caller.
1497 //
1498 action = 0;
1499 }
1500 else {
1501 //
1502 // There is still an reference count on the completion count,
1503 // let the other thread complete it.
1504 //
1505
1506 //
1507 // Make the caller think that the request was queued. By doing
1508 // this, it will not attempt to call IoCallDriver. SubmitSend
1509 // will be cleared after jump to Done: and evaluate status.
1510 //
1512 }
1513
1514 //
1515 // Either way, we want to set STATUS_CANCELLED in the PIRP when we
1516 // are done.
1517 //
1519
1520 //
1521 // Just jump to the end and avoid any more compares.
1522 //
1523 goto CheckError;
1524 }
1525
1526 if (action & SubmitSend) {
1527 if (stateIgnored) {
1529 }
1530 else {
1531 //
1532 // Keep track of the request so that we can cancel it later if needed
1533 //
1534 InsertTailList(&m_SentIoListHead, &Request->m_ListEntry);
1535 }
1536
1537 //
1538 // We know we are going to send the request, set the completion
1539 // routine now. Since IoSetCompletionRoutineEx allocates memory
1540 // which is only freed when the completion routine is called when
1541 // the request is completing, we can only set the CR when we *KNOW*
1542 // the request will be sent, ie SubmitSend is set and returned to
1543 // the caller.
1544 //
1546
1547 //
1548 // NOTE: No need to reference the file object before we drop the lock
1549 // because will not deref the file object while there is outstanding
1550 // I/O.
1551 //
1552 }
1553 else {
1557 "Pending WDFREQUEST %p, WDFIOTARGET %p is paused, %!STATUS!",
1558 Request->GetTraceObjectHandle(), GetObjectHandle(), status);
1559
1560 if (!NT_SUCCESS(status)) {
1561 //
1562 // CanComplete() decrements the count that was set above. If the
1563 // count goes to zero, CanComplete() returns TRUE and
1564 // FxRequestBase::Cancel will not touch the irp. If it returns
1565 // FALSE, we indicate that the request was sent, in actuality we
1566 // don't send the request b/c FxRequestBase::Cancel will call
1567 // CompleteCanceledRequest, where the irp will complete.
1568 //
1569 if (Request->CanComplete()) {
1570 //
1571 // This thread owns the irp.
1572 // Clear any actions we indicate to the caller.
1573 //
1574 action = 0;
1575 }
1576 else {
1577 //
1578 // The cancel/timer routine (whoever has ownership of
1579 // request) will complete the request.
1580 //
1582 DO_NOTHING();
1583 }
1584 }
1585 }
1586
1587 if (NT_SUCCESS(status)) {
1588 //
1589 // Delay starting the timer to the last possible moment where we know
1590 // there will be no error and we don't have to deal with any cancel
1591 // logic in the error case.
1592 //
1593 if (startTimer) {
1595
1596 //
1597 // Set the timer under the lock
1598 //
1601 "Starting timer on WDFREQUEST %p",
1602 Request->GetTraceObjectHandle());
1603
1604 Request->StartTimer(Options->Timeout);
1605 }
1606 }
1607 }
1608
1610 //
1611 // Not an else clause to the if (NT_SUCCESS(status)) above b/c status can
1612 // be changed within the NT_SUCCESS(status) clause.
1613 //
1614 if (!NT_SUCCESS(status)) {
1616 action &= ~SubmitSend;
1617 }
1618 else if (verify) {
1619 Request->SetVerifierFlags(FXREQUEST_FLAG_SENT_TO_TARGET);
1620 }
1621
1622 //
1623 // Keep the IoCount and Request->AddRef() only if the request is going
1624 // to be sent, or it is queued, or another thread took ownership of its
1625 // cancellation.
1626 //
1627 if (addedRef && (action & (SubmitSend | SubmitQueued)) == 0) {
1628 Request->RELEASE(this);
1630 }
1631
1632 return action;
1633}
VOID SetCompletionRoutine(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:834
_Must_inspect_result_ NTSTATUS PendRequestLocked(__in FxRequestBase *Request)
__inline VOID IncrementIoCount(VOID)
Definition: fxiotarget.hpp:767
const WCHAR * action
Definition: action.c:7509
@ SubmitSend
Definition: fxiotarget.hpp:202
@ SubmitQueued
Definition: fxiotarget.hpp:203
#define WDF_REQUEST_SEND_INTERNAL_OPTION_FAIL_ON_PEND
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
void CheckError(HRESULT hr)
Definition: shellclasses.h:167
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
BOOLEAN FxVerifierIO
Definition: fxglobals.h:446
uint32_t ULONG_PTR
Definition: typedefs.h:65
@ WDF_REQUEST_FATAL_ERROR
Definition: wdfbugcodes.h:63
@ WDF_REQUEST_FATAL_ERROR_REQUEST_ALREADY_SENT
Definition: wdfbugcodes.h:78
@ WDF_REQUEST_SEND_OPTION_TIMEOUT
Definition: wdfrequest.h:108
@ WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE
Definition: wdfrequest.h:110
#define STATUS_WDF_QUEUED
Definition: wdfstatus.h:81
static void startTimer(void)
Definition: xmllint.c:460

Referenced by FxUsbPipeContinuousReader::ResubmitRepeater(), and Submit().

◆ SubmitPendedRequest()

VOID FxIoTarget::SubmitPendedRequest ( __in FxRequestBase Request)

Definition at line 206 of file fxiotarget.cpp.

209{
211 FxIrp* irp = NULL;
212
213 irp = Request->GetSubmitFxIrp();
214 action = Submit(Request, NULL, 0);
215 if (action & SubmitSend) {
218 "Sending Pended WDFREQUEST %p, Irp %p",
219 Request->GetTraceObjectHandle(),
220 irp->GetIrp());
221
222 Send(irp->GetIrp());
223 }
224
225 //
226 // If the request was not sent or pended (queued), complete it.
227 //
228 if ((action & (SubmitSend | SubmitQueued)) == 0) {
229 ASSERT(0 == action);
232 "Completing Pended WDFREQUEST %p, Irp %p, %!STATUS!",
233 Request->GetTraceObjectHandle(), irp->GetIrp(), irp->GetStatus());
234
235 //
236 // Fail the request.
237 //
240
241 //
242 // This function updates the outstanding 'io count' value and
243 // decrement the ref count on Request.
244 //
246 }
247 else {
248 //
249 // Submit() updated the 'io count' counter for request that got sent or
250 // queued. Note that the input request was already tracked via this
251 // counter, thus decrement its value.
252 //
254
255 //
256 // SubmitLocked will add another ref if it needs it. Release the
257 // reference taken when the request was pended.
258 //
259 // Release the reference after submitting it in case the request was deleted.
260 // If it was deleted, the reference taken by the target is the only keep
261 // it alive.
262 //
263 Request->RELEASE(this);
264 }
265}
VOID HandleFailedResubmit(__in FxRequestBase *Request)
virtual VOID Send(_In_ MdIrp Irp)
ULONG Submit(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in_opt ULONG Flags)
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466

Referenced by FxUsbDevice::Start(), and SubmitPendedRequests().

◆ SubmitPendedRequests()

VOID FxIoTarget::SubmitPendedRequests ( __in PLIST_ENTRY  RequestListHeadHead)
protected

Definition at line 268 of file fxiotarget.cpp.

271{
273
274 while (!IsListEmpty(RequestListHead)) {
275 ple = RemoveHeadList(RequestListHead);
277 }
278}
VOID SubmitPendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:206

Referenced by FxIoTargetRemote::Open(), and Start().

◆ SubmitSync()

_Must_inspect_result_ NTSTATUS FxIoTarget::SubmitSync ( __in FxRequestBase Request,
__in_opt PWDF_REQUEST_SEND_OPTIONS  Options = NULL,
__out_opt PULONG  Action = NULL 
)

Definition at line 1654 of file fxiotarget.cpp.

1659{
1662 ULONG action;
1664 KIRQL irql;
1665 BOOLEAN clearContext;
1666
1669 "WDFIOTARGET %p, WDFREQUEST %p",
1670 GetObjectHandle(), Request->GetTraceObjectHandle());
1671
1672#if (FX_CORE_MODE == FX_CORE_USER_MODE)
1673 //
1674 // FxCREvent events needs to be initiliazed in UMDF, and failure handled
1675 // gracefully. For KMDF, it will result in double initialization which is
1676 // not a problem. Note that for KMDF, FxCREvent->Initialize will never fail.
1677 //
1678 status = params.SynchEvent.Initialize();
1679 if (!NT_SUCCESS(status)) {
1681 "Failed to initialize sync event for "
1682 "WDFIOTARGET %p, WDFREQUEST %p",
1683 GetObjectHandle(), Request->GetTraceObjectHandle());
1684 if (Action != NULL) {
1685 *Action = 0;
1686 }
1687 return status;
1688 }
1689#endif
1690
1691 clearContext = Request->ShouldClearContext();
1692
1693 if (Action != NULL) {
1694 action = *Action;
1695 }
1696 else {
1697 action = 0;
1698 }
1699
1700 if (Options != NULL &&
1702 Options->Timeout != 0) {
1703 //
1704 // If this flag is set, SubmitLocked will start a timer, which we don't
1705 // want because we will timeout the I/O using KeWaitForSingleObject.
1706 //
1707 // params.Constraints &= ~WDF_REQUEST_SEND_OPTION_TIMEOUT;
1708 timeout = Options->Timeout;
1710 }
1711
1712 //
1713 // Must set the completion routine before calling Submit() so that in the
1714 // pended or sent case, the completion routine is set in place during
1715 // cancelation or delayed completion.
1716 //
1718 params.OrigTargetCompletionContext = Request->m_TargetCompletionContext;
1719 params.OrigTargetCompletionRoutine =
1720 Request->m_CompletionRoutine.m_Completion;
1721 }
1722 else {
1723 params.OrigTargetCompletionContext = NULL;
1724 params.OrigTargetCompletionRoutine = NULL;
1725 }
1726
1727 Request->SetCompletionRoutine(_SyncCompletionRoutine, &params);
1728
1729 //
1730 // SubmitLocked will return whether the request should be sent *right now*.
1731 // If SubmitSend is clear, SubmitQueued must be checked. If set, then
1732 // the request was queued, otherwise, the request has failed and the
1733 // status was already set in the irp.
1734 //
1735 // Clear the WDF_REQUEST_SEND_OPTION_TIMEOUT flag so that SumbitLocked doesn't
1736 // try to allocate a timer
1737 //
1738 action |= Submit(
1739 Request,
1740 Options,
1741 (Options != NULL) ? (Options->Flags & ~WDF_REQUEST_SEND_OPTION_TIMEOUT) : 0);
1742
1744 "WDFREQUEST %p, Action 0x%x", Request->GetTraceObjectHandle(),
1745 action);
1746
1747 //
1748 // Add reference so that if we call Request->Cancel(), Request is still
1749 // a valid object in between the wait timeout and the cancel call if
1750 // request completes before Cancel is called.
1751 //
1752 Request->ADDREF(&status);
1753
1754 if (action & SubmitSend) {
1755 action |= SubmitSent;
1756
1759 "Sending WDFREQUEST %p, Irp %p", Request->GetTraceObjectHandle(),
1760 Request->GetSubmitIrp());
1761
1762 Send(Request->GetSubmitIrp());
1763
1764 //
1765 // We always wait, even in the synchronous case. We do this because
1766 // even though the WDM completion routine ran synchronously in this
1767 // thread, the WDF processing of the completion could have been post-
1768 // poned by another thread attempting to cancel the I/O. The postpone-
1769 // ment would occur when the canceling thread has an oustanding reference
1770 // on m_IrpCompletionReferenceCount, which would cause the call to
1771 // CanComplete() in RequestCompletionRoutine() to return FALSE and not
1772 // call _SyncCompletionRoutine in the context of the WDM completion
1773 // routine, but in the context of the canceling thread.
1774 //
1775 action |= SubmitWait;
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816 }
1817 else if (action & SubmitQueued) {
1818 //
1819 // To the caller, we say we sent the request (and all the cancel
1820 // semantics of a sent request still work).
1821 //
1823 }
1824 else if (action & SubmitSyncCallCompletion) {
1825 //
1826 // The request was not sent nor queued, reset the completion routine
1827 // since we overwrote it.
1828 //
1829 Request->m_TargetCompletionContext = params.OrigTargetCompletionContext;
1830 Request->m_CompletionRoutine.m_Completion =
1831 params.OrigTargetCompletionRoutine;
1832 ASSERT(!NT_SUCCESS(Request->GetSubmitFxIrp()->GetStatus()));
1833 }
1834
1835 if (action & SubmitSent) {
1836 if (action & SubmitWait) {
1837 status = params.SynchEvent.EnterCRAndWaitAndLeave(
1839 );
1840
1841 if (status == STATUS_TIMEOUT) {
1842 //
1843 // By setting FX_REQUEST_CANCELLED_FROM_TIMER, we match the
1844 // async timer behavior where we change the completion status
1845 // from STATUS_CANCELLED to STATUS_IO_TIMEOUT.
1846 //
1847 Lock(&irql);
1849 Unlock(irql);
1850
1851 Request->Cancel();
1852
1853 params.SynchEvent.EnterCRAndWaitAndLeave();
1854 }
1855 }
1856
1857 status = params.Status;
1858 }
1859 else {
1860 status = Request->GetSubmitFxIrp()->GetStatus();
1861 }
1862
1863 Request->RELEASE(&status);
1864
1865 if (Action != NULL) {
1866 *Action = action;
1867 }
1868
1869 if (clearContext) {
1870 Request->ContextReleaseAndRestore();
1871 }
1872
1873 return status;
1874}
static EVT_WDF_REQUEST_COMPLETION_ROUTINE _SyncCompletionRoutine
Definition: fxiotarget.hpp:662
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
@ SubmitTimeout
Definition: fxiotarget.hpp:206
@ SubmitWait
Definition: fxiotarget.hpp:205
@ SubmitSyncCallCompletion
Definition: fxiotarget.hpp:207
@ SubmitSent
Definition: fxiotarget.hpp:204
GLenum const GLfloat * params
Definition: glext.h:5645
Definition: dhcpd.h:245
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by __in_xcount(), FxUsbPipe::_SendTransfer(), FxUsbDevice::Deconfig(), FxIoTargetSendIo(), FxIoTargetSendIoctl(), FxUsbDevice::GetPortStatus(), FxUsbDevice::GetString(), if(), FxUsbDevice::InitDevice(), FxUsbDevice::SelectConfig(), FxUsbInterface::SelectSetting(), FxUsbDevice::SendSyncRequest(), FxUsbDevice::SendSyncUmUrb(), and SubmitSyncRequestIgnoreTargetState().

◆ SubmitSyncRequestIgnoreTargetState()

_Must_inspect_result_ NTSTATUS FxIoTarget::SubmitSyncRequestIgnoreTargetState ( __in FxRequestBase Request,
__in_opt PWDF_REQUEST_SEND_OPTIONS  RequestOptions 
)

Definition at line 2659 of file fxiotarget.cpp.

2668{
2670 WDF_REQUEST_SEND_OPTIONS requestOptions;
2671
2673 if (RequestOptions != NULL) {
2674
2675 //
2676 // Do a copy so that the passed in paramters is
2677 // not modified.
2678 //
2679 RtlCopyMemory(&requestOptions,
2681 sizeof(WDF_REQUEST_SEND_OPTIONS));
2682
2683 if ((requestOptions.Flags & WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE) == 0) {
2685 "Ignoring WDFIOTARGET %p state to send request",
2686 GetHandle());
2688 }
2689 }
2690 else{
2691 WDF_REQUEST_SEND_OPTIONS_INIT(&requestOptions,
2693 }
2694
2695 return SubmitSync(Request, &requestOptions);
2696}
_Must_inspect_result_ NTSTATUS SubmitSync(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS RequestOptions
Definition: wdfiotarget.h:867
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409

Referenced by FxUsbDevice::CyclePort(), FxUsbDevice::Reset(), and FxUsbPipe::Reset().

◆ TimerCallback()

VOID FxIoTarget::TimerCallback ( __in FxRequestBase Request)

Definition at line 2061 of file fxiotarget.cpp.

2078{
2079 KIRQL irql;
2080 BOOLEAN completeRequest, setStopEvent;
2081 LONG completionRefCount;
2082
2083 completeRequest = FALSE;
2084 setStopEvent = FALSE;
2085
2087 "WDFIOTARGET %p, WDFREQUEST %p", GetObjectHandle(),
2088 Request->GetTraceObjectHandle());
2089
2090 Lock(&irql);
2091
2092 //
2093 // Clear the flag so that when the completion routine runs, there is no attempt
2094 // to cancel this timer.
2095 //
2096 Request->ClearTargetFlags(FX_REQUEST_TIMER_SET);
2097
2098 if (Request->GetTargetFlags() & FX_REQUEST_COMPLETED) {
2099 //
2100 // Completion routine ran on a separate processor as the same time as
2101 // the timer DPC. The completion routine will have deferred
2102 // completion to the timer DPC or the caller of Request::Cancel().
2103 //
2104 completeRequest = Request->CanComplete();
2105 }
2106 else {
2107 //
2108 // Attempt to cancel the request later outside of the lock. By setting
2109 // the cancelled from timer flag, the completion routine can morph the
2110 // status to timeout if the request is returned as cancelled.
2111 //
2113
2114 //
2115 // Make sure the completion routine does not complete the request
2116 // while the timer callback is still running, in case the completion
2117 // is invoked in the unlock/lock window below.
2118 //
2119 completionRefCount = FxInterlockedIncrementGTZero(
2120 &Request->m_IrpCompletionReferenceCount);
2121 ASSERT(completionRefCount != 0);
2122 UNREFERENCED_PARAMETER(completionRefCount);
2123
2124 Unlock(irql);
2125
2126 Request->Cancel();
2127
2128 Lock(&irql);
2129
2130 //
2131 // CanComplete() returns true if completion ownership was claimed.
2132 //
2133 completeRequest = Request->CanComplete();
2134 }
2135
2136 //
2137 // If completion ownership was claimed, complete request.
2138 //
2139 if (completeRequest) {
2140 ASSERT(Request->GetTargetFlags() & FX_REQUEST_COMPLETED);
2141
2142 setStopEvent = RemoveCompletedRequestLocked(Request);
2143
2144 if (Request->m_Irp.GetStatus() == STATUS_CANCELLED) {
2145 //
2146 // We cancelled the request in another thread and the timer
2147 // fired at the same time. Treat this as if we did the cancel
2148 // from timer directly.
2149 //
2150 // Morph the status code into a timeout status.
2151 //
2152 // Don't muck with the IoStatus.Information field.
2153 //
2154 Request->m_Irp.SetStatus(STATUS_IO_TIMEOUT);
2155 }
2156 }
2157
2158 Unlock(irql);
2159
2160 if (completeRequest) {
2163 "WDFREQUEST %p completed in timer callback",
2164 Request->GetTraceObjectHandle());
2166 }
2167
2168 if (setStopEvent) {
2171 "WDFIOTARGET %p, setting stop event %p in timer callback",
2173
2175 }
2176
2177 if (completeRequest) {
2179 }
2180}
__inline LONG FxInterlockedIncrementGTZero(__inout LONG volatile *Target)
Definition: fxglobals.h:1045

◆ UpdateTargetIoType()

VOID FxIoTarget::UpdateTargetIoType ( VOID  )

Definition at line 2699 of file fxiotarget.cpp.

2702{
2703 UCHAR ioType = GetTargetIoType();
2704
2705 //
2706 // m_IoCount is initialized to 1
2707 //
2708 if ((ioType != m_TargetIoType) && (m_IoCount > 1)) {
2711 "WDFIOTARGET %p has changed IoType with outstanding IO",
2712 GetHandle());
2713 }
2714 m_TargetIoType = (UCHAR) ioType;
2715}

Referenced by FxDevice::SetFilterIoType().

◆ WaitForDisposeEvent()

VOID FxIoTarget::WaitForDisposeEvent ( VOID  )
protectedvirtual

Definition at line 124 of file fxiotarget.cpp.

127{
128#if (FX_CORE_MODE==FX_CORE_USER_MODE)
130#else
131 FxCREvent eventOnStack;
132 eventOnStack.Initialize();
133 FxCREvent * event = eventOnStack.GetSelfPointer();
134#endif
135
137
139
141 "WDFIOTARGET %p, Waiting on Dispose event %p",
143
145 event->EnterCRAndWaitAndLeave();
146 }
147
149 ASSERT(m_IoCount == 0);
150}
FxCREvent m_DisposeEventUm
Definition: fxiotarget.hpp:892
struct _cl_event * event
Definition: glext.h:7739
FxCREvent * GetSelfPointer(VOID)
Definition: fxwaitlock.hpp:180
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize(__in BOOLEAN InitialState=FALSE)
Definition: fxwaitlock.hpp:51

Referenced by FxIoTargetRemote::Close(), and Remove().

◆ WaitForSentIoToComplete()

virtual VOID FxIoTarget::WaitForSentIoToComplete ( VOID  )
inlineprotectedvirtual

Member Data Documentation

◆ _RequestCompletionRoutine

_Must_inspect_result_ NTSTATUS STDCALL FxIoTarget::_RequestCompletionRoutine
staticprotected

Definition at line 609 of file fxiotarget.hpp.

Referenced by SetCompletionRoutine().

◆ _SyncCompletionRoutine

VOID FxIoTarget::_SyncCompletionRoutine
staticprotected

Definition at line 662 of file fxiotarget.hpp.

Referenced by SubmitSync().

◆ FxRequestBase

friend FxIoTarget::FxRequestBase
private

Definition at line 212 of file fxiotarget.hpp.

◆ m_AddedToDeviceList

BOOLEAN FxIoTarget::m_AddedToDeviceList

Definition at line 860 of file fxiotarget.hpp.

Referenced by Construct(), and Dispose().

◆ m_DisposeEvent

FxCREvent* FxIoTarget::m_DisposeEvent
protected

◆ m_DisposeEventUm

FxCREvent FxIoTarget::m_DisposeEventUm
protected

Definition at line 892 of file fxiotarget.hpp.

Referenced by WaitForDisposeEvent().

◆ m_Driver

FxDriver* FxIoTarget::m_Driver
protected

◆ m_IgnoredIoListHead

LIST_ENTRY FxIoTarget::m_IgnoredIoListHead
protected

◆ m_InStack

BOOLEAN FxIoTarget::m_InStack

◆ m_InStackDevice

MdDeviceObject FxIoTarget::m_InStackDevice
protected

◆ m_IoCount

LONG FxIoTarget::m_IoCount
protected

◆ m_PendedQueue

FxIrpQueue FxIoTarget::m_PendedQueue
protected

◆ m_Removing

BOOLEAN FxIoTarget::m_Removing
protected

◆ m_SentIoEvent

◆ m_SentIoListHead

◆ m_SentRequestTag

const PVOID FxIoTarget::m_SentRequestTag = (PVOID) 'lcnC'
static

Definition at line 862 of file fxiotarget.hpp.

Referenced by _CancelSentRequest(), and GetSentRequestsListLocked().

◆ m_State

◆ m_TargetDevice

◆ m_TargetFileObject

◆ m_TargetIoType

UCHAR FxIoTarget::m_TargetIoType
protected

◆ m_TargetPdo

◆ m_TargetStackSize

CCHAR FxIoTarget::m_TargetStackSize
protected

◆ m_TransactionedEntry

FxTransactionedEntry FxIoTarget::m_TransactionedEntry

Definition at line 853 of file fxiotarget.hpp.

Referenced by _FromEntry(), and Construct().

◆ m_WaitingForSentIo

BOOLEAN FxIoTarget::m_WaitingForSentIo
protected

The documentation for this class was generated from the following files: