ReactOS 0.4.15-dev-5853-gcb454ef
fxpkggeneral.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxPkgGeneral.cpp
8
9Abstract:
10
11 This module implements the wmi package for the driver frameworks.
12
13Author:
14
15
16
17
18Environment:
19
20 Both kernel and user mode
21
22Revision 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
34extern "C" {
35#include "mx.h"
36}
37#include "fxmin.hpp"
38
39extern "C" {
40// #include "FxPkgGeneral.tmh"
41}
42
43
45 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
47 ) :
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
97Routine 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
103Arguments:
104 DeviceInit - Chain of device_init and cx_device_init with file object config.
105
106Return 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
236Done:
237 return status;
238}
239
243 __in PLIST_ENTRY FileObjInfoList
244 )
245/*++
246
247Routine 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
253Arguments:
254 FileObjInfoList - List of FxFileObjectInfo structs.
255
256Returns:
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;
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(),
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
446Done:
447 return status;
448}
449
453 __in PLIST_ENTRY FileObjInfoList
454 )
455/*++
456
457Routine 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
478Arguments:
479 FileObjInfoList - List of FxFileObjectInfo structs.
480
481Returns:
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) !=
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!",
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(),
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
585Done:
586 return status;
587}
588
593 )
594/*++
595
596Routine Description:
597 Optionally registers a shutdown and last chance shutdown notification on
598 behalf of the device.
599
600Arguments:
601 Init - Initialization structure which will indicate if registration is required
602
603Return 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
696 __in FxIoQueue* TargetQueue
697 )
698/*++
699
700Routine Description:
701
702 Used to register driver specified for dispatching create requests.
703
704Arguments:
705
706Return 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
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
756 )
757/*++
758
759Routine Description:
760
761 Dispatch routine for handling create, cleanup, close, and shutdown requests.
762
763Arguments:
764
765
766Return 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:
786 break;
787
788 case IRP_MJ_CLOSE:
789 status = OnClose(&fxIrp);
790 break;
791
792 case IRP_MJ_CLEANUP:
794 break;
795
796 case IRP_MJ_SHUTDOWN:
798 break;
799
800 default:
801 ASSERT(FALSE);
805 break;
806 }
807
808 return status;
809}
810
815 )
816/*++
817
818Routine 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
839Arguments:
840
841Return 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",
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,
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 {
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!",
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!",
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(
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(
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
1341Error:
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
1362
1363 // fallthrough
1364
1365RequestIsGone:
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
1385 __in FxIrp* Irp,
1388 )
1389{
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
1401VOID
1403 __in FxIrp *Irp
1404 )
1405/*++
1406
1407Routine 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
1416Arguments:
1417
1418Return 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
1447STDCALL
1452 )
1453/*++
1454
1455Routine Description:
1456
1457 This completion routine is set only when the IRP is forwarded
1458 directly by the framework to the lower driver. Framework forwards
1459 the IRP request if:
1460 1) The driver happens to be a filter and hasn't registered any
1461 callbacks to handle create request.
1462 2) The driver is not a filter but has explicitly requested the
1463 framework to autoforward create/cleanup/close requests down.
1464
1465 We need to intercept the create in the completion path to find
1466 out whether the lower driver has succeeded or failed the request.
1467 If the request is failed, we should inform the package so that
1468 it can cleanup the state because I/O manager wouldn't send
1469 cleanup & close requests if the create is failed.
1470
1471Arguments:
1472
1473Return Value:
1474
1475 NTSTATUS
1476
1477 --*/
1478{
1479 FxPkgGeneral* pFxPkgGeneral;
1481
1483
1484 pFxPkgGeneral = (FxPkgGeneral*) Context;
1485
1486 ASSERT(pFxPkgGeneral != NULL);
1487
1488 //
1489 // Let the package know that create is completed
1490 // so that it can cleanup the state.
1491 //
1492 pFxPkgGeneral->CreateCompleted(&irp);
1493
1494 //
1495 // Let the irp continue on its way.
1496 //
1498
1499 return irp.GetStatus();
1500}
1501
1504STDCALL
1509 )
1510/*++
1511
1512Routine Description:
1513
1514 Routine Description:
1515
1516 This completion routine is set only when the create request is forwarded by the
1517 framework to the lower driver. Framework forwards the create request using this
1518 completion routine if:
1519
1520 1) Class extension's create callback is set by did not claim the request.
1521 2) Client driver did not register for a create callback or a create queue.
1522
1523Arguments:
1524
1525Return Value:
1526
1527 STATUS_MORE_PROCESSING_REQUIRED
1528
1529 --*/
1530{
1533
1535
1537
1538 ASSERT(request != NULL);
1539
1541
1542 request->Complete(irp.GetStatus());
1543
1545}
1546
1551 )
1552/*++
1553
1554Routine Description:
1555
1556 Called in response to IRP_MJ_CLEANUP. This means an handle to
1557 the device is closed. After invoking the driver registered callback
1558 event, flush all the queues to cancel requests that belong to the
1559 file handle being closed. There is however a possibility for
1560 new requests to come in with the same fileobject.
1561
1562
1563
1564
1565
1566Arguments:
1567
1568Return Value:
1569
1570 NTSTATUS
1571
1572 --*/
1573{
1576 WDFFILEOBJECT hwdfFO = NULL;
1578 FxFileObjectInfo* fileObjInfo;
1579 MxFileObject fileObject;
1580
1581
1582
1583
1584
1585
1586 //
1587 // Check to see if the fileobject represents a stream fileobject
1588 // created using IoCreateStreamFileObjectLite.
1589 //
1590 fileObject.SetFileObject(FxIrp->GetFileObject());
1591 if (FxIrp->GetFileObject() &&
1592 (fileObject.GetFlags() & FO_STREAM_FILE)){
1594 goto Passthru;
1595 }
1596
1598 m_Device,
1601 &pFxFO
1602 );
1603
1605
1606 if (pFxFO != NULL && NT_SUCCESS(status)) {
1607 hwdfFO = pFxFO->GetHandle();
1608 }
1609
1610 //
1611 // Invoke cleanup callbacks.
1612 //
1613 if (NULL == pFxFO) {
1614 //
1615 // Invoke cleanup callbacks of next layer (cx or client driver) based on the
1616 // autoforward setting of previous layer. (top to bottom).
1617 // AutoforwardCleanupClose set to FALSE with a not null create callback
1618 // means that create request was never forwarded to lower layer.
1619 //
1622 next = next->Blink) {
1623
1624 fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1625
1626 if (WdfFalse == fileObjInfo->AutoForwardCleanupClose &&
1627 fileObjInfo->EvtCxFileCreate.Method != NULL) {
1628 next = next->Blink; // one before the real start entry.
1629 break;
1630 }
1631 }
1632 }
1633 else {
1634 //
1635 // 'OnCreate' sets this package context.
1636 //
1638 if (NULL == next) {
1640 }
1641 }
1642
1643 //
1644 // Invoke cleanup callbacks only if this layer (cx or client driver) had the
1645 // opprtunity to see the create request.
1646 //
1647 for (next = next->Flink;
1649 next = next->Flink) {
1650
1651 fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1652 fileObjInfo->EvtFileCleanup.Invoke(hwdfFO);
1653 }
1654
1655 //
1656 // hwdfFO could be NULL depending on the FileObjectClass
1657 //
1658
1659 //
1660 // Scan all the I/O queues associated with this device
1661 // and cancel the requests that matches with the handle
1662 // being closed. We will be able to cancel only requests that
1663 // are waiting to be dispatched. If the requests are already
1664 // presented to the driver then it's the responsibility of the
1665 // driver to complete them when the cleanup callback is invoked.
1666 //
1667 if(FxIrp->GetFileObject() != NULL ) {
1668 FxPkgIo* pPkgIo;
1669
1672 }
1673
1674Passthru:
1678 } else {
1682 }
1683
1684 return status;
1685
1686}
1687
1692 )
1693/*++
1694
1695Routine Description:
1696
1697 Called in response to IRP_MJ_CLOSE. Invoke EvtFileClose event
1698 if registered and destroy the WDFFILEOBJECT.
1699
1700Arguments:
1701
1702Return Value:
1703
1704 NTSTATUS
1705
1706 --*/
1707{
1710 WDFFILEOBJECT hwdfFO = NULL;
1711 BOOLEAN isStreamFileObject = FALSE;
1712 BOOLEAN acquiredRemLock = FALSE;
1714 FxFileObjectInfo* fileObjInfo;
1715 MxFileObject fileObject;
1716 MdIrp irp;
1717
1718 //
1719 // FxIrp.CompleteRequest NULLs the m_Irp so store m_Irp separately
1720 // for use in ReleaseRemoveLock.
1721 //
1722 irp = FxIrp->GetIrp();
1723
1724 //
1725 // Check to see if the fileobject represents a stream fileobject
1726 // created using IoCreateStreamFileObjectLite. If so, this is a
1727 // is spurious close sent by the I/O manager when it invalidates
1728 // the volumes (IopInvalidateVolumesForDevice).
1729 //
1730 fileObject.SetFileObject(FxIrp->GetFileObject());
1731 if (FxIrp->GetFileObject() &&
1732 (fileObject.GetFlags() & FO_STREAM_FILE)){
1733 isStreamFileObject = TRUE;
1735 goto Passthru;
1736 }
1737
1739 m_Device,
1742 &pFxFO
1743 );
1744
1746
1747 if (pFxFO != NULL && NT_SUCCESS(status)) {
1748 hwdfFO = pFxFO->GetHandle();
1749 }
1750
1751 //
1752 // Invoke close callbacks.
1753 //
1754 if (NULL == pFxFO) {
1755 //
1756 // Invoke close callbacks of next layer (cx or client driver) based on the autoforward
1757 // setting of previous layer. (top to bottom).
1758 // AutoforwardCleanupClose set to FALSE with a not null create callback
1759 // means that create request was never forwarded to lower layer.
1760 //
1763 next = next->Blink) {
1764
1765 fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1766
1767 if (WdfFalse == fileObjInfo->AutoForwardCleanupClose &&
1768 fileObjInfo->EvtCxFileCreate.Method != NULL) {
1769 next = next->Blink; // one before the real start entry.
1770 break;
1771 }
1772 }
1773 }
1774 else {
1775 //
1776 // 'OnCreate' sets this package context.
1777 //
1779 if (NULL == next) {
1781 }
1782 }
1783
1784 //
1785 // Invoke close callbacks only if this layer (cx or client driver) had the opprtunity
1786 // to see the create request.
1787 //
1788 for (next = next->Flink;
1790 next = next->Flink) {
1791
1792 fileObjInfo = CONTAINING_RECORD(next, FxFileObjectInfo, ListEntry);
1793 fileObjInfo->EvtFileClose.Invoke(hwdfFO);
1794 }
1795
1796 //
1797 // Destroy the WDFFILEOBJECT. This will result in
1798 // fileobject EvtCleanup and EvtDestroy event.
1799 //
1801 m_Device,
1804 );
1805
1806Passthru:
1807
1811 } else {
1812 //
1813 // We're about to complete the request, but we need to decrement the
1814 // open handle count after we complete the request. However, completing
1815 // the request immediately opens the gate for the remove IRP to arrive
1816 // and run down the device. Hence we'll acquire the remove lock in order
1817 // to ensure that the device is not removed before we've decremented the
1818 // open handle count.
1819 //
1820#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1821 acquiredRemLock = AcquireRemoveLockForClose(FxIrp);
1822#endif
1826 }
1827
1828 if (isStreamFileObject == FALSE) {
1829 //
1830 // Note that after this call returns, this object may have been deleted!
1831
1832
1833
1834
1835
1836
1837
1838
1840 }
1841
1842 if (acquiredRemLock) {
1844 irp);
1845 }
1846
1847 return status;
1848
1849}
1850
1851BOOLEAN
1854 )
1855/*++
1856
1857Routine Description:
1858
1859 For PNP devices, this routine acquires the remove lock when handling the
1860 close IRP.
1861
1862Arguments:
1863 Irp - Pointer to the close IRP
1864
1865Return Value:
1866
1867 A BOOLEAN value that indicates whether or not the function actually acquired
1868 the remove lock
1869
1870 --*/
1871{
1873 BOOLEAN lockAcquired;
1876
1877 //
1878 // Initialization
1879 //
1880 lockAcquired = FALSE;
1881
1882 //
1883 // We attempt to acquire the remove lock only for PNP device objects
1884 //
1885 if (m_Device->IsPnp() == FALSE) {
1886 goto Done;
1887 }
1888
1889 //
1890 // If driver has opted in for remove lock for I/O operations we have
1891 // already acquired remove lock for Close so no need to do it again.
1892 //
1893 if (wdmExtension->RemoveLockOptionFlags &
1895 goto Done;
1896 }
1897
1900 FxIrp->GetIrp());
1901 if (NT_SUCCESS(status)) {
1902 //
1903 // Successfully acquired the remove lock
1904 //
1905 lockAcquired = TRUE;
1906 } else {
1907 //
1908 // This is likely to have failed because we got the remove IRP and
1909 // called IoReleaseRemoveLockAndWait on another thread. This would
1910 // happen if there's a bug in the driver above us in the stack that
1911 // caused it to forward us the remove IRP before we completed the close
1912 // IRP.
1913 //
1914 // There's not much we can do now, since we're already racing against
1915 // the remove IRP.
1916 //
1918
1920
1924 TRACINGIO,
1925 "Unable to acquire remove lock while handling the close IRP"
1926 " 0x%p, %!STATUS!",
1927 FxIrp->GetIrp(), status);
1928
1931 }
1932 }
1933
1934Done:
1935 return lockAcquired;
1936}
1937
1938
1943 )
1944/*++
1945
1946Routine Description:
1947
1948 Called in response to IRP_MJ_SHUTDOWN.
1949
1950Arguments:
1951
1952Return Value:
1953
1954 NTSTATUS
1955
1956 --*/
1957{
1959
1961
1962 if(m_Device->IsFilter()) {
1965 }
1966 else {
1971 }
1972
1973 return status;
1974
1975}
1976
1977VOID
1979 VOID
1980 )
1981{
1984 }
1985}
1986
1987BOOLEAN
1989 VOID
1990 )
1991{
1992 //
1993 // Remove the bias of one that we use to track if a control device should be
1994 // deleted.
1995 //
1997 return TRUE;
1998 }
1999 else {
2000 return FALSE;
2001 }
2002
2003}
2004
2005VOID
2007 __out_opt WDF_EXECUTION_LEVEL* ExecutionLevel,
2008 __out_opt WDF_SYNCHRONIZATION_SCOPE* SynchronizationScope
2009 )
2010/*++
2011
2012Routine Description:
2013 This routine is the helper routine and is used by FxFileObject to get the
2014 ExecutionLevel and SynchronizationScope.
2015
2016Arguments:
2017
2018Return Value:
2019 VOID
2020
2021--*/
2022
2023{
2024 if (ExecutionLevel != NULL) {
2025 *ExecutionLevel = m_ExecutionLevel;
2026 }
2027
2028 if (SynchronizationScope != NULL) {
2029 *SynchronizationScope = m_SynchronizationScope;
2030 }
2031}
2032
2036 )
2037/*++
2038
2039Routine Description:
2040 This routine is the helper routine and is used by FxFileObject to get the
2041 LockObject.
2042
2043
2044Arguments:
2045
2046Return Value:
2047 FxCallbackLock *
2048
2049--*/
2050
2051{
2052 if (LockObject != NULL) {
2054 }
2055
2056 return m_CallbackLockPtr;
2057}
2058
2059
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
BOOL Error
Definition: chkdsk.c:66
BOOLEAN Invoke(__in WDFDEVICE Device, __in WDFREQUEST Request, __in_opt WDFFILEOBJECT FileObject)
PFN_WDFCX_DEVICE_FILE_CREATE Method
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
FxCallbackLock * GetCallbackLockPtr(__out_opt FxObject **LockObject)
VOID GetConstraints(__out_opt WDF_EXECUTION_LEVEL *ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
__inline BOOLEAN IsPnp(VOID)
Definition: fxdevice.hpp:1200
__inline BOOLEAN IsExclusive(VOID)
Definition: fxdevice.hpp:1218
__inline PWDF_OBJECT_ATTRIBUTES GetRequestAttributes(VOID)
Definition: fxdevice.hpp:1315
__inline FxDriver * GetCxDriver(__in FxCxDeviceInfo *CxDeviceInfo)
Definition: fxdevice.hpp:1654
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
__inline BOOLEAN IsLegacy(VOID)
Definition: fxdevice.hpp:1209
__inline BOOLEAN IsCxInIoPath(VOID)
Definition: fxdevice.hpp:1594
FxPkgIo * m_PkgIo
Definition: fxdevice.hpp:669
__inline BOOLEAN IsFilter()
Definition: fxdevice.hpp:1408
__inline VOID SetFileObjectClass(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:1135
__inline WDF_FILEOBJECT_CLASS GetFileObjectClass(VOID)
Definition: fxdevice.hpp:1123
VOID ControlDeviceDelete(VOID)
Definition: fxdevice.hpp:1465
BOOLEAN m_AutoForwardCleanupClose
Definition: fxdevice.hpp:605
__inline WDFDRIVER GetHandle(VOID)
Definition: fxdriver.hpp:202
void Invoke(__in_opt WDFFILEOBJECT FileObject)
void Invoke(__in_opt WDFFILEOBJECT FileObject)
VOID Invoke(__in WDFDEVICE Device, __in WDFREQUEST Request, __in_opt WDFFILEOBJECT FileObject)
PFN_WDF_DEVICE_FILE_CREATE Method
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)
__inline VOID SetPkgCleanupCloseContext(PVOID Context)
VOID DeleteFileObjectFromFailedCreate(VOID)
__inline PVOID GetPkgCleanupCloseContext(VOID)
static _Must_inspect_result_ NTSTATUS _GetFileObjectFromWdm(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
static VOID _DestroyFileObject(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject)
__inline WDFFILEOBJECT GetHandle(VOID)
_Must_inspect_result_ NTSTATUS ForwardRequest(__in FxIoQueue *pDestQueue, __in FxRequest *pRequest)
Definition: fxioqueue.cpp:1712
_Must_inspect_result_ NTSTATUS QueueRequest(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2245
_Must_inspect_result_ NTSTATUS GetRequest(__in_opt MdFileObject FileObject, __in_opt FxRequest *TagRequest, __deref_out FxRequest **pOutRequest)
Definition: fxioqueue.cpp:962
Definition: fxirp.hpp:28
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
MdFileObject GetFileObject(VOID)
Definition: fxirpum.cpp:1460
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
VOID PropagatePendingReturned(VOID)
Definition: fxirpum.cpp:443
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
NTSTATUS CallDriver(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:36
void SetCallbackLockPtr(FxCallbackLock *Lock)
Definition: fxcallback.hpp:105
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
VOID MarkPassiveCallbacks(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:972
FxObject * m_CallbackLockObjectPtr
_Must_inspect_result_ NTSTATUS OnCleanup(__inout FxIrp *FxIrp)
_Must_inspect_result_ NTSTATUS ConfigureForwarding(__in FxIoQueue *FxQueue)
LONG m_OpenHandleCount
BOOLEAN CanDestroyControlDevice(VOID)
FxShutDown m_EvtDeviceShutdown
virtual _Must_inspect_result_ NTSTATUS Dispatch(__inout MdIrp Irp)
BOOLEAN AcquireRemoveLockForClose(__inout FxIrp *FxIrp)
VOID CreateCompleted(__in FxIrp *Irp)
_Must_inspect_result_ NTSTATUS ConfigureFileObjectClass(__in PLIST_ENTRY FileObjInfoList)
WDF_EXECUTION_LEVEL m_ExecutionLevel
FxCallbackLock * m_CallbackLockPtr
FxCallbackLock * GetCallbackLockPtrHelper(__deref_out_opt FxObject **LockObject)
_Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
_Must_inspect_result_ NTSTATUS ConfigureConstraints(__in PLIST_ENTRY FileObjInfoList)
static MdCompletionRoutineType _CreateCompletionRoutine
_Must_inspect_result_ NTSTATUS PostCreateDeviceInitialize(__in PWDFDEVICE_INIT Init)
VOID GetConstraintsHelper(__out_opt WDF_EXECUTION_LEVEL *ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
VOID DecrementOpenHandleCount(VOID)
_Must_inspect_result_ NTSTATUS ForwardCreateRequest(__in FxIrp *FxIrp, __in MdCompletionRoutine CompletionRoutine, __in PVOID Context)
FxIoQueue * m_DefaultQueueForCreates
_Must_inspect_result_ NTSTATUS OnShutdown(__inout FxIrp *FxIrp)
LIST_ENTRY m_FileObjectInfoHeadList
WDF_SYNCHRONIZATION_SCOPE m_SynchronizationScope
static MdCompletionRoutineType _CreateCompletionRoutine2
FxPkgGeneral(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device)
_Must_inspect_result_ NTSTATUS OnClose(__inout FxIrp *FxIrp)
FxIoQueue * m_DriverCreatedQueue
_Must_inspect_result_ NTSTATUS OnCreate(__inout FxIrp *FxIrp)
_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
_Must_inspect_result_ NTSTATUS FlushAllQueuesByFileObject(__in MdFileObject FileObject)
Definition: fxpkgio.cpp:1393
__inline NTSTATUS Complete(__in NTSTATUS Status)
Definition: fxrequest.hpp:770
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
VOID Invoke(__in WDFDEVICE Device)
PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION m_Method
ULONG GetFlags(VOID)
__inline VOID SetFileObject(_In_ MdFileObject FileObject)
Definition: mxfileobject.h:36
static __inline NTSTATUS MxAcquireRemoveLock(__in MdRemoveLock RemoveLock, __in_opt PVOID Tag)
Definition: mxgeneralkm.h:268
static __inline VOID MxReleaseRemoveLock(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:278
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
_In_ PIRP Irp
Definition: csq.h:116
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __deref_out_opt
Definition: dbghelp.h:29
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
PFX_DRIVER_GLOBALS fxDriverGlobals
BOOLEAN __inline FxIsFileObjectOptional(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:112
FxPkgIo * pPkgIo
FX_TRACK_DRIVER(fxDriverGlobals)
FxFileObject * pFxFO
FxIrp fxIrp(Irp)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
@ OkForDownLevel
Definition: fxglobals.h:80
_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
@ ObjectDoNotLock
Definition: fxobject.hpp:128
#define FX_PKG_GENERAL_FLAG_CLIENT_INFO
#define FX_PKG_GENERAL_FLAG_CX_INFO
#define FX_PKG_GENERAL_FLAG_CLIENT_CREATE
#define FX_PKG_GENERAL_FLAG_CX_CREATE
#define FX_PKG_GENERAL_FLAG_CREATE
FxIrp * irp
@ FX_TYPE_PACKAGE_GENERAL
Definition: fxtypes.h:96
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
WUDF_IO_COMPLETION_ROUTINE * MdCompletionRoutine
Definition: mxum.h:142
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
NTSTATUS NTAPI IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1663
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
WDFCX_FILEOBJECT_CONFIG Callbacks
WDF_TRI_STATE AutoForwardCleanupClose
WDF_FILEOBJECT_CLASS Class
WDF_OBJECT_ATTRIBUTES Attributes
FxDriver * Driver
WDF_OBJECT_ATTRIBUTES RequestAttributes
FxFileObjectFileCreate EvtFileCreate
WDF_FILEOBJECT_CLASS FileObjectClass
FxFileObjectFileClose EvtFileClose
FxFileObjectFileCleanup EvtFileCleanup
WDF_TRI_STATE AutoForwardCleanupClose
WDF_OBJECT_ATTRIBUTES Attributes
FxCxFileObjectFileCreate EvtCxFileCreate
FxCxDeviceInfo * CxDeviceInfo
ULONG RemoveLockOptionFlags
Definition: fxdevice.hpp:38
CxFileObjectInit FileObject
FxCxDeviceInfo * CxDeviceInfo
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
PFN_WDF_FILE_CLEANUP EvtFileCleanup
Definition: wdfcx.h:38
PFN_WDFCX_DEVICE_FILE_CREATE EvtCxDeviceFileCreate
Definition: wdfcx.h:28
PFN_WDF_FILE_CLOSE EvtFileClose
Definition: wdfcx.h:33
WDF_TRI_STATE PowerManaged
Definition: wdfio.h:393
WDFOBJECT ParentObject
Definition: wdfobject.h:130
WDF_EXECUTION_LEVEL ExecutionLevel
Definition: wdfobject.h:120
WDF_SYNCHRONIZATION_SCOPE SynchronizationScope
Definition: wdfobject.h:125
Definition: tftpd.h:86
Definition: ps.c:97
#define LockObject(Object)
Definition: titypes.h:34
struct _LIST_ENTRY * PLIST_ENTRY
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STDCALL
Definition: wdf.h:45
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
@ WdfDeviceLastChanceShutdown
Definition: wdfcontrol.h:66
@ WdfDeviceShutdown
Definition: wdfcontrol.h:65
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
enum _WDF_FILEOBJECT_CLASS WDF_FILEOBJECT_CLASS
@ WDF_REMOVE_LOCK_OPTION_ACQUIRE_FOR_IO
Definition: wdfdevice.h:1639
@ WdfRequestTypeCreate
Definition: wdfdevice.h:503
@ WdfFileObjectNotRequired
Definition: wdfdevice.h:460
@ WdfFileObjectWdfCannotUseFsContexts
Definition: wdfdevice.h:463
@ WdfFileObjectCanBeOptional
Definition: wdfdevice.h:464
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:426
@ WdfIoQueueDispatchManual
Definition: wdfio.h:80
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
@ WdfSynchronizationScopeInheritFromParent
Definition: wdfobject.h:63
@ WdfSynchronizationScopeQueue
Definition: wdfobject.h:65
@ WdfSynchronizationScopeNone
Definition: wdfobject.h:66
@ WdfSynchronizationScopeDevice
Definition: wdfobject.h:64
@ WdfExecutionLevelPassive
Definition: wdfobject.h:54
@ WdfExecutionLevelDispatch
Definition: wdfobject.h:55
@ WdfExecutionLevelInheritFromParent
Definition: wdfobject.h:53
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
@ WdfFalse
Definition: wdftypes.h:87
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define FO_STREAM_FILE
Definition: iotypes.h:1783
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP