WDK Mini Filter Example
MetadataManager/operations.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1999 - 2002 Microsoft Corporation
4 
5 Module Name:
6 
7  operations.c
8 
9 Abstract:
10 
11  This is the i/o operations module of the kernel mode filter driver implementing
12  filter metadata management.
13 
14 
15 Environment:
16 
17  Kernel mode
18 
19 
20 --*/
21 
22 #include "pch.h"
23 
24 //
25 // Missing error code on Win2k
26 //
27 
28 #if (WINVER==0x0500)
29 #ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER
30 #define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS)0xC0000369L)
31 #endif
32 #endif
33 
34 //
35 // Assign text sections for each routine.
36 //
37 
38 #ifdef ALLOC_PRAGMA
39 #pragma alloc_text(PAGE, FmmPreCreate)
40 #pragma alloc_text(PAGE, FmmPostCreate)
41 #pragma alloc_text(PAGE, FmmPreCleanup)
42 #pragma alloc_text(PAGE, FmmPostCleanup)
43 #pragma alloc_text(PAGE, FmmPreFSControl)
44 #pragma alloc_text(PAGE, FmmPostFSControl)
45 #pragma alloc_text(PAGE, FmmPreDeviceControl)
46 #pragma alloc_text(NONPAGED, FmmPostDeviceControl)
47 #pragma alloc_text(PAGE, FmmPreShutdown)
48 #pragma alloc_text(PAGE, FmmPrePnp)
49 #pragma alloc_text(PAGE, FmmPostPnp)
50 
51 #endif
52 
53 FLT_PREOP_CALLBACK_STATUS
55  _Inout_ PFLT_CALLBACK_DATA Cbd,
56  _In_ PCFLT_RELATED_OBJECTS FltObjects,
57  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
58  )
59 {
60  NTSTATUS status;
61  FLT_PREOP_CALLBACK_STATUS callbackStatus;
62  BOOLEAN isImpliedLock = FALSE;
63 
64  UNREFERENCED_PARAMETER( FltObjects );
65  UNREFERENCED_PARAMETER( CompletionContext );
66 
67  PAGED_CODE();
68 
69  DebugTrace( DEBUG_TRACE_ALL_IO,
70  ("[Fmm]: FmmPreCreate -> Enter (Cbd = %p, FileObject = %p)\n",
71  Cbd,
72  FltObjects->FileObject) );
73 
74 
75  //
76  // Initialize defaults
77  //
78 
79  status = STATUS_SUCCESS;
80  callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; // pass through - default is no post op callback
81 
82  //
83  // Sanity check to ensure that the volume detection logic works
84  //
85  // If the filename length is 0 and the related file object is NULL,
86  // the the FO_VOLUME_OPEN flag must be set
87  //
88 
89  FLT_ASSERT( (!(Cbd->Iopb->TargetFileObject->FileName.Length == 0 &&
90  Cbd->Iopb->TargetFileObject->RelatedFileObject == NULL)) ||
91  FlagOn( Cbd->Iopb->TargetFileObject->Flags, FO_VOLUME_OPEN ) );
92 
93  if (FmmTargetIsVolumeOpen( Cbd )) {
94 
95  //
96  // Check for implicit volume locks (primarily used by autochk)
97  //
98 
99  status = FmmIsImplicitVolumeLock( Cbd, &isImpliedLock );
100 
101  FLT_ASSERT( NT_SUCCESS( status ) );
102 
103  if (isImpliedLock) {
104 
105  //
106  // This is an implicit volume lock
107  //
108 
109  //
110  // Give up the metadata file handle and the metadata file object
111  //
112 
113  status = FmmReleaseMetadataFileReferences( Cbd );
114 
115  if ( NT_SUCCESS( status )) {
116 
117  //
118  // Continue with the lock/dismount - we need to check if the
119  // lock operation suceeded in the post-op
120  //
121 
122  callbackStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
123  } else {
124 
125  //
126  // Fail the lock/dismount
127  //
128 
129  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
130  ("[Fmm]: Failed to release metadata file references with status 0x%x for a volume lock/dismount\n",
131  status) );
132 
133  //
134  // Since this operation has failed, FmmPreCreateCleanup will
135  // update Cbd->IoStatus.Status with the status code and
136  // complete the operation by returning FLT_PREOP_COMPLETE
137  //
138 
139  }
140 
141  }
142 
143  //
144  // We do not need to process volume opens any further
145  //
146 
147  goto FmmPreCreateCleanup;
148  }
149 
150 
151 #if VERIFY_METADATA_OPENED
152 
153  //
154  // For all non-volume opens, check if the metadata is open in the post-op
155  //
156 
157  callbackStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
158 
159 #endif
160 
161 
162  //
163  // Here the filter can do any further processing it may want to do
164  // in the PreCreate Callback
165  //
166 
167 
168 
169 FmmPreCreateCleanup:
170 
171 
172  //
173  // If any operation has failed then complete and fail the call
174  //
175 
176  if (!NT_SUCCESS( status )) {
177 
178  DebugTrace( DEBUG_TRACE_ERROR,
179  ("[Fmm]: FmmPreCreate -> Failed with status 0x%x \n",
180  status) );
181 
182  Cbd->IoStatus.Status = status;
183  callbackStatus = FLT_PREOP_COMPLETE;
184  }
185 
186  DebugTrace( DEBUG_TRACE_ALL_IO,
187  ("[Fmm]: FmmPreCreate -> Exit (Cbd = %p, FileObject = %p)\n",
188  Cbd,
189  FltObjects->FileObject) );
190 
191  return callbackStatus;
192 
193 }
194 
195 
196 FLT_POSTOP_CALLBACK_STATUS
198  _Inout_ PFLT_CALLBACK_DATA Cbd,
199  _In_ PCFLT_RELATED_OBJECTS FltObjects,
200  _In_ PVOID CbdContext,
201  _In_ FLT_POST_OPERATION_FLAGS Flags
202  )
203 {
204  NTSTATUS status;
205  BOOLEAN isImpliedLock = FALSE;
206 
207  UNREFERENCED_PARAMETER( FltObjects );
208  UNREFERENCED_PARAMETER( CbdContext );
209  UNREFERENCED_PARAMETER( Flags );
210 
211  PAGED_CODE();
212 
213  DebugTrace( DEBUG_TRACE_ALL_IO,
214  ("[Fmm]: FmmPostCreate -> Enter (Cbd = %p, FileObject = %p)\n",
215  Cbd,
216  FltObjects->FileObject) );
217 
218  //
219  // Initialize defaults
220  //
221 
222  status = STATUS_SUCCESS;
223 
224  if (!FlagOn(Flags,FLTFL_POST_OPERATION_DRAINING) &&
225  FmmTargetIsVolumeOpen( Cbd )) {
226 
227  //
228  // Check for implicit volume locks (primarily used by autochk)
229  //
230 
231  status = FmmIsImplicitVolumeLock( Cbd, &isImpliedLock );
232 
233  FLT_ASSERT( NT_SUCCESS( status ) );
234 
235  if (isImpliedLock) {
236 
237  //
238  // This is an implicit volume lock
239  //
240 
241  if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
242 
243  //
244  // The lock failed - reaquire our references to the metadata file
245  // handle and the metadata file object
246  //
247 
248  status = FmmReacquireMetadataFileReferences( Cbd );
249 
250  if (!NT_SUCCESS( status )) {
251 
252  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
253  ("[Fmm]: Failed to re-open metadata with status 0x%x after a failed lock with status 0x%x\n",
254  status,
255  Cbd->IoStatus.Status) );
256 
257  //
258  // Sanity - we are now in a bad state. The lock has failed
259  // but we have not been able to re-acquire references to
260  // our metadata file
261  //
262  // It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
263  // so we should ignore that.
264  //
265  // It is also possible to fail if the instance context was in a transition state
266  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
267  //
268 
269  FLT_ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
270  (status == STATUS_FILE_LOCK_CONFLICT) );
271  }
272 
273  } else {
274 
275  //
276  // The lock operation suceeded - update the
277  // MetadataOpenTriggerFileObject in the instance context to
278  // the File Object that performed the lock operation. This
279  // is so we can recognize an implicit unlock at close time.
280  //
281  // You may have noticed that we set the
282  // MetadataOpenTriggerFileObject in pre-create and may be
283  // wondering why we set it again in this case. This is to
284  // support a lower filter doing a recursive lock operation
285  // from the top of the stack.
286  //
287 
288  status = FmmSetMetadataOpenTriggerFileObject( Cbd );
289 
290  if (!NT_SUCCESS( status )) {
291 
292  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
293  ("[Fmm]: Failed to update MetadataOpenTriggerFileObject in the instance context with status 0x%x after a successful lock.\n",
294  status) );
295 
296  //
297  // Sanity - we are now in a bad state. We have failed to set the TriggerFileObject
298  // We may not be able to detect an unlock operation on which we need to
299  // re-acquire our metadata file references
300  //
301 
302  FLT_ASSERT( status == STATUS_FILE_LOCK_CONFLICT );
303 
304  }
305  }
306  }
307 
308  //
309  // We do not need to process volume opens any further
310  //
311 
312  goto FmmPostCreateCleanup;
313  }
314 
315 #if VERIFY_METADATA_OPENED
316 
317  //
318  // For all successful non-volume opens, check if the metadata is open
319  //
320 
321  if (NT_SUCCESS( Cbd->IoStatus.Status )) {
322 
323  BOOLEAN metadataOpen;
324 
325  status = FmmIsMetadataOpen( Cbd, &metadataOpen );
326 
327  if (NT_SUCCESS( status) && !metadataOpen) {
328 
329  DebugTrace( DEBUG_TRACE_ERROR,
330  ("[Fmm]: FmmPostCreate -> Create successful but metadata not open \n") );
331  }
332 
333  FLT_ASSERT( ((NT_SUCCESS( status) && metadataOpen) ||
334  (status == STATUS_FILE_LOCK_CONFLICT)) );
335  }
336 
337 #endif
338 
339  //
340  // Here the filter can do any further processing it may want to do
341  // in the PostCreate Callback
342  //
343 
344 FmmPostCreateCleanup:
345 
346 
347  if (!NT_SUCCESS( status )) {
348 
349  DebugTrace( DEBUG_TRACE_ERROR,
350  ("[Fmm]: FmmPostCreate -> Failed with status 0x%x \n",
351  status) );
352 
353  //
354  // It does not make sense to fail in the the post op, since the operation has completed
355  //
356  }
357 
358 
359  DebugTrace( DEBUG_TRACE_ALL_IO,
360  ("[Fmm]: FmmPostCreate -> Exit (Cbd = %p, FileObject = %p, Status = 0x%08X)\n",
361  Cbd,
362  FltObjects->FileObject,
363  Cbd->IoStatus.Status) );
364 
365  return FLT_POSTOP_FINISHED_PROCESSING;
366 }
367 
368 
369 FLT_PREOP_CALLBACK_STATUS
371  _Inout_ PFLT_CALLBACK_DATA Cbd,
372  _In_ PCFLT_RELATED_OBJECTS FltObjects,
373  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
374  )
375 {
376 
377  UNREFERENCED_PARAMETER( Cbd );
378  UNREFERENCED_PARAMETER( CompletionContext );
379  UNREFERENCED_PARAMETER( FltObjects );
380 
381  PAGED_CODE();
382 
383  DebugTrace( DEBUG_TRACE_ALL_IO,
384  ("[Fmm]: FmmPreCleanup -> Enter (Cbd = %p, FileObject = %p)\n",
385  Cbd,
386  FltObjects->FileObject) );
387 
388 
389  DebugTrace( DEBUG_TRACE_ALL_IO,
390  ("[Fmm]: FmmPreCleanup -> Exit (Cbd = %p, FileObject = %p)\n",
391  Cbd,
392  FltObjects->FileObject) );
393 
394  return FLT_PREOP_SYNCHRONIZE;
395 }
396 
397 
398 FLT_POSTOP_CALLBACK_STATUS
400  _Inout_ PFLT_CALLBACK_DATA Cbd,
401  _In_ PCFLT_RELATED_OBJECTS FltObjects,
402  _Inout_ PVOID CompletionContext,
403  _In_ FLT_POST_OPERATION_FLAGS Flags
404  )
405 {
406  NTSTATUS status;
407 
408 
409  UNREFERENCED_PARAMETER( FltObjects );
410  UNREFERENCED_PARAMETER( CompletionContext );
411  UNREFERENCED_PARAMETER( Flags );
412 
413  //
414  // The pre-operation callback will return FLT_PREOP_SYNCHRONIZE if it needs a
415  // post operation callback. In this case, the Filter Manager will call the
416  // minifilter's post-operation callback in the context of the pre-operation
417  // thread, at IRQL <= APC_LEVEL. This allows the post-operation code to be
418  // pagable and also allows it to access paged data
419  //
420 
421  PAGED_CODE();
422 
423  DebugTrace( DEBUG_TRACE_ALL_IO,
424  ("[Fmm]: FmmPostCleanup -> Enter (Cbd = %p, FileObject = %p)\n",
425  Cbd,
426  FltObjects->FileObject) );
427 
428  //
429  // Initialize defaults
430  //
431 
432  status = STATUS_SUCCESS;
433 
434 
435  if (!FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) &&
436  FmmTargetIsVolumeOpen( Cbd )) {
437 
438  if (NT_SUCCESS( Cbd->IoStatus.Status )) {
439 
440  //
441  // A close on a volume handle could be an unlock if a lock was
442  // previously called on this handle. Check if this was a close
443  // on a volume handle on which a lock was previously successful.
444  // If so, re-acquire the references to our metadata file
445  //
446 
447  status = FmmReacquireMetadataFileReferences( Cbd );
448 
449  if (!NT_SUCCESS( status )) {
450 
451  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
452  ("[Fmm]: Failed to re-open metadata with status 0x%x after a successful unlock.\n",
453  status) );
454 
455  //
456  // Sanity - we are now in a bad state. The volume was unlocked
457  // but we have not been able to re-acquire references to
458  // our metadata file
459  //
460  // Ntfs dismounts and remounts the volume after an unlock. So we ignore
461  // failures to open the metadata with STATUS_INVALID_DEVICE_OBJECT_PARAMETER
462  // or STATUS_FILE_INVALID because the volume should have been remounted and
463  // the metadata file should have been opened on the newly mounted instance
464  // of that volume
465  //
466  // Note however, that if this is an implicit lock (used by autoXXX.exe) then
467  // ntfs will not automatically dismount the volume. It relies on the application
468  // to restart the system if it has made any changes to the volume. If the
469  // application has not made any changes then ntfs will simply continue on
470  // after the unlock without dismounting the volume. Hence we cannot assume
471  // that ntfs always dismounts the volume. We need to try to re-acquire
472  // a handle to our metadata file and ignore failure with error
473  // STATUS_INVALID_DEVICE_OBJECT_PARAMETER or STATUS_NO_MEDIA_IN_DEVICE which
474  // indicate that the volume has been dismounted
475  //
476  // Also it is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
477  // so we should ignore that as well.
478  //
479  // It is also possible to fail if the instance context was in a transition state
480  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
481  //
482 
483  FLT_ASSERT( (status == STATUS_INVALID_DEVICE_OBJECT_PARAMETER) ||
484  (status == STATUS_NO_MEDIA_IN_DEVICE) ||
485  (status == STATUS_INSUFFICIENT_RESOURCES) ||
486  (status == STATUS_FILE_LOCK_CONFLICT) ||
487  (status == STATUS_FILE_INVALID) );
488 
489  //
490  // There is little use updating the return status since it already has a
491  // failure code from the failed dismount
492  //
493  }
494  }
495 
496  //
497  // We don't need to process a volume CleanUp any further
498  //
499 
500  goto FmmPostCleanupCleanup;
501  }
502 
503 
504  //
505  // Here the filter can do any further processing it may want to do
506  // in the PostCleanUp Callback
507  //
508 
509 FmmPostCleanupCleanup:
510 
511  if (!NT_SUCCESS( status )) {
512 
513  DebugTrace( DEBUG_TRACE_ERROR,
514  ("[Fmm]: FmmPostCleanup -> Failed with status 0x%x \n",
515  status) );
516 
517  //
518  // It does not make sense to fail in the the post op, since the operation has completed
519  //
520 
521  }
522 
523 
524  DebugTrace( DEBUG_TRACE_ALL_IO,
525  ("[Fmm]: FmmPostCleanup -> Exit (Cbd = %p, FileObject = %p)\n",
526  Cbd,
527  FltObjects->FileObject) );
528 
529  return FLT_POSTOP_FINISHED_PROCESSING;
530 }
531 
532 
533 FLT_PREOP_CALLBACK_STATUS
535  _Inout_ PFLT_CALLBACK_DATA Cbd,
536  _In_ PCFLT_RELATED_OBJECTS FltObjects,
537  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
538  )
539 {
540 
541  NTSTATUS status;
542  FLT_PREOP_CALLBACK_STATUS callbackStatus;
543 
544  UNREFERENCED_PARAMETER( CompletionContext );
545  UNREFERENCED_PARAMETER( FltObjects );
546 
547  PAGED_CODE();
548 
549  DebugTrace( DEBUG_TRACE_ALL_IO,
550  ("[Fmm]: FmmPreFsCtl -> Enter (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
551  Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
552  Cbd,
553  FltObjects->FileObject) );
554 
555 
556  //
557  // default to no post-op callback
558  //
559 
560  callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
561 
562 
563  if (Cbd->Iopb->MinorFunction != IRP_MN_USER_FS_REQUEST) {
564 
565  goto FmmPreFSControlCleanup;
566  }
567 
568 
569  switch (Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode) {
570 
571  //
572  // System FSCTLs that we are interested in
573  //
574 
575  case FSCTL_DISMOUNT_VOLUME:
576  case FSCTL_LOCK_VOLUME:
577 
578 
579  if (FmmTargetIsVolumeOpen( Cbd )) {
580 
581  //
582  // Give up the metadata file handle and the metadata file object
583  //
584 
585  status = FmmReleaseMetadataFileReferences( Cbd );
586 
587  if ( NT_SUCCESS( status )) {
588 
589  //
590  // Continue with the lock/dismount - we need to check if the
591  // lock operation suceeded in the post-op
592  //
593 
594  callbackStatus = FLT_PREOP_SYNCHRONIZE;
595  } else {
596 
597  //
598  // Fail the lock/dismount
599  //
600 
601  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
602  ("[Fmm]: Failed to release metadata file references with status 0x%x for a volume lock/dismount\n",
603  status) );
604 
605  Cbd->IoStatus.Status = status;
606  callbackStatus = FLT_PREOP_COMPLETE;
607  }
608  }
609  break;
610 
611  case FSCTL_UNLOCK_VOLUME:
612 
613  //
614  // We need to handle unlock in the post-op
615  //
616 
617  callbackStatus = FLT_PREOP_SYNCHRONIZE;
618  break;
619 
620  }
621 
622 FmmPreFSControlCleanup:
623 
624 
625  DebugTrace( DEBUG_TRACE_ALL_IO,
626  ("[Fmm]: FmmPreFsCtl -> Exit (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
627  Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
628  Cbd,
629  FltObjects->FileObject) );
630 
631  return callbackStatus;
632 
633 }
634 
635 
636 FLT_POSTOP_CALLBACK_STATUS
638  _Inout_ PFLT_CALLBACK_DATA Cbd,
639  _In_ PCFLT_RELATED_OBJECTS FltObjects,
640  _In_ PVOID CompletionContext,
641  _In_ FLT_POST_OPERATION_FLAGS Flags
642  )
643 {
644 
645  NTSTATUS status;
646 
647  UNREFERENCED_PARAMETER( CompletionContext );
648  UNREFERENCED_PARAMETER( Flags );
649 
650  PAGED_CODE();
651 
652  DebugTrace( DEBUG_TRACE_ALL_IO,
653  ("[Fmm]: FmmPostFsCtl -> Enter (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
654  Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
655  Cbd,
656  FltObjects->FileObject) );
657 
658 
659  if (!FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING )) {
660 
661  switch (Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode) {
662 
663  //
664  // System FSCTLs that we are interested in
665  //
666 
667  case FSCTL_DISMOUNT_VOLUME:
668 
669  if (FmmTargetIsVolumeOpen( Cbd )) {
670 
671  if (NT_SUCCESS( Cbd->IoStatus.Status )) {
672 
673  //
674  // Dismount succeeded - teardown our instance because its no longer valid.
675  // If we do not tear down this instance, it will stay around until the
676  // last handle for that volume is closed. This will cause the instance
677  // enumeration APIs to see multiple instances
678  //
679 
680  status = FltDetachVolume( Globals.Filter, FltObjects->Volume, NULL );
681 
682  if (!NT_SUCCESS( status )) {
683 
684  DebugTrace( DEBUG_TRACE_ERROR,
685  ("[Fmm]: Failed to detach instance with status 0x%x after a volume dismount\n",
686  status) );
687 
688  //
689  // Doesn't make sense to update the status code in the post-op with a
690  // failure code since the operation has already been performed by the
691  // file system
692  //
693  }
694 
695  } else {
696 
697  //
698  // The dismount failed - reaquire our references to the metadata file
699  // handle and the metadata file object
700  //
701 
702  status = FmmReacquireMetadataFileReferences( Cbd );
703 
704  if (!NT_SUCCESS( status )) {
705 
706  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
707  ("[Fmm]: Failed to re-open metadata with status 0x%x after a failed dismount with status 0x%x\n",
708  status,
709  Cbd->IoStatus.Status) );
710 
711  //
712  // Sanity - we are now in a bad state. The dismount has failed
713  // but we have not been able to re-acquire references to
714  // our metadata file
715  //
716  // It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
717  // so we should ignore that.
718  //
719  // It is also possible to fail if the instance context was in a transition state
720  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
721  //
722 
723  FLT_ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
724  (status == STATUS_FILE_LOCK_CONFLICT) );
725 
726  //
727  // There is little use updating the return status since it already has a
728  // failure code from the failed dismount
729  //
730  }
731  }
732  }
733 
734  break;
735 
736  case FSCTL_LOCK_VOLUME:
737 
738 
739  if (FmmTargetIsVolumeOpen( Cbd )) {
740 
741  if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
742 
743  //
744  // The lock failed - reaquired our references to the metadata file
745  // handle and the metadata file object
746  //
747 
748  status = FmmReacquireMetadataFileReferences( Cbd );
749 
750  if (!NT_SUCCESS( status )) {
751 
752  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
753  ("[Fmm]: Failed to re-open metadata with status 0x%x after a failed lock with status 0x%x\n",
754  status,
755  Cbd->IoStatus.Status) );
756 
757  //
758  // Sanity - we are now in a bad state. The lock has failed
759  // but we have not been able to re-acquire references to
760  // our metadata file
761  //
762  // It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
763  // so we should ignore that.
764  //
765  // It is also possible to fail if the instance context was in a transition state
766  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
767  //
768 
769  FLT_ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
770  (status == STATUS_FILE_LOCK_CONFLICT) );
771 
772  //
773  // There is little use updating the return status since it already has a
774  // failure code from the failed lock
775  //
776 
777  }
778  } else {
779 
780  //
781  // The lock operation suceeded - update the MetadataOpenTriggerFileObject in the
782  // instance context to the File Object on the lock operation suceeded because this
783  // the file object on close/unlock of which, we need to reacquire our metadata file
784  // references
785  //
786 
787  status = FmmSetMetadataOpenTriggerFileObject( Cbd );
788 
789  if (!NT_SUCCESS( status )) {
790 
791  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
792  ("[Fmm]: Failed to update MetadataOpenTriggerFileObject in the instance context with status 0x%x after a successful lock.\n",
793  status) );
794 
795  //
796  // Sanity - we are now in a bad state. We have failed to
797  // set the TriggerFileObject We may not be able to detect
798  // an unlock operation on which we need to re-acquire our
799  // metadata file references
800  //
801 
802  FLT_ASSERT( status == STATUS_FILE_LOCK_CONFLICT );
803 
804  //
805  // Doesn't make sense to update the status code in the
806  // post-op with a failure code since the operation has
807  // already been performed by the file system
808  //
809  }
810 
811  }
812  }
813 
814  break;
815 
816  case FSCTL_UNLOCK_VOLUME:
817 
818  if (NT_SUCCESS( Cbd->IoStatus.Status )) {
819 
820  //
821  // The unlock suceeded - reaquired our references to the metadata file
822  // handle and the metadata file object
823  //
824 
825  status = FmmReacquireMetadataFileReferences( Cbd );
826 
827  if (!NT_SUCCESS( status )) {
828 
829  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
830  ("[Fmm]: Failed to re-open metadata with status 0x%x after a successful unlock.\n",
831  status) );
832 
833  //
834  // Sanity - we are now in a bad state. The volume was unlocked
835  // but we have not been able to re-acquire references to
836  // our metadata file
837  //
838  // Ntfs dismounts and remounts the volume after an unlock. So we ignore
839  // failures to open the metadata with STATUS_INVALID_DEVICE_OBJECT_PARAMETER
840  // because the volume should have been remounted and the metadata file
841  // should have been opened on the newly mounted instance of that volume
842  //
843  // Note however, that if this is an implicit lock (used by autoXXX.exe) then
844  // ntfs will not automatically dismount the volume. It relies on the application
845  // to restart the system if it has made any changes to the volume. If the
846  // application has not made any changes then ntfs will simply continue on
847  // after the unlock without dismounting the volume. Hence we cannot assume
848  // that ntfs always dismounts the volume. We need to try to re-acquire
849  // a handle to our metadata file and ignore failure with error
850  // STATUS_INVALID_DEVICE_OBJECT_PARAMETER which indicates that the
851  // volume has dismounted
852  //
853  // Also it is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
854  // so we should ignore that as well.
855  //
856  // It is also possible to fail if the instance context was in a transition state
857  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
858  //
859 
860  FLT_ASSERT( (status == STATUS_INVALID_DEVICE_OBJECT_PARAMETER) ||
861  (status == STATUS_INSUFFICIENT_RESOURCES) ||
862  (status == STATUS_FILE_LOCK_CONFLICT) );
863 
864  //
865  // There is little use updating the return status since it already has a
866  // failure code from the failed dismount
867  //
868  }
869  }
870 
871 
872  break;
873 
874  }
875  }
876 
877  DebugTrace( DEBUG_TRACE_ALL_IO,
878  ("[Fmm]: FmmPostFsCtl -> Exit (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
879  Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
880  Cbd,
881  FltObjects->FileObject) );
882 
883 
884  return FLT_POSTOP_FINISHED_PROCESSING;
885 }
886 
887 
888 FLT_PREOP_CALLBACK_STATUS
890  _Inout_ PFLT_CALLBACK_DATA Cbd,
891  _In_ PCFLT_RELATED_OBJECTS FltObjects,
892  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
893  )
894 {
895 
896  NTSTATUS status = STATUS_SUCCESS;
897  FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
898  PFMM_INSTANCE_CONTEXT instanceContext = NULL;
899 
900  UNREFERENCED_PARAMETER( FltObjects );
901 
902  PAGED_CODE();
903 
904  *CompletionContext = NULL;
905 
906 
907  DebugTrace( DEBUG_TRACE_ALL_IO,
908  ("[Fmm]: FmmPreDeviceControl -> Enter (IoControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
909  Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode,
910  Cbd,
911  FltObjects->FileObject) );
912 
913 
914  switch (Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode) {
915 
916  //
917  // System IOCTLs that we are interested in
918  //
919 
920  case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:
921 
922  //
923  // We want the snapshot to have a consistent image
924  // of our metadata file that is in sync with the state
925  // of the volume
926  //
927 
928  //
929  // Get the instance context
930  //
931 
932  status = FltGetInstanceContext( Cbd->Iopb->TargetInstance,
933  &instanceContext );
934  if (!NT_SUCCESS( status )) {
935 
936  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
937  ("[Fmm]: Failed to get instance context in FmmPreDeviceControl.\n") );
938 
939  goto FmmPreDeviceControlCleanup;
940  }
941 
942 
943  //
944  // Here the filter must flush any portion of its metadata
945  // that it has not flushed to disk
946  //
947  // If the filter is using mapped cache buffers to read/write
948  // its metadata then the File System will take care of all the
949  // flushing. The filter just needs to ensure that it does not
950  // write to any of its mapped cache buffers while the FS is
951  // trying to flush changes out to disk.
952  //
953 
954  //
955  // After this point, the filter should not be sending any updates
956  // to its metadata file on disk until the post-op callback for
957  // IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES
958  //
959  // The filter would do this by marking its instance context in some way
960  // (say, by setting a flag) to indicate to other threads that they should
961  // not try to update the metadata file on the disk
962  //
963 
964  //
965  // Do not release the instance context but instead pass it to the PostOp
966  // The PostOp routine would need to unmark the instance context in some way
967  // to indicate that it is now ok to update the metadata file on the disk.
968  //
969  // Since we do not want to fail this unmarking because we cannot acquire the
970  // instance context in the post-op, it is better to pass the instance context from
971  // PreOp to PostOp
972  //
973 
974  *CompletionContext = instanceContext;
975 
976  //
977  // Force a post-op so we may undo our marking and release the instance context
978  //
979 
980  callbackStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
981 
982  break;
983 
984  }
985 
986 FmmPreDeviceControlCleanup:
987 
988 
989  //
990  // If any operation has failed then complete and fail the call
991  //
992 
993  if (!NT_SUCCESS( status )) {
994 
995  DebugTrace( DEBUG_TRACE_ERROR,
996  ("[Fmm]: FmmPreDeviceControl -> Failed with status 0x%x \n",
997  status) );
998 
999  //
1000  // We are not having a post-op since the pre-op failed
1001  // Release the instance context
1002  //
1003 
1004  if (instanceContext != NULL) {
1005 
1006  FltReleaseContext( instanceContext );
1007  *CompletionContext = NULL;
1008  }
1009 
1010  Cbd->IoStatus.Status = status;
1011  callbackStatus = FLT_PREOP_COMPLETE;
1012  }
1013 
1014  DebugTrace( DEBUG_TRACE_ALL_IO,
1015  ("[Fmm]: FmmPreDeviceControl -> Exit (IoControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
1016  Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode,
1017  Cbd,
1018  FltObjects->FileObject) );
1019 
1020  return callbackStatus;
1021 
1022 }
1023 
1024 
1025 FLT_POSTOP_CALLBACK_STATUS
1027  _Inout_ PFLT_CALLBACK_DATA Cbd,
1028  _In_ PCFLT_RELATED_OBJECTS FltObjects,
1029  _In_ PVOID CbdContext,
1030  _In_ FLT_POST_OPERATION_FLAGS Flags
1031  )
1032 {
1033 
1034  PFMM_INSTANCE_CONTEXT instanceContext = NULL;
1035 
1036  UNREFERENCED_PARAMETER( Flags );
1037  UNREFERENCED_PARAMETER( FltObjects );
1038 
1039 
1040  DebugTrace( DEBUG_TRACE_ALL_IO,
1041  ("[Fmm]: FmmPostDeviceControl -> Enter (IoControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
1042  Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode,
1043  Cbd,
1044  FltObjects->FileObject) );
1045 
1046  //
1047  // We need to do this even if we are draining
1048  //
1049 
1050  switch (Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode) {
1051 
1052  //
1053  // System IOCTLs that we are interested in
1054  //
1055 
1056  case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:
1057 
1058  //
1059  // Assign the instance context
1060  //
1061 
1062  instanceContext = (PFMM_INSTANCE_CONTEXT) CbdContext;
1063 
1064  //
1065  // Sanity
1066  //
1067 
1068  FLT_ASSERT( instanceContext != NULL );
1069 
1070 
1071  //
1072  // At this point, it is ok for the filter to send updates to its metadata
1073  // file on disk
1074  //
1075  // The filter would do this by unmarking its instance context (say by,
1076  // resetting the flag that it set in the PreOp) to indicate to other threads
1077  // that it is now ok to update the metadata file on the disk
1078  //
1079 
1080 
1081  //
1082  // Release the instance context
1083  //
1084 
1085  FltReleaseContext( instanceContext );
1086 
1087  break;
1088 
1089  }
1090 
1091  DebugTrace( DEBUG_TRACE_ALL_IO,
1092  ("[Fmm]: FmmPostDeviceControl -> Exit (IoControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
1093  Cbd->Iopb->Parameters.DeviceIoControl.Common.IoControlCode,
1094  Cbd,
1095  FltObjects->FileObject) );
1096 
1097 
1098  return FLT_POSTOP_FINISHED_PROCESSING;
1099 }
1100 
1101 
1102 
1103 FLT_PREOP_CALLBACK_STATUS
1105  _Inout_ PFLT_CALLBACK_DATA Cbd,
1106  _In_ PCFLT_RELATED_OBJECTS FltObjects,
1107  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
1108  )
1109 {
1110  NTSTATUS status;
1111 
1112  UNREFERENCED_PARAMETER( CompletionContext );
1113  UNREFERENCED_PARAMETER( Cbd );
1114 
1115  PAGED_CODE();
1116 
1117  DebugTrace( DEBUG_TRACE_ALL_IO,
1118  ("[Fmm]: FmmPreShutdown -> Enter (Cbd = %p, FileObject = %p, Volume = %p)\n",
1119  Cbd,
1120  FltObjects->FileObject,
1121  FltObjects->Volume) );
1122 
1123  status = FltDetachVolume( Globals.Filter, FltObjects->Volume, NULL );
1124 
1125  if (!NT_SUCCESS( status )) {
1126 
1127  DebugTrace( DEBUG_TRACE_ERROR,
1128  ("[Fmm]: Failed to detach instance with status 0x%x on system shutdown\n",
1129  status) );
1130 
1131  //
1132  // Doesn't really make sense to fail a shutdown, even if this operation failed
1133  //
1134 
1135  }
1136 
1137  DebugTrace( DEBUG_TRACE_ALL_IO,
1138  ("[Fmm]: FmmPreShutdown -> Exit (Cbd = %p, FileObject = %p, Volume = %p)\n",
1139  Cbd,
1140  FltObjects->FileObject,
1141  FltObjects->Volume) );
1142 
1143  return FLT_PREOP_SUCCESS_NO_CALLBACK;
1144 }
1145 
1146 
1147 FLT_PREOP_CALLBACK_STATUS
1149  _Inout_ PFLT_CALLBACK_DATA Cbd,
1150  _In_ PCFLT_RELATED_OBJECTS FltObjects,
1151  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
1152  )
1153 /*
1154 
1155 Routine Description:
1156 
1157  This routine handles the pre-processing of all PNP operations received
1158  on this instance. It handles query, cancel and suprise device removal.
1159  For query device removal we have to close all open file handles we hold
1160  so that the base file system can correctly response to these PNP requests.
1161 
1162 Arguments:
1163 
1164  Cbd - Pointer to the FLT_CALLBACK_DATA structure containing all the relevant
1165  parameters for this operation.
1166 
1167  FltObject - Pointer to the FLT_RELATED_OBJECTS data structure containing,
1168  opaque handles to this filter, instance and its associated volume.
1169 
1170  CompletionContext - Not used.
1171 
1172 Return Value:
1173 
1174  FLT_PREOP_SUCCESS_NO_CALLBACK as we are done with our processing and are
1175  not interested in a post-operartion callback.
1176 
1177 */
1178 {
1179  NTSTATUS status;
1180  FLT_PREOP_CALLBACK_STATUS callbackStatus;
1181 
1182  UNREFERENCED_PARAMETER( CompletionContext );
1183 
1184  PAGED_CODE();
1185 
1186  DebugTrace( DEBUG_TRACE_ALL_IO,
1187  ("[Fmm]: FmmPrePnp -> Enter (Cbd = %p, FileObject = %p, Volume = %p)\n",
1188  Cbd,
1189  FltObjects->FileObject,
1190  FltObjects->Volume) );
1191 
1192  //
1193  // default to no post op callback
1194  //
1195 
1196  callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
1197 
1198  switch (Cbd->Iopb->MinorFunction) {
1199 
1201 
1202  //
1203  // Give up the metadata file handle and the metadata file object
1204  //
1205 
1206  status = FmmReleaseMetadataFileReferences( Cbd );
1207 
1208  if (!NT_SUCCESS( status )) {
1209 
1210  //
1211  // Fail the query removal
1212  //
1213 
1214  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
1215  ("[Fmm]: Failed to release metadata file references with status 0x%x for query removal\n",
1216  status) );
1217 
1218  Cbd->IoStatus.Status = status;
1219  callbackStatus = FLT_PREOP_COMPLETE;
1220  }
1221 
1222  break;
1223 
1225 
1226  //
1227  // We need to pass this notification through to the file system
1228  // so he start allowing IO to the volume. We file for a post op
1229  // so that we can reacquire our resources. We must return
1230  // FLT_PREOP_SYNCRONIZE because we need to be below DPC inorder
1231  // to reopen our metadata file.
1232  //
1233 
1234  callbackStatus = FLT_PREOP_SYNCHRONIZE;
1235 
1236  break;
1237 
1239 
1240  //
1241  // Teardown our instance because its no longer valid.
1242  //
1243 
1244  status = FltDetachVolume( Globals.Filter, FltObjects->Volume, NULL );
1245 
1246  if (!NT_SUCCESS( status )) {
1247 
1248  DebugTrace( DEBUG_TRACE_ERROR,
1249  ("[Fmm]: Failed to detach instance with status 0x%x after a surprise removal\n",
1250  status) );
1251 
1252  }
1253 
1254  break;
1255 
1256  default:
1257 
1258  //
1259  // Pass all PNP minor codes we don't care about.
1260  //
1261 
1262  break;
1263  }
1264 
1265 
1266  DebugTrace( DEBUG_TRACE_ALL_IO,
1267  ("[Fmm]: FmmPrePnp -> Exit (Cbd = %p, FileObject = %p, Volume = %p)\n",
1268  Cbd,
1269  FltObjects->FileObject,
1270  FltObjects->Volume) );
1271 
1272  return callbackStatus;
1273 }
1274 
1275 FLT_POSTOP_CALLBACK_STATUS
1277  _Inout_ PFLT_CALLBACK_DATA Cbd,
1278  _In_ PCFLT_RELATED_OBJECTS FltObjects,
1279  _In_ PVOID CbdContext,
1280  _In_ FLT_POST_OPERATION_FLAGS Flags
1281  )
1282 /*
1283 
1284 Routine Description:
1285 
1286  This routine handles the post-processing of IRP_MN_CANCEL_REMOVE_DEVICE.
1287  We reacquire our references to the metadata file handle and the metadata
1288  file object.
1289 
1290 */
1291 {
1292 
1293 
1294  NTSTATUS status;
1295 
1296  UNREFERENCED_PARAMETER( CbdContext );
1297  UNREFERENCED_PARAMETER( FltObjects );
1298 
1299  PAGED_CODE();
1300 
1301  //
1302  // Sanity - we should only have a post operation for IRP_MN_CANCEL_DEVICE.
1303  //
1304 
1305  FLT_ASSERT( Cbd->Iopb->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE );
1306 
1307  //
1308  // Sanity - IRP_MN_CANCEL_DEVICE cannot fail.
1309  //
1310 
1311  FLT_ASSERT( Cbd->IoStatus.Status == STATUS_SUCCESS );
1312 
1313  if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) ) {
1314 
1315  //
1316  // We are draining. This means that we should not reacquire our
1317  // resources because the IRP may not have completed.
1318  //
1319 
1320  return FLT_POSTOP_FINISHED_PROCESSING;
1321  }
1322 
1323  //
1324  // The device removal was cancelled - reaquire our references to the
1325  // metadata file handle and the metadata file object
1326  //
1327 
1328  status = FmmReacquireMetadataFileReferences( Cbd );
1329 
1330  if (!NT_SUCCESS( status )) {
1331 
1332  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
1333  ("[Fmm]: Failed to re-open metadata with status 0x%x after cancel device removal.\n",
1334  status) );
1335 
1336  //
1337  // Sanity - we are now in a bad state. The removal has been
1338  // cancelled but we have not been able to re-acquire references
1339  // to our metadata file
1340  //
1341  // It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
1342  // so we should ignore that.
1343  //
1344  // It is also possible to fail if the instance context was in a transition state
1345  // so we should ignore STATUS_FILE_LOCK_CONFLICT too.
1346  //
1347 
1348  FLT_ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
1349  (status == STATUS_FILE_LOCK_CONFLICT) );
1350 
1351  }
1352 
1353  return FLT_POSTOP_FINISHED_PROCESSING;
1354 }
1355 
1356 
#define IRP_MN_USER_FS_REQUEST
Definition: mspyLog.h:320
#define IRP_MN_QUERY_REMOVE_DEVICE
Definition: mspyLog.h:339
FLT_PREOP_CALLBACK_STATUS FmmPreShutdown(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
#define DebugTrace(Level, Data)
Definition: cancelSafe.c:36
NTSTATUS FmmSetMetadataOpenTriggerFileObject(_Inout_ PFLT_CALLBACK_DATA Cbd)
Definition: DataStore.c:731
FLT_POSTOP_CALLBACK_STATUS FmmPostFSControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CompletionContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
FLT_POSTOP_CALLBACK_STATUS FmmPostCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
AV_SCANNER_GLOBAL_DATA Globals
Definition: avscan.h:152
NTSTATUS FmmIsImplicitVolumeLock(_In_ PFLT_CALLBACK_DATA Cbd, _Out_ PBOOLEAN IsLock)
FLT_POSTOP_CALLBACK_STATUS FmmPostDeviceControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
PFLT_FILTER Filter
Definition: avscan.h:86
FLT_PREOP_CALLBACK_STATUS FmmPreFSControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
BOOLEAN FmmTargetIsVolumeOpen(_In_ PFLT_CALLBACK_DATA Cbd)
FLT_PREOP_CALLBACK_STATUS FmmPreCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
FLT_PREOP_CALLBACK_STATUS FmmPreDeviceControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
#define FlagOn(_F, _SF)
Definition: minispy.h:247
UNREFERENCED_PARAMETER(FileObject)
NTSTATUS FmmReacquireMetadataFileReferences(_Inout_ PFLT_CALLBACK_DATA Cbd)
Definition: DataStore.c:580
FLT_POSTOP_CALLBACK_STATUS FmmPostPnp(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
FLT_PREOP_CALLBACK_STATUS FmmPrePnp(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
#define IRP_MN_SURPRISE_REMOVAL
Definition: mspyLog.h:360
PAGED_CODE()
FLT_POSTOP_CALLBACK_STATUS FmmPostCleanup(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Inout_ PVOID CompletionContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
FLT_PREOP_CALLBACK_STATUS FmmPreCleanup(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
NTSTATUS FmmReleaseMetadataFileReferences(_Inout_ PFLT_CALLBACK_DATA Cbd)
Definition: DataStore.c:449
struct _FMM_INSTANCE_CONTEXT * PFMM_INSTANCE_CONTEXT
#define IRP_MN_CANCEL_REMOVE_DEVICE
Definition: mspyLog.h:341

Social Network


Services Overview

Architect, implement and test file system filter drivers for a wide range of functionality. We can offer several levels of assistance to meet your specific.

Contact Us

You are welcome to contact us for salse or partnership.

Sales: sales@easefilter.com
Support: support@easefilter.com
Info: info@easefilter.com