ReactOS 0.4.15-dev-8138-g1e75ea8
fxpkgio.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxPkgIo.cpp
8
9Abstract:
10
11 This module implements the I/O package for the driver frameworks.
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23
24
25--*/
26
27#include "ioprivshared.hpp"
28
29// Tracing support
30extern "C" {
31#if defined(EVENT_TRACING)
32#include "FxPkgIo.tmh"
33#endif
34}
35
36//
37// This package is initialized by the FxPkgIo::Install virtual method
38// being invoked.
39//
40// A reference is held on it by the FxDevice which owns it. When the
41// FxDevice is destroyed, its destructor FxDevice::~FxDevice will release
42// its reference to this package, so that FxPkgIo::~FxPkgIo can run.
43//
44// There is no other package remove, or un-install call.
45//
46
48 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
50 ) :
51 FxPackage(FxDriverGlobals, Device, FX_TYPE_PACKAGE_IO),
52 m_InCallerContextCallback(FxDriverGlobals)
53{
54 LARGE_INTEGER tickCount;
55
57
59
61
63
65
67
69
71
72 Mx::MxQueryTickCount(&tickCount);
73
74 m_RandomSeed = tickCount.LowPart;
75
77 "Constructed FxPkgIo 0x%p",this);
78}
79
81{
83
85
86 m_Device = NULL;
87
93 delete info;
94 }
95
97
99 "Destroyed FxPkgIo 0x%p",this);
100}
101
106 )
107{
108 FxIrp fxIrp(Irp);
110
113 "WDFDEVICE 0x%p !devobj 0x%p %!IRPMJ!, IRP_MN %x, IRP 0x%p",
117
119}
120
123FX_VF_METHOD(FxPkgIo, VerifyDispatchContext) (
124 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
126 )
127{
131
133
134 //
135 // Make sure context is valid.
136 //
138 &m_DynamicDispatchInfoListHead ?
139 TRUE : FALSE;
140
141 for (next = m_DynamicDispatchInfoListHead.Flink;
142 next != &m_DynamicDispatchInfoListHead;
143 next = next->Flink) {
145 ctxValid = TRUE;
146 break;
147 }
148 }
149
150 if (FALSE == ctxValid) {
153 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
154 "DispatchContext 0x%p is invalid, %!STATUS!",
156 FxVerifierDbgBreakPoint(FxDriverGlobals);
157 }
158
159 return status;
160}
161
168 )
169/*++
170
171 Routine Description:
172
173 Checks for any registered dynamic dispatch callbacks that handles this type of request, else
174 selects the default queue based on the IRP's major code.
175
176Arguments:
177
178 Irp - WDM request.
179
180 DispatchContext - Is the next FxIrpDynamicDispatchInfo element.
181
182Return Value:
183
184 Irp's status.
185
186--*/
187
188{
190 FxIrp fxIrp(Irp);
191
193
195
196 //
197 // Look for I/O dynamic dispatch callbacks.
198 //
200 int index;
202
203 //
204 // Only read/writes/ctrls/internal_ctrls IRPs are allowed, i.e., request cannot
205 // IRP type in its callback.
206 //
211 "Driver cannot change the IRP type in its dispatch "
212 "callback Irp 0x%p, %!IRPMJ!, IRP_MN %x, Device 0x%p, "
213 "%!STATUS!",
217 goto CompleteIrp;
218 }
219
220 //
221 // Verifier checks.
222 //
223 status = VerifyDispatchContext(GetDriverGlobals(), DispatchContext);
224 if( !NT_SUCCESS(status)){
225 goto CompleteIrp;
226 }
227
228 do {
230
233 ListEntry);
234 //
235 // Advance to next node.
236 //
239
244
245 //
246 // If registered, invoke dispatch callback for this major function.
247 //
249 if (NULL != info->Dispatch[index].EvtDeviceDynamicDispatch){
250 return info->Dispatch[index].EvtDeviceDynamicDispatch(
255 info->Dispatch[index].DriverContext,
256 reinterpret_cast<PIRP> (fxIrp.GetIrp()),
259 );
260 }
261 } while ((PLIST_ENTRY)DispatchContext !=
263 }
264
265 //
266 // Only now push these local variables on the stack, this is to keep the
267 // stack from growing unnecessarily in the dynamic dispatch path above.
268 //
271
272 //
273 // Get the queue from the dispatch-table
274 //
276 if (queue == NULL) {
278 if (ioInCallerCtx->m_Method == NULL) {
279 //
280 // No queue configured yet, fail request unless the driver is a filter.
281 //
282 if (m_Filter) {
283 goto Forward;
284 }
285
289 "No queue configured for WDFDEVICE 0x%p, failing IRP 0x%p,"
290 " %!STATUS!",
292
293 goto CompleteIrp;
294 }
295 }
296 else {
298 }
299
300 //
301 // If the driver is filter and queue is a default-queue then before
302 // calling the queue, we should make sure the queue can dispatch
303 // requests to the driver. If the queue cannot dispatch request,
304 // we should forward it down to the lower driver ourself.
305 // This is to cover the scenario where the driver has registered only
306 // type specific handler and expect the framework to auto-forward other
307 // requests.
308 //
309 if (m_Filter &&
312 queue->IsIoEventHandlerRegistered((WDF_REQUEST_TYPE)fxIrp.GetMajorFunction()) == FALSE) {
313 //
314 // Default queue doesn't have callback events registered to
315 // handle this request. So forward it down.
316 //
317 goto Forward;
318 }
319
320 //
321 // Finally queue request.
322 //
324
325Forward:
326
329
331
335
336 return status;
337}
338
344 __in_opt FxIoInCallerContext* IoInCallerCtx,
346 )
347{
350 BOOLEAN isForwardProgressQueue;
351 BOOLEAN inCriticalRegion;
352 PWDF_OBJECT_ATTRIBUTES reqAttribs;
353 FxIrp fxIrp(Irp);
354
355 request = NULL;
356 inCriticalRegion = FALSE;
357 isForwardProgressQueue = Queue != NULL && Queue->IsForwardProgressQueue();
358
360 ASSERT((IoInCallerCtx != NULL && IoInCallerCtx->m_Method != NULL) ||
361 Queue != NULL);
362 //
363 // The request inserted into the queue can be retrieved and processed
364 // by an arbitrary thread. So we need to make sure that such a thread doesn't
365 // get suspended and deadlock the driver and potentially the system by
366 // entering critical region.The KeEnterCriticalRegion temporarily disables
367 // the delivery of normal kernel APCs used to suspend a thread.
368 // Kernel APCs queued to this thread will get executed when we leave the
369 // critical region.
370 //
372 Mx::MxEnterCriticalRegion();
373 inCriticalRegion = TRUE;
374 }
375
376 if (Queue != NULL && Queue->GetCxDeviceInfo() != NULL) {
377 reqAttribs = &Queue->GetCxDeviceInfo()->RequestAttributes;
378 }
379 else {
380 reqAttribs = m_Device->GetRequestAttributes();
381 }
382
384
385 //
386 // Check if it is forward progress queue and the EnhancedVerifierOption for
387 // testing forward progress are set.
388 //
389 if (isForwardProgressQueue &&
392 //
393 // This function returns STATUS_INSUFFICIENT_RESOURCES
394 // if testing forward progress is enabled and free's the passed in request.
395 //
397 }
398
399 if (!NT_SUCCESS(status)) {
400 if (m_Filter && Queue == NULL) {
401 goto CompleteIrp;
402 }
403
404 if (isForwardProgressQueue) {
405 status = Queue->GetReservedRequest(Irp, &request);
406 if (status == STATUS_PENDING) {
407 goto IrpIsGone;
408 }
409 else if (!NT_SUCCESS(status)) {
410 goto CompleteIrp;
411 }
412 }
413 else {
414 //
415 // Fail the request
416 //
419 "Could not create WDFREQUEST, %!STATUS!", status);
420
421 goto CompleteIrp;
422 }
423 }
424 else {
425 if (isForwardProgressQueue) {
426 status = Queue->InvokeAllocateResourcesCallback(request);
427 if (!NT_SUCCESS(status)) {
428 //
429 // Failure of the callback means the driver wasn't able to
430 // allocate resources for the request. In that case free the
431 // request allocated earlier and use the reserved one.
432 //
433 request->FreeRequest();
434 request = NULL;
435
436 status = Queue->GetReservedRequest(Irp, &request);
437 if (status == STATUS_PENDING) {
438 goto IrpIsGone;
439 }
440 else if (!NT_SUCCESS(status)) {
441 goto CompleteIrp;
442 }
443 }
444 }
445 }
446
447 //
448 // Since we can't guarantee the callback to be called in the context of the
449 // caller for reserved requests, we will skip calling InCallerContextCallback
450 // for reserverd request.
451 //
452 if (IoInCallerCtx != NULL &&
453 IoInCallerCtx->m_Method != NULL &&
454 request->IsReserved() == FALSE) {
455
456 request->SetInternalContext(Queue);
458
459 //
460 // The driver is responsible for calling WdfDeviceEnqueueRequest to
461 // insert it back into the I/O processing pipeline, or completing it.
462 //
463 goto IrpIsGone;
464 }
465
466 ASSERT(Queue != NULL);
467 status = Queue->QueueRequest(request);
468 goto IrpIsGone;
469
471
475 //
476 // fallthrough
477 //
478IrpIsGone:
479
480 if (inCriticalRegion) {
481 Mx::MxLeaveCriticalRegion();
482 }
483
484 return status;
485}
486
492 )
493
494/*++
495
496 Routine Description:
497
498 Make the input queue as the default queue. There can be
499 only one queue as the default queue.
500
501 The default queue is the place all requests go to
502 automatically if a specific queue was not configured
503 for them.
504
505Arguments:
506
507
508Return Value:
509
510 NTSTATUS
511
512--*/
513{
514 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
515 ULONG index;
516
517 if (m_DefaultQueue != NULL) {
519 "Default Queue Already Configured for "
520 "FxPkgIo 0x%p, WDFDEVICE 0x%p %!STATUS!",this,
521 Device->GetHandle(), STATUS_UNSUCCESSFUL);
522 return STATUS_UNSUCCESSFUL;
523 }
524
526 if (m_DispatchTable[index] == NULL) {
528 }
529 }
530
532
533 //
534 // Default queue can't be deleted. So mark the object to fail WdfObjectDelete on
535 // the default queue.
536 //
537 Queue->MarkNoDeleteDDI();
538 return STATUS_SUCCESS;
539}
540
541__inline
544 VOID
545 )
546{
547 return m_Device->GetDriver();
548}
549
552FX_VF_METHOD(FxPkgIo, VerifyEnqueueRequestUpdateFlags) (
553 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
556 )
557{
559
561
563
564 Request->Lock(&irql);
565
567
568 status = Request->VerifyRequestIsInCallerContext(FxDriverGlobals);
570 status = Request->VerifyRequestIsDriverOwned(FxDriverGlobals);
571 }
572
573 if (NT_SUCCESS(status)) {
574 Request->ClearVerifierFlagsLocked(
577 }
578
579 Request->Unlock(irql);
580 return status;
581}
582
583VOID
584FX_VF_METHOD(FxPkgIo, VerifyEnqueueRequestRestoreFlags) (
585 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
588 )
589{
590 UNREFERENCED_PARAMETER(FxDriverGlobals);
591 KIRQL irql;
592
594
595 Request->Lock(&irql);
596 Request->ClearVerifierFlagsLocked(~OrigVerifierFlags);
597 Request->SetVerifierFlagsLocked(OrigVerifierFlags);
598 Request->Unlock(irql);
599}
600
601
602//
603// This inserts a request into the I/O processing pipeline
604//
610 )
611{
614 FxIrp* Irp = NULL;
616 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
617 SHORT origVerifierFlags = 0;
618
619 //
620 // Request is owned by the driver, and has a reference count of == 1
621 // (or > 1 if EvtIoInCallerContext callback took an additional reference),
622 // with a FxPkgIoInProcessRequestComplete callback registered.
623 //
624 ASSERT(pRequest->GetRefCnt() >= 1);
625
626 Irp = pRequest->GetFxIrp();
627
629 "WDFREQUEST 0x%p", pRequest->GetObjectHandle());
630
631 status = VerifyEnqueueRequestUpdateFlags(FxDriverGlobals,
632 pRequest,
633 &origVerifierFlags);
634 if (!NT_SUCCESS(status)) {
635 return status;
636 }
637
638 //
639 // Get the associated queue
640 //
642 if (NULL == pQueue) {
643 pQueue = m_DispatchTable[Irp->GetMajorFunction()];
644 if (pQueue == NULL) {
645 //
646 // No queue configured yet, fail request unless the driver is a filter.
647 //
648 if (m_Filter) {
649 goto Forward;
650 }
651
653
655 "No queue configured for WDFDEVICE 0x%p, "
656 "failing WDFREQUEST 0x%p %!STATUS!",
657 Device->GetHandle(),
659 status);
660
661 FxVerifierDbgBreakPoint(FxDriverGlobals);
662
663 //
664 // Return it back to the driver to decide the outcome
665 //
666 goto Error;
667 }
668 }
669
670 //
671 // If the queue is a default-queue and driver is a filter then before
672 // calling the queue we should make sure the queue can dispatch
673 // requests to the driver. If the queue cannot dispatch request,
674 // we should forward it down to the lower driver ourself.
675 if (m_Filter &&
677 pQueue->IsIoEventHandlerRegistered((WDF_REQUEST_TYPE)Irp->GetMajorFunction()) == FALSE) {
678 //
679 // Default queue doesn't have callback events registered to
680 // handle this request. So forward it down.
681 //
682 goto Forward;
683 }
684
685 pQueue->AddRef();
686
687 // Must add a reference before releasing the callback and its reference
689
690 // Release the callback
693 UNREFERENCED_PARAMETER(oldState);
694
696
697 pQueue->Release();
698
699 //
700 // If not successfull, must place the request back
701 // to the state it was in on entry so that the driver
702 // can decide what to do next with it
703 //
704 if (!NT_SUCCESS(status)) {
705
706 //
707 // If the request comes back to us, it should still
708 // have a reference count of 1
709 //
711
713 UNREFERENCED_PARAMETER(oldState);
714
715 //
716 // Release the reference count on the request since
717 // the callback will hold the only one that gets
718 // decremented when the request is completed
719 //
721 goto Error;
722 }
723 else {
724 //
725 // On success, can not touch the request since it
726 // may have already been completed
727 //
728 }
729
730 return status;
731
732Forward:
733
734 //
735 // Cannot send-and-forget a request with a formatted IO context.
736 //
737 if (pRequest->HasContext()) {
739
741 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
742 "Cannot send-and-forget WDFREQUEST 0x%p with formatted IO"
743 " context for filter WDFDEVICE 0x%p, %!STATUS!",
745 Device->GetHandle(),
746 status );
747
748 FxVerifierDbgBreakPoint(FxDriverGlobals);
749 goto Error;
750 }
751
752 //
753 // This will skip the current stack location and perform
754 // early dispose on the request.
755 //
757
758 (VOID)Irp->CallDriver(Device->GetAttachedDevice());
759
760 //
761 // This will delete the request and free the memory back
762 // to the device lookaside list.
763 //
765
766 //
767 // Return a success status in this code path even if the previous call
768 // to send the request to the lower driver failed. The status code returned
769 // by this function should reflect the status of enqueuing the request and
770 // not the status returned by the lower driver.
771 //
772 return STATUS_SUCCESS;
773
774Error:
775
776 //
777 // If not successful, we must set the original verifier flags.
778 //
779 VerifyEnqueueRequestRestoreFlags(FxDriverGlobals, pRequest, origVerifierFlags);
780
781 return status;
782}
783
788 __in_opt FxCxDeviceInfo* CxDeviceInfo,
791 )
792{
796 FxIrpDynamicDispatchInfo* dispatchInfo;
797 LONG mjIndex;
798 CCHAR driverIndex;
799 BOOLEAN addNew;
800
802 addNew = TRUE;
803
805
806 //
807 // Indirect MajorFunction validation.
808 //
812 "Invalid MajorFunction %!IRPMJ!, %!STATUS!",
814 goto Done;
815 }
816
817 //
818 // Get driver I/O device path index.
819 //
820 driverIndex = FxDevice::GetCxDriverIndex(CxDeviceInfo);
821
822 //
823 // Insert new info into correct slot in the I/O path.
824 // Index goes from higher to lower (..., 2, 1, 0) b/c cx's callback is called before
825 // client's one.
826 //
829 next = next->Flink) {
830
831 CCHAR curIndex = 0;
832
833 dispatchInfo = CONTAINING_RECORD(next,
835 ListEntry);
836 //
837 // Get current I/O device path index.
838 //
839 curIndex = FxDevice::GetCxDriverIndex(dispatchInfo->CxDeviceInfo);
840 if (driverIndex == curIndex) {
841 //
842 // Found it.
843 //
844 if (dispatchInfo->Dispatch[mjIndex].EvtDeviceDynamicDispatch != NULL) {
848 "Driver %p has already set a dispatch callback for "
849 "%!IRPMJ!, %!STATUS!",
850 CxDeviceInfo == NULL ?
851 GetDriver()->GetHandle() :
852 CxDeviceInfo->Driver->GetHandle(),
854 goto Done;
855 }
856
857 dispatchInfo->Dispatch[mjIndex].DriverContext = DriverContext;
858 dispatchInfo->Dispatch[mjIndex].EvtDeviceDynamicDispatch =
860
861 ASSERT(dispatchInfo->CxDeviceInfo == CxDeviceInfo);
862
863 addNew = FALSE;
864 break;
865 }
866 else if (driverIndex > curIndex) {
867 //
868 // Not found (past valid range), add one before current.
869 //
870 break;
871 }
872 else if (driverIndex < curIndex) {
873 //
874 // Keep looking, too high.
875 //
876 continue;
877 }
878 }
879
880 if (addNew) {
881 dispatchInfo = new(fxDriverGlobals) FxIrpDynamicDispatchInfo();
882 if (dispatchInfo == NULL) {
886 "Couldn't create object DynamicDispatchInfo, %!STATUS!",
887 status);
888 goto Done;
889 }
890
891 dispatchInfo->CxDeviceInfo = CxDeviceInfo;
892 dispatchInfo->Dispatch[mjIndex].DriverContext = DriverContext;
893 dispatchInfo->Dispatch[mjIndex].EvtDeviceDynamicDispatch =
895
896 //
897 // We must insert it before 'next' element.
898 //
899 InsertTailList(next, &dispatchInfo->ListEntry);
900 }
901
903
904Done:
905 return status;
906}
907
911 __inout FxIoQueue* TargetQueue,
913 )
914{
915 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
916 KIRQL irql;
918
920
921 if(TargetQueue->IsIoEventHandlerRegistered(RequestType) == FALSE){
924 "Must have EvtIoDefault or %!WDF_REQUEST_TYPE! "
925 "specific dispatch event registered for "
926 "WDFQUEUE 0x%p, %!STATUS!", RequestType,
927 TargetQueue->GetObjectHandle(),
928 status);
929 FxVerifierDbgBreakPoint(FxDriverGlobals);
930 return status;
931 }
932
933 // Lock IoPackage data structure
934
935 Lock(&irql);
936
937 if (TargetQueue == m_DefaultQueue) {
940 "Default WDFQUEUE 0x%p cannot be configured to "
941 "dispatch specific type of request, %!STATUS!",
942 TargetQueue->GetObjectHandle(),
943 status);
944 FxVerifierDbgBreakPoint(FxDriverGlobals);
945 Unlock(irql);
946 return status;
947 }
948
949 // Error if already has an entry
954 "%!WDF_REQUEST_TYPE! is already configured for"
955 "WDFQUEUE 0x%p, %!STATUS!", RequestType,
956 TargetQueue->GetObjectHandle(),
957 status);
958 FxVerifierDbgBreakPoint(FxDriverGlobals);
959 Unlock(irql);
960 return status;
961 }
962
963 //
964 // We don't take an extra reference count since we already
965 // have one from our associated list (DriverQueues)
966 //
967 m_DispatchTable[RequestType] = TargetQueue;
968
969 //
970 // Queues configured to auto-dispatch requests cannot be deleted
971 //
972 TargetQueue->MarkNoDeleteDDI();
973
974 Unlock(irql);
975
976 return STATUS_SUCCESS;
977}
978
984 __in_opt FxDriver* Caller,
985 __deref_out FxIoQueue** ppQueue
986 )
987{
993
994 pParent = NULL;
995 pQueue = NULL;
996 pDriver = NULL;
998
999 if (QueueAttributes != NULL && QueueAttributes->ParentObject != NULL) {
1000 CfxDeviceBase* pSearchDevice;
1001
1003 QueueAttributes->ParentObject,
1005 (PVOID*)&pParent);
1006
1008
1009 if (pSearchDevice == NULL) {
1011
1014 "QueueAttributes->ParentObject 0x%p must have WDFDEVICE as an "
1015 "eventual ancestor, %!STATUS!",
1016 QueueAttributes->ParentObject, status);
1017
1018 return status;
1019 }
1020 else if (pSearchDevice != m_DeviceBase) {
1022
1025 "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but "
1026 "not the same WDFDEVICE 0x%p passed to WdfIoQueueCreate, "
1027 "%!STATUS!",
1028 QueueAttributes->ParentObject, pSearchDevice->GetHandle(),
1030
1031 return status;
1032 }
1033 }
1034 else {
1035 //
1036 // By default, use the package as the parent
1037 //
1038 pParent = this;
1039 }
1040
1041 //
1042 // v1.11 and up: get driver object if driver handle is specified.
1043 // Client driver can also specify a driver handle, the end result in this case is
1044 // a PkgIoContext that is NULL (see below), i.e., the same as if driver handle
1045 // was NULL.
1046 //
1047 if (Config->Size > sizeof(WDF_IO_QUEUE_CONFIG_V1_9) &&
1048 Config->Driver != NULL) {
1049
1051 Config->Driver,
1053 (PVOID*)&pDriver);
1054 }
1055
1058 Config,
1059 Caller,
1060 this,
1062 &pQueue
1063 );
1064
1065 if (!NT_SUCCESS(status)) {
1066 ASSERT(pQueue == NULL);
1067 return status;
1068 }
1069
1070 //
1071 // Class extension support: associate queue with a specific cx layer.
1072 //
1073 if (pDriver != NULL) {
1075 }
1076
1078 if (!NT_SUCCESS(status)) {
1080 return status;
1081 }
1082
1084 *ppQueue = pQueue;
1085
1086 return status;
1087}
1088
1089
1090VOID
1093 )
1094/*++
1095
1096Routine Description:
1097
1098 This is called from FxIoQueue::Dispose to remove
1099 the queue from the transaction list.
1100
1101 Since this acquires the FxPkgIo lock, it assumes that
1102 no calls are made into FxIoQueue while holding the
1103 FxPkgIo lock.
1104
1105Arguments:
1106
1107 None
1108
1109Return Value:
1110 None
1111 --*/
1112{
1113 // Remove it from transacation list
1115 return;
1116}
1117
1122 )
1123{
1124 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
1125
1126 if (m_DefaultQueue != NULL) {
1128 "I/O Package already has a default queue. "
1129 "SetFilter must be called before creating "
1130 "a default queue %!STATUS!",
1132 FxVerifierDbgBreakPoint(FxDriverGlobals);
1134 }
1135
1136 m_Filter = Value;
1137
1138 return STATUS_SUCCESS;
1139}
1140
1145 )
1146
1147/*++
1148
1149 Routine Description:
1150
1151 Stops all PowerManaged queues automatic I/O processing due to
1152 a power event that requires I/O to stop.
1153
1154 This is called on a PASSIVE_LEVEL thread that can block until
1155 I/O has been stopped, or completed/cancelled.
1156
1157Arguments:
1158
1159 Action -
1160
1161 FxIoStopProcessingForPowerHold:
1162 the function returns when the driver has acknowledged that it has
1163 stopped all I/O processing, but may have outstanding "in-flight" requests
1164 that have not been completed.
1165
1166 FxIoStopProcessingForPowerPurgeManaged:
1167 the function returns when all requests from a power managed queue have
1168 been completed and/or cancelled., and there are no more in-flight requests.
1169
1170 FxIoStopProcessingForPowerPurgeNonManaged:
1171 the function returns when all requests from a non-power managed queue have
1172 been completed and/or cancelled., and there are no more in-flight requests.
1173 Only called during device-remove.
1174
1175Return Value:
1176
1177 NTSTATUS
1178
1179--*/
1180
1181{
1182 KIRQL irql;
1184 SINGLE_LIST_ENTRY queueList, *ple;
1185
1187 "Perform %!FxIoStopProcessingForPowerAction! for all queues of "
1188 "WDFDEVICE 0x%p", Action, m_Device->GetHandle());
1189
1190 queueList.Next = NULL;
1191
1192 Lock(&irql);
1193 //
1194 // Device is moving into low power state. So any new queues
1195 // created after this point would start off as powered off.
1196 //
1198
1199 //
1200 // If queues are shutting down, any new queue created after
1201 // this point would not accept any requests.
1202 //
1203 switch(Action) {
1207 break;
1208 }
1209
1211
1212 Unlock(irql);
1213
1214 //
1215 // If the power action is hold then first change the state of all the queues
1216 // to PowerStartTransition. This will prevent the queues from dispatching
1217 // new requests before we start asking each queue to stop processing
1218 // inflight requests.
1219 //
1221
1222 //
1223 // Walk the list without popping entries because we need to scan
1224 // the list again.
1225 //
1226 for(ple = queueList.Next; ple != NULL; ple = ple->Next) {
1227
1229
1230 queue->StartPowerTransitionOff();
1231 }
1232 }
1233
1234 //
1235 // Ask the queues to stop processing inflight requests.
1236 //
1237 for (ple = PopEntryList(&queueList); ple != NULL;
1238 ple = PopEntryList(&queueList)) {
1239
1241
1242 queue->StopProcessingForPower(Action);
1243
1244 ple->Next = NULL;
1245
1246 queue->RELEASE(IO_ITERATOR_POWER_TAG);
1247 }
1248
1249 return STATUS_SUCCESS;
1250}
1251
1255
1256/*++
1257
1258 Routine Description:
1259
1260 Resumes all PowerManaged queues for automatic I/O processing due to
1261 a power event that allows I/O to resume.
1262
1263 Non-PowerManaged queues are left alone.
1264
1265Arguments:
1266
1267Return Value:
1268
1269 NTSTATUS
1270
1271--*/
1272
1273{
1274 KIRQL irql;
1276 SINGLE_LIST_ENTRY queueList, *ple;
1277
1279 "Power resume all queues of WDFDEVICE 0x%p",
1280 m_Device->GetHandle());
1281
1282 queueList.Next = NULL;
1283
1284 Lock(&irql);
1285
1287 //
1288 // Change the state so that new queues created while we
1289 // are resuming the existing queues can be in a powered-on state.
1290 //
1292
1293 //
1294 // Change the accepting state so that new queues created while we
1295 // are resuming the existing queues can be accept request.
1296 //
1298
1299 Unlock(irql);
1300
1301 //
1302 // We will power-up the queues in two steps. First we will resume
1303 // the power of all the queues and then we will start dispatching I/Os.
1304 // This is to avoid a queue being powered up at the begining of the list
1305 // trying to forward a request to another queue lower in the list that's
1306 // not powered up yet.
1307 //
1308 for(ple = queueList.Next; ple != NULL; ple = ple->Next) {
1309
1311
1312 queue->ResumeProcessingForPower();
1313 }
1314
1315 for (ple = PopEntryList(&queueList);
1316 ple != NULL;
1317 ple = PopEntryList(&queueList)) {
1318
1320
1321 queue->StartPowerTransitionOn();
1322
1323 ple->Next = NULL;
1324
1325 queue->RELEASE(IO_ITERATOR_POWER_TAG);
1326 }
1327
1328 return STATUS_SUCCESS;
1329}
1330
1331VOID
1333 VOID
1334 )
1335/*++
1336
1337Routine Description:
1338 This is called on a device which has been restarted from the removed
1339 state. It will reset purged queues so that they can accept new requests
1340 when ResumeProcessingForPower is called afterwards.
1341
1342Arguments:
1343 None
1344
1345Return Value:
1346 None
1347
1348 --*/
1349{
1350 KIRQL irql;
1352 SINGLE_LIST_ENTRY queueList, *ple;
1353
1355 "Restart queues from purged state for WDFDEVICE 0x%p due to "
1356 "device restart", m_Device->GetHandle());
1357
1358 queueList.Next = NULL;
1359
1360 Lock(&irql);
1361
1363
1364 Unlock(irql);
1365
1366 for (ple = PopEntryList(&queueList);
1367 ple != NULL;
1368 ple = PopEntryList(&queueList)) {
1369
1371
1372 queue->ResetStateForRestart();
1373
1374 ple->Next = NULL;
1375
1376 queue->RELEASE(IO_ITERATOR_POWER_TAG);
1377 }
1378
1379 Lock(&irql);
1380
1382
1384
1385 Unlock(irql);
1386
1387 return;
1388
1389}
1390
1395 )
1396
1397/*++
1398
1399 Routine Description:
1400
1401 Enumerate all the queues and cancel the requests that have
1402 the same fileobject as the Cleanup IRP.
1403
1404 We are making an assumption that cleanup irps are sent only
1405 at passive-level.
1406
1407 Return Value:
1408
1409 NTSTATUS
1410
1411--*/
1412{
1413 FxIoQueue* queue = NULL;
1416 KIRQL irql;
1417
1419
1421 "Currently framework allow flushing of queues "
1422 "by fileobject on cleanup only at PASSIVE_LEVEL");
1423
1425 return STATUS_SUCCESS;
1426 }
1427
1428 //
1429 // Iterate through the queue list and flush each one.
1430 //
1431 Lock(&irql);
1433 Unlock(irql);
1434
1435 while(queue != NULL) {
1436
1437 queue->FlushByFileObject(FileObject);
1438
1439 queue->RELEASE(IO_ITERATOR_FLUSH_TAG);
1440
1441 Lock(&irql);
1443 Unlock(irql);
1444 }
1445
1446 return STATUS_SUCCESS;
1447}
1448
1449static
1450VOID
1452 PLIST_ENTRY QueueLE,
1453 PSINGLE_LIST_ENTRY SListHead,
1454 PVOID Tag
1455 )
1456{
1457 FxIoQueueNode* listNode;
1459
1460 //
1461 // Skip any nodes that are not queues. They can be bookmarks for
1462 // in-progress flush operations.
1463 //
1464 listNode = FxIoQueueNode::_FromListEntry(QueueLE);
1465 if (listNode->IsNodeType(FxIoQueueNodeTypeQueue) == FALSE) {
1466 return;
1467 }
1468
1470 PushEntryList(SListHead, &queue->m_PowerSListEntry);
1471
1472 //
1473 // Add a reference since the request will be touched outside of the
1474 // lock being held. We will use the enumerant value as the tag.
1475 //
1476 queue->ADDREF(Tag);
1477}
1478
1479VOID
1481 __in PSINGLE_LIST_ENTRY SListHead,
1482 __inout FxIoIteratorList ListType
1483 )
1484/*++
1485
1486 Routine Description:
1487
1488 Called to make a temporary list of queues for iteration purpose.
1489 Function is called with the FxPkg lock held.
1490
1491--*/
1492{
1493 PLIST_ENTRY listHead, le;
1494
1495 listHead = &m_IoQueueListHead;
1496
1497 if (FxIoQueueIteratorListPowerOn == ListType ||
1498 (FxIoQueueIteratorListPowerOff == ListType && // backwards compatibility order.
1499 m_Device->IsCxInIoPath() == FALSE)) {
1500 //
1501 // Power up: first client driver's queues then cx's queues.
1502 // List is already sorted with client driver's queue first.
1503 // Since we are inserting into the head of the single list head, if we walked
1504 // over the list from first to last, we would reverse the entries. By walking
1505 // the list backwards, we build the single list head in the order of m_IoQueueListHead.
1506 //
1507 for (le = listHead->Blink; le != listHead; le = le->Blink) {
1509 SListHead,
1511 }
1512 }
1513 else if (FxIoQueueIteratorListPowerOff == ListType) {
1514 //
1515 // Power down: first cx's queues then client driver's queues.
1516 // List is already sorted with client driver's queue first.
1517 // Since we are inserting into the head of the single list head, if we walked
1518 // over the list from last to first, we would reverse the entries. By walking
1519 // the list forwards, we build the single list head in the desired order
1520 //
1521 for (le = listHead->Flink; le != listHead; le = le->Flink) {
1523 SListHead,
1525 }
1526 }
1527 else {
1528 ASSERT(FALSE);
1529 }
1530}
1531
1532VOID
1534 __inout FxIoQueue* IoQueue
1535 )
1536{
1537 PLIST_ENTRY listHead, le;
1539 KIRQL irql;
1540 FxIoQueueNode* listNode;
1541 CCHAR queueIndex, curIndex;
1542
1543 listHead = &m_IoQueueListHead;
1544 queueIndex = FxDevice::GetCxDriverIndex(IoQueue->GetCxDeviceInfo());
1545 Lock(&irql);
1546
1547 ASSERT(IoQueue->m_IoPkgListNode.IsNodeType(FxIoQueueNodeTypeQueue));
1548
1549 //
1550 // Insert new queue in sorted list; search from last to first.
1551 //
1552 for (le = listHead->Blink; le != listHead; le = le->Blink) {
1553 //
1554 // Skip any nodes that are not queues. They can be bookmarks for
1555 // in-progress flush operations.
1556 //
1557 listNode = FxIoQueueNode::_FromListEntry(le);
1558 if (listNode->IsNodeType(FxIoQueueNodeTypeQueue) == FALSE) {
1559 continue;
1560 }
1561
1562 //
1563 // Get current queue's driver index.
1564 //
1566 curIndex = FxDevice::GetCxDriverIndex(queue->GetCxDeviceInfo());
1567 //
1568 // Queues are inserted in order at the end of its allowed range.
1569 //
1570 if (curIndex < queueIndex || curIndex == queueIndex) {
1571 break;
1572 }
1573 }
1574
1575 InsertHeadList(le, &IoQueue->m_IoPkgListNode.m_ListEntry);
1576
1577 if (m_PowerStateOn) {
1578 IoQueue->SetPowerState(FxIoQueuePowerOn);
1579 } else {
1580 IoQueue->SetPowerState(FxIoQueuePowerOff);
1582 // Clear accept requests
1583 IoQueue->SetStateForShutdown();
1584 }
1585 }
1586
1587 Unlock(irql);
1588
1589 return;
1590}
1591
1592VOID
1594 __inout FxIoQueue* IoQueue
1595 )
1596{
1597 KIRQL irql;
1598
1599 Lock(&irql);
1600
1601 RemoveEntryList(&IoQueue->m_IoPkgListNode.m_ListEntry);
1602 ASSERT(IoQueue->m_IoPkgListNode.IsNodeType(FxIoQueueNodeTypeQueue));
1603
1604 InitializeListHead(&IoQueue->m_IoPkgListNode.m_ListEntry);
1605
1606 Unlock(irql);
1607}
1608
1609FxIoQueue*
1611 __in FxIoQueueNode* QueueBookmark,
1612 __in PVOID Tag
1613 )
1614/*++
1615
1616 Routine Description:
1617
1618 Inserts the provided bookmark (FxIoQueueNode) at the beginning
1619 of the IO Package's queue list, and calls GetNextIoQueueLocked
1620 to retrieve the first queue and to advance the bookmark.
1621
1622 Function is called with the FxPkg lock held.
1623
1624 Return Value:
1625
1626 NULL if there are no queues in list else
1627 FxIoQueue* reference to first queue in list.
1628
1629--*/
1630{
1631 ASSERT(QueueBookmark->IsNodeType(FxIoQueueNodeTypeBookmark));
1632 ASSERT(IsListEmpty(&QueueBookmark->m_ListEntry));
1633
1634 InsertHeadList(&m_IoQueueListHead, &QueueBookmark->m_ListEntry);
1635
1636 return GetNextIoQueueLocked(QueueBookmark, Tag);
1637}
1638
1639FxIoQueue*
1641 __in FxIoQueueNode* QueueBookmark,
1642 __in PVOID Tag
1643 )
1644/*++
1645
1646 Routine Description:
1647
1648 Moves the provided bookmark ahead in the IO Package's queue list
1649 and returns the next available queue (if any).
1650
1651 Return Value:
1652
1653 NULL if there are no more queues in list else
1654 FxIoQueue* reference to the next queue in list.
1655
1656--*/
1657{
1659 FxIoQueue* queue = NULL;
1660 FxIoQueueNode* listNode = NULL;
1661
1662 ASSERT(QueueBookmark->IsNodeType(FxIoQueueNodeTypeBookmark));
1663 ASSERT(IsListEmpty(&QueueBookmark->m_ListEntry) == FALSE);
1664
1665 //
1666 // Try to advance bookmark to next location.
1667 //
1668 ple = QueueBookmark->m_ListEntry.Flink;
1669 RemoveEntryList(&QueueBookmark->m_ListEntry);
1670 InitializeListHead(&QueueBookmark->m_ListEntry);
1671
1672 for (; ple != &m_IoQueueListHead; ple = ple->Flink) {
1673 //
1674 // Skip any nodes that are not queues. These nodes can be
1675 // bookmarks for in-progress flush operations.
1676 //
1678 if (listNode->IsNodeType(FxIoQueueNodeTypeQueue)) {
1679
1680 //
1681 // This entry is a real queue.
1682 //
1684 queue->ADDREF(Tag);
1685
1686 //
1687 // Insert bookmark after this entry.
1688 //
1689 InsertHeadList(ple, &QueueBookmark->m_ListEntry);
1690
1691 break;
1692 }
1693 }
1694
1695 return queue;
1696}
1697
1700 __in FxIoInCallerContext *InCallerContextInfo,
1703 )
1704{
1706 FxRequestCompletionState oldState;
1707 FxIrp fxIrp(Irp);
1708
1710
1711 //
1712 // Mark the IRP pending since we are going
1713 // to return STATUS_PENDING regardless of whether
1714 // the driver completes the request right away
1715 // or not
1716 //
1718
1722 }
1723
1724 //
1725 // Set a completion callback to manage the reference
1726 // count on the request
1727 //
1728 oldState = Request->SetCompletionState(FxRequestCompletionStateIoPkg);
1729
1731 UNREFERENCED_PARAMETER(oldState);
1732
1733 //
1734 // Release the reference count on the request since
1735 // the callback will hold the only one that gets
1736 // decremented when the request is completed
1737 //
1738 Request->RELEASE(FXREQUEST_STATE_TAG);
1739
1740 Request->SetPresented();
1741
1742 //
1743 // Drivers that use this API are responsible for handling
1744 // all locking, threading, and IRQL level issues...
1745 //
1746 InCallerContextInfo->Invoke(m_Device->GetHandle(),
1747 Request->GetHandle());
1748 //
1749 // The driver is responsible for calling WdfDeviceEnqueueRequest to insert
1750 // it back into the I/O processing pipeline, or completing it.
1751 //
1752
1753 return STATUS_PENDING;
1754}
1755
1760 )
1761{
1762 BOOLEAN failAllocation;
1764
1766 failAllocation = FALSE;
1767 //
1768 // forwardProgressTestFailAll takes precedence over forwardProgressTestFailRandom
1769 //
1771 failAllocation = TRUE;
1772 }
1774 //
1775 // Modulo 17 makes the probability of failure ~6% just like verifier.exe
1776 //
1777 failAllocation = (FxRandom(&m_RandomSeed) % 17 == 0);
1778 }
1779
1780 if (failAllocation) {
1781 //
1782 // Don't use DeleteObject() here as the Request wasn't presented to the
1783 // driver and the cleanup /dispose callback can be invoked unless
1784 // we use FreeRequest() which clears the cleanup /dispose callbacks
1785 //
1786 Request->FreeRequest();
1787
1789 }
1790 else {
1791 return STATUS_SUCCESS;
1792 }
1793}
1794
1795
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
BOOL Error
Definition: chkdsk.c:66
static FxDeviceBase * _SearchForDevice(__in FxObject *Object, __out_opt IFxHasCallbacks **Callbacks)
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
FxCxDeviceInfo * GetCxDeviceInfo(__in FxDriver *CxDriver)
Definition: fxdevice.hpp:1560
__inline PWDF_OBJECT_ATTRIBUTES GetRequestAttributes(VOID)
Definition: fxdevice.hpp:1315
__inline BOOLEAN IsCxInIoPath(VOID)
Definition: fxdevice.hpp:1594
static __inline CCHAR GetCxDriverIndex(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxdevice.hpp:1640
PFN_WDF_IO_IN_CALLER_CONTEXT m_Method
static __inline FxIoQueue * _FromPowerSListEntry(__in PSINGLE_LIST_ENTRY Entry)
Definition: fxioqueue.hpp:1226
static __inline FxIoQueue * _FromIoPkgListEntry(__in PLIST_ENTRY Entry)
Definition: fxioqueue.hpp:1216
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_IO_QUEUE_CONFIG Config, __in_opt FxDriver *Caller, __in FxPkgIo *PkgIo, __in BOOLEAN InitialPowerStateOn, __deref_out FxIoQueue **Object)
Definition: fxioqueue.cpp:164
_Must_inspect_result_ NTSTATUS QueueRequestFromForward(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2351
__inline VOID SetCxDeviceInfo(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxioqueue.hpp:1351
BOOLEAN IsIoEventHandlerRegistered(__in WDF_REQUEST_TYPE RequestType)
Definition: fxioqueue.cpp:6178
Definition: fxirp.hpp:28
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
ULONG GetParameterIoctlCode(VOID)
Definition: fxirpum.cpp:1474
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
UCHAR GetMinorFunction(VOID)
Definition: fxirpum.cpp:297
NTSTATUS CallDriver(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:36
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
ULONG __inline AddRef(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:826
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
virtual ULONG Release(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:853
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
_Must_inspect_result_ NTSTATUS SetFilter(__in BOOLEAN Value)
Definition: fxpkgio.cpp:1120
_Must_inspect_result_ NTSTATUS CreateQueue(__in PWDF_IO_QUEUE_CONFIG Config, __in PWDF_OBJECT_ATTRIBUTES QueueAttributes, __in_opt FxDriver *Caller, __deref_out FxIoQueue **ppQueue)
Definition: fxpkgio.cpp:981
FxIoQueue * m_DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: fxpkgio.hpp:75
_Must_inspect_result_ NTSTATUS FlushAllQueuesByFileObject(__in MdFileObject FileObject)
Definition: fxpkgio.cpp:1393
FxPkgIo(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device)
Definition: fxpkgio.cpp:47
_Must_inspect_result_ NTSTATUS VerifierFreeRequestToTestForwardProgess(__in FxRequest *Request)
Definition: fxpkgio.cpp:1758
FxIoQueue * GetFirstIoQueueLocked(__in FxIoQueueNode *QueueBookmark, __in PVOID Tag)
Definition: fxpkgio.cpp:1610
virtual _Must_inspect_result_ NTSTATUS Dispatch(__inout MdIrp Irp)
Definition: fxpkgio.cpp:104
FxDriver * GetDriver(VOID)
Definition: fxpkgio.cpp:543
_Must_inspect_result_ NTSTATUS ConfigureForwarding(__inout FxIoQueue *TargetQueue, __in WDF_REQUEST_TYPE RequestType)
Definition: fxpkgio.cpp:910
_Must_inspect_result_ NTSTATUS ResumeProcessingForPower()
Definition: fxpkgio.cpp:1254
~FxPkgIo()
Definition: fxpkgio.cpp:80
FxIoQueue * m_DefaultQueue
Definition: fxpkgio.hpp:62
VOID ResetStateForRestart(VOID)
Definition: fxpkgio.cpp:1332
VOID RemoveIoQueue(__inout FxIoQueue *IoQueue)
Definition: fxpkgio.cpp:1593
_Must_inspect_result_ NTSTATUS __fastcall DispatchStep1(__inout MdIrp Irp, __in WDFCONTEXT DispatchContext)
Definition: fxpkgio.cpp:165
_Must_inspect_result_ NTSTATUS EnqueueRequest(__in CfxDevice *Device, __inout FxRequest *pRequest)
Definition: fxpkgio.cpp:607
ULONG m_RandomSeed
Definition: fxpkgio.hpp:81
BOOLEAN m_QueuesAreShuttingDown
Definition: fxpkgio.hpp:91
VOID AddIoQueue(__inout FxIoQueue *IoQueue)
Definition: fxpkgio.cpp:1533
__inline FxIoInCallerContext * GetIoInCallerContextCallback(__in_opt FxCxDeviceInfo *CxDeviceInfo)
Definition: fxpkgio.hpp:396
_Must_inspect_result_ NTSTATUS __fastcall DispatchStep2(__inout MdIrp Irp, __in_opt FxIoInCallerContext *IoInCallerCtx, __in_opt FxIoQueue *Queue)
Definition: fxpkgio.cpp:342
BOOLEAN m_PowerStateOn
Definition: fxpkgio.hpp:86
NTSTATUS DispathToInCallerContextCallback(__in FxIoInCallerContext *InCallerContextInfo, __in FxRequest *Request, __inout MdIrp Irp)
Definition: fxpkgio.cpp:1699
LIST_ENTRY m_IoQueueListHead
Definition: fxpkgio.hpp:70
FxIoQueue * GetNextIoQueueLocked(__in FxIoQueueNode *QueueBookmark, __in PVOID Tag)
Definition: fxpkgio.cpp:1640
VOID RemoveQueueReferences(__inout FxIoQueue *pQueue)
Definition: fxpkgio.cpp:1091
_Must_inspect_result_ NTSTATUS StopProcessingForPower(__in FxIoStopProcessingForPowerAction Action)
Definition: fxpkgio.cpp:1143
_Must_inspect_result_ NTSTATUS ConfigureDynamicDispatching(__in UCHAR MajorFunction, __in_opt FxCxDeviceInfo *CxDeviceInfo, __in PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch, __in_opt WDFCONTEXT DriverContext)
Definition: fxpkgio.cpp:786
BOOLEAN m_Filter
Definition: fxpkgio.hpp:84
VOID GetIoQueueListLocked(__in PSINGLE_LIST_ENTRY SListHead, __inout FxIoIteratorList ListType)
Definition: fxpkgio.cpp:1480
LIST_ENTRY m_DynamicDispatchInfoListHead
Definition: fxpkgio.hpp:98
_Must_inspect_result_ NTSTATUS InitializeDefaultQueue(__in CfxDevice *Device, __inout FxIoQueue *Queue)
Definition: fxpkgio.cpp:489
__inline BOOLEAN HasContext(VOID)
SHORT GetVerifierFlagsLocked(VOID)
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
VOID PreProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1101
FxRequestCompletionState SetCompletionState(__in FxRequestCompletionState NewState)
Definition: fxrequest.cpp:1760
static _Must_inspect_result_ NTSTATUS _CreateForPackage(__in CfxDevice *Device, __in PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in MdIrp Irp, __deref_out FxRequest **Request)
Definition: fxrequest.cpp:75
__inline PVOID GetInternalContext(VOID)
Definition: fxrequest.hpp:1492
VOID PostProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1149
static __inline VOID MxQueryTickCount(__out PLARGE_INTEGER TickCount)
Definition: mxgeneralkm.h:116
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
Definition: _queue.h:67
_In_ PIRP Irp
Definition: csq.h:116
#define __in
Definition: dbghelp.h:35
#define __deref_out
Definition: dbghelp.h:26
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KIRQL irql
Definition: wave.h:1
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
PFX_DRIVER_GLOBALS fxDriverGlobals
return pDevice GetDriver() -> GetHandle()
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ WDFDRIVER _In_ UCHAR _In_ PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch
FX_TRACK_DRIVER(fxDriverGlobals)
FxIoInCallerContext * ioInCallerCtx
FxIrp fxIrp(Irp)
FxIoQueue * pQueue
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
FxDriver * pDriver
PSINGLE_LIST_ENTRY ple
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
FxObject * pParent
Definition: fxdpcapi.cpp:86
__inline ULONG FxRandom(__inout PULONG RandomSeed)
Definition: fxglobals.h:1054
@ FxIoQueueNodeTypeQueue
Definition: fxioqueue.hpp:46
@ FxIoQueueNodeTypeBookmark
Definition: fxioqueue.hpp:47
@ FxIoQueuePowerOn
Definition: fxioqueue.hpp:132
@ FxIoQueuePowerOff
Definition: fxioqueue.hpp:133
#define FX_VF_METHOD(classname, fnName)
Definition: fxmacros.hpp:43
PLIST_ENTRY next
Definition: fxpkgio.cpp:130
PAGED_CODE_LOCKED()
static VOID GetIoQueueList_ProcessQueueListEntry(PLIST_ENTRY QueueLE, PSINGLE_LIST_ENTRY SListHead, PVOID Tag)
Definition: fxpkgio.cpp:1451
KIRQL irql
Definition: fxpkgio.cpp:562
_Must_inspect_result_ NTSTATUS _In_ WDFCONTEXT DispatchContext
Definition: fxpkgio.cpp:127
_Must_inspect_result_ NTSTATUS _In_ FxRequest _Inout_ SHORT * OrigVerifierFlags
Definition: fxpkgio.cpp:557
return status
Definition: fxpkgio.cpp:159
_Must_inspect_result_ NTSTATUS _In_ FxRequest * Request
Definition: fxpkgio.cpp:554
BOOLEAN ctxValid
Definition: fxpkgio.cpp:129
#define FX_IN_DISPATCH_CALLBACK
Definition: fxpkgio.hpp:39
#define IO_ITERATOR_POWER_TAG
Definition: fxpkgio.hpp:48
FxIoIteratorList
Definition: fxpkgio.hpp:41
@ FxIoQueueIteratorListPowerOn
Definition: fxpkgio.hpp:43
@ FxIoQueueIteratorListPowerOff
Definition: fxpkgio.hpp:44
#define IO_ITERATOR_FLUSH_TAG
Definition: fxpkgio.hpp:47
FxIoStopProcessingForPowerAction
@ FxIoStopProcessingForPowerHold
@ FxIoStopProcessingForPowerPurgeNonManaged
@ FxIoStopProcessingForPowerPurgeManaged
#define FXREQUEST_STATE_TAG
Definition: fxrequest.hpp:42
@ FXREQUEST_FLAG_DRIVER_INPROCESS_CONTEXT
@ FXREQUEST_FLAG_DRIVER_OWNED
FxRequestCompletionState
@ FxRequestCompletionStateIoPkg
@ FxRequestCompletionStateNone
@ FX_TYPE_PACKAGE_IO
Definition: fxtypes.h:92
@ FX_TYPE_OBJECT
Definition: fxtypes.h:45
@ FX_TYPE_DRIVER
Definition: fxtypes.h:46
__inline BOOLEAN IsFxVerifierTestForwardProgressFailRandom(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:220
__inline BOOLEAN IsFxVerifierTestForwardProgressFailAll(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:205
__inline BOOLEAN IsFxVerifierTestForwardProgress(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:235
GLuint index
Definition: glext.h:6031
#define ASSERT(a)
Definition: mode.c:44
#define __fastcall
Definition: sync.c:38
#define _Inout_
Definition: ms_sal.h:378
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define _In_
Definition: ms_sal.h:308
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_PENDING
Definition: ntstatus.h:82
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
static FxIoQueueNode * _FromListEntry(__in PLIST_ENTRY Entry)
Definition: fxioqueue.hpp:98
__inline BOOLEAN IsNodeType(__in FxIoQueueNodeType NodeType)
Definition: fxioqueue.hpp:117
PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceDynamicDispatch
static __inline int Mj2Index(UCHAR MajorFunction)
Info Dispatch[DynamicDispatchMax]
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
FxDriver * Driver
Definition: fxglobals.h:374
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: tftpd.h:86
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
struct _LIST_ENTRY * PLIST_ENTRY
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_In_ UCHAR _In_ UCHAR _In_ ULONG _In_ WDFCONTEXT DriverContext
Definition: wdfdevice.h:1703
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_In_ UCHAR _In_ UCHAR _In_ ULONG _In_ WDFCONTEXT _Inout_ PIRP _In_ WDFCONTEXT DispatchContext
Definition: wdfdevice.h:1708
EVT_WDFDEVICE_WDM_IRP_DISPATCH * PFN_WDFDEVICE_WDM_IRP_DISPATCH
Definition: wdfdevice.h:1710
enum _WDF_REQUEST_TYPE WDF_REQUEST_TYPE
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4233
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_IO_QUEUE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES QueueAttributes
Definition: wdfio.h:617
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
PVOID WDFCONTEXT
Definition: wdftypes.h:94
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IRP_MJ_MAXIMUM_FUNCTION
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240
unsigned char UCHAR
Definition: xmlstorage.h:181