WDK Mini Filter Example
nccontext.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1999 - 2002 Microsoft Corporation
4 
5 Module Name:
6 
7  nccontext.c
8 
9 Abstract:
10 
11  Contains routines to manage the lifetime of instance contexts and
12  stream handle contexts. This file performs context-wide setup
13  and teardown, with callouts for specific functions to perform their
14  own setup and teardown.
15 
16 Environment:
17 
18  Kernel mode
19 
20 --*/
21 
22 #include "nc.h"
23 
24 #ifdef ALLOC_PRAGMA
25 #pragma alloc_text(PAGE, NcInstanceContextClose)
26 #pragma alloc_text(PAGE, NcStreamHandleContextAllocAndAttach)
27 #pragma alloc_text(PAGE, NcStreamHandleContextClose)
28 #endif
29 
30 VOID
32  _In_ PFLT_CONTEXT Context,
33  _In_ FLT_CONTEXT_TYPE ContextType
34  )
35 /*++
36 
37 Routine Description:
38 
39  This routine is used to tear down and remove an instance context.
40 
41 Arguments:
42 
43  Context - The context to destroy.
44 
45  ContextType - The type of the context. Since this function is specific
46  to instance contexts, we expect this to always be the instance
47  context type.
48 
49 Return Value:
50 
51  None.
52 
53 --*/
54 {
55  PNC_INSTANCE_CONTEXT InstanceContext = (PNC_INSTANCE_CONTEXT) Context;
56  PAGED_CODE();
57 
58  UNREFERENCED_PARAMETER( ContextType );
59  FLT_ASSERT( ContextType == FLT_INSTANCE_CONTEXT );
60 
61  NcTeardownMapping( &InstanceContext->Mapping );
62 }
63 
64 VOID
66  _In_ PFLT_CONTEXT Context,
67  _In_ FLT_CONTEXT_TYPE ContextType
68  )
69 /*++
70 
71 Routine Description:
72 
73  This routine is used to tear down and remove a stream handle context.
74 
75 Arguments:
76 
77  Context - The context to destroy.
78 
79  ContextType - The type of the context. Since this function is specific
80  to stream handle contexts, we expect this to always be the stream
81  handle context type.
82 
83 Return Value:
84 
85  None.
86 
87 --*/
88 {
89  PNC_STREAM_HANDLE_CONTEXT StreamContext = (PNC_STREAM_HANDLE_CONTEXT) Context;
90 
91  PAGED_CODE();
92 
93  UNREFERENCED_PARAMETER( ContextType );
94  FLT_ASSERT( ContextType == FLT_STREAMHANDLE_CONTEXT );
95 
96  //
97  // Clean up notification context
98  //
99 
101 
102  //
103  // Clean up enumeration context
104  //
105 
107 
108  //
109  // Clean up find by SID context
110  //
111 
113 
114  //
115  // Clean up shared context information
116  //
117 
118  if (StreamContext->Lock != NULL) {
119 
120  NcFreeEResource( StreamContext->Lock );
121  StreamContext->Lock = NULL;
122  }
123 }
124 
125 NTSTATUS
127  _In_ PFLT_FILTER Filter,
128  _In_ PFLT_INSTANCE Instance,
129  _In_ PFILE_OBJECT FileObject,
130  _Out_ PNC_STREAM_HANDLE_CONTEXT * Context
131  )
132 /*++
133 
134 Routine Description:
135 
136  Allocates and initializes an empty stream handle context.
137 
138 Arguments:
139 
140  Filter - The filter we are going to attach with.
141 
142  Instance - The instance we are going to attach with.
143 
144  FileObject - File object we are going to attach to.
145 
146  Context - Pointer to a user allocated PNC_STREAM_HANDLE_CONTEXT.
147 
148 Return Value:
149 
150  On success, returns STATUS_SUCCESS and a pointer to the context in *Context.
151  Otherwise returns an error and NULL in *Context.
152 
153  The user must call FltReleaseContext to balance ref count.
154 
155 --*/
156 {
157  PNC_STREAM_HANDLE_CONTEXT OurContext = NULL;
158  PNC_STREAM_HANDLE_CONTEXT TheirContext = NULL;
159 
160  NTSTATUS Status;
161 
162  PAGED_CODE();
163 
164  //
165  // Default to no return context.
166  //
167 
168  *Context = NULL;
169 
170  //
171  // Check if a context already exists. If so, return it.
172  //
173 
174  Status = FltGetStreamHandleContext( Instance,
175  FileObject,
176  &TheirContext );
177 
178  if (NT_SUCCESS( Status )) {
179 
180  *Context = TheirContext;
181  return Status;
182  }
183 
184  //
185  // Allocate a new context.
186  //
187 
188  Status = FltAllocateContext( Filter,
189  FLT_STREAMHANDLE_CONTEXT,
190  sizeof(NC_STREAM_HANDLE_CONTEXT),
191  PagedPool,
192  &OurContext );
193 
194  if (!NT_SUCCESS( Status )) {
195 
196  goto NcStreamHandleContextAllocAndAttachClose;
197  }
198 
199  //
200  // Zero out the buffer so we can unwind on failure.
201  //
202 
203  RtlZeroMemory( OurContext, sizeof(NC_STREAM_HANDLE_CONTEXT));
204 
205  //
206  // Initialize shared context information.
207  //
208 
209  Status = NcAllocateEResource( &OurContext->Lock );
210 
211  if (!NT_SUCCESS( Status )) {
212 
213  goto NcStreamHandleContextAllocAndAttachClose;
214  }
215 
216  //
217  // Initialize the Directory Notification Structure.
218  //
219 
221 
222  if (!NT_SUCCESS( Status )) {
223 
224  goto NcStreamHandleContextAllocAndAttachClose;
225  }
226 
227  //
228  // Initialize the Directory Enumeration Structure
229  //
230 
232 
233  if (!NT_SUCCESS( Status )) {
234 
235  goto NcStreamHandleContextAllocAndAttachClose;
236  }
237 
238  //
239  // Initialize the Find by SID Structure
240  //
241 
243 
244  if (!NT_SUCCESS( Status )) {
245 
246  goto NcStreamHandleContextAllocAndAttachClose;
247  }
248 
249  //
250  // Now we have a new context, but we could be racing with another thread
251  // attaching a context to this stream. We will now try to attach, but
252  // keep the existing context if it is there. If there is an existing
253  // context, then we return the pre-existing context and free ours.
254  //
255 
256  Status = FltSetStreamHandleContext( Instance,
257  FileObject,
258  FLT_SET_CONTEXT_KEEP_IF_EXISTS,
259  OurContext,
260  &TheirContext );
261 
262  if (Status == STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
263 
264  Status = STATUS_SUCCESS;
265 
266  } else if (!NT_SUCCESS( Status )) {
267 
268  goto NcStreamHandleContextAllocAndAttachClose;
269  }
270 
271  //
272  // We need to keep 1 ref count on the context we are sticking with.
273  // However, if there are two contexts we need to free one of them.
274  // We therefore NULL out the context that is being returned so as
275  // to only clean up the other (if it exists.)
276  //
277 
278  if (TheirContext != NULL) {
279 
280  *Context = TheirContext;
281  TheirContext = NULL;
282 
283  } else {
284 
285  *Context = OurContext;
286  OurContext = NULL;
287  }
288 
289 NcStreamHandleContextAllocAndAttachClose:
290 
291  if (OurContext != NULL) {
292 
293  FltReleaseContext( OurContext );
294  }
295 
296  if (TheirContext != NULL) {
297 
298  FltReleaseContext( TheirContext );
299  }
300 
301  return Status;
302 }
303 
304 
VOID NcFreeEResource(_In_ PERESOURCE Lock)
Definition: nchelper.c:170
NC_DIR_QRY_CONTEXT DirectoryQueryContext
Definition: nc.h:439
struct _NC_STREAM_HANDLE_CONTEXT * PNC_STREAM_HANDLE_CONTEXT
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE Instance
Definition: nc.h:493
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
NC_MAPPING Mapping
Definition: nc.h:233
NC_FIND_BY_SID_CONTEXT FindBySidContext
Definition: nc.h:440
VOID NcStreamHandleContextClose(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
Definition: nccontext.c:65
NTSTATUS NcStreamHandleContextDirEnumCreate(_Out_ PNC_DIR_QRY_CONTEXT Context)
Definition: ncdirenum.c:1132
NTSTATUS NcStreamHandleContextFindBySidCreate(_Out_ PNC_FIND_BY_SID_CONTEXT Context)
Definition: ncfsctrl.c:75
VOID NcStreamHandleContextFindBySidClose(_In_ PNC_FIND_BY_SID_CONTEXT Context)
Definition: ncfsctrl.c:113
NTSTATUS NcAllocateEResource(_Out_ PERESOURCE *OutputLock)
Definition: nchelper.c:104
UNREFERENCED_PARAMETER(FileObject)
NC_DIR_NOT_CONTEXT DirectoryNotificationContext
Definition: nc.h:438
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
VOID NcStreamHandleContextNotClose(_In_ PNC_DIR_NOT_CONTEXT DirContext)
Definition: ncdirnotify.c:3423
VOID NcStreamHandleContextEnumClose(_In_ PNC_DIR_QRY_CONTEXT DirContext)
Definition: ncdirenum.c:1374
NTSTATUS NcStreamHandleContextAllocAndAttach(_In_ PFLT_FILTER Filter, _In_ PFLT_INSTANCE Instance, _In_ PFILE_OBJECT FileObject, _Out_ PNC_STREAM_HANDLE_CONTEXT *Context)
Definition: nccontext.c:126
VOID NcTeardownMapping(_Inout_ PNC_MAPPING Mapping)
Definition: ncmapping.c:688
PAGED_CODE()
struct _NC_INSTANCE_CONTEXT * PNC_INSTANCE_CONTEXT
IoStatus Status
NTSTATUS NcStreamHandleContextNotCreate(_Out_ PNC_DIR_NOT_CONTEXT Context)
Definition: ncdirnotify.c:3276
PERESOURCE Lock
Definition: nc.h:436
VOID NcInstanceContextClose(_In_ PFLT_CONTEXT Context, _In_ FLT_CONTEXT_TYPE ContextType)
Definition: nccontext.c:31
_In_opt_ PFILE_OBJECT FileObject
Definition: nc.h:493

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