WDK Mini Filter Example
ctx/context.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1999 - 2002 Microsoft Corporation
4 
5 Module Name:
6 
7  context.c
8 
9 Abstract:
10 
11  This is the stream nd stream handle context module of the kernel mode
12  context sample filter driver
13 
14 
15 Environment:
16 
17  Kernel mode
18 
19 
20 --*/
21 
22 
23 #include "pch.h"
24 
25 
26 #ifdef ALLOC_PRAGMA
27 #pragma alloc_text(PAGE, CtxFindOrCreateFileContext)
28 #pragma alloc_text(PAGE, CtxCreateFileContext)
29 #pragma alloc_text(PAGE, CtxFindOrCreateStreamContext)
30 #pragma alloc_text(PAGE, CtxCreateStreamContext)
31 #pragma alloc_text(PAGE, CtxUpdateNameInStreamContext)
32 #pragma alloc_text(PAGE, CtxCreateOrReplaceStreamHandleContext)
33 #pragma alloc_text(PAGE, CtxCreateStreamHandleContext)
34 #pragma alloc_text(PAGE, CtxUpdateNameInStreamHandleContext)
35 #endif
36 
37 
38 
39 
40 NTSTATUS
42  _In_ PFLT_CALLBACK_DATA Cbd,
43  _In_ BOOLEAN CreateIfNotFound,
44  _When_( CreateIfNotFound != FALSE, _In_ ) _When_( CreateIfNotFound == FALSE, _In_opt_ ) PUNICODE_STRING FileName,
45  _Outptr_ PCTX_FILE_CONTEXT *FileContext,
46  _Out_opt_ PBOOLEAN ContextCreated
47  )
48 /*++
49 
50 Routine Description:
51 
52  This routine finds the file context for the target file.
53  Optionally, if the context does not exist this routing creates
54  a new one and attaches the context to the file.
55 
56 Arguments:
57 
58  Cbd - Supplies a pointer to the callbackData which
59  declares the requested operation.
60  CreateIfNotFound - Supplies if the file context must be created if missing
61  FileName - Supplies the file name
62  FileContext - Returns the file context
63  ContextCreated - Returns if a new context was created
64 
65 Return Value:
66 
67  Status
68 
69 --*/
70 {
71  NTSTATUS status;
72  PCTX_FILE_CONTEXT fileContext;
73  PCTX_FILE_CONTEXT oldFileContext;
74 
75  PAGED_CODE();
76 
77  *FileContext = NULL;
78  if (ContextCreated != NULL) *ContextCreated = FALSE;
79 
80  //
81  // First try to get the file context.
82  //
83 
84  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
85  ("[Ctx]: Trying to get file context (FileObject = %p, Instance = %p)\n",
86  Cbd->Iopb->TargetFileObject,
87  Cbd->Iopb->TargetInstance) );
88 
89  status = FltGetFileContext( Cbd->Iopb->TargetInstance,
90  Cbd->Iopb->TargetFileObject,
91  &fileContext );
92 
93  //
94  // If the call failed because the context does not exist
95  // and the user wants to creat a new one, the create a
96  // new context
97  //
98 
99  if (!NT_SUCCESS( status ) &&
100  (status == STATUS_NOT_FOUND) &&
101  CreateIfNotFound) {
102 
103 
104  //
105  // Create a file context
106  //
107 
108  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
109  ("[Ctx]: Creating file context (FileObject = %p, Instance = %p)\n",
110  Cbd->Iopb->TargetFileObject,
111  Cbd->Iopb->TargetInstance) );
112 
113  status = CtxCreateFileContext( FileName, &fileContext );
114 
115  if (!NT_SUCCESS( status )) {
116 
117  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
118  ("[Ctx]: Failed to create file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
119  status,
120  Cbd->Iopb->TargetFileObject,
121  Cbd->Iopb->TargetInstance) );
122 
123  return status;
124  }
125 
126 
127  //
128  // Set the new context we just allocated on the file object
129  //
130 
131  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
132  ("[Ctx]: Setting file context %p (FileObject = %p, Instance = %p)\n",
133  fileContext,
134  Cbd->Iopb->TargetFileObject,
135  Cbd->Iopb->TargetInstance) );
136 
137  status = FltSetFileContext( Cbd->Iopb->TargetInstance,
138  Cbd->Iopb->TargetFileObject,
139  FLT_SET_CONTEXT_KEEP_IF_EXISTS,
140  fileContext,
141  &oldFileContext );
142 
143  if (!NT_SUCCESS( status )) {
144 
145  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
146  ("[Ctx]: Failed to set file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
147  status,
148  Cbd->Iopb->TargetFileObject,
149  Cbd->Iopb->TargetInstance) );
150  //
151  // We release the context here because FltSetFileContext failed
152  //
153  // If FltSetFileContext succeeded then the context will be returned
154  // to the caller. The caller will use the context and then release it
155  // when he is done with the context.
156  //
157 
158  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
159  ("[Ctx]: Releasing file context %p (FileObject = %p, Instance = %p)\n",
160  fileContext,
161  Cbd->Iopb->TargetFileObject,
162  Cbd->Iopb->TargetInstance) );
163 
164  FltReleaseContext( fileContext );
165 
166  if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
167 
168  //
169  // FltSetFileContext failed for a reason other than the context already
170  // existing on the file. So the object now does not have any context set
171  // on it. So we return failure to the caller.
172  //
173 
174  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
175  ("[Ctx]: Failed to set file context with status 0x%x != STATUS_FLT_CONTEXT_ALREADY_DEFINED. (FileObject = %p, Instance = %p)\n",
176  status,
177  Cbd->Iopb->TargetFileObject,
178  Cbd->Iopb->TargetInstance) );
179 
180  return status;
181  }
182 
183  //
184  // Race condition. Someone has set a context after we queried it.
185  // Use the already set context instead
186  //
187 
188  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
189  ("[Ctx]: File context already defined. Retaining old file context %p (FileObject = %p, Instance = %p)\n",
190  oldFileContext,
191  Cbd->Iopb->TargetFileObject,
192  Cbd->Iopb->TargetInstance) );
193 
194  //
195  // Return the existing context. Note that the new context that we allocated has already been
196  // realeased above.
197  //
198 
199  fileContext = oldFileContext;
200  status = STATUS_SUCCESS;
201 
202  } else {
203 
204  if (ContextCreated != NULL) *ContextCreated = TRUE;
205  }
206  }
207 
208  *FileContext = fileContext;
209 
210  return status;
211 }
212 
213 
214 NTSTATUS
216  _In_ PUNICODE_STRING FileName,
217  _Outptr_ PCTX_FILE_CONTEXT *FileContext
218  )
219 /*++
220 
221 Routine Description:
222 
223  This routine creates a new file context
224 
225 Arguments:
226 
227  FileName - Supplies the file name
228  FileContext - Returns the file context
229 
230 Return Value:
231 
232  Status
233 
234 --*/
235 {
236  NTSTATUS status;
237  PCTX_FILE_CONTEXT fileContext;
238 
239  PAGED_CODE();
240 
241  //
242  // Allocate a file context
243  //
244 
245  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
246  ("[Ctx]: Allocating file context \n") );
247 
248  status = FltAllocateContext( Globals.Filter,
249  FLT_FILE_CONTEXT,
251  PagedPool,
252  &fileContext );
253 
254  if (!NT_SUCCESS( status )) {
255 
256  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
257  ("[Ctx]: Failed to allocate file context with status 0x%x \n",
258  status) );
259  return status;
260  }
261 
262  //
263  // Initialize the newly created context
264  //
265 
266  //
267  // Allocate and copy off the file name
268  //
269 
270  fileContext->FileName.MaximumLength = FileName->Length;
271  status = CtxAllocateUnicodeString( &fileContext->FileName );
272  if (NT_SUCCESS( status )) {
273 
274  RtlCopyUnicodeString( &fileContext->FileName, FileName );
275  }
276 
277  *FileContext = fileContext;
278 
279  return STATUS_SUCCESS;
280 }
281 
282 
283 NTSTATUS
285  _In_ PFLT_CALLBACK_DATA Cbd,
286  _In_ BOOLEAN CreateIfNotFound,
287  _Outptr_ PCTX_STREAM_CONTEXT *StreamContext,
288  _Out_opt_ PBOOLEAN ContextCreated
289  )
290 /*++
291 
292 Routine Description:
293 
294  This routine finds the stream context for the target stream.
295  Optionally, if the context does not exist this routing creates
296  a new one and attaches the context to the stream.
297 
298 Arguments:
299 
300  Cbd - Supplies a pointer to the callbackData which
301  declares the requested operation.
302  CreateIfNotFound - Supplies if the stream must be created if missing
303  StreamContext - Returns the stream context
304  ContextCreated - Returns if a new context was created
305 
306 Return Value:
307 
308  Status
309 
310 --*/
311 {
312  NTSTATUS status;
313  PCTX_STREAM_CONTEXT streamContext;
314  PCTX_STREAM_CONTEXT oldStreamContext;
315 
316  PAGED_CODE();
317 
318  *StreamContext = NULL;
319  if (ContextCreated != NULL) *ContextCreated = FALSE;
320 
321  //
322  // First try to get the stream context.
323  //
324 
325  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
326  ("[Ctx]: Trying to get stream context (FileObject = %p, Instance = %p)\n",
327  Cbd->Iopb->TargetFileObject,
328  Cbd->Iopb->TargetInstance) );
329 
330  status = FltGetStreamContext( Cbd->Iopb->TargetInstance,
331  Cbd->Iopb->TargetFileObject,
332  &streamContext );
333 
334  //
335  // If the call failed because the context does not exist
336  // and the user wants to creat a new one, the create a
337  // new context
338  //
339 
340  if (!NT_SUCCESS( status ) &&
341  (status == STATUS_NOT_FOUND) &&
342  CreateIfNotFound) {
343 
344 
345  //
346  // Create a stream context
347  //
348 
349  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
350  ("[Ctx]: Creating stream context (FileObject = %p, Instance = %p)\n",
351  Cbd->Iopb->TargetFileObject,
352  Cbd->Iopb->TargetInstance) );
353 
354  status = CtxCreateStreamContext( &streamContext );
355 
356  if (!NT_SUCCESS( status )) {
357 
358  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
359  ("[Ctx]: Failed to create stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
360  status,
361  Cbd->Iopb->TargetFileObject,
362  Cbd->Iopb->TargetInstance) );
363 
364  return status;
365  }
366 
367 
368  //
369  // Set the new context we just allocated on the file object
370  //
371 
372  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
373  ("[Ctx]: Setting stream context %p (FileObject = %p, Instance = %p)\n",
374  streamContext,
375  Cbd->Iopb->TargetFileObject,
376  Cbd->Iopb->TargetInstance) );
377 
378  status = FltSetStreamContext( Cbd->Iopb->TargetInstance,
379  Cbd->Iopb->TargetFileObject,
380  FLT_SET_CONTEXT_KEEP_IF_EXISTS,
381  streamContext,
382  &oldStreamContext );
383 
384  if (!NT_SUCCESS( status )) {
385 
386  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
387  ("[Ctx]: Failed to set stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
388  status,
389  Cbd->Iopb->TargetFileObject,
390  Cbd->Iopb->TargetInstance) );
391  //
392  // We release the context here because FltSetStreamContext failed
393  //
394  // If FltSetStreamContext succeeded then the context will be returned
395  // to the caller. The caller will use the context and then release it
396  // when he is done with the context.
397  //
398 
399  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
400  ("[Ctx]: Releasing stream context %p (FileObject = %p, Instance = %p)\n",
401  streamContext,
402  Cbd->Iopb->TargetFileObject,
403  Cbd->Iopb->TargetInstance) );
404 
405  FltReleaseContext( streamContext );
406 
407  if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
408 
409  //
410  // FltSetStreamContext failed for a reason other than the context already
411  // existing on the stream. So the object now does not have any context set
412  // on it. So we return failure to the caller.
413  //
414 
415  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
416  ("[Ctx]: Failed to set stream context with status 0x%x != STATUS_FLT_CONTEXT_ALREADY_DEFINED. (FileObject = %p, Instance = %p)\n",
417  status,
418  Cbd->Iopb->TargetFileObject,
419  Cbd->Iopb->TargetInstance) );
420 
421  return status;
422  }
423 
424  //
425  // Race condition. Someone has set a context after we queried it.
426  // Use the already set context instead
427  //
428 
429  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
430  ("[Ctx]: Stream context already defined. Retaining old stream context %p (FileObject = %p, Instance = %p)\n",
431  oldStreamContext,
432  Cbd->Iopb->TargetFileObject,
433  Cbd->Iopb->TargetInstance) );
434 
435  //
436  // Return the existing context. Note that the new context that we allocated has already been
437  // realeased above.
438  //
439 
440  streamContext = oldStreamContext;
441  status = STATUS_SUCCESS;
442 
443  } else {
444 
445  if (ContextCreated != NULL) *ContextCreated = TRUE;
446  }
447  }
448 
449  *StreamContext = streamContext;
450 
451  return status;
452 }
453 
454 
455 
456 
457 NTSTATUS
459  _Outptr_ PCTX_STREAM_CONTEXT *StreamContext
460  )
461 /*++
462 
463 Routine Description:
464 
465  This routine creates a new stream context
466 
467 Arguments:
468 
469  StreamContext - Returns the stream context
470 
471 Return Value:
472 
473  Status
474 
475 --*/
476 {
477  NTSTATUS status;
478  PCTX_STREAM_CONTEXT streamContext;
479 
480  PAGED_CODE();
481 
482  //
483  // Allocate a stream context
484  //
485 
486  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
487  ("[Ctx]: Allocating stream context \n") );
488 
489  status = FltAllocateContext( Globals.Filter,
490  FLT_STREAM_CONTEXT,
492  PagedPool,
493  &streamContext );
494 
495  if (!NT_SUCCESS( status )) {
496 
497  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
498  ("[Ctx]: Failed to allocate stream context with status 0x%x \n",
499  status) );
500  return status;
501  }
502 
503  //
504  // Initialize the newly created context
505  //
506 
507  RtlZeroMemory( streamContext, CTX_STREAM_CONTEXT_SIZE );
508 
509  streamContext->Resource = CtxAllocateResource();
510  if(streamContext->Resource == NULL) {
511 
512  FltReleaseContext( streamContext );
513  return STATUS_INSUFFICIENT_RESOURCES;
514  }
515  ExInitializeResourceLite( streamContext->Resource );
516 
517  *StreamContext = streamContext;
518 
519  return STATUS_SUCCESS;
520 }
521 
522 
523 NTSTATUS
525  _In_ PUNICODE_STRING DirectoryName,
526  _Inout_ PCTX_STREAM_CONTEXT StreamContext
527  )
528 /*++
529 
530 Routine Description:
531 
532  This routine updates the name of the target in the supplied stream context
533 
534 Arguments:
535 
536  DirectoryName - Supplies the directory name
537  StreamContext - Returns the updated name in the stream context
538 
539 Return Value:
540 
541  Status
542 
543 Note:
544 
545  The caller must synchronize access to the context. This routine does no
546  synchronization
547 
548 --*/
549 {
550  NTSTATUS status;
551 
552  PAGED_CODE();
553 
554  //
555  // Free any existing name
556  //
557 
558  if (StreamContext->FileName.Buffer != NULL) {
559 
560  CtxFreeUnicodeString(&StreamContext->FileName);
561  }
562 
563 
564  //
565  // Allocate and copy off the directory name
566  //
567 
568  StreamContext->FileName.MaximumLength = DirectoryName->Length;
569  status = CtxAllocateUnicodeString(&StreamContext->FileName);
570  if (NT_SUCCESS(status)) {
571 
572  RtlCopyUnicodeString(&StreamContext->FileName, DirectoryName);
573  }
574 
575  return status;
576 }
577 
578 
579 
580 
581 NTSTATUS
583  _In_ PFLT_CALLBACK_DATA Cbd,
584  _In_ BOOLEAN ReplaceIfExists,
585  _Outptr_ PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext,
586  _Out_opt_ PBOOLEAN ContextReplaced
587  )
588 /*++
589 
590 Routine Description:
591 
592  This routine creates a stream handle context for the target stream
593  handle. Optionally, if the context already exists, this routine
594  replaces it with the new context and releases the old context
595 
596 Arguments:
597 
598  Cbd - Supplies a pointer to the callbackData which
599  declares the requested operation.
600  ReplaceIfExists - Supplies if the stream handle context must be
601  replaced if already present
602  StreamContext - Returns the stream context
603  ContextReplaced - Returns if an existing context was replaced
604 
605 Return Value:
606 
607  Status
608 
609 --*/
610 {
611  NTSTATUS status;
612  PCTX_STREAMHANDLE_CONTEXT streamHandleContext;
613  PCTX_STREAMHANDLE_CONTEXT oldStreamHandleContext;
614 
615  PAGED_CODE();
616 
617  *StreamHandleContext = NULL;
618  if (ContextReplaced != NULL) *ContextReplaced = FALSE;
619 
620  //
621  // Create a stream context
622  //
623 
624  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
625  ("[Ctx]: Creating stream handle context (FileObject = %p, Instance = %p)\n",
626  Cbd->Iopb->TargetFileObject,
627  Cbd->Iopb->TargetInstance) );
628 
629  status = CtxCreateStreamHandleContext( &streamHandleContext );
630 
631  if (!NT_SUCCESS( status )) {
632 
633  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
634  ("[Ctx]: Failed to create stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
635  status,
636  Cbd->Iopb->TargetFileObject,
637  Cbd->Iopb->TargetInstance) );
638 
639  return status;
640  }
641 
642  //
643  // Set the new context we just allocated on the file object
644  //
645 
646  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
647  ("[Ctx]: Setting stream context %p (FileObject = %p, Instance = %p, ReplaceIfExists = %x)\n",
648  streamHandleContext,
649  Cbd->Iopb->TargetFileObject,
650  Cbd->Iopb->TargetInstance,
651  ReplaceIfExists) );
652 
653  status = FltSetStreamHandleContext( Cbd->Iopb->TargetInstance,
654  Cbd->Iopb->TargetFileObject,
655  ReplaceIfExists ? FLT_SET_CONTEXT_REPLACE_IF_EXISTS : FLT_SET_CONTEXT_KEEP_IF_EXISTS,
656  streamHandleContext,
657  &oldStreamHandleContext );
658 
659  if (!NT_SUCCESS( status )) {
660 
661  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
662  ("[Ctx]: Failed to set stream handle context with status 0x%x. (FileObject = %p, Instance = %p)\n",
663  status,
664  Cbd->Iopb->TargetFileObject,
665  Cbd->Iopb->TargetInstance) );
666 
667  //
668  // We release the context here because FltSetStreamContext failed
669  //
670  // If FltSetStreamContext succeeded then the context will be returned
671  // to the caller. The caller will use the context and then release it
672  // when he is done with the context.
673  //
674 
675  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
676  ("[Ctx]: Releasing stream handle context %p (FileObject = %p, Instance = %p)\n",
677  streamHandleContext,
678  Cbd->Iopb->TargetFileObject,
679  Cbd->Iopb->TargetInstance) );
680 
681  FltReleaseContext( streamHandleContext );
682 
683  if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
684 
685  //
686  // FltSetStreamContext failed for a reason other than the context already
687  // existing on the stream. So the object now does not have any context set
688  // on it. So we return failure to the caller.
689  //
690 
691  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
692  ("[Ctx]: Failed to set stream context with status 0x%x != STATUS_FLT_CONTEXT_ALREADY_DEFINED. (FileObject = %p, Instance = %p)\n",
693  status,
694  Cbd->Iopb->TargetFileObject,
695  Cbd->Iopb->TargetInstance) );
696 
697  return status;
698  }
699 
700  //
701  // We will reach here only if we have failed with STATUS_FLT_CONTEXT_ALREADY_DEFINED
702  // and we can fail with that code only if the context already exists and we have used
703  // the FLT_SET_CONTEXT_KEEP_IF_EXISTS flag
704 
705  FLT_ASSERT( ReplaceIfExists == FALSE );
706 
707  //
708  // Race condition. Someone has set a context after we queried it.
709  // Use the already set context instead
710  //
711 
712  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
713  ("[Ctx]: Stream context already defined. Retaining old stream context %p (FileObject = %p, Instance = %p)\n",
714  oldStreamHandleContext,
715  Cbd->Iopb->TargetFileObject,
716  Cbd->Iopb->TargetInstance) );
717 
718  //
719  // Return the existing context. Note that the new context that we allocated has already been
720  // realeased above.
721  //
722 
723  streamHandleContext = oldStreamHandleContext;
724  status = STATUS_SUCCESS;
725 
726  } else {
727 
728  //
729  // FltSetStreamContext has suceeded. The new context will be returned
730  // to the caller. The caller will use the context and then release it
731  // when he is done with the context.
732  //
733  // However, if we have replaced an existing context then we need to
734  // release the old context so as to decrement the ref count on it.
735  //
736  // Note that the memory allocated to the objects within the context
737  // will be freed in the context cleanup and must not be done here.
738  //
739 
740  if ( ReplaceIfExists &&
741  oldStreamHandleContext != NULL) {
742 
743  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
744  ("[Ctx]: Releasing old stream handle context %p (FileObject = %p, Instance = %p)\n",
745  oldStreamHandleContext,
746  Cbd->Iopb->TargetFileObject,
747  Cbd->Iopb->TargetInstance) );
748 
749  FltReleaseContext( oldStreamHandleContext );
750  if (ContextReplaced != NULL) *ContextReplaced = TRUE;
751  }
752  }
753 
754  *StreamHandleContext = streamHandleContext;
755 
756  return status;
757 }
758 
759 
760 
761 
762 
763 NTSTATUS
765  _Outptr_ PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext
766  )
767 /*++
768 
769 Routine Description:
770 
771  This routine creates a new stream context
772 
773 Arguments:
774 
775  StreamContext - Returns the stream context
776 
777 Return Value:
778 
779  Status
780 
781 --*/
782 {
783  NTSTATUS status;
784  PCTX_STREAMHANDLE_CONTEXT streamHandleContext;
785 
786  PAGED_CODE();
787 
788  //
789  // Allocate a stream context
790  //
791 
792  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
793  ("[Ctx]: Allocating stream handle context \n") );
794 
795  status = FltAllocateContext( Globals.Filter,
796  FLT_STREAMHANDLE_CONTEXT,
798  PagedPool,
799  &streamHandleContext );
800 
801  if (!NT_SUCCESS( status )) {
802 
803  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
804  ("[Ctx]: Failed to allocate stream handle context with status 0x%x \n",
805  status) );
806 
807  return status;
808  }
809 
810  //
811  // Initialize the newly created context
812  //
813 
814  RtlZeroMemory( streamHandleContext, CTX_STREAMHANDLE_CONTEXT_SIZE );
815 
816  streamHandleContext->Resource = CtxAllocateResource();
817  if(streamHandleContext->Resource == NULL) {
818 
819  FltReleaseContext( streamHandleContext );
820  return STATUS_INSUFFICIENT_RESOURCES;
821  }
822  ExInitializeResourceLite( streamHandleContext->Resource );
823 
824  *StreamHandleContext = streamHandleContext;
825 
826  return STATUS_SUCCESS;
827 }
828 
829 
830 
831 NTSTATUS
833  _In_ PUNICODE_STRING DirectoryName,
834  _Inout_ PCTX_STREAMHANDLE_CONTEXT StreamHandleContext
835  )
836 /*++
837 
838 Routine Description:
839 
840  This routine updates the name of the target in the supplied stream handle context
841 
842 Arguments:
843 
844  DirectoryName - Supplies the directory name
845  StreamHandleContext - Returns the updated name in the stream context
846 
847 Return Value:
848 
849  Status
850 
851 Note:
852 
853  The caller must synchronize access to the context. This routine does no
854  synchronization
855 
856 --*/
857 {
858  NTSTATUS status;
859 
860  PAGED_CODE();
861 
862  //
863  // Free any existing name
864  //
865 
866  if (StreamHandleContext->FileName.Buffer != NULL) {
867 
868  CtxFreeUnicodeString(&StreamHandleContext->FileName);
869  }
870 
871 
872  //
873  // Allocate and copy off the directory name
874  //
875 
876  StreamHandleContext->FileName.MaximumLength = DirectoryName->Length;
877  status = CtxAllocateUnicodeString(&StreamHandleContext->FileName);
878  if (NT_SUCCESS(status)) {
879 
880  RtlCopyUnicodeString(&StreamHandleContext->FileName, DirectoryName);
881  }
882 
883  return status;
884 }
885 
NTSTATUS CtxFindOrCreateFileContext(_In_ PFLT_CALLBACK_DATA Cbd, _In_ BOOLEAN CreateIfNotFound, _When_(CreateIfNotFound !=FALSE, _In_) _When_(CreateIfNotFound==FALSE, _In_opt_) PUNICODE_STRING FileName, _Outptr_ PCTX_FILE_CONTEXT *FileContext, _Out_opt_ PBOOLEAN ContextCreated)
Definition: ctx/context.c:41
#define CTX_STREAMHANDLE_CONTEXT_SIZE
Definition: CtxStruc.h:178
#define DebugTrace(Level, Data)
Definition: cancelSafe.c:36
_When_(Data==NULL, _Pre_satisfies_(FileObject !=NULL &&Instance !=NULL)) _When_(FileObject
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
return TRUE
AV_SCANNER_GLOBAL_DATA Globals
Definition: avscan.h:152
NTSTATUS CtxCreateStreamContext(_Outptr_ PCTX_STREAM_CONTEXT *StreamContext)
Definition: ctx/context.c:458
NTSTATUS CtxCreateStreamHandleContext(_Outptr_ PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext)
Definition: ctx/context.c:764
NTSTATUS CtxCreateFileContext(_In_ PUNICODE_STRING FileName, _Outptr_ PCTX_FILE_CONTEXT *FileContext)
Definition: ctx/context.c:215
PFLT_FILTER Filter
Definition: avscan.h:86
PERESOURCE Resource
Definition: CtxStruc.h:150
NTSTATUS CtxUpdateNameInStreamHandleContext(_In_ PUNICODE_STRING DirectoryName, _Inout_ PCTX_STREAMHANDLE_CONTEXT StreamHandleContext)
Definition: ctx/context.c:832
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
FORCEINLINE PERESOURCE CtxAllocateResource(VOID)
Definition: CtxProc.h:159
#define CTX_STREAM_CONTEXT_SIZE
Definition: CtxStruc.h:154
UNICODE_STRING FileName
Definition: CtxStruc.h:101
NTSTATUS CtxFindOrCreateStreamContext(_In_ PFLT_CALLBACK_DATA Cbd, _In_ BOOLEAN CreateIfNotFound, _Outptr_ PCTX_STREAM_CONTEXT *StreamContext, _Out_opt_ PBOOLEAN ContextCreated)
Definition: ctx/context.c:284
PAGED_CODE()
#define CTX_FILE_CONTEXT_SIZE
Definition: CtxStruc.h:112
NTSTATUS CtxCreateOrReplaceStreamHandleContext(_In_ PFLT_CALLBACK_DATA Cbd, _In_ BOOLEAN ReplaceIfExists, _Outptr_ PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext, _Out_opt_ PBOOLEAN ContextReplaced)
Definition: ctx/context.c:582
NTSTATUS CtxUpdateNameInStreamContext(_In_ PUNICODE_STRING DirectoryName, _Inout_ PCTX_STREAM_CONTEXT StreamContext)
Definition: ctx/context.c:524

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