WDK Mini Filter Example
nchelper.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 2008 - 2009 Microsoft Corporation
4 
5 Module Name:
6 
7  nchelper.c
8 
9 Abstract:
10 
11  Contains helper routines of general applicability across name changer.
12 
13 Environment:
14 
15  Kernel mode
16 
17 --*/
18 
19 #include "nc.h"
20 
21 #ifdef ALLOC_PRAGMA
22 #pragma alloc_text(PAGE, NcAllocateEResource)
23 #pragma alloc_text(PAGE, NcCreateFileHelper)
24 #pragma alloc_text(PAGE, NcGetFileNameInformation)
25 #endif
26 
29 NTSTATUS
30 NcGetFileNameInformation(
31  _In_opt_ PFLT_CALLBACK_DATA Data,
32  _In_opt_ PFILE_OBJECT FileObject,
33  _In_opt_ PFLT_INSTANCE Instance,
34  _In_ FLT_FILE_NAME_OPTIONS NameOptions,
35  _Outptr_ PFLT_FILE_NAME_INFORMATION *FileNameInformation
36  )
37 /*++
38 
39 Routine Description:
40 
41  This function is a wrapper to call the correct variant of
42  FltGetFileNameInformation depending on the information we happen to
43  have available.
44 
45 Arguments:
46 
47  Data - Pointer to the callback data structure associated with a request.
48  This is optional, but if not specified, FileObject and Instance must
49  be supplied.
50 
51  FileObject - Pointer to the file object to query a name on. Optional,
52  but if not supplied, Data must be supplied.
53 
54  Instance - Pointer to the instance of our filter to query the name on.
55  Optional, but if not supplied, Data must be supplied.
56 
57  NameOptions - FLT_FILE_NAME_* flags for this request.
58 
59  FileNameInformation - On output, contains the file name information
60  resulting from this query. On failure, contents are undefined.
61  On success, caller is responsible for releasing this with
62  FltReleaseFileNameInformation.
63 
64 Return Value:
65 
66  Returns the status of the operation.
67 
68 --*/
69 {
70  NTSTATUS Status;
71 
72  PAGED_CODE();
73 
74  FLT_ASSERT( Data || FileObject );
75 
76  *FileNameInformation = NULL;
77 
78  if (ARGUMENT_PRESENT( Data )) {
79 
80  Status = FltGetFileNameInformation( Data,
81  NameOptions,
82  FileNameInformation );
83 
84  } else if (ARGUMENT_PRESENT( FileObject )) {
85 
86  Status = FltGetFileNameInformationUnsafe( FileObject,
87  Instance,
88  NameOptions,
89  FileNameInformation );
90  //
91  // This should never happen, as either Data or FileObject must be non-NULL.
92  //
93 
94  } else {
95 
96  FLT_ASSERT( FALSE );
97  Status = STATUS_INVALID_PARAMETER;
98  }
99 
100  return Status;
101 }
102 
103 NTSTATUS
105  _Out_ PERESOURCE * OutputLock
106  )
107 /*++
108 
109 Routine Description:
110 
111  This function allocates a new ERESOURCE.
112 
113 Arguments:
114 
115  OutputLock - On output, points to a newly allocated ERESOURCE. This
116  value is undefined on failure. Caller is responsible for deleting
117  this with a call to NcFreeEResource.
118 
119 Return Value:
120 
121  Returns the status of the operation.
122 
123 --*/
124 {
125  NTSTATUS Status;
126 
127  PERESOURCE Lock = NULL;
128  BOOLEAN DeleteLock = FALSE;
129 
130  PAGED_CODE();
131 
132  Lock = ExAllocatePoolWithTag( NonPagedPool,
133  sizeof(ERESOURCE),
134  NC_LOCK_TAG );
135 
136  if (Lock == NULL) {
137 
138  Status = STATUS_INSUFFICIENT_RESOURCES;
139  goto NcAllocateEResourceCleanup;
140  }
141 
142  Status = ExInitializeResourceLite( Lock );
143 
144  if (!NT_SUCCESS( Status )) {
145 
146  goto NcAllocateEResourceCleanup;
147  }
148 
149  Status = STATUS_SUCCESS;
150  DeleteLock = TRUE;
151  *OutputLock = Lock;
152 
153 NcAllocateEResourceCleanup:
154 
155  if (!NT_SUCCESS( Status )) {
156 
157  if (Lock) {
158 
159  if (DeleteLock) {
160 
161  ExDeleteResourceLite( Lock );
162  }
163  ExFreePoolWithTag( Lock, NC_LOCK_TAG );
164  }
165  }
166  return Status;
167 }
168 
169 VOID
171  _In_ PERESOURCE Lock
172  )
173 /*++
174 
175 Routine Description:
176 
177  This function frees an ERESOURCE.
178 
179 Arguments:
180 
181  Lock - Points to an ERESOURCE allocated previously via
182  NcAllocateEResource that needs to be torn down.
183 
184 Return Value:
185 
186  Returns the status of the operation.
187 
188 --*/
189 {
190  ExDeleteResourceLite( Lock );
191  ExFreePoolWithTag( Lock, NC_LOCK_TAG );
192 }
193 
194 NTSTATUS
196  _In_ PFLT_FILTER Filter,
197  _In_opt_ PFLT_INSTANCE Instance,
198  _Out_ PHANDLE FileHandle,
199  _Outptr_opt_ PFILE_OBJECT *FileObject,
200  _In_ ACCESS_MASK DesiredAccess,
201  _In_ POBJECT_ATTRIBUTES ObjectAttributes,
202  _Out_ PIO_STATUS_BLOCK IoStatusBlock,
203  _In_opt_ PLARGE_INTEGER AllocationSize,
204  _In_ ULONG FileAttributes,
205  _In_ ULONG ShareAccess,
206  _In_ ULONG CreateDisposition,
207  _In_ ULONG CreateOptions,
208  _In_reads_bytes_opt_(EaLength) PVOID EaBuffer,
209  _In_ ULONG EaLength,
210  _In_ ULONG Flags,
211  _In_opt_ PFILE_OBJECT ParentFileObject
212  )
213 {
214 
215 #if FLT_MGR_LONGHORN
216  IO_DRIVER_CREATE_CONTEXT DriverContext;
217 #endif
218  NTSTATUS Status;
219 
220  PAGED_CODE();
221 
222 #if FLT_MGR_LONGHORN
223  IoInitializeDriverCreateContext( &DriverContext );
224 
225  if (ARGUMENT_PRESENT( ParentFileObject )) {
226  PTXN_PARAMETER_BLOCK TxnInfo;
227 
228  TxnInfo = IoGetTransactionParameterBlock( ParentFileObject );
229 
230  //
231  // If we have a FileObject, and if it has a transaction, pass the
232  // same transaction context along to our internal creates.
233  //
234  // TxfInfo will be valid so long as the file object is valid, which
235  // it is assumed to be across the call to this routine.
236  //
237 
238  DriverContext.TxnParameters = TxnInfo;
239  }
240 #else
241  UNREFERENCED_PARAMETER( ParentFileObject );
242 #endif
243 
244  Status = NcCreateFileEx2( Filter,
245  Instance,
246  FileHandle,
247  FileObject,
248  DesiredAccess,
249  ObjectAttributes,
250  IoStatusBlock,
251  AllocationSize,
252  FileAttributes,
253  ShareAccess,
254  CreateDisposition,
255  CreateOptions,
256  EaBuffer,
257  EaLength,
258  Flags,
259 #if FLT_MGR_LONGHORN
260  &DriverContext );
261 #else
262  NULL );
263 #endif
264 
265  return Status;
266 }
267 
268 
269 NTSTATUS
271  _In_ PFLT_CALLBACK_DATA Data,
272  _In_ PFLT_COMPLETE_CANCELED_CALLBACK CanceledCallback
273  )
274 /*++
275 
276 Routine Description:
277 
278  This sets the cancel routine attached to the request. We
279  synchronize against the request being cancelled via the system
280  global cancel spinlock, and if the request is already cancelled,
281  this function returns STATUS_CANCELLED to the caller to
282  indicate that the caller must clean up the request. Otherwise,
283  the cancel routine is set and immediately upon return any
284  cancellation will be via that mechanism.
285 
286  NOTE: This routine must be nonpaged, since we require
287  synchronization with the system global cancel spinlock.
288 
289 Arguments:
290 
291  Data - Pointer to the request we wish to assign cancellation to.
292 
293  CanceledCallback - Pointer to the functin to call upon
294  cancellation.
295 
296 Return Value:
297 
298  STATUS_CANCELLED if the request should be completed by the
299  caller, STATUS_SUCCESS to indicate that the cancellation
300  routine is associated with the request.
301 
302 --*/
303 {
304  NTSTATUS Status;
305  KIRQL OldIrql;
306 
307  IoAcquireCancelSpinLock( &OldIrql );
308 
309  if (FltIsIoCanceled( Data )) {
310  IoReleaseCancelSpinLock( OldIrql );
311  return STATUS_CANCELLED;
312 
313  }
314  Status = FltSetCancelCompletion( Data, CanceledCallback );
315 
316  IoReleaseCancelSpinLock( OldIrql );
317  return Status;
318 }
319 
320 
321 LONG
323  _In_ PEXCEPTION_POINTERS ExceptionPointer,
324  _In_ BOOLEAN AccessingUserBuffer
325  )
326 /*++
327 
328 Routine Description:
329 
330  Exception filter to catch errors touching user buffers.
331 
332 Arguments:
333 
334  ExceptionPointer - The exception record.
335 
336  AccessingUserBuffer - If TRUE, overrides FsRtlIsNtStatusExpected to allow
337  the caller to munge the error to a desired status.
338 
339 Return Value:
340 
341  EXCEPTION_EXECUTE_HANDLER - If the exception handler should be run.
342 
343  EXCEPTION_CONTINUE_SEARCH - If a higher exception handler should take care of
344  this exception.
345 
346 --*/
347 {
348  NTSTATUS Status;
349 
350  Status = ExceptionPointer->ExceptionRecord->ExceptionCode;
351 
352  //
353  // Certain exceptions shouldn't be dismissed within the namechanger filter
354  // unless we're touching user memory.
355  //
356 
357  if (!FsRtlIsNtstatusExpected( Status ) &&
358  !AccessingUserBuffer) {
359 
360  return EXCEPTION_CONTINUE_SEARCH;
361  }
362 
363  return EXCEPTION_EXECUTE_HANDLER;
364 }
365 
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE Instance
Definition: nc.h:493
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
return TRUE
_Pre_satisfies_(Data !=NULL)) NTSTATUS NcGetFileNameInformation(_In_opt_ PFLT_CALLBACK_DATA Data
NTSTATUS NcAllocateEResource(_Out_ PERESOURCE *OutputLock)
Definition: nchelper.c:104
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE _In_ FLT_FILE_NAME_OPTIONS NameOptions
Definition: nc.h:493
NC_CREATE_FILE_EX2_TYPE NcCreateFileEx2
Definition: nccompat.c:80
_When_(Data==NULL, _Pre_satisfies_(FileObject !=NULL &&Instance !=NULL))
Definition: nchelper.c:27
#define NC_LOCK_TAG
Definition: nc.h:16
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE _In_ FLT_FILE_NAME_OPTIONS _Outptr_ PFLT_FILE_NAME_INFORMATION * FileNameInformation
Definition: nc.h:493
UNREFERENCED_PARAMETER(FileObject)
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
NTSTATUS NcSetCancelCompletion(_In_ PFLT_CALLBACK_DATA Data, _In_ PFLT_COMPLETE_CANCELED_CALLBACK CanceledCallback)
Definition: nchelper.c:270
PAGED_CODE()
IoStatus Status
VOID NcFreeEResource(_In_ PERESOURCE Lock)
Definition: nchelper.c:170
LONG NcExceptionFilter(_In_ PEXCEPTION_POINTERS ExceptionPointer, _In_ BOOLEAN AccessingUserBuffer)
Definition: nchelper.c:322
NTSTATUS NcCreateFileHelper(_In_ PFLT_FILTER Filter, _In_opt_ PFLT_INSTANCE Instance, _Out_ PHANDLE FileHandle, _Outptr_opt_ PFILE_OBJECT *FileObject, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_opt_ PLARGE_INTEGER AllocationSize, _In_ ULONG FileAttributes, _In_ ULONG ShareAccess, _In_ ULONG CreateDisposition, _In_ ULONG CreateOptions, _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, _In_ ULONG EaLength, _In_ ULONG Flags, _In_opt_ PFILE_OBJECT ParentFileObject)
Definition: nchelper.c:195
_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