ReactOS  0.4.14-dev-115-g4576127
Object.c
Go to the documentation of this file.
1 /*
2 * PROJECT: Filesystem Filter Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filters/fltmgr/Object.c
5 * PURPOSE: Miscellaneous library functions
6 * PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
7 */
8 
9 // NOTE: Split this file into filter object and device object functions
10 // when the code base grows sufficiently
11 
12 /* INCLUDES ******************************************************************/
13 
14 #include "fltmgr.h"
15 #include "fltmgrint.h"
16 
17 #define NDEBUG
18 #include <debug.h>
19 
20 
21 /* DATA *********************************************************************/
22 
23 #define ExpChangePushlock(x, y, z) InterlockedCompareExchangePointer((PVOID*)x, (PVOID)y, (PVOID)z)
24 
25 //
26 // Pushlock bits
27 //
28 #define EX_PUSH_LOCK_LOCK_V ((ULONG_PTR)0x0)
29 #define EX_PUSH_LOCK_LOCK ((ULONG_PTR)0x1)
30 #define EX_PUSH_LOCK_WAITING ((ULONG_PTR)0x2)
31 #define EX_PUSH_LOCK_WAKING ((ULONG_PTR)0x4)
32 #define EX_PUSH_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8)
33 #define EX_PUSH_LOCK_SHARE_INC ((ULONG_PTR)0x10)
34 #define EX_PUSH_LOCK_PTR_BITS ((ULONG_PTR)0xf)
35 
36 /* EXPORTED FUNCTIONS ******************************************************/
37 
38 
40 FLTAPI
42 {
44  {
46  }
47 
48  return STATUS_SUCCESS;
49 }
50 
51 VOID
52 FLTAPI
54 {
56 }
57 
58 
59 _Acquires_lock_(_Global_critical_region_)
61 VOID
62 FLTAPI
63 FltAcquirePushLockExclusive(_Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
64 {
66 
67  /* Try acquiring the lock */
69  {
70  /* Someone changed it, use the slow path */
72  }
73 
74  /* Sanity check */
75  FLT_ASSERT(PushLock->Locked);
76 }
77 
78 
79 _Acquires_lock_(_Global_critical_region_)
81 VOID
82 FLTAPI
83 FltAcquirePushLockShared(_Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
84 {
85  EX_PUSH_LOCK NewValue;
86 
88 
89  /* Try acquiring the lock */
91  if (ExpChangePushlock(PushLock, NewValue.Ptr, 0))
92  {
93  /* Someone changed it, use the slow path */
94  ExfAcquirePushLockShared(PushLock);
95  }
96 
97  /* Sanity checks */
98  ASSERT(PushLock->Locked);
99 }
100 
101 _Releases_lock_(_Global_critical_region_)
103 VOID
104 FLTAPI
105 FltReleasePushLock(_Inout_ _Requires_lock_held_(*_Curr_) _Releases_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
106 {
107  EX_PUSH_LOCK OldValue = *PushLock;
108  EX_PUSH_LOCK NewValue;
109 
110  /* Sanity checks */
111  FLT_ASSERT(OldValue.Locked);
112 
113  /* Check if the pushlock is shared */
114  if (OldValue.Shared > 1)
115  {
116  /* Decrease the share count */
117  NewValue.Value = OldValue.Value - EX_PUSH_LOCK_SHARE_INC;
118  }
119  else
120  {
121  /* Clear the pushlock entirely */
122  NewValue.Value = 0;
123  }
124 
125  /* Check if nobody is waiting on us and try clearing the lock here */
126  if ((OldValue.Waiting) ||
127  (ExpChangePushlock(PushLock, NewValue.Ptr, OldValue.Ptr) !=
128  OldValue.Ptr))
129  {
130  /* We have waiters, use the long path */
131  ExfReleasePushLock(PushLock);
132  }
133 
135 }
136 
138 NTSTATUS
139 FLTAPI
140 FltClose(_In_ HANDLE FileHandle)
141 {
142  PAGED_CODE();
143 
144  return ZwClose(FileHandle);
145 }
146 
149 NTSTATUS
150 FLTAPI
151 FltCreateFileEx(_In_ PFLT_FILTER Filter,
165  _In_ ULONG Flags)
166 {
168  return STATUS_NOT_IMPLEMENTED;
169 }
170 
173 NTSTATUS
174 FLTAPI
175 FltCreateFile(_In_ PFLT_FILTER Filter,
188  _In_ ULONG Flags)
189 {
190  return FltCreateFileEx(Filter,
191  Instance,
192  FileHandle,
193  NULL,
199  ShareAccess,
202  EaBuffer,
203  EaLength,
204  Flags);
205 }
206 
207 
208 
209 /* INTERNAL FUNCTIONS ******************************************************/
210 
211 VOID
213 {
214  ExInitializeRundownProtection(RundownRef);
215 }
216 
217 BOOLEAN
219 {
220  return ExAcquireRundownProtection(RundownRef);
221 }
222 
223 BOOLEAN
225 {
226  ExReleaseRundownProtection(RundownRef);
227  return TRUE;
228 }
229 
230 BOOLEAN
232 {
233  return _InterlockedExchange((PLONG)RundownRef, 1);
234 }
235 
236 NTSTATUS
237 NTAPI
239 {
240  //return FltpExWaitForRundownProtectionRelease(RundownRef);
241  return 0;
242 }
243 
244 NTSTATUS
247 {
248  PDEVICE_OBJECT BaseDeviceObject;
250 
251  /*
252  * Get the lowest device object on the stack, which may be the
253  * object we were passed, and lookup the name for that object
254  */
255  BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
256  Status = FltpGetObjectName(BaseDeviceObject, ObjectName);
257  ObDereferenceObject(BaseDeviceObject);
258 
259  return Status;
260 }
261 
262 NTSTATUS
265 {
266  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
267  OBJECT_NAME_INFORMATION LocalNameInfo;
270 
271  if (ObjectName == NULL)
273 
274  /* Get the size of the buffer required to hold the nameinfo */
276  &LocalNameInfo,
277  sizeof(LocalNameInfo),
278  &ReturnLength);
280  {
281  ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
282  ReturnLength,
284  if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES;
285 
286  /* Get the actual name info now we have the buffer to hold it */
288  ObjectNameInfo,
289  ReturnLength,
290  &ReturnLength);
291  }
292 
293 
294  if (NT_SUCCESS(Status))
295  {
296  /* Make sure the buffer we were passed is large enough to hold the string */
297  if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length)
298  {
299  /* It wasn't, let's enlarge the buffer */
301  ObjectNameInfo->Name.Length,
302  FALSE);
303 
304  }
305 
306  if (NT_SUCCESS(Status))
307  {
308  /* Copy the object name into the callers buffer */
309  RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name);
310  }
311  }
312 
313  if (ObjectNameInfo)
314  {
315  ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING);
316  }
317 
318  return Status;
319 }
320 
321 ULONG
323 {
324  PULONG Result;
325 
326  /* Store the old count and increment */
327  Result = &Object->PointerCount;
328  InterlockedIncrementSizeT(&Object->PointerCount);
329 
330  /* Return the initial value */
331  return *Result;
332 }
333 
334 VOID
336 {
337  if (InterlockedDecrementSizeT(&Object->PointerCount) == 0)
338  {
339  // Cleanup
340  FLT_ASSERT(FALSE);
341  }
342 }
ULONG_PTR Value
Definition: extypes.h:465
#define STATUS_FLT_DELETING_OBJECT
Definition: ntstatus.h:1214
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define _Must_inspect_result_
Definition: no_sal2.h:314
#define TRUE
Definition: types.h:120
_Releases_lock_(_Global_critical_region_)
Definition: Object.c:101
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
#define _In_reads_bytes_opt_(size)
Definition: no_sal2.h:230
PVOID Ptr
Definition: extypes.h:466
VOID FLTAPI FltObjectDereference(_Inout_ PVOID Object)
Definition: Object.c:53
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_opt_ PVOID EaBuffer
Definition: iofuncs.h:835
LONG NTSTATUS
Definition: precomp.h:26
#define ExAcquireRundownProtection
Definition: ex.h:130
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
NTSTATUS NTAPI FltpObjectRundownWait(_Inout_ PEX_RUNDOWN_REF RundownRef)
Definition: Object.c:238
_Requires_lock_not_held_(Vcb->fcb_lock) _Acquires_shared_lock_(Vcb -> fcb_lock) static __inline void acquire_fcb_lock_shared(device_extension *Vcb)
Definition: btrfs_drv.h:923
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_Acquires_lock_(_Global_critical_region_)
Definition: Object.c:59
UNICODE_STRING Name
Definition: nt_native.h:1270
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
NTKERNELAPI VOID FASTCALL ExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RunRef)
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4157
#define PAGED_CODE()
Definition: video.h:57
#define _In_opt_
Definition: no_sal2.h:213
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
PDEVICE_OBJECT NTAPI IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1419
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PUNICODE_STRING ObjectName)
Definition: Object.c:245
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FM_TAG_UNICODE_STRING
Definition: fltmgr.h:18
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:220
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
VOID FltpExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RundownRef)
Definition: Object.c:212
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
ULONG_PTR Waiting
Definition: extypes.h:460
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _Out_
Definition: no_sal2.h:323
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1230
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
BOOLEAN FltpExAcquireRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
Definition: Object.c:218
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
NTSTATUS FltpReallocateUnicodeString(_In_ PUNICODE_STRING String, _In_ SIZE_T NewLength, _In_ BOOLEAN CopyExisting)
Definition: Lib.c:39
BOOLEAN FltpExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
Definition: Object.c:224
#define EX_PUSH_LOCK_LOCK
Definition: Object.c:29
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:866
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL ExfReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: pushlock.c:810
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define _Inout_
Definition: no_sal2.h:244
* PFILE_OBJECT
Definition: iotypes.h:1955
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExpChangePushlock(x, y, z)
Definition: Object.c:23
_IRQL_requires_max_(PASSIVE_LEVEL)
Definition: Object.c:137
VOID FASTCALL ExfAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: pushlock.c:471
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define _Outptr_opt_
Definition: no_sal2.h:397
ULONG FltpObjectPointerReference(_In_ PFLT_OBJECT Object)
Definition: Object.c:322
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
ULONG_PTR Shared
Definition: extypes.h:463
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID FltpObjectPointerDereference(_In_ PFLT_OBJECT Object)
Definition: Object.c:335
VOID FASTCALL ExfAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: pushlock.c:645
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
NTSTATUS FLTAPI FltObjectReference(_Inout_ PVOID Object)
Definition: Object.c:41
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define EX_PUSH_LOCK_LOCK_V
Definition: Object.c:28
IN PVOID Instance
Definition: pci.h:359
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define EX_PUSH_LOCK_SHARE_INC
Definition: Object.c:33
return STATUS_SUCCESS
Definition: btrfs.c:2966
signed int * PLONG
Definition: retypes.h:5
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT _In_ ULONG CreateDisposition
Definition: create.c:4157
#define APC_LEVEL
Definition: env_spec_w32.h:695
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define _Requires_lock_held_(a)
Definition: btrfs_drv.h:184
BOOLEAN FltpExRundownCompleted(_Inout_ PEX_RUNDOWN_REF RundownRef)
Definition: Object.c:231
ULONG_PTR Locked
Definition: extypes.h:459
NTSTATUS FltpGetObjectName(_In_ PVOID Object, _Inout_ PUNICODE_STRING ObjectName)
Definition: Object.c:263
#define FLT_ASSERT(_e)
Definition: fltkernel.h:49