WDK Mini Filter Example
MetadataManagerInit.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1999 - 2003 Microsoft Corporation
4 
5 Module Name:
6 
7  MetadataManagerInit.c
8 
9 Abstract:
10 
11  This is the main 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 // Global variables
26 //
27 
29 
30 
31 //
32 // Local constants
33 //
34 
35 #define FMM_UNSUPPORTED_DEVICE_CHARACS FILE_FLOPPY_DISKETTE | \
36  FILE_READ_ONLY_DEVICE | \
37  FILE_VIRTUAL_VOLUME
38 
39 //
40 // Local function prototypes
41 //
42 
43 DRIVER_INITIALIZE DriverEntry;
44 NTSTATUS
46  _In_ PDRIVER_OBJECT DriverObject,
47  _In_ PUNICODE_STRING RegistryPath
48  );
49 
50 NTSTATUS
51 FmmUnload (
52  _In_ FLT_FILTER_UNLOAD_FLAGS Flags
53  );
54 
55 VOID
57  _In_ PFLT_CONTEXT Context,
58  _In_ FLT_CONTEXT_TYPE ContextType
59  );
60 
61 NTSTATUS
63  _In_ PCFLT_RELATED_OBJECTS FltObjects,
64  _In_ FLT_INSTANCE_SETUP_FLAGS Flags,
65  _In_ DEVICE_TYPE VolumeDeviceType,
66  _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
67  );
68 
69 NTSTATUS
71  _In_ PCFLT_RELATED_OBJECTS FltObjects,
72  _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
73  );
74 
75 VOID
77  _In_ PCFLT_RELATED_OBJECTS FltObjects,
78  _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
79  );
80 
81 VOID
83  _In_ PCFLT_RELATED_OBJECTS FltObjects,
84  _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
85  );
86 
87 #if DBG
88 
89 VOID
90 FmmInitializeDebugLevel (
91  _In_ PUNICODE_STRING RegistryPath
92  );
93 
94 #endif
95 
96 //
97 // Assign text sections for each routine.
98 //
99 
100 #ifdef ALLOC_PRAGMA
101 #pragma alloc_text(INIT, DriverEntry)
102 
103 #if DBG
104 #pragma alloc_text(INIT, FmmInitializeDebugLevel)
105 #endif
106 
107 #pragma alloc_text(PAGE, FmmUnload)
108 #pragma alloc_text(PAGE, FmmContextCleanup)
109 #pragma alloc_text(PAGE, FmmInstanceSetup)
110 #pragma alloc_text(PAGE, FmmInstanceQueryTeardown)
111 #pragma alloc_text(PAGE, FmmInstanceTeardownStart)
112 #pragma alloc_text(PAGE, FmmInstanceTeardownComplete)
113 #endif
114 
115 
116 //
117 // If we need to verify that the metadata file is indeed open whenever
118 // a create suceeds on the volume, then we need to monitor all creates
119 // not just DASD creates.
120 
121 // If that is not the case, then we are better off telling filter manager
122 // to show us only DASD creates. That way we can avoid the performance
123 // penalty of being called for all creates when we only have use for DASD
124 // creates.
125 //
126 
127 
128 #if VERIFY_METADATA_OPENED
129 
130 #define OPERATION_REGISTRATION_FLAGS_FOR_CREATE (FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO)
131 
132 #else
133 
134 #define OPERATION_REGISTRATION_FLAGS_FOR_CREATE (FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO | FLTFL_OPERATION_REGISTRATION_SKIP_NON_DASD_IO)
135 
136 #endif
137 
138 
139 
140 //
141 // Filters callback routines
142 //
143 
144 FLT_OPERATION_REGISTRATION Callbacks[] = {
145 
146  { IRP_MJ_CREATE,
148  FmmPreCreate,
149  FmmPostCreate },
150 
151  { IRP_MJ_CLEANUP,
152  FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO | FLTFL_OPERATION_REGISTRATION_SKIP_NON_DASD_IO,
154  FmmPostCleanup },
155 
157  FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO | FLTFL_OPERATION_REGISTRATION_SKIP_NON_DASD_IO,
160 
162  FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
165 
166  { IRP_MJ_SHUTDOWN,
167  FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
169  NULL },
170 
171  { IRP_MJ_PNP,
172  FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
173  FmmPrePnp,
174  FmmPostPnp },
175 
176  { IRP_MJ_OPERATION_END }
177 };
178 
179 const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
180 
181  { FLT_INSTANCE_CONTEXT,
182  0,
186 
187  { FLT_CONTEXT_END }
188 };
189 
190 //
191 // Filters registration data structure
192 //
193 
194 FLT_REGISTRATION FilterRegistration = {
195 
196  sizeof( FLT_REGISTRATION ), // Size
197  FLT_REGISTRATION_VERSION, // Version
198  0, // Flags
199  ContextRegistration, // Context
200  Callbacks, // Operation callbacks
201  FmmUnload, // Filters unload routine
202  FmmInstanceSetup, // InstanceSetup routine
203  FmmInstanceQueryTeardown, // InstanceQueryTeardown routine
204  FmmInstanceTeardownStart, // InstanceTeardownStart routine
205  FmmInstanceTeardownComplete, // InstanceTeardownComplete routine
206  NULL, NULL, NULL // Unused naming support callbacks
207 };
208 
209 //
210 // Filter driver initialization and unload routines
211 //
212 
213 NTSTATUS
215  _In_ PDRIVER_OBJECT DriverObject,
216  _In_ PUNICODE_STRING RegistryPath
217  )
218 /*++
219 
220 Routine Description:
221 
222  This is the initialization routine for this filter driver. It registers
223  itself with the filter manager and initializes all its global data structures.
224 
225 Arguments:
226 
227  DriverObject - Pointer to driver object created by the system to
228  represent this driver.
229 
230  RegistryPath - Unicode string identifying where the parameters for this
231  driver are located in the registry.
232 
233 Return Value:
234 
235  Returns STATUS_SUCCESS.
236 
237 --*/
238 {
239  NTSTATUS status;
240 
241  //
242  // Default to NonPagedPoolNx for non paged pool allocations where supported.
243  //
244 
245  ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
246 
247 
248  RtlZeroMemory( &Globals, sizeof( Globals ) );
249 
250 #if DBG
251 
252  //
253  // Initialize global debug level
254  //
255 
256  FmmInitializeDebugLevel( RegistryPath );
257 
258 #else
259 
260  UNREFERENCED_PARAMETER( RegistryPath );
261 
262 #endif
263 
264  DebugTrace( DEBUG_TRACE_LOAD_UNLOAD,
265  ("[Fmm]: Driver being loaded\n") );
266 
267 
268 
269  //
270  // Register with the filter manager
271  //
272 
273  status = FltRegisterFilter( DriverObject,
275  &Globals.Filter );
276 
277  if (!NT_SUCCESS( status )) {
278 
279  return status;
280  }
281 
282  //
283  // Start filtering I/O
284  //
285 
286  status = FltStartFiltering( Globals.Filter );
287 
288  if (!NT_SUCCESS( status )) {
289 
290  FltUnregisterFilter( Globals.Filter );
291  }
292 
293  DebugTrace( DEBUG_TRACE_LOAD_UNLOAD,
294  ("[Fmm]: Driver loaded complete (Status = 0x%08X)\n",
295  status) );
296 
297  return status;
298 }
299 
300 #if DBG
301 
302 VOID
303 FmmInitializeDebugLevel (
304  _In_ PUNICODE_STRING RegistryPath
305  )
306 /*++
307 
308 Routine Description:
309 
310  This routine tries to read the filter DebugLevel parameter from
311  the registry. This value will be found in the registry location
312  indicated by the RegistryPath passed in.
313 
314 Arguments:
315 
316  RegistryPath - The path key passed to the driver during DriverEntry.
317 
318 Return Value:
319 
320  None.
321 
322 --*/
323 {
324  OBJECT_ATTRIBUTES attributes;
325  HANDLE driverRegKey;
326  NTSTATUS status;
327  ULONG resultLength;
328  UNICODE_STRING valueName;
329  UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )];
330 
331  Globals.DebugLevel = DEBUG_TRACE_ERROR;
332 
333  //
334  // Open the desired registry key
335  //
336 
337  InitializeObjectAttributes( &attributes,
338  RegistryPath,
339  OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
340  NULL,
341  NULL );
342 
343  status = ZwOpenKey( &driverRegKey,
344  KEY_READ,
345  &attributes );
346 
347  if (NT_SUCCESS( status )) {
348 
349  //
350  // Read the DebugFlags value from the registry.
351  //
352 
353  RtlInitUnicodeString( &valueName, L"DebugLevel" );
354 
355  status = ZwQueryValueKey( driverRegKey,
356  &valueName,
358  buffer,
359  sizeof(buffer),
360  &resultLength );
361 
362  if (NT_SUCCESS( status )) {
363 
364  Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
365  }
366 
367  //
368  // Close the registry entry
369  //
370 
371  ZwClose( driverRegKey );
372 
373  }
374 
375 }
376 
377 #endif
378 
379 NTSTATUS
381  _In_ FLT_FILTER_UNLOAD_FLAGS Flags
382  )
383 /*++
384 
385 Routine Description:
386 
387  This is the unload routine for this filter driver. This is called
388  when the minifilter is about to be unloaded. We can fail this unload
389  request if this is not a mandatory unloaded indicated by the Flags
390  parameter.
391 
392 Arguments:
393 
394  Flags - Indicating if this is a mandatory unload.
395 
396 Return Value:
397 
398  Returns the final status of this operation.
399 
400 --*/
401 {
402  UNREFERENCED_PARAMETER( Flags );
403 
404  PAGED_CODE();
405 
406  DebugTrace( DEBUG_TRACE_LOAD_UNLOAD,
407  ("[Fmm]: Unloading driver\n") );
408 
409 
410  FltUnregisterFilter( Globals.Filter );
411  Globals.Filter = NULL;
412 
413  return STATUS_SUCCESS;
414 }
415 
416 VOID
418  _In_ PFLT_CONTEXT Context,
419  _In_ FLT_CONTEXT_TYPE ContextType
420  )
421 {
422  PFMM_INSTANCE_CONTEXT instanceContext;
423 
424  PAGED_CODE();
425 
426  switch(ContextType) {
427 
428  case FLT_INSTANCE_CONTEXT:
429 
430  instanceContext = Context;
431 
432  DebugTrace( DEBUG_TRACE_INFO,
433  ("[Fmm]: Cleaning up instance context for volume (Context = %p)\n",
434  instanceContext) );
435 
436  ExDeleteResourceLite( &instanceContext->MetadataResource );
437 
438  break;
439 
440  }
441 
442  DebugTrace( DEBUG_TRACE_INFO,
443  ("[Fmm]: Context cleanup complete.\n") );
444 
445 }
446 
447 //
448 // Instance setup/teardown routines.
449 //
450 
451 NTSTATUS
453  _In_ PCFLT_RELATED_OBJECTS FltObjects,
454  _In_ FLT_INSTANCE_SETUP_FLAGS Flags,
455  _In_ DEVICE_TYPE VolumeDeviceType,
456  _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
457  )
458 /*++
459 
460 Routine Description:
461 
462  This routine is called whenever a new instance is created on a volume. This
463  gives us a chance to decide if we need to attach to this volume or not.
464 
465 Arguments:
466 
467  FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
468  opaque handles to this filter, instance and its associated volume.
469 
470  Flags - Flags describing the reason for this attach request.
471 
472 Return Value:
473 
474  STATUS_SUCCESS - attach
475  STATUS_FLT_DO_NOT_ATTACH - do not attach
476 
477 --*/
478 {
479  PFMM_INSTANCE_CONTEXT instanceContext = NULL;
480  PDEVICE_OBJECT diskDeviceObject;
481  NTSTATUS status = STATUS_SUCCESS;
482 
483  UNREFERENCED_PARAMETER( VolumeDeviceType );
484 
485  PAGED_CODE();
486 
487  DebugTrace( DEBUG_TRACE_INSTANCES,
488  ("[Fmm]: Instance setup started (Volume = %p, Instance = %p)\n",
489  FltObjects->Volume,
490  FltObjects->Instance) );
491 
492  //
493  // Check if the file system mounted is ntfs or fat
494  //
495  // The sample picks NTFS, FAT and ReFS as examples. The metadata
496  // handling demostrated in the sample can be applied
497  // to any file system
498  //
499 
500  if (VolumeFilesystemType != FLT_FSTYPE_NTFS && VolumeFilesystemType != FLT_FSTYPE_FAT && VolumeFilesystemType != FLT_FSTYPE_REFS) {
501 
502  //
503  // An unknown file system is mounted which we do not care
504  //
505 
506  DebugTrace( DEBUG_TRACE_INSTANCES,
507  ("[Fmm]: Unsupported file system mounted (Volume = %p, Instance = %p)\n",
508  FltObjects->Volume,
509  FltObjects->Instance) );
510 
511  status = STATUS_NOT_SUPPORTED;
512  goto FmmInstanceSetupCleanup;
513  }
514 
515  //
516  // Get the disk device object and make sure it is a disk device type and does not
517  // have any of the device characteristics we do not support.
518  //
519  // The sample picks the device characteristics to demonstrate how to access and
520  // check the device characteristics in order to make a decision to attach. The
521  // metadata handling demostrated in the sample is not limited to the
522  // characteristics we have used in the sample.
523  //
524 
525  status = FltGetDiskDeviceObject( FltObjects->Volume, &diskDeviceObject );
526 
527  if (!NT_SUCCESS( status )) {
528 
529  DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
530  ("[Fmm]: Failed to get device object (Volume = %p, Status = 0x%08X)\n",
531  FltObjects->Volume,
532  status) );
533  goto FmmInstanceSetupCleanup;
534  }
535 
536  if (diskDeviceObject->DeviceType != FILE_DEVICE_DISK ||
537  FlagOn( diskDeviceObject->Characteristics, FMM_UNSUPPORTED_DEVICE_CHARACS )) {
538 
539  DebugTrace( DEBUG_TRACE_INSTANCES,
540  ("[Fmm]: Unsupported device type or device characteristics (Volume = %p, Instance = %p DiskDeviceObjectDeviceTYpe = 0x%x, DiskDeviceObjectCharacteristics = 0x%x)\n",
541  FltObjects->Volume,
542  FltObjects->Instance,
543  diskDeviceObject->DeviceType,
544  diskDeviceObject->Characteristics) );
545 
546  ObDereferenceObject( diskDeviceObject );
547  status = STATUS_NOT_SUPPORTED;
548  goto FmmInstanceSetupCleanup;
549  }
550 
551  ObDereferenceObject( diskDeviceObject );
552 
553  //
554  // Allocate and initialize the context for this volume
555  //
556 
557  status = FltAllocateContext( FltObjects->Filter,
558  FLT_INSTANCE_CONTEXT,
560  NonPagedPool,
561  &instanceContext );
562 
563  if( !NT_SUCCESS( status )) {
564 
565  DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
566  ("[Fmm]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
567  FltObjects->Volume,
568  FltObjects->Instance,
569  status) );
570 
571  goto FmmInstanceSetupCleanup;
572  }
573 
574  FLT_ASSERT( instanceContext != NULL );
575 
576  RtlZeroMemory( instanceContext, FMM_INSTANCE_CONTEXT_SIZE );
577 
578  instanceContext->Flags = 0;
579  instanceContext->Instance = FltObjects->Instance;
580  instanceContext->FilesystemType = VolumeFilesystemType;
581  instanceContext->Volume = FltObjects->Volume;
582  ExInitializeResourceLite( &instanceContext->MetadataResource );
583 
584 
585  //
586  // Set the instance context.
587  //
588 
589  status = FltSetInstanceContext( FltObjects->Instance,
590  FLT_SET_CONTEXT_KEEP_IF_EXISTS,
591  instanceContext,
592  NULL );
593 
594  if( !NT_SUCCESS( status )) {
595 
596  DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
597  ("[Fmm]: Failed to set instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
598  FltObjects->Volume,
599  FltObjects->Instance,
600  status) );
601  goto FmmInstanceSetupCleanup;
602  }
603 
604  //
605  // Acquire exclusive access to the instance context
606  //
607 
608  FmmAcquireResourceExclusive( &instanceContext->MetadataResource );
609 
610  //
611  // Sanity - the instance context cannot be in a transition state during instance setup
612  //
613 
614  FLT_ASSERT( !FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION) );
615 
616  //
617  // Open the filter metadata on disk
618  //
619  // The sample will attach to volume if it finds its metadata file on the volume.
620  // If this is a manual attachment then the sample filter will create its metadata
621  // file and attach to the volume.
622  //
623 
624  status = FmmOpenMetadata( instanceContext,
625  BooleanFlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT ) );
626 
627  //
628  // Relinquish exclusive access to the instance context
629  //
630 
631  FmmReleaseResource( &instanceContext->MetadataResource );
632 
633  if (!NT_SUCCESS( status )) {
634 
635  goto FmmInstanceSetupCleanup;
636  }
637 
638 
639 FmmInstanceSetupCleanup:
640 
641  //
642  // If FltAllocateContext suceeded then we MUST release the context,
643  // irrespective of whether FltSetInstanceContext suceeded or not.
644  //
645  // FltAllocateContext increments the ref count by one.
646  // A successful FltSetInstanceContext increments the ref count by one
647  // and also associates the context with the file system object
648  //
649  // FltReleaseContext decrements the ref count by one.
650  //
651  // When FltSetInstanceContext succeeds, calling FltReleaseContext will
652  // leave the context with a ref count of 1 corresponding to the internal
653  // reference to the context from the file system structures
654  //
655  // When FltSetInstanceContext fails, calling FltReleaseContext will
656  // leave the context with a ref count of 0 which is correct since
657  // there is no reference to the context from the file system structures
658  //
659 
660  if ( instanceContext != NULL ) {
661 
662  FltReleaseContext( instanceContext );
663  }
664 
665 
666  if (NT_SUCCESS( status )) {
667 
668  DebugTrace( DEBUG_TRACE_INSTANCES,
669  ("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n",
670  FltObjects->Volume,
671  FltObjects->Instance) );
672  } else {
673 
674  DebugTrace( DEBUG_TRACE_INSTANCES,
675  ("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n",
676  FltObjects->Volume,
677  FltObjects->Instance) );
678  }
679 
680  //
681  // If this is an automatic attachment (mount, load, etc) and we are not
682  // attaching to this volume because we do not support attaching to this
683  // volume, then simply return STATUS_FLT_DO_NOT_ATTACH. If we return
684  // anything else fltmgr logs an event log indicating failure to attach.
685  // Since this failure to attach is not really an error, we do not want
686  // this failure to be logged as an error in the event log. For all other
687  // error codes besides the ones we consider "normal", if is ok for fltmgr
688  // to actually log the failure to attach.
689  //
690  // If this is a manual attach attempt that we have failed then we want to
691  // give the user a clear indication of why the attachment failed. Hence in
692  // this case, we will not override the error status with STATUS_FLT_DO_NOT_ATTACH
693  // irrespective of the cause of the failure to attach
694  //
695 
696  if (status == STATUS_NOT_SUPPORTED &&
697  !FlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT )) {
698 
699  status = STATUS_FLT_DO_NOT_ATTACH;
700  }
701 
702  return status;
703 }
704 
705 
706 NTSTATUS
708  _In_ PCFLT_RELATED_OBJECTS FltObjects,
709  _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
710  )
711 /*++
712 
713 Routine Description:
714 
715  This is called when an instance is being manually deleted by a
716  call to FltDetachVolume or FilterDetach thereby giving us a
717  chance to fail that detach request.
718 
719 Arguments:
720 
721  FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
722  opaque handles to this filter, instance and its associated volume.
723 
724  Flags - Indicating where this detach request came from.
725 
726 Return Value:
727 
728  Returns the status of this operation.
729 
730 --*/
731 {
732  UNREFERENCED_PARAMETER( FltObjects );
733  UNREFERENCED_PARAMETER( Flags );
734 
735  PAGED_CODE();
736 
737  DebugTrace( DEBUG_TRACE_INSTANCES,
738  ("[Fmm]: Instance query teardown started (Instance = %p)\n",
739  FltObjects->Instance) );
740 
741 
742  DebugTrace( DEBUG_TRACE_INSTANCES,
743  ("[Fmm]: Instance query teadown ended (Instance = %p)\n",
744  FltObjects->Instance) );
745  return STATUS_SUCCESS;
746 }
747 
748 
749 VOID
751  _In_ PCFLT_RELATED_OBJECTS FltObjects,
752  _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
753  )
754 /*++
755 
756 Routine Description:
757 
758  This routine is called at the start of instance teardown.
759 
760 Arguments:
761 
762  FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
763  opaque handles to this filter, instance and its associated volume.
764 
765  Flags - Reason why this instance is been deleted.
766 
767 Return Value:
768 
769  None.
770 
771 --*/
772 {
773  UNREFERENCED_PARAMETER( FltObjects );
774  UNREFERENCED_PARAMETER( Flags );
775 
776  PAGED_CODE();
777 
778  DebugTrace( DEBUG_TRACE_INSTANCES,
779  ("[Fmm]: Instance teardown start started (Instance = %p)\n",
780  FltObjects->Instance) );
781 
782 
783  DebugTrace( DEBUG_TRACE_INSTANCES,
784  ("[Fmm]: Instance teardown start ended (Instance = %p)\n",
785  FltObjects->Instance) );
786 }
787 
788 
789 VOID
791  _In_ PCFLT_RELATED_OBJECTS FltObjects,
792  _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
793  )
794 /*++
795 
796 Routine Description:
797 
798  This routine is called at the end of instance teardown.
799 
800 Arguments:
801 
802  FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
803  opaque handles to this filter, instance and its associated volume.
804 
805  Flags - Reason why this instance is been deleted.
806 
807 Return Value:
808 
809  None.
810 
811 --*/
812 {
813  PFMM_INSTANCE_CONTEXT instanceContext;
814  NTSTATUS status;
815 
816  UNREFERENCED_PARAMETER( Flags );
817 
818  PAGED_CODE();
819 
820  DebugTrace( DEBUG_TRACE_INSTANCES,
821  ("[Fmm]: Instance teardown complete started (Instance = %p)\n",
822  FltObjects->Instance) );
823 
824  status = FltGetInstanceContext( FltObjects->Instance,
825  &instanceContext );
826 
827  if (NT_SUCCESS( status )) {
828 
829  //
830  // Acquire exclusive access to the instance context
831  //
832 
833  FmmAcquireResourceExclusive( &instanceContext->MetadataResource );
834 
835  //
836  // Sanity - the instance context cannot be in a transition state during instance teardown complete
837  //
838 
839  FLT_ASSERT( !FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION) );
840 
841 
842  if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED )) {
843 
844  //
845  // Close the metadata file
846  //
847 
848  FmmCloseMetadata( instanceContext );
849  }
850 
851 
852  //
853  // Relinquish exclusive access to the instance context
854  //
855 
856  FmmReleaseResource( &instanceContext->MetadataResource );
857 
858  FltReleaseContext( instanceContext );
859  }
860 
861  DebugTrace( DEBUG_TRACE_INSTANCES,
862  ("[Fmm]: Instance teardown complete ended (Instance = %p)\n",
863  FltObjects->Instance) );
864 }
865 
FLT_POSTOP_CALLBACK_STATUS FmmPostCleanup(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Inout_ PVOID CompletionContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
_In_ PCWSTR valueName
Definition: ncinit.c:8
#define IRP_MJ_CLEANUP
Definition: mspyLog.h:302
#define IRP_MJ_DEVICE_CONTROL
Definition: mspyLog.h:298
#define FMM_INSTANCE_CONTEXT_TAG
DRIVER_INITIALIZE DriverEntry
#define DebugTrace(Level, Data)
Definition: cancelSafe.c:36
#define INSTANCE_CONTEXT_F_TRANSITION
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
NcLoadRegistryStringRetry KeyValuePartialInformation
Definition: ncinit.c:53
#define INSTANCE_CONTEXT_F_METADATA_OPENED
FLT_POSTOP_CALLBACK_STATUS FmmPostDeviceControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
FLT_POSTOP_CALLBACK_STATUS FmmPostFSControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CompletionContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
#define FlagOn(_F, _SF)
Definition: minispy.h:247
#define OPERATION_REGISTRATION_FLAGS_FOR_CREATE
FLT_PREOP_CALLBACK_STATUS FmmPrePnp(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
FLT_PREOP_CALLBACK_STATUS FmmPreFSControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
FLT_POSTOP_CALLBACK_STATUS FmmPostPnp(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
UNREFERENCED_PARAMETER(FileObject)
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
FLT_REGISTRATION FilterRegistration
NTSTATUS FmmInstanceQueryTeardown(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
PAGED_CODE()
FLT_PREOP_CALLBACK_STATUS FmmPreCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
VOID FmmInstanceTeardownStart(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags)
FLT_POSTOP_CALLBACK_STATUS FmmPostCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
#define IRP_MJ_FILE_SYSTEM_CONTROL
Definition: mspyLog.h:297
#define FMM_INSTANCE_CONTEXT_SIZE
FLT_OPERATION_REGISTRATION Callbacks[]
#define IRP_MJ_PNP
Definition: mspyLog.h:311
NTSTATUS FmmUnload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags)
FMM_GLOBAL_DATA Globals
FLT_PREOP_CALLBACK_STATUS FmmPreDeviceControl(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
NTSTATUS FmmInstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_SETUP_FLAGS Flags, _In_ DEVICE_TYPE VolumeDeviceType, _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType)
FLT_PREOP_CALLBACK_STATUS FmmPreCleanup(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
FLT_FILESYSTEM_TYPE FilesystemType
FLT_PREOP_CALLBACK_STATUS FmmPreShutdown(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
#define FMM_UNSUPPORTED_DEVICE_CHARACS
const FLT_CONTEXT_REGISTRATION ContextRegistration[]
#define IRP_MJ_SHUTDOWN
Definition: mspyLog.h:300
VOID FmmContextCleanup(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
VOID FmmInstanceTeardownComplete(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags)
#define IRP_MJ_CREATE
Definition: mspyLog.h:284

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