ReactOS  0.4.15-dev-2700-g4b4ffa9
fxpkgio.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxPkgIo.cpp
8 
9 Abstract:
10 
11  This module implements the I/O package for the driver frameworks.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19  Both kernel and user mode
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #include "ioprivshared.hpp"
28 
29 // Tracing support
30 extern "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 
56  m_Device = Device;
57 
59 
61 
62  m_Filter = FALSE;
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 
103 NTSTATUS
106  )
107 {
108  FxIrp fxIrp(Irp);
110 
113  "WDFDEVICE 0x%p !devobj 0x%p %!IRPMJ!, IRP_MN %x, IRP 0x%p",
117 
119 }
120 
122 NTSTATUS
123 FX_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) {
144  if ((PLIST_ENTRY)DispatchContext == next) {
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 
163 NTSTATUS
166  __inout MdIrp Irp,
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 
176 Arguments:
177 
178  Irp - WDM request.
179 
180  DispatchContext - Is the next FxIrpDynamicDispatchInfo element.
181 
182 Return 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(
251  m_Device->GetHandle(),
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  //
269  FxIoQueue* queue;
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 {
297  ioInCallerCtx = GetIoInCallerContextCallback(queue->GetCxDeviceInfo());
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 &&
311  queue == m_DefaultQueue &&
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 
325 Forward:
326 
329 
331 
335 
336  return status;
337 }
338 
340 NTSTATUS
343  __inout MdIrp Irp,
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  //
371  if (Mx::MxGetCurrentIrql() <= APC_LEVEL) {
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 &&
390  NT_SUCCESS(status) &&
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  //
478 IrpIsGone:
479 
480  if (inCriticalRegion) {
481  Mx::MxLeaveCriticalRegion();
482  }
483 
484  return status;
485 }
486 
488 NTSTATUS
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 
505 Arguments:
506 
507 
508 Return 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 
525  for (index=0; index <= IRP_MJ_MAXIMUM_FUNCTION; index++) {
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
542 FxDriver*
544  VOID
545  )
546 {
547  return m_Device->GetDriver();
548 }
549 
551 NTSTATUS
552 FX_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 
583 VOID
584 FX_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 //
606 NTSTATUS
610  )
611 {
613  FxIoQueue* pQueue;
614  FxIrp* Irp = NULL;
615  FxRequestCompletionState oldState;
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 &&
676  pQueue == m_DefaultQueue &&
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
688  pRequest->ADDREF(FXREQUEST_STATE_TAG);
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  //
720  pRequest->RELEASE(FXREQUEST_STATE_TAG);
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 
732 Forward:
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 
774 Error:
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 
785 NTSTATUS
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 
904 Done:
905  return status;
906 }
907 
909 NTSTATUS
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
950  if (m_DispatchTable[RequestType] != NULL &&
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 
980 NTSTATUS
984  __in_opt FxDriver* Caller,
985  __deref_out FxIoQueue** ppQueue
986  )
987 {
989  FxObject* pParent;
990  FxIoQueue* pQueue;
992  FxDriver* pDriver;
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 
1007  pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL);
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(),
1029  m_Device->GetHandle(), status);
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 
1083  AddIoQueue(pQueue);
1084  *ppQueue = pQueue;
1085 
1086  return status;
1087 }
1088 
1089 
1090 VOID
1093  )
1094 /*++
1095 
1096 Routine 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 
1105 Arguments:
1106 
1107  None
1108 
1109 Return Value:
1110  None
1111  --*/
1112 {
1113  // Remove it from transacation list
1115  return;
1116 }
1117 
1119 NTSTATUS
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 
1142 NTSTATUS
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 
1157 Arguments:
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 
1175 Return Value:
1176 
1177  NTSTATUS
1178 
1179 --*/
1180 
1181 {
1182  KIRQL irql;
1183  FxIoQueue* queue;
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 
1253 NTSTATUS
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 
1265 Arguments:
1266 
1267 Return Value:
1268 
1269  NTSTATUS
1270 
1271 --*/
1272 
1273 {
1274  KIRQL irql;
1275  FxIoQueue* queue;
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  //
1291  m_PowerStateOn = TRUE;
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 
1331 VOID
1333  VOID
1334  )
1335 /*++
1336 
1337 Routine 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 
1342 Arguments:
1343  None
1344 
1345 Return Value:
1346  None
1347 
1348  --*/
1349 {
1350  KIRQL irql;
1351  FxIoQueue* queue;
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 
1381  m_PowerStateOn = TRUE;
1382 
1384 
1385  Unlock(irql);
1386 
1387  return;
1388 
1389 }
1390 
1392 NTSTATUS
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 
1449 static
1450 VOID
1452  PLIST_ENTRY QueueLE,
1453  PSINGLE_LIST_ENTRY SListHead,
1454  PVOID Tag
1455  )
1456 {
1457  FxIoQueueNode* listNode;
1458  FxIoQueue* queue;
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 
1479 VOID
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 
1532 VOID
1534  __inout FxIoQueue* IoQueue
1535  )
1536 {
1537  PLIST_ENTRY listHead, le;
1538  FxIoQueue* queue;
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 
1592 VOID
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 
1609 FxIoQueue*
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 
1639 FxIoQueue*
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 {
1658  PLIST_ENTRY ple = NULL;
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  //
1677  listNode = FxIoQueueNode::_FromListEntry(ple);
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 
1698 NTSTATUS
1700  __in FxIoInCallerContext *InCallerContextInfo,
1702  __inout MdIrp Irp
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 
1730  ASSERT(oldState == FxRequestCompletionStateNone);
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 
1757 NTSTATUS
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 
struct _LIST_ENTRY * PLIST_ENTRY
VOID ResetStateForRestart(VOID)
Definition: fxpkgio.cpp:1332
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
NTSTATUS DispathToInCallerContextCallback(__in FxIoInCallerContext *InCallerContextInfo, __in FxRequest *Request, __inout MdIrp Irp)
Definition: fxpkgio.cpp:1699
CfxDevice * m_Device
Definition: fxobject.hpp:329
_Must_inspect_result_ NTSTATUS ResumeProcessingForPower()
Definition: fxpkgio.cpp:1254
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126
#define GetHandle(h)
Definition: treelist.c:116
FxRequestCompletionState SetCompletionState(__in FxRequestCompletionState NewState)
Definition: fxrequest.cpp:1760
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_IO_QUEUE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES QueueAttributes
Definition: wdfio.h:613
_In_ UCHAR _In_ UCHAR _In_ ULONG _In_ WDFCONTEXT _Inout_ PIRP _In_ WDFCONTEXT DispatchContext
Definition: wdfdevice.h:1697
#define _Must_inspect_result_
Definition: no_sal2.h:62
virtual ULONG Release(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:853
FxIoQueue * queue
ULONG m_RandomSeed
Definition: fxpkgio.hpp:81
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
FxIoQueue * pQueue
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LIST_ENTRY m_DynamicDispatchInfoListHead
Definition: fxpkgio.hpp:98
VOID RemoveQueueReferences(__inout FxIoQueue *pQueue)
Definition: fxpkgio.cpp:1091
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
_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
Definition: ntbasedef.h:628
static __inline VOID MxQueryTickCount(__out PLARGE_INTEGER TickCount)
Definition: mxgeneralkm.h:116
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
#define __fastcall
Definition: sync.c:38
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
FxIoQueue * GetFirstIoQueueLocked(__in FxIoQueueNode *QueueBookmark, __in PVOID Tag)
Definition: fxpkgio.cpp:1610
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
__inline BOOLEAN IsNodeType(__in FxIoQueueNodeType NodeType)
Definition: fxioqueue.hpp:117
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
static __inline FxIoQueue * _FromIoPkgListEntry(__in PLIST_ENTRY Entry)
Definition: fxioqueue.hpp:1216
static FxIoQueueNode * _FromListEntry(__in PLIST_ENTRY Entry)
Definition: fxioqueue.hpp:98
BOOLEAN m_PowerStateOn
Definition: fxpkgio.hpp:86
FxRequest * pRequest
Definition: fxirp.hpp:28
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Must_inspect_result_ NTSTATUS _In_ FxRequest * Request
Definition: fxpkgio.cpp:554
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
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
__inline BOOLEAN IsFxVerifierTestForwardProgressFailAll(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:205
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
FxIoQueue * m_DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: fxpkgio.hpp:75
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
#define InsertTailList(ListHead, Entry)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FxIoQueue * GetNextIoQueueLocked(__in FxIoQueueNode *QueueBookmark, __in PVOID Tag)
Definition: fxpkgio.cpp:1640
static __inline int Mj2Index(UCHAR MajorFunction)
_Must_inspect_result_ NTSTATUS __fastcall DispatchStep2(__inout MdIrp Irp, __in_opt FxIoInCallerContext *IoInCallerCtx, __in_opt FxIoQueue *Queue)
Definition: fxpkgio.cpp:342
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
VOID PostProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1149
PSINGLE_LIST_ENTRY ple
EVT_WDFDEVICE_WDM_IRP_DISPATCH * PFN_WDFDEVICE_WDM_IRP_DISPATCH
Definition: wdfdevice.h:1710
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
static FxDeviceBase * _SearchForDevice(__in FxObject *Object, __out_opt IFxHasCallbacks **Callbacks)
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4227
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxRequest * request
BOOLEAN m_Filter
Definition: fxpkgio.hpp:84
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define IO_ITERATOR_FLUSH_TAG
Definition: fxpkgio.hpp:47
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
_Must_inspect_result_ NTSTATUS EnqueueRequest(__in CfxDevice *Device, __inout FxRequest *pRequest)
Definition: fxpkgio.cpp:607
long LONG
Definition: pedump.c:60
static __inline CCHAR GetCxDriverIndex(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxdevice.hpp:1640
VOID GetIoQueueListLocked(__in PSINGLE_LIST_ENTRY SListHead, __inout FxIoIteratorList ListType)
Definition: fxpkgio.cpp:1480
short SHORT
Definition: pedump.c:59
FxDriver * Driver
Definition: fxglobals.h:374
FxPkgIo(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device)
Definition: fxpkgio.cpp:47
#define IO_ITERATOR_POWER_TAG
Definition: fxpkgio.hpp:48
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
BOOLEAN m_QueuesAreShuttingDown
Definition: fxpkgio.hpp:91
VOID PreProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1101
_Must_inspect_result_ NTSTATUS FX_VF_METHOD(FxPkgIo, VerifyDispatchContext)(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
Definition: _queue.h:59
unsigned char BOOLEAN
NTSTATUS CallDriver(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:36
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
FxIoInCallerContext * ioInCallerCtx
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
IWudfIrp * MdIrp
Definition: mxum.h:103
PLIST_ENTRY next
Definition: fxpkgio.cpp:130
#define FXREQUEST_STATE_TAG
Definition: fxrequest.hpp:42
GLuint index
Definition: glext.h:6031
static __inline FxIoQueue * _FromPowerSListEntry(__in PSINGLE_LIST_ENTRY Entry)
Definition: fxioqueue.hpp:1226
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240
__inline VOID SetCxDeviceInfo(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxioqueue.hpp:1351
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
BOOLEAN ctxValid
Definition: fxpkgio.cpp:129
FxIoQueue * m_DefaultQueue
Definition: fxpkgio.hpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
FxDriver * pDriver
#define TRACINGDEVICE
Definition: dbgtrace.h:58
PVOID WDFCONTEXT
Definition: wdftypes.h:94
PFX_DRIVER_GLOBALS pFxDriverGlobals
_Must_inspect_result_ NTSTATUS SetFilter(__in BOOLEAN Value)
Definition: fxpkgio.cpp:1120
enum _WDF_REQUEST_TYPE WDF_REQUEST_TYPE
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ WDFDRIVER _In_ UCHAR _In_ PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch
char CCHAR
Definition: typedefs.h:51
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
PFN_WDF_IO_IN_CALLER_CONTEXT m_Method
__inline PVOID GetInternalContext(VOID)
Definition: fxrequest.hpp:1492
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
BOOL Error
Definition: chkdsk.c:66
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
FxRequestCompletionState
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define _Inout_
Definition: no_sal2.h:162
FxIoStopProcessingForPowerAction
VOID AddIoQueue(__inout FxIoQueue *IoQueue)
Definition: fxpkgio.cpp:1533
_Must_inspect_result_ NTSTATUS QueueRequestFromForward(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2351
_Must_inspect_result_ NTSTATUS VerifierFreeRequestToTestForwardProgess(__in FxRequest *Request)
Definition: fxpkgio.cpp:1758
struct _test_info info[]
Definition: SetCursorPos.c:19
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ NTSTATUS __fastcall DispatchStep1(__inout MdIrp Irp, __in WDFCONTEXT DispatchContext)
Definition: fxpkgio.cpp:165
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
#define index(s, c)
Definition: various.h:29
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
#define VOID
Definition: acefi.h:82
ULONG LowPart
Definition: typedefs.h:106
BOOLEAN IsIoEventHandlerRegistered(__in WDF_REQUEST_TYPE RequestType)
Definition: fxioqueue.cpp:6178
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
FxIoIteratorList
Definition: fxpkgio.hpp:41
#define __inout
Definition: dbghelp.h:50
Definition: typedefs.h:119
_Must_inspect_result_ NTSTATUS InitializeDefaultQueue(__in CfxDevice *Device, __inout FxIoQueue *Queue)
Definition: fxpkgio.cpp:489
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define _In_
Definition: no_sal2.h:158
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
SHORT GetVerifierFlagsLocked(VOID)
__inline BOOLEAN HasContext(VOID)
__inline BOOLEAN IsCxInIoPath(VOID)
Definition: fxdevice.hpp:1594
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__inline BOOLEAN IsFxVerifierTestForwardProgress(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:235
_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
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
_Must_inspect_result_ NTSTATUS FlushAllQueuesByFileObject(__in MdFileObject FileObject)
Definition: fxpkgio.cpp:1393
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
_Must_inspect_result_ NTSTATUS _In_ FxRequest _Inout_ SHORT * OrigVerifierFlags
Definition: fxpkgio.cpp:557
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
FxCxDeviceInfo * GetCxDeviceInfo(__in FxDriver *CxDriver)
Definition: fxdevice.hpp:1560
Info Dispatch[DynamicDispatchMax]
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PFX_DRIVER_GLOBALS fxDriverGlobals
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxIrp fxIrp(Irp)
#define NULL
Definition: types.h:112
_Must_inspect_result_ NTSTATUS ConfigureForwarding(__inout FxIoQueue *TargetQueue, __in WDF_REQUEST_TYPE RequestType)
Definition: fxpkgio.cpp:910
Definition: tftpd.h:85
ULONG __inline AddRef(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:826
#define IRP_MJ_READ
Definition: rdpdr.c:46
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
FX_TRACK_DRIVER(fxDriverGlobals)
#define __deref_out
Definition: dbghelp.h:26
UCHAR GetMinorFunction(VOID)
Definition: fxirpum.cpp:297
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
_Must_inspect_result_ NTSTATUS _In_ WDFCONTEXT DispatchContext
Definition: fxpkgio.cpp:127
__inline PWDF_OBJECT_ATTRIBUTES GetRequestAttributes(VOID)
Definition: fxdevice.hpp:1315
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
FxObject * pParent
Definition: fxdpcapi.cpp:86
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
static VOID GetIoQueueList_ProcessQueueListEntry(PLIST_ENTRY QueueLE, PSINGLE_LIST_ENTRY SListHead, PVOID Tag)
Definition: fxpkgio.cpp:1451
virtual _Must_inspect_result_ NTSTATUS Dispatch(__inout MdIrp Irp)
Definition: fxpkgio.cpp:104
LIST_ENTRY m_IoQueueListHead
Definition: fxpkgio.hpp:70
return status
Definition: fxpkgio.cpp:159
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIO
Definition: dbgtrace.h:66
ULONG GetParameterIoctlCode(VOID)
Definition: fxirpum.cpp:1474
PAGED_CODE_LOCKED()
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
#define FX_IN_DISPATCH_CALLBACK
Definition: fxpkgio.hpp:39
#define __in
Definition: dbghelp.h:35
VOID RemoveIoQueue(__inout FxIoQueue *IoQueue)
Definition: fxpkgio.cpp:1593
__inline BOOLEAN IsFxVerifierTestForwardProgressFailRandom(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:220
#define APC_LEVEL
Definition: env_spec_w32.h:695
_In_ UCHAR _In_ UCHAR _In_ ULONG _In_ WDFCONTEXT DriverContext
Definition: wdfdevice.h:1697
PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceDynamicDispatch
__inline FxIoInCallerContext * GetIoInCallerContextCallback(__in_opt FxCxDeviceInfo *CxDeviceInfo)
Definition: fxpkgio.hpp:396
~FxPkgIo()
Definition: fxpkgio.cpp:80
__inline ULONG FxRandom(__inout PULONG RandomSeed)
Definition: fxglobals.h:1054
_Must_inspect_result_ NTSTATUS StopProcessingForPower(__in FxIoStopProcessingForPowerAction Action)
Definition: fxpkgio.cpp:1143
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
FxDriver * GetDriver(VOID)
Definition: fxpkgio.cpp:543
KIRQL irql
Definition: fxpkgio.cpp:562
Definition: ps.c:97
_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