ReactOS 0.4.15-dev-7958-gcd0bb1a
fxirpqueue.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxIrpQueue.cpp
8
9Abstract:
10
11 This module implements a common queue structure for the
12 driver frameworks built around the Cancel Safe Queue model
13
14Author:
15
16
17
18
19
20
21
22Environment:
23
24 Both kernel and user mode
25
26Revision History:
27
28
29--*/
30
31#include "coreprivshared.hpp"
32
33// Tracing support
34extern "C" {
35// #include "FxIrpQueue.tmh"
36}
37
38//
39// Public constructors
40//
41
43 VOID
44 )
45{
47
49
51
53}
54
56{
58}
59
60VOID
64 )
65
66/*++
67
68Routine Description:
69
70 Initialize the FxIrpQueue.
71
72 Set the callback for when an IRP gets cancelled.
73
74 The callback function is only called when an IRP
75 gets cancelled, and is called with no locks held.
76
77 The cancel function that the caller registers is
78 responsible for completing the IRP with IoCompleteRequest.
79
80 If no Cancel Callback is set, or is set to NULL, IRP's will
81 be automatically completed with STATUS_CANCELED by
82 the FxIrpQueue when they are canceled.
83
84
85 If the caller supplies a LockObject, this object is used
86 to synchronize cancellation access to the list, but it is
87 expected that the caller be holding the same lock for insert/remove
88 operations. This allows the caller to perform insert/remove operations
89 using its own lock in a race free manner.
90
91 If a LockObject is not supplied, the FxIrpQueue uses its own lock.
92
93Arguments:
94
95 LockObject - Object whose lock controls the queue
96
97 Callback - Driver callback function
98
99Returns:
100
101 None
102
103--*/
104
105{
107
110}
111
112
118 __out_opt ULONG* pRequestCount
119 )
120
121/*++
122
123Routine Description:
124
125 Enqueue a request to the end of the queue (FIFO) and
126 marks it as pending.
127
128 The PMdIoCsqIrpContext is associated with the IRP.
129
130 PIO_CSQ_IRP_CONTEXT must be in non-paged pool, and can
131 not be released until the IRP is is finally released from
132 the queue.
133
134Arguments:
135
136 Irp - Pointer to IRP
137
138 Context - Pointer to caller allocated CSQ context
139
140 pRequestCount - Location to return new request count of queue
141 after insertion
142
143Returns:
144
145 STATUS_SUCCESS - Operation completed.
146
147 STATUS_CANCELLED - Request was cancelled, and not inserted
148 Call is responsible for completing it.
149--*/
150
151{
153
154 // Note: This marks the IRP Pending
156 Irp, // Irp to insert
157 Context, // PIO_CSQ_IRP_CONTEXT
158 FALSE, // InsertInHead
159 pRequestCount
160 );
161
162 return Status;
163}
164
165
171 __out_opt ULONG* pRequestCount
172 )
173
174/*++
175
176Routine Description:
177
178 Enqueue a request to the head of the queue and
179 marks it as pending.
180
181 The PIO_CSQ_IRP_CONTEXT is associated with the IRP.
182
183 PIO_CSQ_IRP_CONTEXT must be in non-paged pool, and can
184 not be released until the IRP is is finally released from
185 the queue.
186
187Arguments:
188
189 Irp - Pointer to IRP
190
191 Context - Pointer to caller allocated CSQ context
192
193 pRequestCount - Location to return new request count of queue
194 after insertion
195Returns:
196
197 STATUS_SUCCESS - Operation completed.
198
199 STATUS_CANCELLED - Request was cancelled, and not inserted
200 Call is responsible for completing it.
201--*/
202
203{
205
206 // Note: This marks the IRP Pending
208 Irp, // Irp to insert
209 Context, // PIO_CSQ_IRP_CONTEXT
210 TRUE, // InsertInHead
211 pRequestCount
212 );
213
214 return Status;
215}
216
217
218MdIrp
221 )
222
223/*++
224
225Routine Description:
226
227 Returns an IRP from the queue, and if successful
228 the IRP is no longer on the CSQ (m_Queue) and
229 is not non-cancellable.
230
231--*/
232
233{
235}
236
237
241 __in_opt PMdIoCsqIrpContext TagContext,
243 __out FxRequest** ppOutRequest
244 )
245
246/*++
247
248Routine Description:
249
250 Returns a request from the queue using an optional
251 FileObject or TagContext.
252
253--*/
254
255{
256 MdIrp Irp;
259
260 if( TagContext == NULL ) {
261
262 //
263 // Returns an IRP from the queue, and if successful
264 // the IRP is no longer on the CSQ (m_Queue) and
265 // is not non-cancellable.
266 //
268 FileObject, // PeekContext
270 );
271
272 if( Irp != NULL ) {
273
275
276 *ppOutRequest = pRequest;
277
278 return STATUS_SUCCESS;
279 }
280 else {
282 }
283 }
284 else {
285
286 // Handle TagRequest Case
288 TagContext
289 );
290
291 if( Irp != NULL ) {
293
294 *ppOutRequest = pRequest;
295
296 return STATUS_SUCCESS;
297 }
298 else {
299 return STATUS_NOT_FOUND;
300 }
301 }
302}
303
307 __in_opt PMdIoCsqIrpContext TagContext,
309 __out FxRequest** ppOutRequest
310 )
311
312/*++
313
314Routine Description:
315
316 PeekRequest allows a caller to enumerate through requests in
317 a queue, optionally only returning requests that match a specified
318 FileObject.
319
320 The first call specifies TagContext == NULL, and the first request
321 in the queue that matches the FileObject is returned.
322
323 Subsequent requests specify the previous request value as the
324 TagContext, and searching will continue at the request that follows.
325
326 If the queue is empty, there are no requests after TagContext, or no
327 requests match the FileObject, NULL is returned.
328
329 If FileObject == NULL, this matches any FileObject in a request.
330
331 If a WDF_REQUEST_PARAMETERS structure is supplied, the information
332 from the request is returned to allow the driver to further examine
333 the request to decide whether to service it.
334
335 If a TagRequest is specified, and it is not found, the return
336 status STATUS_NOT_FOUND means that the queue should
337 be re-scanned. This is because the TagRequest was cancelled from
338 the queue, or if the queue was active, delivered to the driver.
339 There may still be un-examined requests on the queue that match
340 the drivers search criteria, but the search marker has been lost.
341
342 Re-scanning the queue starting with TagRequest == NULL and
343 continuing until STATUS_NO_MORE_ENTRIES is returned will ensure
344 all requests have been examined.
345
346 Enumerating an active queue with this API could result in the
347 driver frequently having to re-scan.
348
349 If a successful return of a Request object handle occurs, the driver
350 *must* call WdfObjectDereference when done with it.
351
352 NOTE: Synchronization Details
353
354 The driver is allowed to "peek" at requests that are still on
355 the Cancel Safe Queue without removing them. This means that
356 the peek context value used (TagRequest) could go away while
357 still holding it. This does not seem bad in itself, but the request
358 could immediately be re-used by a look aside list and be re-submitted
359 to the queue. At this point, the "tag" value means a completely different
360 request.
361
362 This race is dealt with by reference counting the FxRequest object
363 that contains our PIO_CSQ_IRP_CONTEXT, so its memory remains valid
364 after a cancel, and the driver explicitly releases it with
365 WdfObjectDereference.
366
367 But if this reference is not added under the CSQ's spinlock, there
368 could be a race in which the I/O gets cancelled and the cancel
369 callback completes the request, before we add our reference count.
370 This would then result in attempting to reference count invalid
371 memory. So to close this race, this routine returns the referenced
372 FxRequest object as its result.
373
374Arguments:
375
376 TagRequest - If !NULL, request to begin search at
377
378 FileObject - If !NULL, FileObject to match in the request
379
380
381Returns:
382
383 STATUS_NOT_FOUND - TagContext was specified, but not
384 found in the queue. This could be
385 because the request was cancelled,
386 or is part of an active queue and
387 the request was passed to the driver
388 or forwarded to another queue.
389
390 STATUS_NO_MORE_ENTRYS - The queue is empty, or no more requests
391 match the selection criteria of TagRequest
392 and FileObject specified above.
393
394 STATUS_SUCCESS - A request context was returned in
395 pOutRequest.
396
397--*/
398
399{
400 PLIST_ENTRY nextEntry;
401 FxIrp nextIrp(NULL);
403 BOOLEAN FoundTag = (TagContext == NULL) ? TRUE : FALSE;
405
406 for( nextEntry = m_Queue.Flink; nextEntry != &this->m_Queue; nextEntry = nextEntry->Flink) {
407
408 nextIrp.SetIrp(FxIrp::GetIrpFromListEntry(nextEntry));
409
410 if(nextIrp.IsCanceled()) {
411 //
412 // This IRP is cancelled and the WdmCancelRoutine is about to run or waiting
413 // for us to drop the lock. So skip this one.
414 //
415 continue;
416 }
417
419
420 if( FoundTag ) {
421
422 if( FileObject != NULL ) {
423
424 if(nextIrp.GetFileObject() == FileObject ) {
425
427
428 //
429 // Must add the reference here under the protection
430 // of the cancel safe queues spinlock
431 //
432 pRequest->ADDREF(NULL);
433
434 *ppOutRequest = pRequest;
435
436 return STATUS_SUCCESS;
437 }
438 }
439 else {
440
442
443 //
444 // Must add the reference here under the protection
445 // of the cancel safe queues spinlock
446 //
447 pRequest->ADDREF(NULL);
448
449 *ppOutRequest = pRequest;
450
451 return STATUS_SUCCESS;
452 }
453 }
454 else {
455
456 // If we found the tag, we want the *next* entry
457 if( pCsqContext == TagContext ) {
458 FoundTag = TRUE;
459 }
460 }
461
462 }
463
464 //
465 // If the caller supplied a tag, and it was
466 // not found, return a different code since
467 // the caller needs to re-scan the queue.
468 //
469 if( (TagContext != NULL) && !FoundTag ) {
470 return STATUS_NOT_FOUND;
471 }
472 else {
474 }
475}
476
477MdIrp
480 )
481/*++
482
483Routine Description:
484
485 Returns a request from the queue.
486
487--*/
488{
489 MdIrp Irp;
490
491 ASSERT(Context != NULL);
492
493 //
494 // Returns an IRP from the queue, and if success
495 // the IRP is no longer on the CSQ (m_Queue) and
496 // is not non-cancellable.
497 //
499
500 return Irp;
501}
502
508 __in BOOLEAN InsertInHead,
509 __out_opt ULONG* pRequestCount
510 )
511/*++
512
513Routine Description:
514
515 Insert the IRP in the queue. If the IRP is already cancelled
516 it removes the IRP from the queue and returns STATUS_CANCELLED.
517
518 If the IRP is cancelled and the CancelRoutine has already started
519 execution, then this function returns STATUS_SUCCESS.
520
521Arguments:
522
523 Irp - Pointer to IRP
524
525 Context - Pointer to caller allocated CSQ context
526
527 InsertInHead - TRUE for head, FALSE for tail.
528
529 pRequestCount - Location to return new request count of queue
530 after insertion
531
532Returns:
533
534 STATUS_SUCCESS - Operation completed.
535
536 STATUS_CANCELLED - if the request is already cancelled.
537
538--*/
539{
540 FxIrp irp(Irp);
541 MdCancelRoutine cancelRoutine;
543
544 //
545 // Set the association between the context and the IRP.
546 //
547
548 if (Context) {
550 Context->Irp = Irp;
551 Context->Csq = (PIO_CSQ)this;
552
553
554
555
556
557
558
559
560
561
563 } else {
564
565 //
566 // Currently always require context, but this will change when we
567 // allow queuing or low level IRP's without FxRequest headers allocated
568 //
569 ASSERT(FALSE);
570
572 }
573
574 // See if it's a head insertion
575 if( InsertInHead ) {
577 &m_Queue,
578 irp.ListEntry()
579 );
580 }
581 else {
583 &m_Queue,
584 irp.ListEntry()
585 );
586 }
587
589
590 if( pRequestCount != NULL ) {
591 *pRequestCount = m_RequestCount;
592 }
593
595
597
598 ASSERT(!cancelRoutine);
599 UNREFERENCED_PARAMETER(cancelRoutine);
600
601 if (irp.IsCanceled()) {
602
603 cancelRoutine = irp.SetCancelRoutine(NULL);
604
605 if (cancelRoutine) {
606
607 // Remove the IRP from the list
609
610 if (Context) {
611 Context->Irp = NULL;
612 }
613
615
616 //
617 // Caller does not want us to recurse on their lock by invoking
618 // the m_CancelCallback on the insert path. So they will complete
619 // the IRP themselves.
620 //
621 return STATUS_CANCELLED;
622 } else {
623
624 //
625 // The cancel routine beat us to it.
626 //
627 DO_NOTHING();
628 }
629
630 }
631
632 return status;
633}
634
635VOID
636FX_VF_METHOD(FxIrpQueue, VerifyRemoveIrpFromQueueByContext)(
637 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
639 )
640/*++
641
642Routine Description:
643
644 Makes sure that the specified Request (context) belongs to this IRP queue.
645
646--*/
647{
649
650 if (FxDriverGlobals->IsVerificationEnabled(1, 11, OkForDownLevel)) {
651 if (Context->Irp != NULL &&
653 Context->Csq != (PIO_CSQ)this)) {
654
655 //
656 // This should never happen. Bugcheck before corrupting memory.
657 //
659 "Irp 0x%p (Context 0x%p) not on IRP queue 0x%p\n",
660 Context->Irp, Context, this);
661
662 FxVerifierBugCheck(FxDriverGlobals,
666 }
667 }
668}
669
670MdIrp
673 )
674/*++
675
676Routine Description:
677
678 Using the context it remove the associated IRP from the queue.
679
680--*/
681{
682 MdIrp irp;
683 MdCancelRoutine cancelRoutine;
684
685 if (Context->Irp ) {
686 //
687 // Make sure the Irp belongs to this queue.
688 //
689 ASSERT(Context->Csq == (PIO_CSQ)this);
690 VerifyRemoveIrpFromQueueByContext(m_LockObject->GetDriverGlobals(),
691 Context);
692
693 irp = Context->Irp;
694
695 FxIrp fxIrp(irp);
696
697 cancelRoutine = fxIrp.SetCancelRoutine(NULL);
698 if (!cancelRoutine) {
699 return NULL;
700 }
701
703
705
706 //
707 // Break the association.
708 //
709
710 Context->Irp = NULL;
712
713 ASSERT(Context->Csq == (PIO_CSQ)this);
714
715 return irp;
716
717 } else {
718 return NULL;
719 }
720}
721
722
723MdIrp
727 )
728/*++
729
730Routine Description:
731
732 This API look up IRP's in the queue.
733
734 If Irp == NULL, it returns one from the head
735 of the queue.
736
737 If Irp != NULL, it is a "peek context", and the
738 routine returns the *next* IRP in the queue.
739
740--*/
741{
742 PLIST_ENTRY nextEntry;
743 PLIST_ENTRY listHead;
744 FxIrp irp(Irp);
745 FxIrp nextIrp(NULL);
746
747 listHead = &m_Queue;
748
749 //
750 // If the IRP is NULL, we will start peeking from the listhead, else
751 // we will start from that IRP onwards. This is done under the
752 // assumption that new IRPs are always inserted at the tail.
753 //
754
755 if(Irp == NULL) {
756 nextEntry = listHead->Flink;
757 } else {
758 nextEntry = irp.ListEntry()->Flink;
759 }
760
761 while(nextEntry != listHead) {
762
763 nextIrp.SetIrp(FxIrp::GetIrpFromListEntry(nextEntry));
764
765 //
766 // If PeekContext is supplied, it's a search for an IRP associated
767 // with a particular file object.
768 //
769 if(PeekContext) {
770
771 if(nextIrp.GetFileObject() == (MdFileObject) PeekContext) {
772 break;
773 }
774 } else {
775 break;
776 }
777
778 nextIrp.SetIrp(NULL);
779
780 nextEntry = nextEntry->Flink;
781 }
782
783 return nextIrp.GetIrp();
784}
785
786MdIrp
790 )
791/*++
792
793Routine Description:
794
795 This routine will return a pointer to the next IRP in the queue adjacent to
796 the irp passed as a parameter. If the irp is NULL, it returns the IRP at the head of
797 the queue.
798
799--*/
800{
802 MdCancelRoutine cancelRoutine;
804
806
807 for (;;) {
808
809 if (!fxIrp.GetIrp()) {
810 return NULL;
811 }
812
813 cancelRoutine = fxIrp.SetCancelRoutine(NULL);
814 if (!cancelRoutine) {
816 continue;
817 }
818
819 RemoveIrpFromListEntry(&fxIrp); // Remove this IRP from the queue
820
821 break;
822 }
823
826 context->Irp = NULL;
827 ASSERT(context->Csq == (PIO_CSQ)this);
828 }
829
830 if(pCsqContext != NULL) {
832 }
833
835
836 return fxIrp.GetIrp();
837}
838
839
840VOID
844 )
845/*++
846
847Routine Description:
848
849 This is the function called by WDM on the IRP when a cancel occurs
850
851--*/
852{
853 PMdIoCsqIrpContext irpContext;
854 FxIrpQueue* p;
855 KIRQL irql;
856 FxIrp irp(Irp);
857
859
860 Mx::ReleaseCancelSpinLock(irp.GetCancelIrql());
861
863
864 //
865 // Decide if we have a PIO_CSQ_IRP_CONTEXT or an FxIrpQueue*
866 //
867 if (irpContext->Type == FX_IRP_QUEUE_ENTRY_IDENTIFIER) {
868 p = (FxIrpQueue*)irpContext->Csq;
869 } else {
870 ASSERT(FALSE);
871 p = (FxIrpQueue*)irpContext;
872 }
873
874 ASSERT(p);
875
876 p->LockFromCancel(&irql);
877
878 // Remove the IRP from the list
879 p->RemoveIrpFromListEntry(&irp);
880
881 //
882 // Break the association if necessary.
883 //
884
885 if (irpContext != (PMdIoCsqIrpContext)p) {
886 irpContext->Irp = NULL;
887
889 }
890
891 //
892 // We are calling cancel-callback of the owning object with the lock
893 // held so that it can successfully deliver the canceled request to the driver
894 // if needed. If we don't hold the lock, we run into a race condition between
895 // thread that's deleting the queue and this routine that's trying to deliver
896 // a request to the queue being deleted. So the way it happens is that the dispose
897 // call of queue waits for the request count to go zero. When we remove the
898 // last Irp from the list above, we end up dropping the count to zero. This causes
899 // the delete thread to run thru and destroy the FxIoQueue object. So to avoid that
900 // after popping the request from the FxIrpQueue, we have to call into the FxIoQueue
901 // with the lock and insert the request back into the FxIoQueue list so that delete
902 // thread will wait until the request is delivered to the driver.
903 //
904 if( p->m_CancelCallback != NULL ) {
905 p->m_CancelCallback(p, Irp, irpContext, irql);
906 }
907 else {
908
909 p->UnlockFromCancel(irql);
910
911 //
912 // Dispose of the IRP ourselves
913 //
916
917 DoTraceLevelMessage(p->m_LockObject->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
918 "Irp 0x%p on Queue 0x%p Cancelled\n", Irp, p);
919
920 //
921 // Breakpoint for now. This usually means that someone
922 // is going to leak some driver frameworks state...
923 //
924 FxVerifierDbgBreakPoint(p->m_LockObject->GetDriverGlobals());
925
927 }
928}
929
933 )
934/*++
935
936Routine Description:
937 Enumerates the list to see if any of the IRPs there has
938 a context that matches the input one.
939
940--*/
941{
942 PLIST_ENTRY nextEntry;
943 FxIrp nextIrp(NULL);
945
946 nextEntry = m_Queue.Flink;
947
948 while( nextEntry != &m_Queue ) {
949 nextIrp.SetIrp(FxIrp::GetIrpFromListEntry(nextEntry));
950
952
953 if( pCsqContext == Context ) {
954 ASSERT(Context->Irp == nextIrp.GetIrp());
955 return TRUE;
956 }
957
958 nextEntry = nextEntry->Flink;
959 }
960
961 return FALSE;
962}
963
964
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
MdIrp RemoveRequest(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:478
VOID RemoveIrpFromListEntry(__inout FxIrp *Irp)
Definition: fxirpqueue.hpp:257
LONG m_RequestCount
Definition: fxirpqueue.hpp:107
_Must_inspect_result_ NTSTATUS InsertHeadRequest(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext CsqContext, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:168
_Must_inspect_result_ NTSTATUS PeekRequest(__in_opt PMdIoCsqIrpContext TagContext, __in_opt MdFileObject FileObject, __out FxRequest **ppOutRequest)
Definition: fxirpqueue.cpp:306
_Must_inspect_result_ NTSTATUS InsertTailRequest(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext CsqContext, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:115
MdIrp RemoveIrpFromQueueByContext(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:671
FxNonPagedObject * m_LockObject
Definition: fxirpqueue.hpp:97
MdIrp RemoveNextIrpFromQueue(__in_opt PVOID PeekContext, __out_opt PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:787
FxIrpQueue(VOID)
Definition: fxirpqueue.cpp:42
_Must_inspect_result_ NTSTATUS InsertIrpInQueue(__inout MdIrp Irp, __in_opt PMdIoCsqIrpContext Context, __in BOOLEAN InsertInHead, __out_opt ULONG *pRequestCount)
Definition: fxirpqueue.cpp:505
MdIrp PeekNextIrpFromQueue(__in_opt MdIrp Irp, __in_opt PVOID PeekContext)
Definition: fxirpqueue.cpp:724
static MdCancelRoutineType _WdmCancelRoutineInternal
Definition: fxirpqueue.hpp:273
BOOLEAN IsIrpInQueue(__in PMdIoCsqIrpContext Context)
Definition: fxirpqueue.cpp:931
VOID Initialize(__in FxNonPagedObject *LockObject, __in PFN_IRP_QUEUE_CANCEL Callback)
Definition: fxirpqueue.cpp:61
MdIrp GetNextRequest(__out PMdIoCsqIrpContext *pCsqContext)
Definition: fxirpqueue.cpp:219
~FxIrpQueue(VOID)
Definition: fxirpqueue.cpp:55
PFN_IRP_QUEUE_CANCEL m_CancelCallback
Definition: fxirpqueue.hpp:102
LIST_ENTRY m_Queue
Definition: fxirpqueue.hpp:91
Definition: fxirp.hpp:28
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
MdCancelRoutine SetCancelRoutine(__in_opt MdCancelRoutine CancelRoutine)
Definition: fxirpum.cpp:124
KIRQL GetCancelIrql()
Definition: fxirpum.cpp:492
MdFileObject GetFileObject(VOID)
Definition: fxirpum.cpp:1460
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
PLIST_ENTRY ListEntry()
Definition: fxirpum.cpp:535
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
PVOID GetContext(__in ULONG Index)
Definition: fxirpum.cpp:361
static MdIrp GetIrpFromListEntry(__in PLIST_ENTRY Ple)
Definition: fxirpum.cpp:1190
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
BOOLEAN IsCanceled()
Definition: fxirpum.cpp:484
VOID SetContext(__in ULONG Index, __in PVOID Value)
Definition: fxirpum.cpp:351
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
static __inline FxRequest * RetrieveFromCsqContext(__in PMdIoCsqIrpContext pCsqContext)
Definition: fxrequest.hpp:1163
_In_ PIRP Irp
Definition: csq.h:116
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:160
struct _IO_CSQ * PIO_CSQ
Definition: csq.h:69
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGREQUEST
Definition: dbgtrace.h:65
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
KIRQL irql
Definition: wave.h:1
#define __drv_useCancelIRQL
Definition: driverspecs.h:332
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxIrp fxIrp(Irp)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
@ OkForDownLevel
Definition: fxglobals.h:80
VOID __in PMdIoCsqIrpContext Context
Definition: fxirpqueue.cpp:647
__in MdIrp __in PMdIoCsqIrpContext pCsqContext
Definition: fxirpqueue.hpp:75
EVT_IRP_QUEUE_CANCEL * PFN_IRP_QUEUE_CANCEL
Definition: fxirpqueue.hpp:79
#define FX_IRP_QUEUE_ENTRY_IDENTIFIER
Definition: fxirpqueue.hpp:52
#define FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY
Definition: fxirpqueue.hpp:47
__in MdIrp Irp
Definition: fxirpqueue.hpp:74
#define FX_VF_METHOD(classname, fnName)
Definition: fxmacros.hpp:43
FxIrp * irp
IO_CSQ_IRP_CONTEXT * PMdIoCsqIrpContext
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
WUDF_DRIVER_CANCEL * MdCancelRoutine
Definition: mxum.h:143
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PIO_CSQ Csq
Definition: csq.h:87
ULONG Type
Definition: csq.h:85
Definition: csq.h:222
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: http.c:7252
Definition: ps.c:97
#define LockObject(Object)
Definition: titypes.h:34
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
@ WDF_REQUEST_FATAL_ERROR
Definition: wdfbugcodes.h:63
@ WDF_REQUEST_FATAL_ERROR_REQUEST_NOT_IN_QUEUE
Definition: wdfbugcodes.h:80
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define PAGED_CODE_LOCKED()
Definition: kefuncs.h:1417