ReactOS  0.4.15-dev-2703-g05fb0f1
fxirpqueue.hpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxIrpQueue.hpp
8 
9 Abstract:
10 
11  This module implements a common queue structure for the
12  driver frameworks built around the Cancel Safe Queues pattern
13 
14 Author:
15 
16 
17 
18 
19 
20 
21 Environment:
22 
23  Both kernel and user mode
24 
25 Revision History:
26 
27 
28 --*/
29 
30 #ifndef _FXIRPQUEUE_H_
31 #define _FXIRPQUEUE_H_
32 
33 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
34 #include "fxirpkm.hpp"
35 #else
36 #include "fxirpum.hpp"
37 #endif
38 
39 
40 //
41 // IRP DriverContext[] entry used.
42 //
43 // We use the same entry that the CSQ package does
44 // which is OK since we can't use CSQ if we implement the
45 // cancel handler ourselves
46 //
47 #define FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY 3
48 
49 //
50 // FxIrpQueue entry identifier
51 //
52 #define FX_IRP_QUEUE_ENTRY_IDENTIFIER 1
53 
54 #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
55 #include "fxirpkm.hpp"
56 #elif ((FX_CORE_MODE)==(FX_CORE_USER_MODE))
57 #include "fxirpum.hpp"
58 #endif
59 
60 
61 //
62 // This is the cancel function callback for the IrpQueue to its caller/parent
63 // This is called holding the lock of the object owning the IrpQueue, and it
64 // is responsible for completing the IRP.
65 //
66 
67 extern "C" {
68 __drv_functionClass(EVT_IRP_QUEUE_CANCEL)
70 typedef
71 VOID
72 EVT_IRP_QUEUE_CANCEL (
77  );
78 
79 typedef EVT_IRP_QUEUE_CANCEL *PFN_IRP_QUEUE_CANCEL;
80 }
81 
82 class FxIrpQueue {
83 
84  friend VOID GetTriageInfo(VOID);
85 
86 private:
87 
88  //
89  // The Queue
90  //
92 
93  //
94  // The object whose lock controls the queue.
95  // Provided by the client object.
96  //
98 
99  //
100  // Callers registered cancel callback
101  //
103 
104  //
105  // Count of requests in the Queue
106  //
108 
109 public:
110 
111  FxIrpQueue(
112  VOID
113  );
114 
115  ~FxIrpQueue(
116  VOID
117  );
118 
119  VOID
120  Initialize(
123  );
124 
126  NTSTATUS
128  __inout MdIrp Irp,
129  __in_opt PMdIoCsqIrpContext CsqContext,
130  __out_opt ULONG* pRequestCount
131  );
132 
134  NTSTATUS
136  __inout MdIrp Irp,
137  __in_opt PMdIoCsqIrpContext CsqContext,
138  __out_opt ULONG* pRequestCount
139  );
140 
141  MdIrp
144  );
145 
147  NTSTATUS
149  __in_opt PMdIoCsqIrpContext TagContext,
151  __out FxRequest** ppOutRequest
152  );
153 
155  NTSTATUS
156  PeekRequest(
157  __in_opt PMdIoCsqIrpContext TagContext,
159  __out FxRequest** ppOutRequest
160  );
161 
162  MdIrp
165  );
166 
167  //
168  // Return whether the queue is empty
169  // (for optimizing the non-pending case in the caller)
170  //
171  inline
172  BOOLEAN
174 
175  if( IsListEmpty(&m_Queue) ) {
176 
177  ASSERT(m_RequestCount == 0);
178 
179  return TRUE;
180  }
181  else {
182  ASSERT(m_RequestCount != 0);
183 
184  return FALSE;
185  }
186  }
187 
188  //
189  // Return count of queued and driver pending requests.
190  //
191  inline
192  LONG
194  return m_RequestCount;
195  }
196 
197  BOOLEAN
198  IsIrpInQueue(
200  );
201 
202 
203 private:
204 
205  //
206  // Insert an IRP on the cancel list
207  //
209  NTSTATUS
211  __inout MdIrp Irp,
213  __in BOOLEAN InsertInHead,
214  __out_opt ULONG* pRequestCount
215  );
216 
217  // Do not specify argument names
219  VOID,
220  VerifyRemoveIrpFromQueueByContext,
222  );
223 
224  //
225  // Ask to remove an IRP from the cancel list by Context,
226  // and return NULL if its been cancelled
227  //
228  MdIrp
231  );
232 
233  //
234  // Remove a request from the head of the queue if PeekContext == NULL,
235  // or the next request after PeekContext if != NULL
236  //
237  MdIrp
241  );
242 
243  //
244  // Peek an IRP in the queue
245  //
246  MdIrp
250  );
251 
252  //
253  // Unconditionally remove the IRP from the list entry
254  //
255  inline
256  VOID
258  __inout FxIrp* Irp
259  )
260  {
261  PLIST_ENTRY entry = Irp->ListEntry();
264  m_RequestCount--;
265  ASSERT(m_RequestCount >= 0);
266  }
267 
268  //
269  // WDM IRP cancel function
270  //
271  static
274 
275  //
276  // Lock functions accessed from WDM cancel callback
277  //
278  __inline
279  void
281  __out PKIRQL PreviousIrql
282  )
283  {
284  m_LockObject->Lock(PreviousIrql);
285  }
286 
287  __inline
288  void
290  __in KIRQL PreviousIrql
291  )
292  {
293  m_LockObject->Unlock(PreviousIrql);
294  }
295 };
296 
297 #endif // _FXIRPQUEUE_H
__in MdIrp __in PMdIoCsqIrpContext __in KIRQL CallerIrql
Definition: fxirpqueue.hpp:74
FxNonPagedObject * m_LockObject
Definition: fxirpqueue.hpp:97
friend VOID GetTriageInfo(VOID)
LONG m_RequestCount
Definition: fxirpqueue.hpp:107
#define _Must_inspect_result_
Definition: no_sal2.h:62
__in MdIrp __in PMdIoCsqIrpContext pCsqContext
Definition: fxirpqueue.hpp:74
_Must_inspect_result_ NTSTATUS InsertHeadRequest(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext CsqContext, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:168
BOOLEAN IsIrpInQueue(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:931
MdIrp GetNextRequest(__out PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:219
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
LONG NTSTATUS
Definition: precomp.h:26
Definition: fxirp.hpp:28
PFN_IRP_QUEUE_CANCEL m_CancelCallback
Definition: fxirpqueue.hpp:102
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
~FxIrpQueue(VOID)
Definition: fxirpqueue.cpp:55
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
EVT_IRP_QUEUE_CANCEL * PFN_IRP_QUEUE_CANCEL
Definition: fxirpqueue.hpp:79
#define LockObject(Object, Irql)
Definition: titypes.h:34
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
LIST_ENTRY m_Queue
Definition: fxirpqueue.hpp:91
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define __out_opt
Definition: dbghelp.h:65
VOID RemoveIrpFromListEntry(__inout FxIrp *Irp)
Definition: fxirpqueue.hpp:257
#define FALSE
Definition: types.h:117
MdIrp RemoveNextIrpFromQueue(__in_opt PVOID PeekContext, __out_opt PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:787
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
__drv_functionClass(EVT_IRP_QUEUE_CANCEL) __drv_requiresIRQL(DISPATCH_LEVEL) typedef VOID EVT_IRP_QUEUE_CANCEL(__in FxIrpQueue *Queue
#define __out
Definition: dbghelp.h:62
LONG GetRequestCount()
Definition: fxirpqueue.hpp:193
unsigned char BOOLEAN
IWudfIrp * MdIrp
Definition: mxum.h:103
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
MdIrp RemoveRequest(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:478
__inline void LockFromCancel(__out PKIRQL PreviousIrql)
Definition: fxirpqueue.hpp:280
_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 __drv_requiresIRQL(irql)
Definition: driverspecs.h:303
uint32_t entry
Definition: isohybrid.c:63
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define __inout
Definition: dbghelp.h:50
Definition: typedefs.h:119
WUDF_DRIVER_CANCEL MdCancelRoutineType
Definition: mxum.h:143
static MdCancelRoutineType _WdmCancelRoutineInternal
Definition: fxirpqueue.hpp:273
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
MdIrp PeekNextIrpFromQueue(__in_opt MdIrp Irp, __in_opt PVOID PeekContext)
Definition: fxirpqueue.cpp:724
FX_DECLARE_VF_FUNCTION_P1(VOID, VerifyRemoveIrpFromQueueByContext, __in PMdIoCsqIrpContext)
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
MdIrp RemoveIrpFromQueueByContext(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:671
__inline void UnlockFromCancel(__in KIRQL PreviousIrql)
Definition: fxirpqueue.hpp:289
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:159
VOID Initialize(__in FxNonPagedObject *LockObject, __in PFN_IRP_QUEUE_CANCEL Callback)
Definition: fxirpqueue.cpp:61
FxIrpQueue(VOID)
Definition: fxirpqueue.cpp:42
BOOLEAN IsQueueEmpty()
Definition: fxirpqueue.hpp:173
unsigned int ULONG
Definition: retypes.h:1
#define __in
Definition: dbghelp.h:35
_Must_inspect_result_ NTSTATUS InsertIrpInQueue(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext Context, __in BOOLEAN InsertInHead, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:505
_Must_inspect_result_ NTSTATUS PeekRequest(__in_opt PMdIoCsqIrpContext TagContext, __in_opt MdFileObject FileObject, __out FxRequest **ppOutRequest)
Definition: fxirpqueue.cpp:306