WDK Mini Filter Example
ctx/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  context sample
13 
14 
15 Environment:
16 
17  Kernel mode
18 
19 
20 --*/
21 
22 #include "pch.h"
23 
24 
25 //
26 // Assign text sections for each routine.
27 //
28 
29 #ifdef ALLOC_PRAGMA
30 #pragma alloc_text(PAGE, CtxPreCreate)
31 #pragma alloc_text(PAGE, CtxPostCreate)
32 #pragma alloc_text(PAGE, CtxPreCleanup)
33 #pragma alloc_text(PAGE, CtxPreClose)
34 #pragma alloc_text(PAGE, CtxPreSetInfo)
35 #pragma alloc_text(PAGE, CtxPostSetInfo)
36 #endif
37 
38 
39 FLT_PREOP_CALLBACK_STATUS
41  _Inout_ PFLT_CALLBACK_DATA Cbd,
42  _In_ PCFLT_RELATED_OBJECTS FltObjects,
43  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
44  )
45 {
47  UNREFERENCED_PARAMETER( FltObjects );
48  UNREFERENCED_PARAMETER( CompletionContext );
49 
50  PAGED_CODE();
51 
52  DebugTrace( DEBUG_TRACE_ALL_IO,
53  ("[Ctx]: CtxPreCreate -> Enter (Cbd = %p, FileObject = %p)\n",
54  Cbd,
55  FltObjects->FileObject) );
56 
57 
58  DebugTrace( DEBUG_TRACE_ALL_IO,
59  ("[Ctx]: CtxPreCreate -> Exit (Cbd = %p, FileObject = %p)\n",
60  Cbd,
61  FltObjects->FileObject) );
62 
63  //
64  // Force a post-op callback so we can add our contexts to the opened
65  // objects
66  //
67 
68  return FLT_PREOP_SUCCESS_WITH_CALLBACK;
69 
70 }
71 
72 
73 FLT_POSTOP_CALLBACK_STATUS
75  _Inout_ PFLT_CALLBACK_DATA Cbd,
76  _In_ PCFLT_RELATED_OBJECTS FltObjects,
77  _Inout_opt_ PVOID CbdContext,
78  _In_ FLT_POST_OPERATION_FLAGS Flags
79  )
80 {
81 
82  PCTX_FILE_CONTEXT fileContext = NULL;
83  PCTX_STREAM_CONTEXT streamContext = NULL;
84  PCTX_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
85  PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
86  UNICODE_STRING fileName;
87 
88  NTSTATUS status;
89  BOOLEAN fileContextCreated, streamContextCreated, streamHandleContextReplaced;
90 
91 
92  UNREFERENCED_PARAMETER( FltObjects );
93  UNREFERENCED_PARAMETER( Flags );
94  UNREFERENCED_PARAMETER( CbdContext );
95 
96  PAGED_CODE();
97 
98  DebugTrace( DEBUG_TRACE_ALL_IO,
99  ("[Ctx]: CtxPostCreate -> Enter (Cbd = %p, FileObject = %p)\n",
100  Cbd,
101  FltObjects->FileObject) );
102 
103  //
104  // Initialize defaults
105  //
106 
107  status = STATUS_SUCCESS;
108 
109  //
110  // If the Create has failed, do nothing
111  //
112 
113  if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
114 
115  goto CtxPostCreateCleanup;
116  }
117 
118 
119  //
120  // Get the file name
121  //
122 
123  status = FltGetFileNameInformation( Cbd,
124  FLT_FILE_NAME_NORMALIZED |
125  FLT_FILE_NAME_QUERY_DEFAULT,
126  &nameInfo );
127 
128  if (!NT_SUCCESS( status )) {
129 
130  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
131  ("[Ctx]: CtxPostCreate -> Failed to get name information (Cbd = %p, FileObject = %p)\n",
132  Cbd,
133  FltObjects->FileObject) );
134 
135  goto CtxPostCreateCleanup;
136  }
137 
138 
139  //
140  // Find or create a stream context
141  //
142 
143  status = CtxFindOrCreateStreamContext(Cbd,
144  TRUE,
145  &streamContext,
146  &streamContextCreated);
147  if (!NT_SUCCESS( status )) {
148 
149  //
150  // This failure will most likely be because stream contexts are not supported
151  // on the object we are trying to assign a context to or the object is being
152  // deleted
153  //
154 
155  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
156  ("[Ctx]: CtxPostCreate -> Failed to find or create stream context (Cbd = %p, FileObject = %p)\n",
157  Cbd,
158  FltObjects->FileObject) );
159 
160  goto CtxPostCreateCleanup;
161  }
162 
163  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
164  ("[Ctx]: CtxPostCreate -> Getting/Creating stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
165  &nameInfo->Name,
166  Cbd,
167  FltObjects->FileObject,
168  streamContext,
169  streamContextCreated) );
170 
171  //
172  // Acquire write acccess to the context
173  //
174 
175  CtxAcquireResourceExclusive(streamContext->Resource);
176 
177  //
178  // Increment the create count
179  //
180 
181  streamContext->CreateCount++;
182 
183  //
184  // Update the file name in the context
185  //
186 
187  status = CtxUpdateNameInStreamContext( &nameInfo->Name,
188  streamContext);
189 
190 
191  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
192  ("[Ctx]: CtxPostCreate -> Stream context info for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
193  &nameInfo->Name,
194  Cbd,
195  FltObjects->FileObject,
196  streamContext,
197  &streamContext->FileName,
198  streamContext->CreateCount,
199  streamContext->CleanupCount,
200  streamContext->CloseCount) );
201 
202  //
203  // Relinquish write acccess to the context
204  //
205 
206  CtxReleaseResource(streamContext->Resource);
207 
208  //
209  // Quit on failure after we have given up
210  // the resource
211  //
212 
213  if (!NT_SUCCESS( status )) {
214 
215  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
216  ("[Ctx]: CtxPostCreate -> Failed to update name in stream context for file %wZ (Cbd = %p, FileObject = %p)\n",
217  &nameInfo->Name,
218  Cbd,
219  FltObjects->FileObject) );
220 
221  goto CtxPostCreateCleanup;
222  }
223 
224 
225 
226  //
227  // Create or replace a stream handle context
228  //
229 
231  TRUE,
232  &streamHandleContext,
233  &streamHandleContextReplaced);
234  if (!NT_SUCCESS( status )) {
235 
236  //
237  // This failure will most likely be because stream contexts are not supported
238  // on the object we are trying to assign a context to or the object is being
239  // deleted
240  //
241 
242  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
243  ("[Ctx]: CtxPostCreate -> Failed to find or create stream handle context (Cbd = %p, FileObject = %p)\n",
244  Cbd,
245  FltObjects->FileObject) );
246 
247  goto CtxPostCreateCleanup;
248  }
249 
250  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
251  ("[Ctx]: CtxPostCreate -> Creating/Replacing stream handle context for file %wZ (Cbd = %p, FileObject = %p StreamHandleContext = %p, StreamHandleContextReplaced = %x)\n",
252  &nameInfo->Name,
253  Cbd,
254  FltObjects->FileObject,
255  streamHandleContext,
256  streamHandleContextReplaced) );
257 
258  //
259  // Acquire write acccess to the context
260  //
261 
262  CtxAcquireResourceExclusive( streamHandleContext->Resource );
263 
264  //
265  // Update the file name in the context
266  //
267 
268  status = CtxUpdateNameInStreamHandleContext( &nameInfo->Name,
269  streamHandleContext);
270 
271  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
272  ("[Ctx]: CtxPostCreate -> Stream handle context info for file %wZ (Cbd = %p, FileObject = %p, StreamHandleContext = %p) \n\tName = %wZ\n",
273  &nameInfo->Name,
274  Cbd,
275  FltObjects->FileObject,
276  streamHandleContext,
277  &streamHandleContext->FileName) );
278 
279  //
280  // Relinquish write acccess to the context
281  //
282 
283  CtxReleaseResource(streamHandleContext->Resource);
284 
285  //
286  // Quit on failure after we have given up
287  // the resource
288  //
289 
290  if (!NT_SUCCESS( status )) {
291 
292  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
293  ("[Ctx]: CtxPostCreate -> Failed to update name in stream handle context for file %wZ (Cbd = %p, FileObject = %p)\n",
294  &nameInfo->Name,
295  Cbd,
296  FltObjects->FileObject) );
297 
298  goto CtxPostCreateCleanup;
299  }
300 
301  //
302  // After FltParseFileNameInformation, nameInfo->Name also
303  // contains the stream name. We need only the filename and do
304  // not want to include the stream name in the file context
305  //
306 
307  fileName.Buffer = nameInfo->Name.Buffer;
308  fileName.Length = nameInfo->Name.Length - nameInfo->Stream.Length;
309  fileName.MaximumLength = fileName.Length;
310 
311  //
312  // Find or create a file context
313  //
314 
315  status = CtxFindOrCreateFileContext( Cbd,
316  TRUE,
317  &fileName,
318  &fileContext,
319  &fileContextCreated);
320  if (!NT_SUCCESS( status )) {
321 
322  //
323  // This failure will most likely be because file contexts are not supported
324  // on the object we are trying to assign a context to or the object is being
325  // deleted
326  //
327 
328  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
329  ("[Ctx]: CtxPostCreate -> Failed to find or create file context (Cbd = %p, FileObject = %p)\n",
330  Cbd,
331  FltObjects->FileObject) );
332 
333  goto CtxPostCreateCleanup;
334  }
335 
336  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
337  ("[Ctx]: CtxPostCreate -> Getting/Creating file context for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p. FileContextCreated = %x)\n",
338  &nameInfo->Name,
339  Cbd,
340  FltObjects->FileObject,
341  fileContext,
342  fileContextCreated) );
343 
344 
345  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
346  ("[Ctx]: CtxPostCreate -> File context info for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p) \n\tName = %wZ\n",
347  &nameInfo->Name,
348  Cbd,
349  FltObjects->FileObject,
350  fileContext,
351  &fileContext->FileName) );
352 
353 
354 CtxPostCreateCleanup:
355 
356 
357  //
358  // Release the references we have acquired
359  //
360 
361  if (nameInfo != NULL) {
362 
363  FltReleaseFileNameInformation( nameInfo );
364  }
365 
366  if (fileContext != NULL) {
367 
368  FltReleaseContext( fileContext );
369  }
370 
371  if (streamContext != NULL) {
372 
373  FltReleaseContext( streamContext );
374  }
375 
376  if (streamHandleContext != NULL) {
377 
378  FltReleaseContext( streamHandleContext );
379  }
380 
381  if (!NT_SUCCESS( status )) {
382 
383  DebugTrace( DEBUG_TRACE_ERROR,
384  ("[Ctx]: CtxPostCreate -> Failed with status 0x%x \n",
385  status) );
386 
387  //
388  // It doesn't make sense to udate Cbd->IoStatus.Status on failure since the
389  // file system has successfully completed the operation
390  //
391 
392  }
393 
394 
395  DebugTrace( DEBUG_TRACE_ALL_IO,
396  ("[Ctx]: CtxPostCreate -> Exit (Cbd = %p, FileObject = %p, Status = 0x%x)\n",
397  Cbd,
398  FltObjects->FileObject,
399  Cbd->IoStatus.Status) );
400 
401  return FLT_POSTOP_FINISHED_PROCESSING;
402 }
403 
404 
405 FLT_PREOP_CALLBACK_STATUS
407  _Inout_ PFLT_CALLBACK_DATA Cbd,
408  _In_ PCFLT_RELATED_OBJECTS FltObjects,
409  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
410  )
411 {
412 
413  PCTX_STREAM_CONTEXT streamContext = NULL;
414  NTSTATUS status;
415  BOOLEAN streamContextCreated;
416 
417  UNREFERENCED_PARAMETER( FltObjects );
418  UNREFERENCED_PARAMETER( CompletionContext );
419 
420  PAGED_CODE();
421 
422  DebugTrace( DEBUG_TRACE_ALL_IO,
423  ("[Ctx]: CtxPreCleanup -> Enter (Cbd = %p, FileObject = %p)\n",
424  Cbd,
425  FltObjects->FileObject) );
426 
427  //
428  // Get the stream context
429  //
430 
431  status = CtxFindOrCreateStreamContext(Cbd,
432  FALSE, // do not create if one does not exist
433  &streamContext,
434  &streamContextCreated);
435  if (!NT_SUCCESS( status )) {
436 
437  //
438  // This failure will most likely be because stream contexts are not supported
439  // on the object we are trying to assign a context to or the object is being
440  // deleted
441  //
442 
443  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
444  ("[Ctx]: CtxPreCleanup -> Failed to find stream context (Cbd = %p, FileObject = %p)\n",
445  Cbd,
446  FltObjects->FileObject) );
447 
448  goto CtxPreCleanupCleanup;
449  }
450 
451  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
452  ("[Ctx]: CtxPreCleanup -> Getting stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
453  Cbd,
454  FltObjects->FileObject,
455  streamContext,
456  streamContextCreated) );
457 
458  //
459  // Acquire write acccess to the context
460  //
461 
462  CtxAcquireResourceExclusive(streamContext->Resource);
463 
464 
465  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
466  ("[Ctx]: CtxPreCleanup -> Old info in stream context for file(Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
467  Cbd,
468  FltObjects->FileObject,
469  streamContext,
470  &streamContext->FileName,
471  streamContext->CreateCount,
472  streamContext->CleanupCount,
473  streamContext->CloseCount) );
474 
475 
476 
477  //
478  // Update the cleanup count in the context
479  //
480 
481  streamContext->CleanupCount++;
482 
483 
484  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
485  ("[Ctx]: CtxPreCleanup -> New info in stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
486  Cbd,
487  FltObjects->FileObject,
488  streamContext,
489  &streamContext->FileName,
490  streamContext->CreateCount,
491  streamContext->CleanupCount,
492  streamContext->CloseCount) );
493 
494  //
495  // Relinquish write acccess to the context
496  //
497 
498  CtxReleaseResource(streamContext->Resource);
499 
500 
501 CtxPreCleanupCleanup:
502 
503  //
504  // Release the references we have acquired
505  //
506 
507  if (streamContext != NULL) {
508 
509  FltReleaseContext( streamContext );
510  }
511 
512  DebugTrace( DEBUG_TRACE_ALL_IO,
513  ("[Ctx]: CtxPreCleanup -> Exit (Cbd = %p, FileObject = %p)\n",
514  Cbd,
515  FltObjects->FileObject) );
516 
517  //
518  // It doesn't make sense to fail the cleanup - so ignore any errors we may
519  // encounter and return success
520  //
521 
522  return FLT_PREOP_SUCCESS_NO_CALLBACK;
523 }
524 
525 
526 
527 
528 
529 FLT_PREOP_CALLBACK_STATUS
531  _Inout_ PFLT_CALLBACK_DATA Cbd,
532  _In_ PCFLT_RELATED_OBJECTS FltObjects,
533  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
534  )
535 {
536 
537  PCTX_STREAM_CONTEXT streamContext = NULL;
538  NTSTATUS status;
539  BOOLEAN streamContextCreated;
540 
541  UNREFERENCED_PARAMETER( FltObjects );
542  UNREFERENCED_PARAMETER( CompletionContext );
543 
544  PAGED_CODE();
545 
546  DebugTrace( DEBUG_TRACE_ALL_IO,
547  ("[Ctx]: CtxPreClose -> Enter (Cbd = %p, FileObject = %p)\n",
548  Cbd,
549  FltObjects->FileObject) );
550 
551  //
552  // Get the stream context
553  //
554 
555  status = CtxFindOrCreateStreamContext(Cbd,
556  FALSE, // do not create if one does not exist
557  &streamContext,
558  &streamContextCreated);
559  if (!NT_SUCCESS( status )) {
560 
561  //
562  // This failure will most likely be because stream contexts are not supported
563  // on the object we are trying to assign a context to or the object is being
564  // deleted
565  //
566 
567  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
568  ("[Ctx]: CtxPreClose -> Failed to find stream context (Cbd = %p, FileObject = %p)\n",
569  Cbd,
570  FltObjects->FileObject) );
571 
572  goto CtxPreCloseCleanup;
573  }
574 
575  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
576  ("[Ctx]: CtxPreClose -> Getting stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
577  Cbd,
578  FltObjects->FileObject,
579  streamContext,
580  streamContextCreated) );
581 
582  //
583  // Acquire write acccess to the context
584  //
585 
586  CtxAcquireResourceExclusive(streamContext->Resource);
587 
588 
589  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
590  ("[Ctx]: CtxPreClose -> Old info in stream context for file(Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
591  Cbd,
592  FltObjects->FileObject,
593  streamContext,
594  &streamContext->FileName,
595  streamContext->CreateCount,
596  streamContext->CleanupCount,
597  streamContext->CloseCount) );
598 
599  //
600  // Update the close count in the context
601  //
602 
603  streamContext->CloseCount++;
604 
605 
606  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
607  ("[Ctx]: CtxPreClose -> New info in stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
608  Cbd,
609  FltObjects->FileObject,
610  streamContext,
611  &streamContext->FileName,
612  streamContext->CreateCount,
613  streamContext->CleanupCount,
614  streamContext->CloseCount) );
615 
616  //
617  // Relinquish write acccess to the context
618  //
619 
620  CtxReleaseResource(streamContext->Resource);
621 
622 
623 CtxPreCloseCleanup:
624 
625  //
626  // Release the references we have acquired
627  //
628 
629  if (streamContext != NULL) {
630 
631  FltReleaseContext( streamContext );
632  }
633 
634 
635  DebugTrace( DEBUG_TRACE_ALL_IO,
636  ("[Ctx]: CtxPreClose -> Exit (Cbd = %p, FileObject = %p)\n",
637  Cbd,
638  FltObjects->FileObject) );
639 
640  //
641  // It doesn't make sense to fail the cleanup - so ignore any errors we may
642  // encounter and return success
643  //
644 
645  return FLT_PREOP_SUCCESS_NO_CALLBACK;
646 }
647 
648 
649 FLT_PREOP_CALLBACK_STATUS
651  _Inout_ PFLT_CALLBACK_DATA Cbd,
652  _In_ PCFLT_RELATED_OBJECTS FltObjects,
653  _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
654  )
655 {
656  FILE_INFORMATION_CLASS fileInformationClass;
657  FLT_PREOP_CALLBACK_STATUS callbackStatus;
658 
659  UNREFERENCED_PARAMETER( FltObjects );
660  UNREFERENCED_PARAMETER( CompletionContext );
661 
662  PAGED_CODE();
663 
664  DebugTrace( DEBUG_TRACE_ALL_IO,
665  ("[Ctx]: CtxPreSetInfo -> Enter (Cbd = %p, FileObject = %p)\n",
666  Cbd,
667  FltObjects->FileObject) );
668 
669  callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; // pass through - default is no post op callback
670 
671  fileInformationClass = Cbd->Iopb->Parameters.SetFileInformation.FileInformationClass;
672 
673  //
674  // Ignore the ops we do not care about
675  //
676 
677  if ((fileInformationClass != FileRenameInformation) &&
678  (fileInformationClass != FileRenameInformationEx)) {
679 
680  DebugTrace( DEBUG_TRACE_ALL_IO,
681  ("[Ctx]: CtxPreSetInfo -> Ignoring SetInfo operations other than FileRenameInformation/FileRenameInformationEx (Cbd = %p, FileObject = %p)\n",
682  Cbd,
683  FltObjects->FileObject) );
684 
685  goto CtxPreSetInfoCleanup;
686  }
687 
688  //
689  // We want to process renames in the post-op callback
690  //
691 
692  callbackStatus = FLT_PREOP_SYNCHRONIZE;
693 
694 
695 CtxPreSetInfoCleanup:
696 
697 
698  DebugTrace( DEBUG_TRACE_ALL_IO,
699  ("[Ctx]: CtxPreSetInfo -> Exit (Cbd = %p, FileObject = %p)\n",
700  Cbd,
701  FltObjects->FileObject) );
702 
703  return callbackStatus;
704 
705 }
706 
707 
708 
709 
710 FLT_POSTOP_CALLBACK_STATUS
712  _Inout_ PFLT_CALLBACK_DATA Cbd,
713  _In_ PCFLT_RELATED_OBJECTS FltObjects,
714  _Inout_opt_ PVOID CbdContext,
715  _In_ FLT_POST_OPERATION_FLAGS Flags
716  )
717 {
718  PCTX_INSTANCE_CONTEXT instanceContext = NULL;
719  PCTX_FILE_CONTEXT fileContext = NULL;
720  PCTX_STREAM_CONTEXT streamContext = NULL;
721  PCTX_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
722  PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
723 
724  NTSTATUS status;
725  BOOLEAN streamContextCreated, fileContextCreated, streamHandleContextReplaced;
726 
727  UNREFERENCED_PARAMETER( Flags );
728  UNREFERENCED_PARAMETER( FltObjects );
729  UNREFERENCED_PARAMETER( CbdContext );
730 
731  //
732  // The pre-operation callback will return FLT_PREOP_SYNCHRONIZE if it needs a
733  // post operation callback. In this case, the Filter Manager will call the
734  // minifilter's post-operation callback in the context of the pre-operation
735  // thread, at IRQL <= APC_LEVEL. This allows the post-operation code to be
736  // pagable and also allows it to access paged data
737  //
738 
739  PAGED_CODE();
740 
741  DebugTrace( DEBUG_TRACE_ALL_IO,
742  ("[Ctx]: CtxPostSetInfo -> Enter (Cbd = %p, FileObject = %p)\n",
743  Cbd,
744  FltObjects->FileObject) );
745 
746 
747  //
748  // Initialize defaults
749  //
750 
751  status = STATUS_SUCCESS;
752 
753  //
754  // If the SetInfo has failed, do nothing
755  //
756 
757  if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
758 
759  goto CtxPostSetInfoCleanup;
760  }
761 
762 
763  //
764  // Get the instance context for the target instance
765  //
766 
767  DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
768  ("[Ctx]: CtxPostSetInfo -> Trying to get instance context (TargetInstance = %p, Cbd = %p, FileObject = %p)\n",
769  Cbd->Iopb->TargetInstance,
770  Cbd,
771  FltObjects->FileObject) );
772 
773  status = FltGetInstanceContext( Cbd->Iopb->TargetInstance,
774  &instanceContext );
775  if (!NT_SUCCESS( status )) {
776 
777  DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
778  ("[Ctx]: CtxPostSetInfo -> Failed to get instance context (Cbd = %p, FileObject = %p)\n",
779  Cbd,
780  FltObjects->FileObject) );
781 
782  goto CtxPostSetInfoCleanup;
783  }
784 
785  DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
786  ("[Ctx]: CtxPostSetInfo -> Instance context info for volume %wZ (Cbd = %p, FileObject = %p, InstanceContext = %p) \n\tVolumeName = %wZ \n\tInstance = %p \n\tVolume = %p\n",
787  &instanceContext->VolumeName,
788  Cbd,
789  FltObjects->FileObject,
790  instanceContext,
791  &instanceContext->VolumeName,
792  &instanceContext->Instance,
793  &instanceContext->Volume) );
794 
795 
796  //
797  // Get the directory name
798  //
799 
800  status = FltGetFileNameInformation( Cbd,
801  FLT_FILE_NAME_NORMALIZED |
802  FLT_FILE_NAME_QUERY_DEFAULT,
803  &nameInfo );
804 
805  if (!NT_SUCCESS( status )) {
806 
807  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
808  ("[Ctx]: CtxPostSetInfo -> Failed to get file name information (Cbd = %p, FileObject = %p)\n",
809  Cbd,
810  FltObjects->FileObject) );
811 
812  goto CtxPostSetInfoCleanup;
813  }
814 
815 
816  //
817  // Get the stream context
818  //
819 
820  status = CtxFindOrCreateStreamContext(Cbd,
821  FALSE, // do not create if one does not exist
822  &streamContext,
823  &streamContextCreated);
824  if (!NT_SUCCESS( status )) {
825 
826  //
827  // This failure will most likely be because stream contexts are not supported
828  // on the object we are trying to assign a context to or the object is being
829  // deleted
830  //
831 
832  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
833  ("[Ctx]: CtxPostSetInfo -> Failed to find stream context (Cbd = %p, FileObject = %p)\n",
834  Cbd,
835  FltObjects->FileObject) );
836 
837  goto CtxPostSetInfoCleanup;
838  }
839 
840  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
841  ("[Ctx]: CtxPostSetInfo -> Getting stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
842  &nameInfo->Name,
843  Cbd,
844  FltObjects->FileObject,
845  streamContext,
846  streamContextCreated) );
847 
848  //
849  // Acquire write acccess to the context
850  //
851 
852  CtxAcquireResourceExclusive(streamContext->Resource);
853 
854 
855  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
856  ("[Ctx]: CtxPostSetInfo -> Old info in stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
857  &nameInfo->Name,
858  Cbd,
859  FltObjects->FileObject,
860  streamContext,
861  &streamContext->FileName,
862  streamContext->CreateCount,
863  streamContext->CleanupCount,
864  streamContext->CloseCount) );
865 
866 
867 
868  //
869  // Update the file name in the context
870  //
871 
872  status = CtxUpdateNameInStreamContext( &nameInfo->Name,
873  streamContext);
874 
875 
876  DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
877  ("[Ctx]: CtxPostSetInfo -> New info in stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
878  &nameInfo->Name,
879  Cbd,
880  FltObjects->FileObject,
881  streamContext,
882  &streamContext->FileName,
883  streamContext->CreateCount,
884  streamContext->CleanupCount,
885  streamContext->CloseCount) );
886 
887  //
888  // Relinquish write acccess to the context
889  //
890 
891  CtxReleaseResource(streamContext->Resource);
892 
893  //
894  // Quit on failure after we have given up
895  // the resource
896  //
897 
898  if (!NT_SUCCESS( status )) {
899 
900  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
901  ("[Ctx]: CtxPostSetInfo -> Failed to update name in stream context for file %wZ (Cbd = %p, FileObject = %p)\n",
902  &nameInfo->Name,
903  Cbd,
904  FltObjects->FileObject) );
905 
906  goto CtxPostSetInfoCleanup;
907  }
908 
909 
910 
911  //
912  // Create or replace a stream handle context
913  //
914 
916  TRUE,
917  &streamHandleContext,
918  &streamHandleContextReplaced);
919  if (!NT_SUCCESS( status )) {
920 
921  //
922  // This failure will most likely be because stream contexts are not supported
923  // on the object we are trying to assign a context to or the object is being
924  // deleted
925  //
926 
927  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
928  ("[Ctx]: CtxPostSetInfo -> Failed to find or create stream handle context (Cbd = %p, FileObject = %p)\n",
929  Cbd,
930  FltObjects->FileObject) );
931 
932  goto CtxPostSetInfoCleanup;
933  }
934 
935  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
936  ("[Ctx]: CtxPostSetInfo -> Creating/Replacing stream handle context for file %wZ (Cbd = %p, FileObject = %p StreamHandleContext = %p, StreamHandleContextReplaced = %x)\n",
937  &nameInfo->Name,
938  Cbd,
939  FltObjects->FileObject,
940  streamHandleContext,
941  streamHandleContextReplaced) );
942 
943  //
944  // Acquire write acccess to the context
945  //
946 
947  CtxAcquireResourceExclusive(streamHandleContext->Resource);
948 
949  //
950  // Update the file name in the context
951  //
952 
953  status = CtxUpdateNameInStreamHandleContext( &nameInfo->Name,
954  streamHandleContext);
955 
956  DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
957  ("[Ctx]: CtxPostSetInfo -> Stream handle context info for file %wZ (Cbd = %p, FileObject = %p, StreamHandleContext = %p) \n\tName = %wZ\n",
958  &nameInfo->Name,
959  Cbd,
960  FltObjects->FileObject,
961  streamHandleContext,
962  &streamHandleContext->FileName) );
963 
964  //
965  // Relinquish write acccess to the context
966  //
967 
968  CtxReleaseResource( streamHandleContext->Resource );
969 
970  //
971  // Quit on failure after we have given up
972  // the resource
973  //
974 
975  if (!NT_SUCCESS( status )) {
976 
977  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
978  ("[Ctx]: CtxPostSetInfo -> Failed to update name in stream handle context for file %wZ (Cbd = %p, FileObject = %p)\n",
979  &nameInfo->Name,
980  Cbd,
981  FltObjects->FileObject) );
982 
983  goto CtxPostSetInfoCleanup;
984  }
985 
986 
987  //
988  // Get the file context
989  //
990 
991  status = CtxFindOrCreateFileContext( Cbd,
992  FALSE, // do not create if one does not exist
993  NULL,
994  &fileContext,
995  &fileContextCreated);
996  if (!NT_SUCCESS( status )) {
997 
998  //
999  // This failure will most likely be because file contexts are not supported
1000  // on the object we are trying to assign a context to or the object is being
1001  // deleted
1002  //
1003 
1004  DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
1005  ("[Ctx]: CtxPostSetInfo -> Failed to find file context (Cbd = %p, FileObject = %p)\n",
1006  Cbd,
1007  FltObjects->FileObject) );
1008 
1009  goto CtxPostSetInfoCleanup;
1010  }
1011 
1012  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
1013  ("[Ctx]: CtxPostSetInfo -> Getting file context for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p. FileContextCreated = %x)\n",
1014  &nameInfo->Name,
1015  Cbd,
1016  FltObjects->FileObject,
1017  fileContext,
1018  fileContextCreated) );
1019 
1020  DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
1021  ("[Ctx]: CtxPostSetInfo -> File context info for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p) \n\tName = %wZ\n",
1022  &nameInfo->Name,
1023  Cbd,
1024  FltObjects->FileObject,
1025  fileContext,
1026  &fileContext->FileName) );
1027 
1028 
1029 CtxPostSetInfoCleanup:
1030 
1031 
1032  //
1033  // Release the references we have acquired
1034  //
1035 
1036  if (instanceContext != NULL) {
1037 
1038  FltReleaseContext( instanceContext );
1039  }
1040 
1041  if (fileContext != NULL) {
1042 
1043  FltReleaseContext( fileContext );
1044  }
1045 
1046  if (streamContext != NULL) {
1047 
1048  FltReleaseContext( streamContext );
1049  }
1050 
1051  if (streamHandleContext != NULL) {
1052 
1053  FltReleaseContext( streamHandleContext );
1054  }
1055 
1056  if (nameInfo != NULL) {
1057 
1058  FltReleaseFileNameInformation( nameInfo );
1059  }
1060 
1061  if (!NT_SUCCESS( status )) {
1062 
1063  DebugTrace( DEBUG_TRACE_ERROR,
1064  ("[Ctx]: CtxPostSetInfo -> Failed with status 0x%x \n",
1065  status) );
1066 
1067  //
1068  // It doesn't make sense to udate Cbd->IoStatus.Status on failure since the
1069  // file system has suceesfully completed the operation
1070  //
1071  }
1072 
1073  DebugTrace( DEBUG_TRACE_ALL_IO,
1074  ("[Ctx]: CtxPostSetInfo -> Exit (Cbd = %p, FileObject = %p)\n",
1075  Cbd,
1076  FltObjects->FileObject) );
1077 
1078  return FLT_POSTOP_FINISHED_PROCESSING;
1079 }
1080 
1081 
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
FLT_PREOP_CALLBACK_STATUS CtxPreCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
UNICODE_STRING FileName
Definition: CtxStruc.h:168
FLT_PREOP_CALLBACK_STATUS CtxPreCleanup(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
FLT_POSTOP_CALLBACK_STATUS CtxPostSetInfo(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Inout_opt_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)
#define DebugTrace(Level, Data)
Definition: cancelSafe.c:36
return TRUE
FLT_PREOP_CALLBACK_STATUS CtxPreClose(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
PFLT_VOLUME Volume
Definition: CtxStruc.h:78
PERESOURCE Resource
Definition: CtxStruc.h:150
UNREFERENCED_PARAMETER(FileObject)
NTSTATUS CtxUpdateNameInStreamHandleContext(_In_ PUNICODE_STRING DirectoryName, _Inout_ PCTX_STREAMHANDLE_CONTEXT StreamHandleContext)
Definition: ctx/context.c:832
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
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
UNICODE_STRING VolumeName
Definition: CtxStruc.h:84
PAGED_CODE()
FLT_PREOP_CALLBACK_STATUS CtxPreSetInfo(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
PFLT_INSTANCE Instance
Definition: CtxStruc.h:72
UNICODE_STRING FileName
Definition: CtxStruc.h:126
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
FLT_POSTOP_CALLBACK_STATUS CtxPostCreate(_Inout_ PFLT_CALLBACK_DATA Cbd, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Inout_opt_ PVOID CbdContext, _In_ FLT_POST_OPERATION_FLAGS Flags)

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