WDK Mini Filter Example
avscan/filter/context.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 2011 Microsoft Corporation
4 
5 Module Name:
6 
7  context.c
8 
9 Abstract:
10 
11  Filter Context-related module implementation.
12 
13 Environment:
14 
15  Kernel mode
16 
17 --*/
18 
19 #include "avscan.h"
20 
21 //
22 // Local function prototypes.
23 //
24 
25 VOID
27  _In_ PFLT_CONTEXT Context,
28  _In_ FLT_CONTEXT_TYPE ContextType
29  );
30 
31 VOID
33  _In_ PFLT_CONTEXT Context,
34  _In_ FLT_CONTEXT_TYPE ContextType
35  );
36 
37 VOID
39  _In_ PFLT_CONTEXT Context,
40  _In_ FLT_CONTEXT_TYPE ContextType
41  );
42 
43 VOID
45  _In_ PFLT_CONTEXT Context,
46  _In_ FLT_CONTEXT_TYPE ContextType
47  );
48 
49 #ifdef ALLOC_PRAGMA
50 #pragma alloc_text(PAGE, AvCreateStreamContext)
51 #pragma alloc_text(PAGE, AvCreateStreamHandleContext)
52 #pragma alloc_text(PAGE, AvFindOrCreateTransactionContext)
53 #pragma alloc_text(PAGE, AvCreateSectionContext)
54 #pragma alloc_text(PAGE, AvStreamContextCleanup)
55 #pragma alloc_text(PAGE, AvTransactionContextCleanup)
56 #pragma alloc_text(PAGE, AvSectionContextCleanup)
57 #pragma alloc_text(PAGE, AvInstanceContextCleanup)
58 #pragma alloc_text(PAGE, AvAllocateScanContext)
59 #pragma alloc_text(PAGE, AvReferenceScanContext)
60 #pragma alloc_text(PAGE, AvReleaseScanContext)
61 #endif
62 
63 
64 //
65 // Context registration structure
66 //
67 
68 const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
69 
70  { FLT_STREAM_CONTEXT,
71  0,
75 
76  { FLT_STREAMHANDLE_CONTEXT,
77  0,
78  NULL,
81 
82  { FLT_TRANSACTION_CONTEXT,
83  0,
87 
88  { FLT_SECTION_CONTEXT,
89  0,
93 
94  { FLT_INSTANCE_CONTEXT,
95  0,
99 
100  { FLT_CONTEXT_END }
101 };
102 
103 
104 VOID
106  _In_ PFLT_CONTEXT Context,
107  _In_ FLT_CONTEXT_TYPE ContextType
108  )
109 /*++
110 
111 Routine Description:
112 
113  This function is called by the filter manager before freeing any of the minifilter
114  driver's contexts of that type.
115 
116  In this routine, the driver has to perform any needed cleanup, such as freeing
117  additional memory that the minifilter driver allocated inside the context structure
118 
119 Arguments:
120 
121  Context - Pointer to the minifilter driver's portion of the context.
122  ContextType - Supposed to be FLT_STREAM_CONTEXT.
123 
124 Return Value:
125 
126  None
127 
128 --*/
129 {
130  PAV_STREAM_CONTEXT streamContext = (PAV_STREAM_CONTEXT) Context;
131  UNREFERENCED_PARAMETER( ContextType );
132 
133  PAGED_CODE();
134 
135  FLT_ASSERTMSG( "[AV]: Stream context is not supposed to be in the transaction context list at cleanup.!\n",
136  NULL == streamContext->TxContext );
137 
138  AvFreeKevent( streamContext->ScanSynchronizationEvent );
139 }
140 
141 VOID
143  _In_ PFLT_CONTEXT Context,
144  _In_ FLT_CONTEXT_TYPE ContextType
145  )
146 /*++
147 
148 Routine Description:
149 
150  This function is called by the filter manager before freeing any of the minifilter
151  driver's contexts of that type.
152 
153  In this routine, the driver has to perform any needed cleanup, such as freeing
154  additional memory that the minifilter driver allocated inside the context structure
155 
156  We delete the stream context list in transaction context here.
157 
158 Arguments:
159 
160  Context - Pointer to the minifilter driver's portion of the context.
161  ContextType - Supposed to be FLT_TRANSACTION_CONTEXT.
162 
163 Return Value:
164 
165  None
166 
167 --*/
168 {
169  PAV_TRANSACTION_CONTEXT transactionContext = (PAV_TRANSACTION_CONTEXT) Context;
170 
171  UNREFERENCED_PARAMETER( ContextType );
172 
173  PAGED_CODE();
174 
175  AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
176  ("[Av]: AvTransactionContextCleanup context cleanup entered.\n") );
177 
178  ExDeleteResourceLite( transactionContext->Resource );
179  AvFreeResource( transactionContext->Resource );
180  transactionContext->Resource = NULL;
181  ObDereferenceObject( transactionContext->Transaction );
182  transactionContext->Transaction = NULL;
183 }
184 
185 VOID
187  _In_ PFLT_CONTEXT Context,
188  _In_ FLT_CONTEXT_TYPE ContextType
189  )
190 /*++
191 
192 Routine Description:
193 
194  This function is called by the filter manager before freeing any of the minifilter
195  driver's contexts of that type.
196 
197  In this routine, the driver has to perform any needed cleanup, such as freeing
198  additional memory that the minifilter driver allocated inside the context structure
199 
200 Arguments:
201 
202  Context - Pointer to the minifilter driver's portion of the context.
203  ContextType - Supposed to be FLT_SECTION_CONTEXT (win8 or later).
204 
205 Return Value:
206 
207  None
208 
209 --*/
210 {
211  PAGED_CODE();
212 
213  UNREFERENCED_PARAMETER( Context );
214  UNREFERENCED_PARAMETER( ContextType );
215 
216  FLT_ASSERTMSG( "[AV] AvSectionContextCleanup: Section handle should be NULL at cleanup.\n",
217  ((PAV_SECTION_CONTEXT) Context)->SectionHandle == NULL );
218  FLT_ASSERTMSG( "[AV] AvSectionContextCleanup: Section object should be NULL at cleanup.\n",
219  ((PAV_SECTION_CONTEXT) Context)->SectionObject == NULL );
220 
221 }
222 
223 VOID
225  _In_ PFLT_CONTEXT Context,
226  _In_ FLT_CONTEXT_TYPE ContextType
227  )
228 /*++
229 
230 Routine Description:
231 
232  This function is called by the filter manager before freeing any of the minifilter
233  driver's contexts of that type.
234 
235  In this routine, the driver has to perform any needed cleanup, such as freeing
236  additional memory that the minifilter driver allocated inside the context structure.
237 
238  We delete the cache table if the file system supports one.
239 
240 Arguments:
241 
242  Context - Pointer to the minifilter driver's portion of the context.
243  ContextType - Supposed to be FLT_INSTANCE_CONTEXT (win8 or later).
244 
245 Return Value:
246 
247  None
248 
249 --*/
250 {
251 
252  PAV_INSTANCE_CONTEXT instanceContext = (PAV_INSTANCE_CONTEXT) Context;
253 
254  UNREFERENCED_PARAMETER( Context );
255  UNREFERENCED_PARAMETER( ContextType );
256 
257  PAGED_CODE();
258 
259  AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
260  ( "[Av]: AvInstanceContextCleanup context cleanup entered\n") );
261 
262  if (FS_SUPPORTS_FILE_STATE_CACHE( instanceContext->VolumeFSType )) {
263 
264  FLT_ASSERTMSG( "[AV] AvInstanceContextCleanup: The generic table should be empty at cleanup.\n",
265  RtlIsGenericTableEmpty( &instanceContext->FileStateCacheTable ) );
266  ExDeleteResourceLite( &instanceContext->Resource );
267  }
268 }
269 
270 NTSTATUS
272  _In_ PFLT_FILTER Filter,
273  _Outptr_ PAV_STREAMHANDLE_CONTEXT *StreamHandleContext
274  )
275 /*++
276 
277 Routine Description:
278 
279  This routine creates a new streamhandle context
280 
281 Arguments:
282 
283  StreamHandleContext - Returns the streamhandle context
284 
285 Return Value:
286 
287  Status
288 
289 --*/
290 {
291  NTSTATUS status;
292  PAV_STREAMHANDLE_CONTEXT streamHandleContext;
293 
294  PAGED_CODE();
295 
296  //
297  // Allocate a streamhandle context
298  //
299 
300  status = FltAllocateContext( Filter,
301  FLT_STREAMHANDLE_CONTEXT,
303  PagedPool,
304  &streamHandleContext );
305 
306  if (!NT_SUCCESS( status )) {
307 
308  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
309  ("[Av]: Failed to allocate stream handle context with status 0x%x \n",
310  status) );
311  return status;
312  }
313 
314  //
315  // Initialize the newly created context
316  //
317 
318  RtlZeroMemory(streamHandleContext, AV_STREAMHANDLE_CONTEXT_SIZE);
319  *StreamHandleContext = streamHandleContext;
320 
321  return STATUS_SUCCESS;
322 }
323 
324 NTSTATUS
326  _In_ PFLT_FILTER Filter,
327  _Outptr_ PAV_STREAM_CONTEXT *StreamContext
328  )
329 /*++
330 
331 Routine Description:
332 
333  This routine creates a new stream context
334 
335 Arguments:
336 
337  StreamContext - Returns the stream context
338 
339 Return Value:
340 
341  Status
342 
343 --*/
344 {
345  NTSTATUS status;
346  PKEVENT event = NULL;
347  PAV_STREAM_CONTEXT streamContext;
348 
349  PAGED_CODE();
350 
351  //
352  // Allocate the kernel event object
353  //
354 
355  event = AvAllocateKevent();
356 
357  if (NULL == event) {
358 
359  return STATUS_INSUFFICIENT_RESOURCES;
360  }
361 
362  //
363  // Allocate a stream context
364  //
365 
366  status = FltAllocateContext( Filter,
367  FLT_STREAM_CONTEXT,
369  PagedPool,
370  &streamContext );
371 
372  if (!NT_SUCCESS( status )) {
373 
374  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
375  ("[Av]: Failed to allocate stream context with status 0x%x \n",
376  status) );
377  AvFreeKevent( event );
378  return status;
379  }
380 
381  //
382  // Initialize the newly created context
383  //
384 
385  RtlZeroMemory(streamContext, AV_STREAM_CONTEXT_SIZE);
386  streamContext->ScanSynchronizationEvent = event;
387  KeInitializeEvent( streamContext->ScanSynchronizationEvent, SynchronizationEvent, TRUE );
388  SET_FILE_MODIFIED( streamContext );
389  SET_FILE_TX_MODIFIED( streamContext );
390  *StreamContext = streamContext;
391 
392  return STATUS_SUCCESS;
393 }
394 
395 NTSTATUS
397  _In_ PCFLT_RELATED_OBJECTS FltObjects,
398  _Outptr_ PAV_TRANSACTION_CONTEXT *TransactionContext
399  )
400 /*++
401 
402 Routine Description
403 
404  This routine finds the transaction context, if not found, it will
405  try to create a new one. The caller is responsible for calling
406  FltReleaseContext to decrement its reference count.
407 
408 Arguments
409 
410  FltObjects - Contains parameters required to enlist in a transaction.
411 
412  TransactionContext - Returns the transaction context
413 
414 Return value
415 
416  Returns STATUS_SUCCESS if we were able to successfully find/create
417  a transaction context. Returns an appropriate error code on a failure.
418 
419 --*/
420 {
421  NTSTATUS status;
422  PAV_TRANSACTION_CONTEXT transactionContext = NULL;
423  PAV_TRANSACTION_CONTEXT oldTransactionContext = NULL;
424  PERESOURCE pResource = NULL;
425 
426  PAGED_CODE();
427 
428  AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
429  ("[Av]: AvFindOrCreateTransactionContext entered. \n") );
430 
431  status = FltGetTransactionContext( FltObjects->Instance,
432  FltObjects->Transaction,
433  &transactionContext );
434 
435  if (NT_SUCCESS( status )) {
436 
437  *TransactionContext = transactionContext;
438  return STATUS_SUCCESS;
439  }
440 
441  if (status != STATUS_NOT_FOUND) {
442 
443  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
444  ("[AV]: Failed to get transaction context with status 0x%x \n",
445  status) );
446  return status;
447  }
448 
449  //
450  // Allocate the resource
451  //
452 
453  pResource = AvAllocateResource();
454 
455  if ( NULL == pResource ) {
456 
457  return STATUS_INSUFFICIENT_RESOURCES;
458  }
459 
460  //
461  // Allocate a transaction context.
462  //
463 
464  status = FltAllocateContext( Globals.Filter,
465  FLT_TRANSACTION_CONTEXT,
467  PagedPool,
468  &transactionContext );
469 
470  if (!NT_SUCCESS( status )) {
471 
472  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
473  ("[AV]: Failed to allocate transaction context with status 0x%x \n",
474  status) );
475  AvFreeResource( pResource );
476  return status;
477  }
478 
479  FLT_ASSERTMSG( "[AV]: Transaction object pointer is not supposed to be NULL !\n", FltObjects->Transaction != NULL);
480 
481  //
482  // Initialization of transaction context.
483  // The reason we allocate eResource seperately is because
484  // eResource has to be allocated in the non-paged pool.
485  //
486 
487  RtlZeroMemory(transactionContext, AV_TRANSACTION_CONTEXT_SIZE);
488  transactionContext->Resource = pResource;
489  ObReferenceObject( FltObjects->Transaction );
490  transactionContext->Transaction = FltObjects->Transaction;
491  InitializeListHead( &transactionContext->ScListHead );
492  ExInitializeResourceLite( transactionContext->Resource );
493 
494  status = FltSetTransactionContext( FltObjects->Instance,
495  FltObjects->Transaction,
496  FLT_SET_CONTEXT_KEEP_IF_EXISTS,
497  transactionContext,
498  &oldTransactionContext );
499 
500  if (NT_SUCCESS( status )) {
501 
502  *TransactionContext = transactionContext;
503  return STATUS_SUCCESS;
504  }
505 
506  FltReleaseContext( transactionContext );
507 
508  if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
509 
510  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
511  ("[Av]: Failed to set transaction context with status 0x%x \n",
512  status) );
513 
514  return status;
515  }
516 
517  if (NULL == oldTransactionContext) {
518 
519  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
520  ("[Av]: Failed to set transaction context oldTransactionContext is NULL \n") );
521 
522  return status;
523  }
524 
525  *TransactionContext = oldTransactionContext;
526 
527 
528  return STATUS_SUCCESS;
529 }
530 
531 NTSTATUS
533  _In_ PFLT_INSTANCE Instance,
534  _In_ PFILE_OBJECT FileObject,
535  _Outptr_ PAV_SECTION_CONTEXT *SectionContext
536  )
537 /*++
538 
539 Routine Description:
540 
541  This routine creates a new section context.
542 
543 Arguments:
544 
545  Instance - Opaque instance pointer for the caller. This parameter is required and cannot be NULL.
546 
547  FileObject - File object pointer for the file. This parameter is required and cannot be NULL.
548 
549  SectionContext - Returns the section context
550 
551 Return Value:
552 
553  Status
554 
555 --*/
556 {
557  NTSTATUS status;
558  LONGLONG fileSize;
559  PAV_SECTION_CONTEXT sectionContext = NULL;
560 
561  PAGED_CODE();
562 
563  status = FltAllocateContext( Globals.Filter,
564  FLT_SECTION_CONTEXT,
566  PagedPool,
567  &sectionContext );
568  if (!NT_SUCCESS( status )) {
569 
570  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
571  ("[Av]: Failed to allocate section context.\n, 0x%08x\n",
572  status) );
573  return status;
574  }
575 
576  RtlZeroMemory(sectionContext, AV_SECTION_CONTEXT_SIZE);
577 
578  status = AvGetFileSize( Instance,
579  FileObject,
580  &fileSize );
581 
582  if (!NT_SUCCESS( status )) {
583 
584  AV_DBG_PRINT( AVDBG_TRACE_ERROR,
585  ("[Av]: Failed to get file size with status 0x%x. (FileObject = %p, Instance = %p)\n",
586  status,
587  FileObject,
588  Instance ));
589  } else {
590 
591  sectionContext->FileSize = fileSize;
592  }
593 
594  *SectionContext = sectionContext;
595 
596  return STATUS_SUCCESS;
597 }
598 
599 NTSTATUS
601  _Outptr_result_buffer_(*NumberInstances) PFLT_INSTANCE **InstanceArray,
602  _Out_ PULONG NumberInstances
603  )
604 /*++
605 
606 Routine Description:
607 
608  This routine returns all the instances available of this filter
609  The caller is responsible for calling AvFreeInstances(...) to release the instance references.
610 
611 Arguments:
612 
613  InstanceArray - This function will allocate the memory of the arrary containing the instances.
614 
615  NumberInstances - The number of instances in InstanceArray.
616 
617 Return Value:
618 
619  Status
620 
621 --*/
622 {
623  PFLT_INSTANCE *instArray = NULL;
624  NTSTATUS status = STATUS_SUCCESS;
625  ULONG i = 0;
626  ULONG instCnt = 0;
627  ULONG newCount = 0;
628 
629 
630  //
631  // Get a count of how many instances there are
632  //
633 
634  status = FltEnumerateInstances( NULL,
635  Globals.Filter,
636  NULL,
637  0,
638  &instCnt );
639 
640  if (!NT_SUCCESS(status) &&
641  (status != STATUS_BUFFER_TOO_SMALL)) {
642 
643  goto Cleanup;
644  }
645 
646  //
647  // Get handles for all instances. This will loop in case too many
648  // filters load between the time we got the count and the time
649  // we actually get the list.
650  //
651 
652  for (;;) {
653 
654  //
655  // Free old memory if we have some
656  //
657 
658  if (instArray != NULL) {
659 
660  ExFreePoolWithTag( instArray, AV_INSTANCES_ARRAY_TAG);
661  instArray = NULL;
662  }
663 
664  //
665  // Allocate memory for list, add a couple of entries in case
666  // a filter loads while we are doing this
667  //
668 
669  instCnt += 2;
670 
671  instArray = ExAllocatePoolWithTag( PagedPool,
672  (instCnt * sizeof(PFLT_INSTANCE)),
674 
675  if (instArray == NULL) {
676 
677  status = STATUS_INSUFFICIENT_RESOURCES;
678  goto Cleanup;
679  }
680 
681  //
682  // This time get list of filters (and a new count)
683  //
684 
685  status = FltEnumerateInstances( NULL,
686  Globals.Filter,
687  instArray,
688  instCnt,
689  &newCount );
690 
691  //
692  // exit loop if we succeeded
693  //
694 
695  if (NT_SUCCESS(status)) {
696 
697  instCnt = newCount;
698  break;
699  }
700 
701  //
702  // If it was an unexpected error, quit processing, else allocate
703  // more memory and try again
704  //
705 
706  if (status != STATUS_BUFFER_TOO_SMALL) {
707 
708  goto Cleanup;
709  }
710 
711  //
712  // The buffer was too small, try again
713  //
714 
715  FLT_ASSERT(newCount > instCnt);
716  instCnt = newCount;
717  }
718 
719  *InstanceArray = instArray;
720  *NumberInstances = instCnt;
721 
722 Cleanup:
723 
724  if ( !NT_SUCCESS(status) ) {
725 
726  if (instArray) {
727 
728  //
729  // Release all the objects in the array
730  //
731 
732  for (i = 0; i < instCnt; i++) {
733 
734  FltObjectDereference( instArray[i] );
735  instArray[i] = NULL;
736  }
737 
738  ExFreePoolWithTag( instArray, AV_INSTANCES_ARRAY_TAG );
739  instArray = NULL;
740  }
741  }
742 
743 
744  return status;
745 
746 }
747 
748 VOID
750  _In_reads_(InstanceCount) PFLT_INSTANCE *InstanceArray,
751  _In_ ULONG InstanceCount
752  )
753 /*++
754 
755 Routine Description:
756 
757  This routine frees the reference count and memory of instance array obtained from AvEnumerateInstances(...).
758 
759 Arguments:
760 
761  InstanceArray - The instance arrary to be freed.
762 
763  NumberInstances - The number of instances in InstanceArray.
764 
765 Return Value:
766 
767  None.
768 
769 --*/
770 {
771  ULONG i = 0;
772 
773  //
774  // Release all the objects in the array
775  //
776 
777  for (i = 0; i < InstanceCount; i++) {
778 
779  FltObjectDereference( InstanceArray[i] );
780  InstanceArray[i] = NULL;
781  }
782 
783  ExFreePoolWithTag( InstanceArray, AV_INSTANCES_ARRAY_TAG );
784 }
785 
786 NTSTATUS
788  _In_ PFLT_INSTANCE Instance,
789  _In_ PFILE_OBJECT FileObject,
790  _Outptr_ PAV_SCAN_CONTEXT *ScanContext
791  )
792 /*++
793 
794 Routine Description:
795 
796  The routine allocates the scan context
797 
798 Arguments:
799 
800  Instance - Opaque instance pointer for the caller. This parameter is required and cannot be NULL.
801 
802  FileObject - File object pointer for the file. This parameter is required and cannot be NULL.
803 
804  ScanContext - The output scan context.
805 
806 Return Value:
807 
808  STATUS_INSUFFICIENT_RESOURCES if allocation failed.
809  STATUS_SUCCESS if successfully allocated.
810 
811 --*/
812 {
813  NTSTATUS status = STATUS_SUCCESS;
814  PAV_SCAN_CONTEXT scanCtx = NULL;
815 
816  PAGED_CODE();
817 
818  ASSERT(Instance != NULL);
819  ASSERT(FileObject != NULL);
820 
821  scanCtx = ExAllocatePoolWithTag( NonPagedPoolNx,
822  sizeof(AV_SCAN_CONTEXT),
823  AV_SCAN_CTX_TAG );
824 
825  if (NULL == scanCtx) {
826 
827  return STATUS_INSUFFICIENT_RESOURCES;
828  }
829  scanCtx->RefCount = 1;
831 
832  //
833  // Keeps a reference in scan contex.
834  // We also handle the case that the instance is being torn down.
835  //
836  status = FltObjectReference( Instance );
837  if (!NT_SUCCESS(status)) {
838 
839  ExFreePoolWithTag( scanCtx, AV_SCAN_CTX_TAG );
840  return status;
841  }
842  scanCtx->FilterInstance = Instance;
843 
844  //
845  // Keeps a reference in scan context
846  //
847  ObReferenceObject( FileObject );
848  scanCtx->FileObject = FileObject;
849 
850  *ScanContext = scanCtx;
851  return STATUS_SUCCESS;
852 }
853 
854 NTSTATUS
856  _In_ PAV_SCAN_CONTEXT ScanContext
857  )
858 /*++
859 
860 Routine Description:
861 
862  The routine increments the reference count of scan context to prevent it from deletion.
863 
864 Arguments:
865 
866  ScanContext - The scan context to be added reference.
867 
868 Return Value:
869 
870  STATUS_INVALID_PARAMETER if ScanContext is NULL.
871  STATUS_SUCCESS if successfully incremented.
872 
873 --*/
874 {
875  PAGED_CODE();
876 
877  if (ScanContext == NULL) {
878 
879  return STATUS_INVALID_PARAMETER;
880  }
881 
882  ASSERT(ScanContext->RefCount != 0);
883  ASSERT(ScanContext->FilterInstance != NULL);
884  ASSERT(ScanContext->FileObject != NULL);
885 
886  InterlockedIncrement(&ScanContext->RefCount);
887 
888  return STATUS_SUCCESS;
889 }
890 
891 NTSTATUS
893  _In_ PAV_SCAN_CONTEXT ScanContext
894  )
895 /*++
896 
897 Routine Description:
898 
899  The routine decrements the reference count of scan context.
900  Release it if reference count goes to zero.
901 
902 Arguments:
903 
904  ScanContext - The scan context to be released.
905 
906 Return Value:
907 
908  STATUS_INVALID_PARAMETER if ScanContext is NULL.
909  STATUS_SUCCESS if successfully decremented.
910 
911 --*/
912 {
913  ULONG newRefCount = 0;
914 
915  PAGED_CODE();
916 
917  if (ScanContext == NULL) {
918 
919  return STATUS_INVALID_PARAMETER;
920  }
921 
922  ASSERT(ScanContext->FilterInstance != NULL);
923  ASSERT(ScanContext->FileObject != NULL);
924 
925  //
926  // Assume the usage of AvReferenceScanContext and AvReleaseScanContext are not raced,
927  // This simple version would suffice.
928  //
929 
930  newRefCount = InterlockedDecrement(&ScanContext->RefCount);
931  if (newRefCount == 0) {
932 
933  //
934  // Before freeing scan context, we need to release the file object and instance.
935  //
936  FltObjectDereference( ScanContext->FilterInstance );
937  ObDereferenceObject( ScanContext->FileObject );
938  ExFreePoolWithTag( ScanContext, AV_SCAN_CTX_TAG );
939  }
940  return STATUS_SUCCESS;
941 }
942 
943 
#define SET_FILE_TX_MODIFIED(_sCtx)
#define AV_INSTANCE_CONTEXT_SIZE
#define FS_SUPPORTS_FILE_STATE_CACHE(VolumeFilesystemType)
#define AV_SECTION_CONTEXT_SIZE
VOID AvTransactionContextCleanup(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
LONG RefCount
Definition: avscan.h:54
PAV_TRANSACTION_CONTEXT TxContext
#define AV_STREAMHANDLE_CONTEXT_SIZE
#define AV_SCAN_CTX_TAG
FLT_FILESYSTEM_TYPE VolumeFSType
struct _AV_INSTANCE_CONTEXT * PAV_INSTANCE_CONTEXT
PFILE_OBJECT FileObject
Definition: avscan.h:56
PFLT_INSTANCE FilterInstance
Definition: avscan.h:55
NTSTATUS AvCreateSectionContext(_In_ PFLT_INSTANCE Instance, _In_ PFILE_OBJECT FileObject, _Outptr_ PAV_SECTION_CONTEXT *SectionContext)
VOID AvInstanceContextCleanup(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
VOID AvFreeInstances(_In_reads_(InstanceCount) PFLT_INSTANCE *InstanceArray, _In_ ULONG InstanceCount)
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE Instance
Definition: nc.h:493
NTSTATUS AvReleaseScanContext(_In_ PAV_SCAN_CONTEXT ScanContext)
#define AV_STREAM_CONTEXT_TAG
FORCEINLINE VOID AvFreeResource(_In_ PERESOURCE Resource)
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
return TRUE
AV_SCANNER_GLOBAL_DATA Globals
Definition: avscan.h:152
FORCEINLINE PERESOURCE AvAllocateResource(VOID)
VOID AvStreamContextCleanup(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
NTSTATUS AvFindOrCreateTransactionContext(_In_ PCFLT_RELATED_OBJECTS FltObjects, _Outptr_ PAV_TRANSACTION_CONTEXT *TransactionContext)
#define AV_SECTION_CONTEXT_TAG
FORCEINLINE VOID AvFreeKevent(_In_ PKEVENT Event)
NTSTATUS AvGetFileSize(_In_ PFLT_INSTANCE Instance, _In_ PFILE_OBJECT FileObject, _Out_ PLONGLONG Size)
#define AV_STREAM_CONTEXT_SIZE
struct _AV_STREAM_CONTEXT * PAV_STREAM_CONTEXT
PFLT_FILTER Filter
Definition: avscan.h:86
#define AV_TRANSACTION_CONTEXT_SIZE
RTL_GENERIC_TABLE FileStateCacheTable
#define SET_FILE_MODIFIED(_sCtx)
const FLT_CONTEXT_REGISTRATION ContextRegistration[]
VOID AvSectionContextCleanup(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
NTSTATUS AvEnumerateInstances(_Outptr_result_buffer_(*NumberInstances) PFLT_INSTANCE **InstanceArray, _Out_ PULONG NumberInstances)
#define AV_STREAMHANDLE_CONTEXT_TAG
BOOLEAN IoWaitOnScanCompleteNotificationAborted
Definition: avscan.h:65
UNREFERENCED_PARAMETER(FileObject)
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
NTSTATUS AvCreateStreamContext(_In_ PFLT_FILTER Filter, _Outptr_ PAV_STREAM_CONTEXT *StreamContext)
#define AV_INSTANCES_ARRAY_TAG
NTSTATUS AvCreateStreamHandleContext(_In_ PFLT_FILTER Filter, _Outptr_ PAV_STREAMHANDLE_CONTEXT *StreamHandleContext)
#define AV_INSTANCE_CONTEXT_TAG
struct _AV_TRANSACTION_CONTEXT * PAV_TRANSACTION_CONTEXT
PAGED_CODE()
NTSTATUS AvAllocateScanContext(_In_ PFLT_INSTANCE Instance, _In_ PFILE_OBJECT FileObject, _Outptr_ PAV_SCAN_CONTEXT *ScanContext)
#define AV_TRANSACTION_CONTEXT_TAG
NTSTATUS AvReferenceScanContext(_In_ PAV_SCAN_CONTEXT ScanContext)
_In_opt_ PFILE_OBJECT FileObject
Definition: nc.h:493
FORCEINLINE PKEVENT AvAllocateKevent(VOID)
#define AV_DBG_PRINT(_dbgLevel, _string)
Definition: avscan.h:172

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