[FLTMGR]
[reactos.git] / reactos / drivers / filters / fltmgr / Object.c
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
24
25 /* EXPORTED FUNCTIONS ******************************************************/
26
27
28 NTSTATUS
29 FLTAPI
30 FltObjectReference(_Inout_ PVOID Object)
31 {
32 if (!FltpExAcquireRundownProtection(&((PFLT_OBJECT)Object)->RundownRef))
33 {
34 return STATUS_FLT_DELETING_OBJECT;
35 }
36
37 return STATUS_SUCCESS;
38 }
39
40 VOID
41 FLTAPI
42 FltObjectDereference(_Inout_ PVOID Object)
43 {
44 FltpExReleaseRundownProtection(&((PFLT_OBJECT)Object)->RundownRef);
45 }
46
47
48
49 /* INTERNAL FUNCTIONS ******************************************************/
50
51 VOID
52 FltpExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RundownRef)
53 {
54 ExInitializeRundownProtection(RundownRef);
55 }
56
57 BOOLEAN
58 FltpExAcquireRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
59 {
60 return ExAcquireRundownProtection(RundownRef);
61 }
62
63 BOOLEAN
64 FltpExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
65 {
66 ExReleaseRundownProtection(RundownRef);
67 return TRUE;
68 }
69
70 BOOLEAN
71 FltpExRundownCompleted(_Inout_ PEX_RUNDOWN_REF RundownRef)
72 {
73 return _InterlockedExchange((PLONG)RundownRef, 1);
74 }
75
76 NTSTATUS
77 NTAPI
78 FltpObjectRundownWait(_Inout_ PEX_RUNDOWN_REF RundownRef)
79 {
80 //return FltpExWaitForRundownProtectionRelease(RundownRef);
81 return 0;
82 }
83
84 NTSTATUS
85 FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject,
86 _Inout_ PUNICODE_STRING ObjectName)
87 {
88 PDEVICE_OBJECT BaseDeviceObject;
89 NTSTATUS Status;
90
91 /*
92 * Get the lowest device object on the stack, which may be the
93 * object we were passed, and lookup the name for that object
94 */
95 BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
96 Status = FltpGetObjectName(BaseDeviceObject, ObjectName);
97 ObDereferenceObject(BaseDeviceObject);
98
99 return Status;
100 }
101
102 NTSTATUS
103 FltpGetObjectName(_In_ PVOID Object,
104 _Inout_ PUNICODE_STRING ObjectName)
105 {
106 POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
107 OBJECT_NAME_INFORMATION LocalNameInfo;
108 ULONG ReturnLength;
109 NTSTATUS Status;
110
111 if (ObjectName == NULL)
112 return STATUS_INVALID_PARAMETER;
113
114 /* Get the size of the buffer required to hold the nameinfo */
115 Status = ObQueryNameString(Object,
116 &LocalNameInfo,
117 sizeof(LocalNameInfo),
118 &ReturnLength);
119 if (Status == STATUS_INFO_LENGTH_MISMATCH)
120 {
121 ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
122 ReturnLength,
123 FM_TAG_UNICODE_STRING);
124 if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES;
125
126 /* Get the actual name info now we have the buffer to hold it */
127 Status = ObQueryNameString(Object,
128 ObjectNameInfo,
129 ReturnLength,
130 &ReturnLength);
131 }
132
133
134 if (NT_SUCCESS(Status))
135 {
136 /* Make sure the buffer we were passed is large enough to hold the string */
137 if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length)
138 {
139 /* It wasn't, let's enlarge the buffer */
140 Status = FltpReallocateUnicodeString(ObjectName,
141 ObjectNameInfo->Name.Length,
142 FALSE);
143
144 }
145
146 if (NT_SUCCESS(Status))
147 {
148 /* Copy the object name into the callers buffer */
149 RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name);
150 }
151 }
152
153 if (ObjectNameInfo)
154 {
155 ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING);
156 }
157
158 return Status;
159 }