ReactOS  0.4.15-dev-2996-gf777e6b
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)
 
_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 }
FxNonPagedObject(__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID Construct(VOID)
Definition: fxiotarget.cpp:54

◆ 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 }
FxNonPagedObject(__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID Construct(VOID)
Definition: fxiotarget.cpp:54

◆ ~FxIoTarget()

FxIoTarget::~FxIoTarget ( )
protected

Definition at line 91 of file fxiotarget.cpp.

92 {
95  ASSERT(m_IoCount == 0);
96 }
LONG m_IoCount
Definition: fxiotarget.hpp:935
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define ASSERT(a)
Definition: mode.c:44
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873

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 }
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
static const PVOID m_SentRequestTag
Definition: fxiotarget.hpp:862

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 __inline FxRequestBase * _FromDrainEntry(__in PSINGLE_LIST_ENTRY Entry)
Definition: ntbasedef.h:628
PSINGLE_LIST_ENTRY ple
static VOID _CancelSentRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:534
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
#define NULL
Definition: types.h:112

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
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
base of all file and directory entries
Definition: entries.h:82

◆ _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);
2575  pFxIrp.SkipCurrentIrpStackLocation();
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 }
__in MdIrp __in PMdIoCsqIrpContext __in KIRQL CallerIrql
Definition: fxirpqueue.hpp:74
__inline ULONG ClearTargetFlags(__in UCHAR Flags)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
FxRequest * pRequest
Definition: fxirp.hpp:28
VOID FailPendedRequest(__in FxRequestBase *Request, __in NTSTATUS Status)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
LIST_ENTRY m_ListEntry
UCHAR KIRQL
Definition: env_spec_w32.h:591
__inline UCHAR GetTargetFlags(VOID)
_In_ PIRP Irp
Definition: csq.h:116
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
__inline PVOID GetTraceObjectHandle(VOID)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
static __inline FxRequestBase * _FromCsqContext(__in PMdIoCsqIrpContext Context)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxIrpQueue m_PendedQueue
Definition: fxiotarget.hpp:895
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
Definition: ntbasedef.h:628
VOID GetSentRequestsListLocked(__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
Definition: fxiotarget.cpp:582
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
unsigned char BOOLEAN
PFX_DRIVER_GLOBALS pFxDriverGlobals
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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  }
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734

Referenced by DrainPendedRequestsLocked(), and RemoveCompletedRequestLocked().

◆ ClearTargetPointers()

virtual VOID FxIoTarget::ClearTargetPointers ( VOID  )
inlineprotectedvirtual

Reimplemented in FxIoTargetRemote.

Definition at line 618 of file fxiotarget.hpp.

621  {
623  m_TargetPdo = NULL;
625 
626  m_TargetStackSize = 0;
628  }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
MdFileObject m_TargetFileObject
Definition: fxiotarget.hpp:923
MdDeviceObject m_TargetPdo
Definition: fxiotarget.hpp:918
UCHAR m_TargetIoType
Definition: fxiotarget.hpp:947
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941
#define NULL
Definition: types.h:112

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 
2219  m_SentIoEvent.Set();
2220  }
2221 
2222  DecrementIoCount();
2223 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
PVOID GetEvent(VOID)
Definition: fxwaitlock.hpp:172
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
__inline VOID CompleteRequest(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:580
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
BOOLEAN RemoveCompletedRequestLocked(__in FxRequestBase *Request)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
__inline VOID DecrementIoCount(VOID)
Definition: fxiotarget.hpp:785
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 }
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID FailPendedRequest(__in FxRequestBase *Request, __in NTSTATUS Status)
#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
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PSINGLE_LIST_ENTRY ple
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
Definition: typedefs.h:119
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static __inline FxRequestBase * _FromListEntry(__in PLIST_ENTRY Entry)

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  }
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

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

◆ Construct()

VOID FxIoTarget::Construct ( VOID  )
private

Definition at line 54 of file fxiotarget.cpp.

57 {
60 
61  m_InStack = TRUE;
62 
64 
66  m_Removing = FALSE;
68 
69  m_Driver = NULL;
72  m_TargetPdo = 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 }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
LONG m_IoCount
Definition: fxiotarget.hpp:935
FxTransactionedEntry m_TransactionedEntry
Definition: fxiotarget.hpp:853
#define TRUE
Definition: types.h:120
VOID MarkPassiveDispose(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:944
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
VOID SetTransactionedObject(__in FxObject *Object)
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
MdDeviceObject m_InStackDevice
Definition: fxiotarget.hpp:905
FxDriver * m_Driver
Definition: fxiotarget.hpp:900
#define FALSE
Definition: types.h:117
BOOLEAN m_AddedToDeviceList
Definition: fxiotarget.hpp:860
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
MdFileObject m_TargetFileObject
Definition: fxiotarget.hpp:923
MdDeviceObject m_TargetPdo
Definition: fxiotarget.hpp:918
BOOLEAN m_InStack
Definition: fxiotarget.hpp:855
BOOLEAN m_Removing
Definition: fxiotarget.hpp:955
UCHAR m_TargetIoType
Definition: fxiotarget.hpp:947
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
FxCREvent * m_DisposeEvent
Definition: fxiotarget.hpp:885
static VOID _RequestCancelled(__in FxIrpQueue *Queue, __in MdIrp Irp, __in PMdIoCsqIrpContext pCsqContext, __in KIRQL CallerIrql)
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
VOID Initialize(__in FxNonPagedObject *LockObject, __in PFN_IRP_QUEUE_CANCEL Callback)
Definition: fxirpqueue.cpp:61
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873
FxIrpQueue m_PendedQueue
Definition: fxiotarget.hpp:895

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
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define FALSE
Definition: types.h:117
MdFileObject m_TargetFileObject
Definition: fxiotarget.hpp:923
BOOLEAN m_InStack
Definition: fxiotarget.hpp:855
VOID SetNextStackFlags(__in UCHAR Flags)
Definition: fxirpum.cpp:1556
VOID SetNextStackFileObject(_In_ MdFileObject FileObject)
Definition: fxirpum.cpp:1573
MdFileObject GetCurrentStackFileObject(VOID)
Definition: fxirpum.cpp:1258
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) {
797  m_DisposeEvent->Set();
798  }
799  }
LONG m_IoCount
Definition: fxiotarget.hpp:935
VOID PrintDisposeMessage(VOID)
Definition: fxiotarget.cpp:99
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
long LONG
Definition: pedump.c:60
#define ASSERT(a)
Definition: mode.c:44
int ret
#define InterlockedDecrement
Definition: armddk.h:52
FxCREvent * m_DisposeEvent
Definition: fxiotarget.hpp:885
#define NULL
Definition: types.h:112

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

◆ Dispose()

BOOLEAN FxIoTarget::Dispose ( VOID  )
protectedvirtual

Reimplemented from FxObject.

Reimplemented in FxUsbPipe, and FxUsbDevice.

Definition at line 154 of file fxiotarget.cpp.

175 {
177 
178  if (m_AddedToDeviceList) {
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
#define FALSE
Definition: types.h:117
BOOLEAN m_AddedToDeviceList
Definition: fxiotarget.hpp:860
virtual VOID Remove(VOID)
#define ASSERT(a)
Definition: mode.c:44
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
__inline VOID CallCleanup(VOID)
Definition: fxobject.hpp:815
#define NULL
Definition: types.h:112

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();
431  pFxIrp->SkipCurrentIrpStackLocation();
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 }
__inline ULONG ClearTargetFlags(__in UCHAR Flags)
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
MdIrp GetNextRequest(__out PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:219
#define TRUE
Definition: types.h:120
_Must_inspect_result_ BOOLEAN CancelTimer(VOID)
FxRequest * pRequest
__inline FxIrp * GetSubmitFxIrp(VOID)
Definition: fxirp.hpp:28
VOID ClearCompletedRequestVerifierFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:814
FxIrp * pIrp
#define InsertTailList(ListHead, Entry)
LIST_ENTRY m_ListEntry
__inline UCHAR GetTargetFlags(VOID)
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
unsigned char BOOLEAN
__inline PVOID GetTraceObjectHandle(VOID)
IWudfIrp * MdIrp
Definition: mxum.h:103
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
__inline BOOLEAN CanComplete(VOID)
static __inline FxRequestBase * _FromCsqContext(__in PMdIoCsqIrpContext Context)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
__inline VOID SetTargetFlags(__in UCHAR Flags)
FxIrpQueue m_PendedQueue
Definition: fxiotarget.hpp:895
#define TRACINGIOTARGET
Definition: dbgtrace.h:72

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  //
1909  irp->SetStatus(Status);
1910  irp->SetInformation(0);
1911 
1912  //
1913  // Manaully process the irp as if it has completed back from the target.
1914  //
1916 }
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID RequestCompletionRoutine(__in FxRequestBase *Request)
Status
Definition: gdiplustypes.h:24
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
FxIrp * irp

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 {
2460  FxInternalIoctlOthersContext *pContext;
2462  NTSTATUS status;
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 {
2475  pContext = new(GetDriverGlobals()) FxInternalIoctlOthersContext();
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 }
VOID SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
const GLenum * bufs
Definition: glext.h:6026
PVOID Buffers[0x100]
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID CopyFileObjectAndFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:743
#define FX_REQUEST_NUM_OTHER_PARAMS
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ __in WDFIOTARGET __in_opt WDFREQUEST __in ULONG Ioctl
PVOID * GetNextStackParameterOthersArgument4Pointer()
Definition: fxirpum.cpp:1447
VOID ClearNextStackLocation(VOID)
Definition: fxirpum.cpp:1581
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PVOID * GetNextStackParameterOthersArgument2Pointer()
Definition: fxirpum.cpp:1434
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
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
return status
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
PVOID * GetNextStackParameterOthersArgument1Pointer()
Definition: fxirpum.cpp:1421
VOID StoreAndReferenceOtherMemories(__in FxRequestBuffer *Buffer1, __in FxRequestBuffer *Buffer2, __in FxRequestBuffer *Buffer4)
Definition: fxiotarget.hpp:129
VOID SetParameterIoctlCode(__in ULONG DeviceIoControlCode)
Definition: fxirpum.cpp:1157
unsigned int ULONG
Definition: retypes.h:1
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxIrp * irp
Definition: ps.c:97

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;
291  PVOID pBuffer;
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)) {
369  irp->SetSystemBuffer(pContext->m_BufferToFree);
370  setBufferAndLength = FALSE;
371  }
372  else {
373  irp->SetSystemBuffer(FxPoolAllocate(GetDriverGlobals(),
374  NonPagedPool,
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 }
VOID SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
VOID SetParameterIoctlType3InputBuffer(__in PVOID Type3InputBuffer)
Definition: fxirpum.cpp:1175
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define METHOD_DIRECT_TO_HARDWARE
#define METHOD_FROM_CTL_CODE(ctrlCode)
PMDL m_MdlToFree
Definition: fxiotarget.hpp:94
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID CopyFileObjectAndFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:743
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define METHOD_DIRECT_FROM_HARDWARE
VOID SetUserBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1341
size_t m_BufferToFreeLength
Definition: fxiotarget.hpp:102
_Must_inspect_result_ __in WDFIOTARGET __in_opt WDFREQUEST __in ULONG Ioctl
UCHAR m_MajorFunction
Definition: fxiotarget.hpp:114
PMDL * GetMdlAddressPointer()
Definition: fxirpum.cpp:1323
VOID SetParameterIoctlOutputBufferLength(__in ULONG OutputBufferLength)
Definition: fxirpum.cpp:1532
#define METHOD_NEITHER
Definition: nt_native.h:597
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
PVOID pBuffer
VOID ClearNextStackLocation(VOID)
Definition: fxirpum.cpp:1581
VOID SetSystemBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1313
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:859
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:949
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID SetParameterIoctlInputBufferLength(__in ULONG InputBufferLength)
Definition: fxirpum.cpp:1166
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID SetBufferAndLength(__in PVOID Buffer, __in size_t BufferLength, __in BOOLEAN CopyBackToBuffer)
BOOLEAN m_UnlockPages
Definition: fxiotarget.hpp:105
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PVOID GetSystemBuffer()
Definition: fxirpum.cpp:543
PVOID m_BufferToFree
Definition: fxiotarget.hpp:91
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define METHOD_BUFFERED
Definition: nt_native.h:594
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
UCHAR majorFunction
VOID SetParameterIoctlCode(__in ULONG DeviceIoControlCode)
Definition: fxirpum.cpp:1157
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID CaptureState(__in FxIrp *Irp)
BOOLEAN m_CopyBackToBuffer
Definition: fxiotarget.hpp:104
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
static SERVICE_STATUS status
Definition: service.c:31
size_t m_MdlToFreeSize
Definition: fxiotarget.hpp:103
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxIrp * irp
VOID StoreAndReferenceOtherMemory(__in FxRequestBuffer *Buffer)
Definition: fxiotarget.hpp:44
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: ps.c:97

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;
43  PVOID pBuffer;
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) {
108  case WdfDeviceIoBuffered:
110 
111  if (ioLength != 0) {
112 
113 
114  if ((pContext->m_BufferToFreeLength >= ioLength) &&
115  (pContext->m_BufferToFree != NULL)) {
116  irp->SetSystemBuffer(pContext->m_BufferToFree);
117  setBufferAndLength = FALSE;
118  }
119  else {
120  irp->SetSystemBuffer(FxPoolAllocate(GetDriverGlobals(),
121  NonPagedPool,
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;
184  case WdfDeviceIoDirect:
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  }
213  case WdfDeviceIoNeither:
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 
256  irp->SetNextParameterWriteLength(ioLength);
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 SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _IO_STACK_LOCATION::@3741::@3745 Read
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
PMDL m_MdlToFree
Definition: fxiotarget.hpp:94
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG DeviceOffset
Definition: wdfiotarget.h:859
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
struct _IO_STACK_LOCATION::@3741::@3746 Write
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID CopyFileObjectAndFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:743
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID SetUserBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1341
size_t m_BufferToFreeLength
Definition: fxiotarget.hpp:102
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
UCHAR m_MajorFunction
Definition: fxiotarget.hpp:114
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
PMDL * GetMdlAddressPointer()
Definition: fxirpum.cpp:1323
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
PVOID pBuffer
VOID ClearNextStackLocation(VOID)
Definition: fxirpum.cpp:1581
VOID SetSystemBuffer(__in PVOID Value)
Definition: fxirpum.cpp:1313
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID SetNextParameterWriteLength(__in ULONG IoLength)
Definition: fxirpum.cpp:1398
VOID SetNextParameterWriteByteOffsetQuadPart(__in LONGLONG DeviceOffset)
Definition: fxirpum.cpp:1385
VOID SetBufferAndLength(__in PVOID Buffer, __in size_t BufferLength, __in BOOLEAN CopyBackToBuffer)
BOOLEAN m_UnlockPages
Definition: fxiotarget.hpp:105
UCHAR m_TargetIoType
Definition: fxiotarget.hpp:947
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PVOID GetSystemBuffer()
Definition: fxirpum.cpp:543
PVOID m_BufferToFree
Definition: fxiotarget.hpp:91
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
VOID CaptureState(__in FxIrp *Irp)
BOOLEAN m_CopyBackToBuffer
Definition: fxiotarget.hpp:104
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
static SERVICE_STATUS status
Definition: service.c:31
size_t m_MdlToFreeSize
Definition: fxiotarget.hpp:103
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxIrp * irp
Definition: ps.c:97

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  }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_In_ PIRP Irp
Definition: csq.h:116

◆ 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  }
CfxDevice * m_Device
Definition: fxobject.hpp:329
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237

◆ GetDriver()

__inline FxDriver* FxIoTarget::GetDriver ( VOID  )
inline

Definition at line 316 of file fxiotarget.hpp.

319  {
320  return m_Driver;
321  }
FxDriver * m_Driver
Definition: fxiotarget.hpp:900

◆ GetHandle()

◆ 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 }
#define TRUE
Definition: types.h:120
FxRequest * pRequest
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PSINGLE_LIST_ENTRY ple
#define FALSE
Definition: types.h:117
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
static const PVOID m_SentRequestTag
Definition: fxiotarget.hpp:862
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: typedefs.h:119
SINGLE_LIST_ENTRY m_DrainSingleEntry
static __inline FxRequestBase * _FromListEntry(__in PLIST_ENTRY Entry)

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  }
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928

◆ GetTargetDevice()

__inline MdDeviceObject FxIoTarget::GetTargetDevice ( VOID  )
inline

Definition at line 272 of file fxiotarget.hpp.

275  {
276  return m_TargetDevice;
277  }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910

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  }
MdFileObject m_TargetFileObject
Definition: fxiotarget.hpp:923

◆ 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  }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
GLbitfield flags
Definition: glext.h:7161
MxDeviceObject deviceObject
unsigned int ULONG
Definition: retypes.h:1
ULONG GetFlags(VOID)

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  }
MdDeviceObject m_TargetPdo
Definition: fxiotarget.hpp:918

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.",
877  GetObjectHandle());
878 
880  }
881  }
882  else {
883  wait = TRUE;
884  }
885  break;
886 
887  case WdfIoTargetPurgeIo:
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  //
909  m_SentIoEvent.Set();
910  }
911 
912  if (LockSelf) {
913  Unlock(irql);
914  }
915 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
VOID DrainPendedRequestsLocked(__in PLIST_ENTRY RequestListHead, __in BOOLEAN RequestWillBeResent)
Definition: fxiotarget.cpp:395
VOID GetSentRequestsListLocked(__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
Definition: fxiotarget.cpp:582
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
VOID Clear(VOID)
Definition: fxwaitlock.hpp:152
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxVerifierDbgBreakPoint(pFxDriverGlobals)
KIRQL irql

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.",
987  GetObjectHandle());
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  //
1044  m_SentIoEvent.Clear();
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  //
1054  m_SentIoEvent.Set();
1055  }
1056  }
1057 
1058  if (Lock) {
1059  Unlock(irql);
1060  }
1061 
1062  return;
1063 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
VOID DrainPendedRequestsLocked(__in PLIST_ENTRY RequestListHead, __in BOOLEAN RequestWillBeResent)
Definition: fxiotarget.cpp:395
VOID GetSentRequestsListLocked(__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
Definition: fxiotarget.cpp:582
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
VOID Clear(VOID)
Definition: fxwaitlock.hpp:152
BOOLEAN m_Removing
Definition: fxiotarget.hpp:955
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
virtual VOID ClearTargetPointers(VOID)
Definition: fxiotarget.hpp:618
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 
316  ADDREF(START_TAG);
317 
318  if (Lock) {
320  }
321 
322 CheckState:
323  if (m_State == WdfIoTargetDeleted) {
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.",
337  GetObjectHandle());
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  //
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 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
#define CheckState(OldState, NewState)
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
VOID DrainPendedRequestsLocked(__in PLIST_ENTRY RequestListHead, __in BOOLEAN RequestWillBeResent)
Definition: fxiotarget.cpp:395
#define RELEASE(_tag)
Definition: fxobject.hpp:50
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define START_TAG
Definition: fxiotarget.cpp:302
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define ADDREF(_tag)
Definition: fxobject.hpp:49
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID Clear(VOID)
Definition: fxwaitlock.hpp:152
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
return status
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxVerifierDbgBreakPoint(pFxDriverGlobals)
KIRQL irql
Definition: ps.c:97

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.",
698  GetObjectHandle());
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  //
739  m_SentIoEvent.Set();
740  }
741 
742  if (LockSelf) {
743  Unlock(irql);
744  }
745 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
VOID GetSentRequestsListLocked(__in PSINGLE_LIST_ENTRY RequestListHead, __in PLIST_ENTRY SendList, __out PBOOLEAN AddedToList)
Definition: fxiotarget.cpp:582
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
VOID Clear(VOID)
Definition: fxwaitlock.hpp:152
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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",
2297  m_SentIoEvent.Set();
2298  }
2299 
2300  DecrementIoCount();
2301 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
PVOID GetEvent(VOID)
Definition: fxwaitlock.hpp:172
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
__inline VOID CompleteRequest(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:580
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
BOOLEAN RemoveCompletedRequestLocked(__in FxRequestBase *Request)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
__inline VOID DecrementIoCount(VOID)
Definition: fxiotarget.hpp:785
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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  }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941

◆ HasValidStackSize()

__inline BOOLEAN FxIoTarget::HasValidStackSize ( VOID  )

Definition at line 250 of file fxiotargetkm.hpp.

253 {
254  return (m_TargetStackSize == 0 ? FALSE : TRUE);
255 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941

◆ 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  }
LONG m_IoCount
Definition: fxiotarget.hpp:935
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
long LONG
Definition: pedump.c:60
#define ASSERT(a)
Definition: mode.c:44
int ret
#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 {
1123  NTSTATUS status;
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 ||
1146  m_TargetDevice == NULL || m_TargetPdo == 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 }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
CCHAR GetStackSize(VOID)
LONG NTSTATUS
Definition: precomp.h:26
VOID SetDeviceBase(__in CfxDeviceBase *DeviceBase)
Definition: fxobject.hpp:797
_Must_inspect_result_ NTSTATUS InitModeSpecific(__in CfxDeviceBase *Device)
MdDeviceObject m_InStackDevice
Definition: fxiotarget.hpp:905
FxDriver * m_Driver
Definition: fxiotarget.hpp:900
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
MdDeviceObject m_TargetPdo
Definition: fxiotarget.hpp:918
UCHAR GetTargetIoType(VOID)
Definition: fxiotarget.hpp:631
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
UCHAR m_TargetIoType
Definition: fxiotarget.hpp:947
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
MxDeviceObject deviceObject
virtual _Must_inspect_result_ MdDeviceObject GetTargetDeviceObject(_In_ CfxDeviceBase *Device)
Definition: fxiotarget.hpp:326
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CCHAR m_TargetStackSize
Definition: fxiotarget.hpp:941
return status
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
Definition: ps.c:97

Referenced by 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 UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define STATUS_SUCCESS
Definition: shellext.h:65
#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 {
2021  NTSTATUS status;
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 
2042  status = m_PendedQueue.InsertTailRequest(irp->GetIrp(), &Request->m_CsqContext, NULL);
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 }
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN IsCurrentIrpStackLocationValid(VOID)
Definition: fxirpum.cpp:1761
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID SetNextIrpStackLocation(VOID)
Definition: fxirpum.cpp:1235
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
_Must_inspect_result_ NTSTATUS InsertTailRequest(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext CsqContext, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:115
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
return status
#define NULL
Definition: types.h:112
FxIrpQueue m_PendedQueue
Definition: fxiotarget.hpp:895
FxIrp * irp
Definition: ps.c:97

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 }
PVOID GetEvent(VOID)
Definition: fxwaitlock.hpp:172
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
FxCREvent * m_DisposeEvent
Definition: fxiotarget.hpp:885
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define TRACINGIOTARGET
Definition: dbgtrace.h:72

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 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
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
VOID CompletePendedRequestList(__in PLIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:520
Definition: ntbasedef.h:628
#define TRUE
Definition: types.h:120
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
unsigned char BOOLEAN
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: typedefs.h:119
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 }
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
#define STATUS_SUCCESS
Definition: shellext.h:65

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 }
VOID CompletePendedRequestList(__in PLIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:520
Definition: ntbasedef.h:628
#define TRUE
Definition: types.h:120
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: typedefs.h:119
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
virtual VOID WaitForDisposeEvent(VOID)
Definition: fxiotarget.cpp:124
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
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
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550

Referenced by Dispose().

◆ 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 TRUE
Definition: types.h:120
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID ClearCompletedRequestVerifierFlags(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:814
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN m_Removing
Definition: fxiotarget.hpp:955
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
virtual VOID ClearTargetPointers(VOID)
Definition: fxiotarget.hpp:618
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873
unsigned int ULONG
Definition: retypes.h:1
#define TRACINGIOTARGET
Definition: dbgtrace.h:72

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",
2395  m_SentIoEvent.Set();
2396  }
2397 
2398  if (completeRequest) {
2399  DecrementIoCount();
2400  }
2401 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
PVOID GetEvent(VOID)
Definition: fxwaitlock.hpp:172
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
VOID Set(VOID)
Definition: fxwaitlock.hpp:144
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
FxCREvent m_SentIoEvent
Definition: fxiotarget.hpp:878
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
__inline VOID CompleteRequest(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:580
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
BOOLEAN RemoveCompletedRequestLocked(__in FxRequestBase *Request)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
__inline VOID DecrementIoCount(VOID)
Definition: fxiotarget.hpp:785
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 }
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218

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  }
#define TRUE
Definition: types.h:120
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
MdDeviceObject m_InStackDevice
Definition: fxiotarget.hpp:905
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
static MdCompletionRoutineType _RequestCompletionRoutine
Definition: fxiotarget.hpp:609
FxIrp * irp

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
LONG NTSTATUS
Definition: precomp.h:26
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
Definition: typedefs.h:119
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxiotarget.cpp:306
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
return status
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
VOID SubmitPendedRequests(__in PLIST_ENTRY RequestListHeadHead)
Definition: fxiotarget.cpp:268
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
Definition: ps.c:97

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 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
Definition: ntbasedef.h:628
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define TRUE
Definition: types.h:120
BOOLEAN m_WaitingForSentIo
Definition: fxiotarget.hpp:953
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
unsigned char BOOLEAN
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
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
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
KIRQL irql

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 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
GLuint64EXT * result
Definition: glext.h:11304
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG SubmitLocked(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in ULONG Flags)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
unsigned int ULONG
Definition: retypes.h:1
KIRQL irql

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 {
1286  NTSTATUS status;
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 {
1412  action |= SubmitQueued;
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 
1440 Done:
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  //
1457  IncrementIoCount();
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  //
1511  action |= SubmitQueued;
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) {
1528  InsertTailList(&m_IgnoredIoListHead, &Request->m_ListEntry);
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 
1609 CheckError:
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)) {
1615  irp->SetStatus(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);
1629  DecrementIoCount();
1630  }
1631 
1632  return action;
1633 }
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
_Must_inspect_result_ NTSTATUS PendRequestLocked(__in FxRequestBase *Request)
#define TRUE
Definition: types.h:120
#define WDF_REQUEST_SEND_INTERNAL_OPTION_FAIL_ON_PEND
LONG NTSTATUS
Definition: precomp.h:26
Definition: fxirp.hpp:28
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define InsertTailList(ListHead, Entry)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
__inline VOID IncrementIoCount(VOID)
Definition: fxiotarget.hpp:767
static void startTimer(void)
Definition: xmllint.c:468
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
unsigned char BOOLEAN
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
BOOLEAN m_Removing
Definition: fxiotarget.hpp:955
void CheckError(HRESULT hr)
Definition: shellclasses.h:167
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
BOOLEAN FxVerifierIO
Definition: fxglobals.h:446
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
const WCHAR * action
Definition: action.c:7783
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
return status
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
VOID SetCompletionRoutine(__in FxRequestBase *Request)
Definition: fxiotarget.hpp:834
LIST_ENTRY m_IgnoredIoListHead
Definition: fxiotarget.hpp:873
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_WDF_QUEUED
Definition: wdfstatus.h:81
__inline VOID DecrementIoCount(VOID)
Definition: fxiotarget.hpp:785
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxIrp * irp
#define DO_NOTHING()
Definition: mxgeneral.h:32
Definition: ps.c:97

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

◆ SubmitPendedRequest()

VOID FxIoTarget::SubmitPendedRequest ( __in FxRequestBase Request)

Definition at line 206 of file fxiotarget.cpp.

209 {
210  ULONG action;
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