ReactOS  0.4.15-dev-2704-gd5265b0
fxpkggeneral.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxPkgGeneral.cpp
8 
9 Abstract:
10 
11  This module implements the wmi package for the driver frameworks.
12 
13 Author:
14 
15 
16 
17 
18 Environment:
19 
20  Both kernel and user mode
21 
22 Revision History:
23 
24 --*/
25 
26 #if ((FX_CORE_MODE)==(FX_CORE_USER_MODE))
27 #define FX_IS_USER_MODE (TRUE)
28 #define FX_IS_KERNEL_MODE (FALSE)
29 #elif ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
30 #define FX_IS_USER_MODE (FALSE)
31 #define FX_IS_KERNEL_MODE (TRUE)
32 #endif
33 
34 extern "C" {
35 #include "mx.h"
36 }
37 #include "fxmin.hpp"
38 
39 extern "C" {
40 // #include "FxPkgGeneral.tmh"
41 }
42 
43 
45  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
47  ) :
48  FxPackage(FxDriverGlobals, Device, FX_TYPE_PACKAGE_GENERAL)
49 {
50  //
51  // The count is biased to one and not zero for control device objects. When
52  // a control devobj is deleted, we will decrement this bias out so that we
53  // know when the last handle has been closed and it is now safe to free the
54  // FxDevice.
55  //
57 
58  //
59  // List of file object info.
60  //
62 
63  m_Flags = 0;
70 }
71 
73 {
75 
77 
78  //
79  // Delete the file object info list if present.
80  //
86  delete info;
87  }
88 }
89 
94  )
95 /*++
96 
97 Routine Description:
98  Initiliazes how the driver will handle fileobjects and their associated
99  event callbacks (create, close, cleanup).
100 
101  Assumes that FileObjectAttributes has been validated by the caller.
102 
103 Arguments:
104  DeviceInit - Chain of device_init and cx_device_init with file object config.
105 
106 Return Value:
107  STATUS_SUCCESS or other NTSTATUS values.
108 
109  --*/
110 {
113  FxFileObjectInfo* fileObjInfo;
115 
117 
118  //
119  // Init file object info.
120  //
121  if (DeviceInit->FileObject.Set) {
122  fileObjInfo = new(fxDriverGlobals) FxFileObjectInfo();
123  if (fileObjInfo == NULL) {
127  "Couldn't create object FileObjectInfo, "
128  "%!STATUS!", status);
129  goto Done;
130  }
131 
132  fileObjInfo->ClassExtension = FALSE;
133  fileObjInfo->FileObjectClass = DeviceInit->FileObject.Class;
134  fileObjInfo->Attributes = DeviceInit->FileObject.Attributes;
135 
136  fileObjInfo->AutoForwardCleanupClose =
137  DeviceInit->FileObject.AutoForwardCleanupClose;
138 
139  fileObjInfo->EvtFileCreate.Method =
140  DeviceInit->FileObject.Callbacks.EvtDeviceFileCreate;
141 
142  fileObjInfo->EvtFileCleanup.Method =
143  DeviceInit->FileObject.Callbacks.EvtFileCleanup;
144 
145  fileObjInfo->EvtFileClose.Method =
146  DeviceInit->FileObject.Callbacks.EvtFileClose;
147 
149 
151 
152  if (fileObjInfo->EvtFileCreate.Method != NULL) {
154  }
155  }
156 
157  //
158  // Build file object info chain for any class extension.
159  //
160  for (next = DeviceInit->CxDeviceInitListHead.Flink;
161  next != &DeviceInit->CxDeviceInitListHead;
162  next = next->Flink) {
163 
164  PWDFCXDEVICE_INIT cxInit;
165 
166  cxInit = CONTAINING_RECORD(next, WDFCXDEVICE_INIT, ListEntry);
167 
168  if (cxInit->FileObject.Set == FALSE) {
169  continue;
170  }
171 
172  fileObjInfo = new(fxDriverGlobals) FxFileObjectInfo();
173  if (fileObjInfo == NULL) {
177  "Couldn't create object FileObjectInfo, "
178  "%!STATUS!", status);
179  goto Done;
180  }
181 
182  fileObjInfo->ClassExtension = TRUE;
183  fileObjInfo->FileObjectClass = cxInit->FileObject.Class;
184  fileObjInfo->Attributes = cxInit->FileObject.Attributes;
185 
186  fileObjInfo->AutoForwardCleanupClose =
188 
189  fileObjInfo->EvtCxFileCreate.Method =
191 
192  fileObjInfo->EvtFileCleanup.Method =
194 
195  fileObjInfo->EvtFileClose.Method =
197 
198  fileObjInfo->CxDeviceInfo = cxInit->CxDeviceInfo;
199 
201 
203 
204  if (fileObjInfo->EvtCxFileCreate.Method != NULL) {
206  }
207  }
208 
209  //
210  // Nothing to do if list if empty.
211  //
214  goto Done;
215  }
216 
217  //
218  // We will enable this once the unlocking model is figured out.
219  // It's not okay to sent request downstack with the presentation lock held.
220  //
222  if(!NT_SUCCESS(status)) {
223  goto Done;
224  }
225 
226  //
227  // Configure file object class.
228  //
230  if (!NT_SUCCESS(status)) {
231  goto Done;
232  }
233 
235 
236 Done:
237  return status;
238 }
239 
241 NTSTATUS
243  __in PLIST_ENTRY FileObjInfoList
244  )
245 /*++
246 
247 Routine Description:
248 
249  Configure the callback synchronization according to the configuration supplied by the
250  client and class extension device driver.
251  It is a requirement for this driver chain (CXs and client driver) to use the same settings.
252 
253 Arguments:
254  FileObjInfoList - List of FxFileObjectInfo structs.
255 
256 Returns:
257  NTSTATUS
258 
259 --*/
260 {
261  WDF_EXECUTION_LEVEL execLevel, parentExecLevel;
262  WDF_SYNCHRONIZATION_SCOPE synchScope, parentSynchScope;
263  BOOLEAN automaticLockingRequired;
265  FxFileObjectInfo *fileObjInfo;
268 
269  automaticLockingRequired = FALSE;
271 
272  ASSERT(!IsListEmpty(FileObjInfoList));
273 
274  //
275  // Get parent values.
276  //
277  m_Device->GetConstraints(&parentExecLevel, &parentSynchScope);
278 
279  //
280  // Default constraints settings when driver uses WDF_NO_OBJECT_ATTRIBUTES:
281  //
282  // v1.9 and below:
283  // WdfExecutionLevelDispatch and WdfSynchronizationScopeNone
284  //
285  // v1.11 and above:
286  // WdfExecutionLevelPassive and WdfSynchronizationScopeNone
287  //
288  // In v1.9 and below if driver used WDF_NO_OBJECT_ATTRIBUTES for
289  // the file object's attributes, the synchronization scope and execution
290  // level were left uninitialized (i.e., zero), which means that WDF
291  // defaulted to WdfSynchronizationScopeInvalid and WdfExecutionLevelInvalid,
292  // WDF interpreted these values as no_passive and no_synchronization.
293  //
294  // This default execution level is used when disposing the device's
295  // general package object and file object object.
296  // Independently of these settings WDF guarantees that Create,
297  // Cleanup and Close callbacks are always called at passive level.
298  //
302 
304 
305  //
306  // Make sure file object info chain follow these constrains:
307  // Cx's synch scope: none
308  //
309  for (next = FileObjInfoList->Blink;
310  next != FileObjInfoList;
311  next = next->Blink) {
312 
313  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
314 
315  //
316  // Size is zero if driver didn't specify any attributes.
317  //
318  if (0 == fileObjInfo->Attributes.Size) {
319  continue;
320  }
321 
322  //
323  // Execution level checks.
324  //
325  execLevel = fileObjInfo->Attributes.ExecutionLevel;
326  if (WdfExecutionLevelInheritFromParent == execLevel) {
327  execLevel = parentExecLevel;
328  }
329 
330  //
331  // Passive level wins over DPC level.
332  //
333  if (WdfExecutionLevelPassive == execLevel) {
335  }
336 
337  //
338  // Synchronization scope checks.
339  //
340  synchScope = fileObjInfo->Attributes.SynchronizationScope;
341  if (WdfSynchronizationScopeInheritFromParent == synchScope) {
342  synchScope = parentSynchScope;
343  }
344 
345  //
346  // Make sure the Cx's synch scope is none.
347  //
348  if (fileObjInfo->ClassExtension) {
349  if (synchScope != WdfSynchronizationScopeNone) {
353  "Driver 0x%p - Device 0x%p - synchronization scope: "
354  "%!WDF_SYNCHRONIZATION_SCOPE! should be"
355  "WdfSynchronizationScopeNone, %!STATUS!",
356  m_Device->GetCxDriver(fileObjInfo->CxDeviceInfo)->GetHandle(),
357  m_Device->GetHandle(),
358  synchScope,
359  status
360  );
361 
363  goto Done;
364  }
365  }
366  else {
367  //
368  // Always use client's synch scope for file object.
369  //
370  m_SynchronizationScope = synchScope;
371  }
372  }
373 
378  "WdfSynchronizationScopeQueue is not allowed on "
379  "FileObject, %!STATUS!",
380  status);
381  goto Done;
382  }
383 
385 
386  //
387  // Mark FxObject as passive level to ensure that Dispose and Destroy
388  // callbacks are passive to the driver
389  //
391  //
392  // We aren't going to use a workitem to defer the invocation of fileevents
393  // to passive-level if the caller is at DISPATCH_LEVEL because we wouldn't
394  // be able to guarantee the caller's context for fileevents. It's up to the
395  // driver writer to ensure that the layer above doesn't send create requests
396  // at dispatch-level.
397  //
398  }
399 
402  goto Done;
403  }
404 
406  //
407  // Since FileEvents can be invoked only at passive-level, we check the
408  // parent executionlevel to see if it's set to passive. If not, we return an error
409  // because we can't use the presentation lock of the device.
410  //
411  if(parentExecLevel != WdfExecutionLevelPassive) {
415  "WdfSynchronizationScopeDevice or "
416  "WdfSynchronizationScopeInheritFromParent "
417  "allowed only if the parent WDFDEVICE 0x%p, "
418  "ExecutionLevel is passive, %!STATUS!",
420  goto Done;
421  }
422 
424  automaticLockingRequired = TRUE;
425  }
426 
427  //
428  // Set lock constraint in client's callbacks object only.
429  //
430  if (automaticLockingRequired) {
431  if (!IsListEmpty(FileObjInfoList)) {
432  fileObjInfo = CONTAINING_RECORD(FileObjInfoList->Flink,
434  ListEntry);
435 
436  if (FALSE == fileObjInfo->ClassExtension) {
440  }
441  }
442  }
443 
445 
446 Done:
447  return status;
448 }
449 
451 NTSTATUS
453  __in PLIST_ENTRY FileObjInfoList
454  )
455 /*++
456 
457 Routine Description:
458 
459  Configure the file object class for this device.
460 
461  These are the possible class settings:
462 
463  WdfFileObjectNotRequired
464  WdfFileObjectWdfCanUseFsContext*
465  WdfFileObjectWdfCanUseFsContext2*,
466  WdfFileObjectWdfCannotUseFsContexts*
467 
468  * these can also be combined with WdfFileObjectCanBeOptional flag.
469 
470  Logic:
471 
472  - default: not_required.
473  - if cx/driver selects not_required, skip it.
474  - if cx/driver selects !not_required, than
475  . if everyone agrees on the setting, use that setting.
476  . else use cannot_use_fs_contexts.
477 
478 Arguments:
479  FileObjInfoList - List of FxFileObjectInfo structs.
480 
481 Returns:
482  NTSTATUS
483 
484 --*/
485 {
487  FxFileObjectInfo* fileObjInfo;
490  WDF_FILEOBJECT_CLASS fileObjClass;
491  FxCxDeviceInfo* previousCxInfo;
492 
494  fileObjClass = WdfFileObjectNotRequired;
495  previousCxInfo = NULL;
496 
497  ASSERT(!IsListEmpty(FileObjInfoList));
498 
499  //
500  // Compute the execution level and synchronization scope for all the chain.
501  //
502  for (next = FileObjInfoList->Blink;
503  next != FileObjInfoList;
504  next = next->Blink) {
505 
506  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
507 
508  //
509  // If not required, skip it.
510  //
511  if (WdfFileObjectNotRequired == fileObjInfo->FileObjectClass) {
512  continue;
513  }
514 
515  //
516  // If the same, skip it.
517  //
518  if (fileObjClass == fileObjInfo->FileObjectClass) {
519  continue;
520  }
521 
522  //
523  // If not set yet, use new value.
524  //
525  if (WdfFileObjectNotRequired == fileObjClass) {
526  fileObjClass = fileObjInfo->FileObjectClass;
527  previousCxInfo = fileObjInfo->CxDeviceInfo;
528  continue;
529  }
530 
531  //
532  // Make sure optional flag is compatible.
533  //
534  if (FxIsFileObjectOptional(fileObjClass) !=
535  FxIsFileObjectOptional(fileObjInfo->FileObjectClass)) {
536 
541  "Device 0x%p - "
542  "Driver 0x%p - WdfFileObjectCanBeOptional (%d) is not "
543  "compatible with wdf extension "
544  "Driver 0x%p - WdfFileObjectCanBeOptional (%d), %!STATUS!",
545  m_Device->GetHandle(),
546  m_Device->GetCxDriver(fileObjInfo->CxDeviceInfo)->GetHandle(),
547  FxIsFileObjectOptional(fileObjInfo->FileObjectClass) ? 1:0,
548  previousCxInfo->Driver->GetHandle(),
549  FxIsFileObjectOptional(fileObjClass) ? 1:0,
550  status
551  );
552 
554  goto Done;
555  }
556 
557  //
558  // Drivers do not agree on the location, set cannot use fx contexts.
559  //
561  if (FxIsFileObjectOptional(fileObjInfo->FileObjectClass)) {
562  fileObjClass = (WDF_FILEOBJECT_CLASS)
563  ((ULONG)fileObjClass | WdfFileObjectCanBeOptional);
564  }
565 
569  "Converting file object class for Driver 0x%p - Device 0x%p, "
570  "from 0x%x to 0x%x",
571  m_Device->GetCxDriver(fileObjInfo->CxDeviceInfo)->GetHandle(),
572  m_Device->GetHandle(),
573  fileObjInfo->FileObjectClass,
574  fileObjClass
575  );
576  }
577 
578  //
579  // Set the file object support level on the FxDevice
580  //
581  m_Device->SetFileObjectClass(fileObjClass);
582 
584 
585 Done:
586  return status;
587 }
588 
590 NTSTATUS
593  )
594 /*++
595 
596 Routine Description:
597  Optionally registers a shutdown and last chance shutdown notification on
598  behalf of the device.
599 
600 Arguments:
601  Init - Initialization structure which will indicate if registration is required
602 
603 Return Value:
604  NTSTATUS
605 
606  --*/
607 {
610  WDF_IO_QUEUE_CONFIG queueConfig;
611  WDF_OBJECT_ATTRIBUTES attributes;
613 
616 
617 
618 
619 
620 #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
621  if (Init->Control.Flags != 0) {
623 
624  if (Init->Control.Flags & WdfDeviceShutdown) {
626  }
627 
628  if (NT_SUCCESS(status) &&
629  (Init->Control.Flags & WdfDeviceLastChanceShutdown)) {
631 
632  }
633 
634  if (NT_SUCCESS(status)) {
635  //
636  // IoDeleteDevice will automatically unregister the shutdown
637  // notifications if the device is deleted before the machine is
638  // shutdown, so we don't need to track registration beyond this point.
639  //
640  m_EvtDeviceShutdown.m_Method = Init->Control.ShutdownNotification;
641  }
642  else {
643  //
644  // This unregisters both the normal and last chance notifications
645  //
647  }
648  }
649 #else
652 #endif
653 
655  //
656  // Create an internal queue to track create requests presented to the driver.
657  // This special queue is used so that we can invoke the events in the context
658  // of the caller.
659  //
661 
662  //
663  // non power managed queue because we don't anticipate drivers touching
664  // hardware in the fileevent callbacks. If they do, then they should make sure
665  // to power up the device.
666  //
667  queueConfig.PowerManaged = WdfFalse;
668 
669  //
670  // Queue inherits the sync & exec level of fileobject.
671  //
672  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
673  attributes.ExecutionLevel = m_ExecutionLevel;
675 
676  status = m_Device->m_PkgIo->CreateQueue(&queueConfig,
677  &attributes,
678  NULL,
680 
681  if (!NT_SUCCESS(status)) {
684  "Unable to create an internal queue for creates for WDFDEVICE "
685  "0x%p, %!STATUS!", m_Device->GetHandle(), status);
686  return status;
687  }
688  }
689 
690  return status;
691 }
692 
694 NTSTATUS
696  __in FxIoQueue* TargetQueue
697  )
698 /*++
699 
700 Routine Description:
701 
702  Used to register driver specified for dispatching create requests.
703 
704 Arguments:
705 
706 Return Value:
707 
708  NTSTATUS
709 
710  --*/
711 {
714  KIRQL irql;
715 
718 
719  if(TargetQueue->IsIoEventHandlerRegistered(WdfRequestTypeCreate) == FALSE){
723  "Must have EvtIoDefault registered to receive "
724  "WdfRequestTypeCreate requests for WDFQUEUE 0x%p, "
725  "%!STATUS!", TargetQueue->GetObjectHandle(), status);
727  return status;
728  }
729 
730  Lock(&irql);
731 
732  if (m_DriverCreatedQueue) {
734 
737  "Another WDFQUEUE 0x%p is already configured for auto dispatching "
738  "create request, %!STATUS!",
740 
742  }
743  else {
744  m_DriverCreatedQueue = TargetQueue;
745  }
746 
747  Unlock(irql);
748 
749  return status;
750 }
751 
753 NTSTATUS
756  )
757 /*++
758 
759 Routine Description:
760 
761  Dispatch routine for handling create, cleanup, close, and shutdown requests.
762 
763 Arguments:
764 
765 
766 Return Value:
767 
768  NTSTATUS
769 
770  --*/
771 {
774  FxIrp fxIrp(Irp);
775 
777 
779  "WDFDEVICE 0x%p !devobj 0x%p %!IRPMJ! IRP 0x%p",
782 
783  switch (fxIrp.GetMajorFunction()) {
784  case IRP_MJ_CREATE:
785  status = OnCreate(&fxIrp);
786  break;
787 
788  case IRP_MJ_CLOSE:
789  status = OnClose(&fxIrp);
790  break;
791 
792  case IRP_MJ_CLEANUP:
793  status = OnCleanup(&fxIrp);
794  break;
795 
796  case IRP_MJ_SHUTDOWN:
797  status = OnShutdown(&fxIrp);
798  break;
799 
800  default:
801  ASSERT(FALSE);
805  break;
806  }
807 
808  return status;
809 }
810 
812 NTSTATUS
815  )
816 /*++
817 
818 Routine Description:
819 
820  1) Allow only one handle to be open for exclusive device.
821  2) Create a WDFFILEOBJECT to represent the WDM fileobject. This
822  fileobject is created only if the driver registers for EvtFile events and
823  doesn't specify WdfFileObjectNotRequired. If the file-events are not
824  registered, the default FileobjectClass is WdfFileObjectNotRequired - set
825  during DeviceInit.
826  3) If the EvtFileCreate event is *not* set or any driver queue is not configured,
827  then complete or forward the request to the lower
828  driver depending on AutoForwardCleanupClose. AutoForwardCleanupClose
829  is set to TRUE by default for filter drivers.
830  4) Create a FxRequest.
831  5) First try to dispatch it to a driver specified queue.
832  6) If there is no driver specified queue, then check to see if the driver has
833  registered EvtDeviceFileCreate event.
834  7) If EvtFileCreate is set then dispatch the request to to an internal
835  manual queue, retrieve the request by fileobject and present the request to
836  the driver in the EvtFileCreate event. This allow the driver to forward the request
837  to another queue to mark the request cancelable and complete it later.
838 
839 Arguments:
840 
841 Return Value:
842 
843  NTSTATUS
844 
845  --*/
846 {
849  WDFFILEOBJECT hwdfFO;
852  MdFileObject fileObject;
853  LONG count;
854  BOOLEAN inCriticalRegion;
855  BOOLEAN inDefaultQueue;
856  FxFileObjectInfo* fileObjInfo;
857  WDF_OBJECT_ATTRIBUTES attributes;
859 
860  pFxFO = NULL;
861  hwdfFO = NULL;
862  pRequest = NULL;
863  inCriticalRegion = FALSE;
864  inDefaultQueue = FALSE;
866  fileObject = FxIrp->GetFileObject();
867  fileObjInfo = NULL;
868 
869  //
870  // Check for exclusivity.
871  //
873 
874  //
875  // The count is biased by one to help track when to delete the control
876  // device, so we need to check for 2, not 1.
877  //
878  if (m_Device->IsExclusive() && count > 2) {
881  "Exclusive WDFDEVICE 0x%p, only one open handle is allowed",
882  m_Device->GetHandle());
884  goto Error;
885  }
886 
887  // ------------------------------------------------------------------------
888  //
889  // Create WDFFILEOBJECT. By default we allocate the root driver's file obj
890  // context; then we attach the other file obj contexts.
891  //
892 
893  //
894  // Init the file obj's attributes. Use default if not present (legacy behavior).
895  //
896  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
898  //
899  // file obj info is set, use the top most driver's info, i.e., cx if present.
900  //
903  ListEntry);
904 
905  //
906  // Use this layer's attributes if present.
907  // Size is zero if driver didn't specify file object's attributes.
908  //
909  if (0 != fileObjInfo->Attributes.Size) {
910  ASSERT(fileObjInfo->Attributes.Size == sizeof(WDF_OBJECT_ATTRIBUTES));
911  attributes = fileObjInfo->Attributes;
912  }
913 
914  //
915  // Use computed constraint settings.
916  //
917  attributes.ExecutionLevel = m_ExecutionLevel;
919  }
920 
921  //
922  // Create the file object.
923  //
925  m_Device,
926  FxIrp->GetIrp(),
928  &attributes,
929  fileObject,
930  &pFxFO
931  );
932 
933  if (!NT_SUCCESS(status) ) {
936  "Could not create WDFFILEOBJECT for WDFDEVICE 0x%p, failing "
937  "IRP_MJ_CREATE %!STATUS!", m_Device->GetHandle(), status);
938  goto Error;
939  }
940 
941  if (pFxFO != NULL) {
942  hwdfFO = pFxFO->GetHandle();
943 
944  //
945  // If any, attach the file obj's contexts of the other drivers in this chain.
946  //
947  for (next = m_FileObjectInfoHeadList.Blink->Blink; // skip one.
949  next = next->Blink) {
950 
951  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
952 
953  attributes = fileObjInfo->Attributes;
954 
955  //
956  // Size is zero if driver didn't specify file object's attributes.
957  //
958  if (0 == attributes.Size) {
959  continue;
960  }
961 
962  //
963  // Don't need these settings for extra contexts.
964  //
967  attributes.ParentObject = NULL;
968 
970  &attributes,
971  TRUE,
972  NULL);
973  if(!NT_SUCCESS(status)) {
976  "Couldn't allocate file object context 0x%p for "
977  "device 0x%p - driver 0x%p, %!STATUS!",
978  &fileObjInfo->Attributes,
979  m_Device->GetHandle(),
980  m_Device->GetCxDriver(fileObjInfo->CxDeviceInfo)->GetHandle(),
981  status
982  );
983 
984  goto Error;
985  }
986  }
987  }
988 
989  // ------------------------------------------------------------------------
990  //
991  // If there is no driver configured queue or m_EvtFileCreate is not registered,
992  // complete the request with status-success. The reason for making this
993  // check after creating the fileobject is to allow WdfRequestGetFileObject even
994  // if the driver hasn't registered any file-event callbacks.
995  //
996  if (m_DriverCreatedQueue == NULL &&
998 
999  //
1000  // Check to see if the driver has opted to autoforward cleanup and close.
1001  // If so, we should forward create requests also. Else, we should
1002  // complete the request with STATUS_SUCCESS. Note, if the driver is
1003  // a filter driver, the default value of m_AutoForwardCleanupClose is TRUE.
1004  //
1005  //
1008  //
1009  // _CreateCompletionRoutine will do the cleanup when the request is
1010  // completed with error status by the lower driver.
1011  //
1012  }
1013  else {
1016  FxIrp->SetInformation(0);
1018  }
1019 
1020  goto RequestIsGone;
1021  }
1022 
1023  // ------------------------------------------------------------------------
1024  //
1025  // Create a FxRequest for this IRP. By default we allocate the top most driver's request
1026  // context; then we attach the other request contexts.
1027  //
1028 
1029  //
1030  // Init the request's attributes.
1031  //
1033  //
1034  // file obj info is set, use the top most driver's info, i.e., cx if present.
1035  //
1038  ListEntry);
1039  if (fileObjInfo->ClassExtension) {
1040  attributes = fileObjInfo->CxDeviceInfo->RequestAttributes;
1041  }
1042  else {
1043  attributes = *m_Device->GetRequestAttributes();
1044  }
1045  }
1046  else {
1047  attributes = *m_Device->GetRequestAttributes();
1048  }
1049 
1050  if (m_Device->IsCxInIoPath()) {
1051  //
1052  // Apply cx's constrains for create requests:
1053  //
1056  attributes.ParentObject = NULL;
1057  }
1058 
1059  //
1060  // Create the request.
1061  //
1063  &attributes,
1064  FxIrp->GetIrp(),
1065  &pRequest);
1066  if(!NT_SUCCESS(status)) {
1068  "Could not create request for WDFDEVICE 0x%p, %!STATUS!",
1069  m_Device->GetHandle(), status);
1070  goto Error;
1071  }
1072 
1073  //
1074  // If any, attach the request's contexts of the other drivers in this chain.
1075  //
1076  for (next = m_FileObjectInfoHeadList.Blink->Blink; // skip one.
1078  next = next->Blink) {
1079 
1080  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1081 
1082  if (fileObjInfo->ClassExtension) {
1083  attributes = fileObjInfo->CxDeviceInfo->RequestAttributes;
1084  }
1085  else {
1086  attributes = *m_Device->GetRequestAttributes();
1087  }
1088 
1089  //
1090  // Size is zero if driver didn't specify request's attributes.
1091  //
1092  if (0 == attributes.Size) {
1093  continue;
1094  }
1095 
1096  //
1097  // Don't need these settings for extra contexts.
1098  //
1101  attributes.ParentObject = NULL;
1102 
1104  pRequest,
1105  &attributes,
1106  TRUE,
1107  NULL);
1108 
1109  if(!NT_SUCCESS(status)) {
1112  "Couldn't allocate request context for "
1113  "device 0x%p - driver 0x%p, %!STATUS!",
1114  m_Device->GetHandle(),
1115  m_Device->GetCxDriver(fileObjInfo->CxDeviceInfo)->GetHandle(),
1116  status
1117  );
1118 
1119  goto Error;
1120  }
1121  }
1122 
1123  //
1124  // Disable thread suspension beyond this point by entering critical region.
1125  //
1127  {
1128  Mx::MxEnterCriticalRegion();
1129  inCriticalRegion = TRUE;
1130  }
1131 
1132  // ------------------------------------------------------------------------
1133  //
1134  // Queue request in default queue before invoking cx or client's create callbacks.
1135  //
1138 
1139  FxRequest* outputRequest;
1140 
1142 
1143  //
1144  // Make sure we are calling FileEvents at the right IRQL level.
1145  //
1148 
1152  "WDFDEVICE 0x%p cannot handle create request at or above "
1153  "dispatch-level, fail the Irp: 0x%p, %!STATUS!",
1155 
1156  goto Error;
1157  }
1158 
1159  //
1160  // Now queue and immediately retrieve the request by FileObject.
1161  // QueueRequest will return an error if the queue is not accepting request
1162  // or the request is already cancelled. Either way, the request is completed by
1163  // the FxIoQueue.
1164  //
1166  if (!NT_SUCCESS(status)) {
1169  "Couldn't forward request to the WDFQUEUE 0x%p, %!STATUS!",
1171  goto RequestIsGone;
1172  }
1173 
1175  NULL,
1176  &outputRequest);
1177  if (!NT_SUCCESS(status)) {
1178  //
1179  // Oops, request got cancelled and completed by another thread.
1180  //
1182  status = STATUS_PENDING; // IRP was already marked pending.
1183  goto RequestIsGone;
1184  }
1185 
1186  ASSERT(outputRequest == pRequest);
1187 
1188  inDefaultQueue = TRUE;
1189  }
1190 
1191  // ------------------------------------------------------------------------
1192  //
1193  // Invoke Cx's create callbacks. Here we add the cx's file obj and request contexts.
1194  //
1196 
1197  //
1198  // Loop through all cx's file obj info.
1199  //
1202  next = next->Blink) {
1203 
1204  //
1205  // Get ready to invoke next layer cx's create.
1206  //
1207  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1208 
1209  //
1210  // Do not invoke the client driver's create callback (if any). For compatibility
1211  // we need to check first the driver 'create' queue.
1212  //
1213  if (FALSE == fileObjInfo->ClassExtension) {
1214  break;
1215  }
1216 
1217  ASSERT(fileObjInfo->EvtFileCreate.Method == NULL);
1218  ASSERT(fileObjInfo->EvtCxFileCreate.Method != NULL);
1219 
1220  //
1221  // Keep track where we stopped (end, not inclusive node).
1222  // Note that we cannot do this after the Invoke b/c File Object
1223  // may be gone by the time callback returns.
1224  //
1225  if (pFxFO) {
1227  }
1228 
1229  //
1230  // Invoke knows how to handle NULL callbacks.
1231  //
1232  if (fileObjInfo->EvtCxFileCreate.Invoke(
1233  m_Device->GetHandle(),
1234  (WDFREQUEST)pRequest->GetObjectHandle(),
1235  hwdfFO)) {
1236  //
1237  // Callback claimed the request.
1238  //
1239  status = STATUS_PENDING; // IRP was already marked pending.
1240  goto RequestIsGone;
1241  }
1242  }
1243  }
1244 
1245  //-------------------------------------------------------------------------
1246  //
1247  // First check for driver configured queue. If there is one, dispatch the request
1248  // to that queue.
1249  //
1250  if (m_DriverCreatedQueue != NULL) {
1251  if (inDefaultQueue) {
1253 
1256  pRequest);
1257 
1258  if(!NT_SUCCESS(status)) {
1261  "Couldn't forward request to the WDFQUEUE 0x%p, %!STATUS!",
1263 
1265  }
1266 
1267  status = STATUS_PENDING; // IRP was already marked pending.
1268  goto RequestIsGone;
1269  }
1270  else {
1271  ASSERT(pRequest->GetRefCnt() == 1);
1272  //
1273  // QueueRequest will return an error if the queue is not accepting request
1274  // or the request is already cancelled. Either way, the request is completed by
1275  // the FxIoQueue.
1276  //
1278  if(!NT_SUCCESS(status)) {
1281  "Couldn't forward request to the WDFQUEUE 0x%p, %!STATUS!",
1283  }
1284 
1285  goto RequestIsGone;
1286  }
1287  }
1288 
1289  //-------------------------------------------------------------------------
1290  //
1291  // At this point invoke the client driver callback if present.
1292  //
1295  ASSERT(TRUE == inDefaultQueue);
1296  ASSERT(fileObjInfo->EvtFileCreate.Method != NULL);
1297  ASSERT(fileObjInfo->EvtCxFileCreate.Method == NULL);
1298 
1299  //
1300  // Invoke the client driver create requests.
1301  //
1302  fileObjInfo->EvtFileCreate.Invoke(
1303  m_Device->GetHandle(),
1304  (WDFREQUEST)pRequest->GetObjectHandle(),
1305  hwdfFO);
1306  //
1307  // QueueRequest has already marked the request pending.
1308  //
1310  goto RequestIsGone;
1311  }
1312 
1313  //
1314  // We should be here only if CX's create returned 'continue' but client didn't have
1315  // a create callback.
1316  //
1318 
1319  //
1320  // Check to see if the driver has opted to autoforward cleanup and close.
1321  // If so, we should forward create requests to lower drivers. Else, we should
1322  // complete the request with STATUS_SUCCESS. Note, if the driver is
1323  // a filter driver, the default value of m_AutoForwardCleanupClose is TRUE.
1324  //
1327  //
1328  // _CreateCompletionRoutine2 will complete the WDF request.
1329  //
1330  }
1331  else {
1333  }
1334 
1335  //
1336  // Done processing this request.
1337  //
1338  status = STATUS_PENDING; // IRP was already marked pending.
1339  goto RequestIsGone;
1340 
1341 Error:
1342  if (pRequest != NULL) {
1344  pRequest = NULL;
1345  }
1346 
1348 
1349  if (pFxFO != NULL) {
1351  pFxFO = NULL;
1352  }
1353 
1354  //
1355  // NOTE: after this call, this object may have been deleted!
1356  //
1358 
1360  FxIrp->SetInformation(0);
1362 
1363  // fallthrough
1364 
1365 RequestIsGone:
1366 
1367  //
1368  // We have lost the ownership of the request. We have either successfully
1369  // presented the request to the driver or the queue function we called to
1370  // present the request returned error but completed the FxRequest on its own.
1371  // Either way we don't need to worry about cleaning up the resources
1372  // (fileobject, handle-count, etc) because the FxRequest:Completion routine
1373  // will call FxPkgGeneral::CreateCompleted to post process IRP upon completion.
1374  //
1375  if (inCriticalRegion) {
1376  Mx::MxLeaveCriticalRegion();
1377  }
1378 
1379  return status;
1380 }
1381 
1383 NTSTATUS
1385  __in FxIrp* Irp,
1388  )
1389 {
1390  NTSTATUS status;
1391 
1392  Irp->CopyCurrentIrpStackLocationToNext();
1393  Irp->SetCompletionRoutineEx(m_Device->GetDeviceObject(),
1395  Context);
1396  status = Irp->CallDriver(m_Device->GetAttachedDevice());
1397 
1398  return status;
1399 }
1400 
1401 VOID
1403  __in FxIrp *Irp
1404  )
1405 /*++
1406 
1407 Routine Description:
1408 
1409  This method is called when the WDFREQUEST for Irp
1410  is completed either by the driver or framework.
1411 
1412  Here, we check the completion status of the IRP and if
1413  it's not success, we destroy the fileobject and decrement
1414  the openhandle count on the device.
1415 
1416 Arguments:
1417 
1418 Return Value:
1419 
1420  VOID
1421 
1422  --*/
1423 {
1424  NTSTATUS status = Irp->GetStatus();
1425 
1426  //
1427  // If the create is completed with error status,
1428  // we destroy the WDFFILEOBJECT since the IoMgr will destroy
1429  // the PFILE_OBJECT if the IRP_MJ_CREATE fails and wouldn't send
1430  // Cleanup or Close IRP.
1431  //
1432  if (!NT_SUCCESS(status)) {
1433 
1434  // Now destroy the WDFFILEOBJECT
1436  m_Device,
1438  Irp->GetFileObject()
1439  );
1440 
1442  }
1443 }
1444 
1446 NTSTATUS
1451  )
1452 /*++
1453 
1454 Routine Description:
1455 
1456  This completion routine is set only when the IRP is forwarded
1457  directly by the framework to the lower driver. Framework forwards
1458  the IRP request if:
1459  1) The driver happens to be a filter and hasn't registered any
1460  callbacks to handle create request.
1461  2) The driver is not a filter but has explicitly requested the
1462  framework to autoforward create/cleanup/close requests down.
1463 
1464  We need to intercept the create in the completion path to find
1465  out whether the lower driver has succeeded or failed the request.
1466  If the request is failed, we should inform the package so that
1467  it can cleanup the state because I/O manager wouldn't send
1468  cleanup & close requests if the create is failed.
1469 
1470 Arguments:
1471 
1472 Return Value:
1473 
1474  NTSTATUS
1475 
1476  --*/
1477 {
1478  FxPkgGeneral* pFxPkgGeneral;
1480 
1482 
1483  pFxPkgGeneral = (FxPkgGeneral*) Context;
1484 
1485  ASSERT(pFxPkgGeneral != NULL);
1486 
1487  //
1488  // Let the package know that create is completed
1489  // so that it can cleanup the state.
1490  //
1491  pFxPkgGeneral->CreateCompleted(&irp);
1492 
1493  //
1494  // Let the irp continue on its way.
1495  //
1497 
1498  return irp.GetStatus();
1499 }
1500 
1502 NTSTATUS
1507  )
1508 /*++
1509 
1510 Routine Description:
1511 
1512  Routine Description:
1513 
1514  This completion routine is set only when the create request is forwarded by the
1515  framework to the lower driver. Framework forwards the create request using this
1516  completion routine if:
1517 
1518  1) Class extension's create callback is set by did not claim the request.
1519  2) Client driver did not register for a create callback or a create queue.
1520 
1521 Arguments:
1522 
1523 Return Value:
1524 
1525  STATUS_MORE_PROCESSING_REQUIRED
1526 
1527  --*/
1528 {
1529  FxRequest* request;
1531 
1533 
1534  request = (FxRequest*) Context;
1535 
1536  ASSERT(request != NULL);
1537 
1539 
1540  request->Complete(irp.GetStatus());
1541 
1543 }
1544 
1546 NTSTATUS
1549  )
1550 /*++
1551 
1552 Routine Description:
1553 
1554  Called in response to IRP_MJ_CLEANUP. This means an handle to
1555  the device is closed. After invoking the driver registered callback
1556  event, flush all the queues to cancel requests that belong to the
1557  file handle being closed. There is however a possibility for
1558  new requests to come in with the same fileobject.
1559 
1560 
1561 
1562 
1563 
1564 Arguments:
1565 
1566 Return Value:
1567 
1568  NTSTATUS
1569 
1570  --*/
1571 {
1572  NTSTATUS status;
1573  FxFileObject* pFxFO = NULL;
1574  WDFFILEOBJECT hwdfFO = NULL;
1575  PLIST_ENTRY next;
1576  FxFileObjectInfo* fileObjInfo;
1577  MxFileObject fileObject;
1578 
1579 
1580 
1581 
1582 
1583 
1584  //
1585  // Check to see if the fileobject represents a stream fileobject
1586  // created using IoCreateStreamFileObjectLite.
1587  //
1588  fileObject.SetFileObject(FxIrp->GetFileObject());
1589  if (FxIrp->GetFileObject() &&
1590  (fileObject.GetFlags() & FO_STREAM_FILE)){
1592  goto Passthru;
1593  }
1594 
1596  m_Device,
1598  FxIrp->GetFileObject(),
1599  &pFxFO
1600  );
1601 
1603 
1604  if (pFxFO != NULL && NT_SUCCESS(status)) {
1605  hwdfFO = pFxFO->GetHandle();
1606  }
1607 
1608  //
1609  // Invoke cleanup callbacks.
1610  //
1611  if (NULL == pFxFO) {
1612  //
1613  // Invoke cleanup callbacks of next layer (cx or client driver) based on the
1614  // autoforward setting of previous layer. (top to bottom).
1615  // AutoforwardCleanupClose set to FALSE with a not null create callback
1616  // means that create request was never forwarded to lower layer.
1617  //
1620  next = next->Blink) {
1621 
1622  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1623 
1624  if (WdfFalse == fileObjInfo->AutoForwardCleanupClose &&
1625  fileObjInfo->EvtCxFileCreate.Method != NULL) {
1626  next = next->Blink; // one before the real start entry.
1627  break;
1628  }
1629  }
1630  }
1631  else {
1632  //
1633  // 'OnCreate' sets this package context.
1634  //
1636  if (NULL == next) {
1638  }
1639  }
1640 
1641  //
1642  // Invoke cleanup callbacks only if this layer (cx or client driver) had the
1643  // opprtunity to see the create request.
1644  //
1645  for (next = next->Flink;
1647  next = next->Flink) {
1648 
1649  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1650  fileObjInfo->EvtFileCleanup.Invoke(hwdfFO);
1651  }
1652 
1653  //
1654  // hwdfFO could be NULL depending on the FileObjectClass
1655  //
1656 
1657  //
1658  // Scan all the I/O queues associated with this device
1659  // and cancel the requests that matches with the handle
1660  // being closed. We will be able to cancel only requests that
1661  // are waiting to be dispatched. If the requests are already
1662  // presented to the driver then it's the responsibility of the
1663  // driver to complete them when the cleanup callback is invoked.
1664  //
1665  if(FxIrp->GetFileObject() != NULL ) {
1666  FxPkgIo* pPkgIo;
1667 
1670  }
1671 
1672 Passthru:
1676  } else {
1678  FxIrp->SetInformation(0);
1680  }
1681 
1682  return status;
1683 
1684 }
1685 
1687 NTSTATUS
1690  )
1691 /*++
1692 
1693 Routine Description:
1694 
1695  Called in response to IRP_MJ_CLOSE. Invoke EvtFileClose event
1696  if registered and destroy the WDFFILEOBJECT.
1697 
1698 Arguments:
1699 
1700 Return Value:
1701 
1702  NTSTATUS
1703 
1704  --*/
1705 {
1706  NTSTATUS status;
1707  FxFileObject* pFxFO = NULL;
1708  WDFFILEOBJECT hwdfFO = NULL;
1709  BOOLEAN isStreamFileObject = FALSE;
1710  BOOLEAN acquiredRemLock = FALSE;
1711  PLIST_ENTRY next;
1712  FxFileObjectInfo* fileObjInfo;
1713  MxFileObject fileObject;
1714  MdIrp irp;
1715 
1716  //
1717  // FxIrp.CompleteRequest NULLs the m_Irp so store m_Irp separately
1718  // for use in ReleaseRemoveLock.
1719  //
1720  irp = FxIrp->GetIrp();
1721 
1722  //
1723  // Check to see if the fileobject represents a stream fileobject
1724  // created using IoCreateStreamFileObjectLite. If so, this is a
1725  // is spurious close sent by the I/O manager when it invalidates
1726  // the volumes (IopInvalidateVolumesForDevice).
1727  //
1728  fileObject.SetFileObject(FxIrp->GetFileObject());
1729  if (FxIrp->GetFileObject() &&
1730  (fileObject.GetFlags() & FO_STREAM_FILE)){
1731  isStreamFileObject = TRUE;
1733  goto Passthru;
1734  }
1735 
1737  m_Device,
1739  FxIrp->GetFileObject(),
1740  &pFxFO
1741  );
1742 
1744 
1745  if (pFxFO != NULL && NT_SUCCESS(status)) {
1746  hwdfFO = pFxFO->GetHandle();
1747  }
1748 
1749  //
1750  // Invoke close callbacks.
1751  //
1752  if (NULL == pFxFO) {
1753  //
1754  // Invoke close callbacks of next layer (cx or client driver) based on the autoforward
1755  // setting of previous layer. (top to bottom).
1756  // AutoforwardCleanupClose set to FALSE with a not null create callback
1757  // means that create request was never forwarded to lower layer.
1758  //
1761  next = next->Blink) {
1762 
1763  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1764 
1765  if (WdfFalse == fileObjInfo->AutoForwardCleanupClose &&
1766  fileObjInfo->EvtCxFileCreate.Method != NULL) {
1767  next = next->Blink; // one before the real start entry.
1768  break;
1769  }
1770  }
1771  }
1772  else {
1773  //
1774  // 'OnCreate' sets this package context.
1775  //
1777  if (NULL == next) {
1779  }
1780  }
1781 
1782  //
1783  // Invoke close callbacks only if this layer (cx or client driver) had the opprtunity
1784  // to see the create request.
1785  //
1786  for (next = next->Flink;
1788  next = next->Flink) {
1789 
1790  fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1791  fileObjInfo->EvtFileClose.Invoke(hwdfFO);
1792  }
1793 
1794  //
1795  // Destroy the WDFFILEOBJECT. This will result in
1796  // fileobject EvtCleanup and EvtDestroy event.
1797  //
1799  m_Device,
1801  FxIrp->GetFileObject()
1802  );
1803 
1804 Passthru:
1805 
1809  } else {
1810  //
1811  // We're about to complete the request, but we need to decrement the
1812  // open handle count after we complete the request. However, completing
1813  // the request immediately opens the gate for the remove IRP to arrive
1814  // and run down the device. Hence we'll acquire the remove lock in order
1815  // to ensure that the device is not removed before we've decremented the
1816  // open handle count.
1817  //
1818 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1819  acquiredRemLock = AcquireRemoveLockForClose(FxIrp);
1820 #endif
1822  FxIrp->SetInformation(0);
1824  }
1825 
1826  if (isStreamFileObject == FALSE) {
1827  //
1828  // Note that after this call returns, this object may have been deleted!
1829 
1830 
1831 
1832 
1833 
1834 
1835 
1836 
1838  }
1839 
1840  if (acquiredRemLock) {
1842  irp);
1843  }
1844 
1845  return status;
1846 
1847 }
1848 
1849 BOOLEAN
1851  __in FxIrp* FxIrp
1852  )
1853 /*++
1854 
1855 Routine Description:
1856 
1857  For PNP devices, this routine acquires the remove lock when handling the
1858  close IRP.
1859 
1860 Arguments:
1861  Irp - Pointer to the close IRP
1862 
1863 Return Value:
1864 
1865  A BOOLEAN value that indicates whether or not the function actually acquired
1866  the remove lock
1867 
1868  --*/
1869 {
1870  NTSTATUS status;
1871  BOOLEAN lockAcquired;
1874 
1875  //
1876  // Initialization
1877  //
1878  lockAcquired = FALSE;
1879 
1880  //
1881  // We attempt to acquire the remove lock only for PNP device objects
1882  //
1883  if (m_Device->IsPnp() == FALSE) {
1884  goto Done;
1885  }
1886 
1887  //
1888  // If driver has opted in for remove lock for I/O operations we have
1889  // already acquired remove lock for Close so no need to do it again.
1890  //
1891  if (wdmExtension->RemoveLockOptionFlags &
1893  goto Done;
1894  }
1895 
1898  FxIrp->GetIrp());
1899  if (NT_SUCCESS(status)) {
1900  //
1901  // Successfully acquired the remove lock
1902  //
1903  lockAcquired = TRUE;
1904  } else {
1905  //
1906  // This is likely to have failed because we got the remove IRP and
1907  // called IoReleaseRemoveLockAndWait on another thread. This would
1908  // happen if there's a bug in the driver above us in the stack that
1909  // caused it to forward us the remove IRP before we completed the close
1910  // IRP.
1911  //
1912  // There's not much we can do now, since we're already racing against
1913  // the remove IRP.
1914  //
1916 
1918 
1922  TRACINGIO,
1923  "Unable to acquire remove lock while handling the close IRP"
1924  " 0x%p, %!STATUS!",
1925  FxIrp->GetIrp(), status);
1926 
1929  }
1930  }
1931 
1932 Done:
1933  return lockAcquired;
1934 }
1935 
1936 
1938 NTSTATUS
1941  )
1942 /*++
1943 
1944 Routine Description:
1945 
1946  Called in response to IRP_MJ_SHUTDOWN.
1947 
1948 Arguments:
1949 
1950 Return Value:
1951 
1952  NTSTATUS
1953 
1954  --*/
1955 {
1956  NTSTATUS status;
1957 
1959 
1960  if(m_Device->IsFilter()) {
1963  }
1964  else {
1967  FxIrp->SetInformation(0);
1969  }
1970 
1971  return status;
1972 
1973 }
1974 
1975 VOID
1977  VOID
1978  )
1979 {
1982  }
1983 }
1984 
1985 BOOLEAN
1987  VOID
1988  )
1989 {
1990  //
1991  // Remove the bias of one that we use to track if a control device should be
1992  // deleted.
1993  //
1995  return TRUE;
1996  }
1997  else {
1998  return FALSE;
1999  }
2000 
2001 }
2002 
2003 VOID
2005  __out_opt WDF_EXECUTION_LEVEL* ExecutionLevel,
2006  __out_opt WDF_SYNCHRONIZATION_SCOPE* SynchronizationScope
2007  )
2008 /*++
2009 
2010 Routine Description:
2011  This routine is the helper routine and is used by FxFileObject to get the
2012  ExecutionLevel and SynchronizationScope.
2013 
2014 Arguments:
2015 
2016 Return Value:
2017  VOID
2018 
2019 --*/
2020 
2021 {
2022  if (ExecutionLevel != NULL) {
2023  *ExecutionLevel = m_ExecutionLevel;
2024  }
2025 
2026  if (SynchronizationScope != NULL) {
2027  *SynchronizationScope = m_SynchronizationScope;
2028  }
2029 }
2030 
2034  )
2035 /*++
2036 
2037 Routine Description:
2038  This routine is the helper routine and is used by FxFileObject to get the
2039  LockObject.
2040 
2041 
2042 Arguments:
2043 
2044 Return Value:
2045  FxCallbackLock *
2046 
2047 --*/
2048 
2049 {
2050  if (LockObject != NULL) {
2052  }
2053 
2054  return m_CallbackLockPtr;
2055 }
2056 
2057 
struct _LIST_ENTRY * PLIST_ENTRY
static __inline NTSTATUS MxAcquireRemoveLock(__in MdRemoveLock RemoveLock, __in_opt PVOID Tag)
Definition: mxgeneralkm.h:268
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
CfxDevice * m_Device
Definition: fxobject.hpp:329
FxFileObjectFileClose EvtFileClose
VOID Invoke(__in WDFDEVICE Device)
FxFileObjectFileCleanup EvtFileCleanup
static _Must_inspect_result_ NTSTATUS _CreateFileObject(__in FxDevice *pDevice, __in MdIrp Irp, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt PWDF_OBJECT_ATTRIBUTES pObjectAttributes, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
return STATUS_NOT_SUPPORTED
#define _Must_inspect_result_
Definition: no_sal2.h:62
MdFileObject GetFileObject(VOID)
Definition: fxirpum.cpp:1460
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define FX_PKG_GENERAL_FLAG_CX_INFO
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
__inline NTSTATUS Complete(__in NTSTATUS Status)
Definition: fxrequest.hpp:770
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
BOOLEAN Invoke(__in WDFDEVICE Device, __in WDFREQUEST Request, __in_opt WDFFILEOBJECT FileObject)
FxCxDeviceInfo * CxDeviceInfo
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
ULONG GetFlags(VOID)
#define IRP_MJ_SHUTDOWN
#define __in_opt
Definition: dbghelp.h:38
__inline VOID SetFileObject(_In_ MdFileObject FileObject)
Definition: mxfileobject.h:36
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PFN_WDFCX_DEVICE_FILE_CREATE Method
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
GLuint GLuint GLsizei count
Definition: gl.h:1545
_Must_inspect_result_ NTSTATUS ForwardRequest(__in FxIoQueue *pDestQueue, __in FxRequest *pRequest)
Definition: fxioqueue.cpp:1712
void Invoke(__in_opt WDFFILEOBJECT FileObject)
LONG NTSTATUS
Definition: precomp.h:26
__inline BOOLEAN IsPnp(VOID)
Definition: fxdevice.hpp:1200
_Must_inspect_result_ NTSTATUS PostCreateDeviceInitialize(__in PWDFDEVICE_INIT Init)
_Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
FxRequest * pRequest
FxIoQueue * m_DriverCreatedQueue
Definition: fxirp.hpp:28
WDFCX_FILEOBJECT_CONFIG Callbacks
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
FxFileObjectFileCreate EvtFileCreate
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
KIRQL irql
Definition: wave.h:1
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
CxFileObjectInit FileObject
#define InsertTailList(ListHead, Entry)
__inline BOOLEAN IsLegacy(VOID)
Definition: fxdevice.hpp:1209
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ NTSTATUS QueueRequest(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2245
FxFileObject * pFxFO
_Must_inspect_result_ NTSTATUS ForwardCreateRequest(__in FxIrp *FxIrp, __in MdCompletionRoutine CompletionRoutine, __in PVOID Context)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID CreateCompleted(__in FxIrp *Irp)
PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION m_Method
LONG m_OpenHandleCount
VOID PropagatePendingReturned(VOID)
Definition: fxirpum.cpp:443
#define LockObject(Object, Irql)
Definition: titypes.h:34
WDF_EXECUTION_LEVEL ExecutionLevel
Definition: wdfobject.h:120
FxDriver * Driver
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxRequest * request
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define __out_opt
Definition: dbghelp.h:65
FxPkgGeneral(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device)
PFN_WDFCX_DEVICE_FILE_CREATE EvtCxDeviceFileCreate
Definition: wdfcx.h:28
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
VOID Invoke(__in WDFDEVICE Device, __in WDFREQUEST Request, __in_opt WDFFILEOBJECT FileObject)
long LONG
Definition: pedump.c:60
_Must_inspect_result_ NTSTATUS GetRequest(__in_opt MdFileObject FileObject, __in_opt FxRequest *TagRequest, __deref_out FxRequest **pOutRequest)
Definition: fxioqueue.cpp:962
#define FX_PKG_GENERAL_FLAG_CLIENT_CREATE
enum _WDF_FILEOBJECT_CLASS WDF_FILEOBJECT_CLASS
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline WDF_FILEOBJECT_CLASS GetFileObjectClass(VOID)
Definition: fxdevice.hpp:1123
_Must_inspect_result_ NTSTATUS OnCleanup(__inout FxIrp *FxIrp)
FxCxDeviceInfo * CxDeviceInfo
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
unsigned char BOOLEAN
FxCxFileObjectFileCreate EvtCxFileCreate
VOID ControlDeviceDelete(VOID)
Definition: fxdevice.hpp:1465
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
NTSTATUS CallDriver(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:36
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
WDF_FILEOBJECT_CLASS FileObjectClass
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
IWudfIrp * MdIrp
Definition: mxum.h:103
#define FX_PKG_GENERAL_FLAG_CLIENT_INFO
PFN_WDF_DEVICE_FILE_CREATE Method
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
_Must_inspect_result_ NTSTATUS ConfigureForwarding(__in FxIoQueue *FxQueue)
PFN_WDF_FILE_CLOSE EvtFileClose
Definition: wdfcx.h:33
VOID MarkPassiveCallbacks(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:972
_Must_inspect_result_ NTSTATUS OnClose(__inout FxIrp *FxIrp)
WDF_TRI_STATE AutoForwardCleanupClose
FxDevice * pDevice
__inline PVOID GetPkgCleanupCloseContext(VOID)
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE
__inline WDFDRIVER GetHandle(VOID)
Definition: fxdriver.hpp:202
FxIoQueue * m_DefaultQueueForCreates
#define TRACINGDEVICE
Definition: dbgtrace.h:58
__inline FxDriver * GetCxDriver(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxdevice.hpp:1654
PFX_DRIVER_GLOBALS pFxDriverGlobals
BOOLEAN __inline FxIsFileObjectOptional(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:112
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
__inline VOID SetFileObjectClass(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:1135
__inline BOOLEAN IsFilter()
Definition: fxdevice.hpp:1408
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
BOOLEAN m_AutoForwardCleanupClose
Definition: fxdevice.hpp:605
_Must_inspect_result_ NTSTATUS FxObjectAllocateContext(__in FxObject *Object, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in BOOLEAN AllowCallbacksOnly, __deref_opt_out PVOID *Context)
Definition: handleapi.cpp:397
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
NTSTATUS NTAPI IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1663
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
BOOL Error
Definition: chkdsk.c:66
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
static MdCompletionRoutineType _CreateCompletionRoutine2
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static _Must_inspect_result_ NTSTATUS _GetFileObjectFromWdm(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
void Invoke(__in_opt WDFFILEOBJECT FileObject)
struct _test_info info[]
Definition: SetCursorPos.c:19
void SetCallbackLockPtr(FxCallbackLock *Lock)
Definition: fxcallback.hpp:105
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define InterlockedDecrement
Definition: armddk.h:52
FxCallbackLock * GetCallbackLockPtrHelper(__deref_out_opt FxObject **LockObject)
FxCallbackLock * m_CallbackLockPtr
FxPkgIo * m_PkgIo
Definition: fxdevice.hpp:669
LIST_ENTRY m_FileObjectInfoHeadList
FxObject * m_CallbackLockObjectPtr
#define __inout
Definition: dbghelp.h:50
Definition: typedefs.h:119
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define FX_PKG_GENERAL_FLAG_CREATE
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ NTSTATUS ConfigureConstraints(__in PLIST_ENTRY FileObjInfoList)
_Must_inspect_result_ NTSTATUS OnCreate(__inout FxIrp *FxIrp)
static VOID _DestroyFileObject(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject)
FxPkgIo * pPkgIo
#define FX_PKG_GENERAL_FLAG_CX_CREATE
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
WDF_TRI_STATE AutoForwardCleanupClose
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
static __inline VOID MxReleaseRemoveLock(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:278
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
__inline BOOLEAN IsCxInIoPath(VOID)
Definition: fxdevice.hpp:1594
WDF_SYNCHRONIZATION_SCOPE m_SynchronizationScope
static unsigned __int64 next
Definition: rand_nt.c:6
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InterlockedIncrement
Definition: armddk.h:53
_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
WDF_TRI_STATE PowerManaged
Definition: wdfio.h:393
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
_Must_inspect_result_ NTSTATUS FlushAllQueuesByFileObject(__in MdFileObject FileObject)
Definition: fxpkgio.cpp:1393
_Must_inspect_result_ NTSTATUS OnShutdown(__inout FxIrp *FxIrp)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxCallbackLock * GetCallbackLockPtr(__out_opt FxObject **LockObject)
PFX_DRIVER_GLOBALS fxDriverGlobals
WDF_OBJECT_ATTRIBUTES RequestAttributes
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:893
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
WDFOBJECT ParentObject
Definition: wdfobject.h:130
FxShutDown m_EvtDeviceShutdown
__inline WDFFILEOBJECT GetHandle(VOID)
ULONG RemoveLockOptionFlags
Definition: fxdevice.hpp:38
FxIrp fxIrp(Irp)
#define NULL
Definition: types.h:112
Definition: tftpd.h:85
#define __deref_out_opt
Definition: dbghelp.h:29
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
virtual _Must_inspect_result_ NTSTATUS Dispatch(__inout MdIrp Irp)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
#define IRP_MJ_CLEANUP
WUDF_IO_COMPLETION_ROUTINE * MdCompletionRoutine
Definition: mxum.h:142
struct tagContext Context
Definition: acpixf.h:1034
FX_TRACK_DRIVER(fxDriverGlobals)
VOID GetConstraints(__out_opt WDF_EXECUTION_LEVEL *ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
__inline PWDF_OBJECT_ATTRIBUTES GetRequestAttributes(VOID)
Definition: fxdevice.hpp:1315
VOID DeleteFileObjectFromFailedCreate(VOID)
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:426
WDF_SYNCHRONIZATION_SCOPE SynchronizationScope
Definition: wdfobject.h:125
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
_Must_inspect_result_ NTSTATUS ConfigureFileObjectClass(__in PLIST_ENTRY FileObjInfoList)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIO
Definition: dbgtrace.h:66
__inline BOOLEAN IsExclusive(VOID)
Definition: fxdevice.hpp:1218
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
VOID GetConstraintsHelper(__out_opt WDF_EXECUTION_LEVEL *ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
WDF_FILEOBJECT_CLASS Class
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
BOOLEAN CanDestroyControlDevice(VOID)
#define APC_LEVEL
Definition: env_spec_w32.h:695
WDF_OBJECT_ATTRIBUTES Attributes
static MdCompletionRoutineType _CreateCompletionRoutine
BOOLEAN AcquireRemoveLockForClose(__inout FxIrp *FxIrp)
FxIrp * irp
__inline VOID SetPkgCleanupCloseContext(PVOID Context)
VOID DecrementOpenHandleCount(VOID)
#define FO_STREAM_FILE
Definition: iotypes.h:1783
FxVerifierDbgBreakPoint(pFxDriverGlobals)
WDF_OBJECT_ATTRIBUTES Attributes
WDF_EXECUTION_LEVEL m_ExecutionLevel
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
Definition: ps.c:97
PFN_WDF_FILE_CLEANUP EvtFileCleanup
Definition: wdfcx.h:38