- use inlined probing macros for basic types
[reactos.git] / reactos / ntoskrnl / include / internal / ob.h
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: include/internal/objmgr.h
5 * PURPOSE: Object manager definitions
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 */
8
9 #ifndef __INCLUDE_INTERNAL_OBJMGR_H
10 #define __INCLUDE_INTERNAL_OBJMGR_H
11
12 struct _EPROCESS;
13
14 typedef struct _DIRECTORY_OBJECT
15 {
16 CSHORT Type;
17 CSHORT Size;
18
19 /*
20 * PURPOSE: Head of the list of our subdirectories
21 */
22 LIST_ENTRY head;
23 KSPIN_LOCK Lock;
24 } DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
25
26 typedef struct _SYMLINK_OBJECT
27 {
28 CSHORT Type;
29 CSHORT Size;
30 UNICODE_STRING TargetName;
31 LARGE_INTEGER CreateTime;
32 } SYMLINK_OBJECT, *PSYMLINK_OBJECT;
33
34 /*
35 * Enumeration of object types
36 */
37 enum
38 {
39 OBJTYP_INVALID,
40 OBJTYP_TYPE,
41 OBJTYP_DIRECTORY,
42 OBJTYP_SYMLNK,
43 OBJTYP_DEVICE,
44 OBJTYP_THREAD,
45 OBJTYP_FILE,
46 OBJTYP_PROCESS,
47 OBJTYP_SECTION,
48 OBJTYP_MAX,
49 };
50
51 #define BODY_TO_HEADER(objbdy) \
52 CONTAINING_RECORD((objbdy), OBJECT_HEADER, Body)
53
54 #define HEADER_TO_OBJECT_NAME(objhdr) ((POBJECT_HEADER_NAME_INFO) \
55 (!(objhdr)->NameInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->NameInfoOffset)))
56
57 #define HEADER_TO_HANDLE_INFO(objhdr) ((POBJECT_HEADER_HANDLE_INFO) \
58 (!(objhdr)->HandleInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->HandleInfoOffset)))
59
60 #define HEADER_TO_CREATOR_INFO(objhdr) ((POBJECT_HEADER_CREATOR_INFO) \
61 (!((objhdr)->Flags & OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(objhdr) - sizeof(OBJECT_HEADER_CREATOR_INFO))))
62
63 #define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER))
64
65 extern PDIRECTORY_OBJECT NameSpaceRoot;
66 extern POBJECT_TYPE ObSymbolicLinkType;
67 extern PHANDLE_TABLE ObpKernelHandleTable;
68
69 #define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
70 #define ObIsKernelHandle(Handle, ProcessorMode) \
71 (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) && \
72 ((ProcessorMode) == KernelMode))
73 #define ObKernelHandleToHandle(Handle) \
74 (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
75
76 VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
77 POBJECT_HEADER Header,
78 PWSTR Name);
79 VOID ObpRemoveEntryDirectory(POBJECT_HEADER Header);
80
81 VOID
82 ObInitSymbolicLinkImplementation(VOID);
83
84
85 NTSTATUS ObpCreateHandle(struct _EPROCESS* Process,
86 PVOID ObjectBody,
87 ACCESS_MASK GrantedAccess,
88 BOOLEAN Inherit,
89 PHANDLE Handle);
90 VOID ObCreateHandleTable(struct _EPROCESS* Parent,
91 BOOLEAN Inherit,
92 struct _EPROCESS* Process);
93 NTSTATUS ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
94 PUNICODE_STRING ObjectName,
95 PVOID* ReturnedObject,
96 PUNICODE_STRING RemainingPath,
97 POBJECT_TYPE ObjectType);
98
99 NTSTATUS
100 ObpQueryHandleAttributes(HANDLE Handle,
101 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
102
103 NTSTATUS
104 ObpSetHandleAttributes(HANDLE Handle,
105 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
106
107 NTSTATUS
108 STDCALL
109 ObpCreateTypeObject(struct _OBJECT_TYPE_INITIALIZER *ObjectTypeInitializer,
110 PUNICODE_STRING TypeName,
111 POBJECT_TYPE *ObjectType);
112
113 ULONG
114 ObGetObjectHandleCount(PVOID Object);
115 NTSTATUS
116 ObDuplicateObject(PEPROCESS SourceProcess,
117 PEPROCESS TargetProcess,
118 HANDLE SourceHandle,
119 PHANDLE TargetHandle,
120 ACCESS_MASK DesiredAccess,
121 BOOLEAN InheritHandle,
122 ULONG Options);
123
124 ULONG
125 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
126
127 VOID
128 STDCALL
129 ObQueryDeviceMapInformation(PEPROCESS Process, PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo);
130
131 VOID FASTCALL
132 ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent);
133
134 VOID
135 STDCALL
136 ObKillProcess(PEPROCESS Process);
137 /* Security descriptor cache functions */
138
139 NTSTATUS
140 ObpInitSdCache(VOID);
141
142 NTSTATUS
143 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD,
144 OUT PSECURITY_DESCRIPTOR *DestinationSD);
145
146 NTSTATUS
147 ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
148
149 VOID
150 ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
151
152 VOID
153 ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
154
155 VOID
156 FASTCALL
157 ObInitializeFastReference(IN PEX_FAST_REF FastRef,
158 PVOID Object);
159
160 PVOID
161 FASTCALL
162 ObFastReplaceObject(IN PEX_FAST_REF FastRef,
163 PVOID Object);
164
165 PVOID
166 FASTCALL
167 ObFastReferenceObject(IN PEX_FAST_REF FastRef);
168
169 VOID
170 FASTCALL
171 ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
172 PVOID Object);
173
174 /* Secure object information functions */
175
176 typedef struct _CAPTURED_OBJECT_ATTRIBUTES
177 {
178 HANDLE RootDirectory;
179 ULONG Attributes;
180 PSECURITY_DESCRIPTOR SecurityDescriptor;
181 PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
182 } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
183
184 NTSTATUS
185 STDCALL
186 ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
187 IN PUNICODE_STRING ObjectName,
188 IN KPROCESSOR_MODE AccessMode);
189
190 NTSTATUS
191 STDCALL
192 ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
193 IN KPROCESSOR_MODE AccessMode,
194 IN POBJECT_TYPE ObjectType,
195 IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
196 OUT PUNICODE_STRING ObjectName);
197
198 VOID
199 STDCALL
200 ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo);
201
202 /* object information classes */
203
204 #define ICIF_QUERY 0x1
205 #define ICIF_SET 0x2
206 #define ICIF_QUERY_SIZE_VARIABLE 0x4
207 #define ICIF_SET_SIZE_VARIABLE 0x8
208 #define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
209
210 typedef struct _INFORMATION_CLASS_INFO
211 {
212 ULONG RequiredSizeQUERY;
213 ULONG RequiredSizeSET;
214 ULONG AlignmentSET;
215 ULONG AlignmentQUERY;
216 ULONG Flags;
217 } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
218
219 #define ICI_SQ_SAME(Size, Alignment, Flags) \
220 { Size, Size, Alignment, Alignment, Flags }
221
222 #define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \
223 { SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags }
224
225 #define CheckInfoClass(Class, BufferLen, ClassList, StatusVar, Mode) \
226 do { \
227 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
228 { \
229 if(!(ClassList[Class].Flags & ICIF_##Mode)) \
230 { \
231 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
232 } \
233 else if(ClassList[Class].RequiredSize##Mode > 0 && \
234 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
235 { \
236 if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
237 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
238 { \
239 *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
240 } \
241 } \
242 } \
243 else \
244 { \
245 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
246 } \
247 } while(0)
248
249
250 #define GetInfoClassAlignment(Class, ClassList, AlignmentVar, Mode) \
251 do { \
252 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
253 { \
254 *(AlignmentVar) = ClassList[Class].Alignment##Mode; \
255 } \
256 else \
257 { \
258 *(AlignmentVar) = sizeof(ULONG); \
259 } \
260 } while(0)
261
262 #define ProbeQueryInfoBuffer(Buffer, BufferLen, Alignment, RetLen, PrevMode, StatusVar) \
263 do { \
264 if(PrevMode != KernelMode) \
265 { \
266 _SEH_TRY \
267 { \
268 ProbeForWrite(Buffer, \
269 BufferLen, \
270 Alignment); \
271 if(RetLen != NULL) \
272 { \
273 ProbeForWrite(RetLen, \
274 sizeof(ULONG), \
275 1); \
276 } \
277 } \
278 _SEH_HANDLE \
279 { \
280 *(StatusVar) = _SEH_GetExceptionCode(); \
281 } \
282 _SEH_END; \
283 \
284 if(!NT_SUCCESS(*(StatusVar))) \
285 { \
286 DPRINT1("ProbeQueryInfoBuffer failed: 0x%x\n", *(StatusVar)); \
287 return *(StatusVar); \
288 } \
289 } \
290 } while(0)
291
292 #define ProbeSetInfoBuffer(Buffer, BufferLen, Alignment, PrevMode, StatusVar) \
293 do { \
294 if(PrevMode != KernelMode) \
295 { \
296 _SEH_TRY \
297 { \
298 ProbeForRead(Buffer, \
299 BufferLen, \
300 Alignment); \
301 } \
302 _SEH_HANDLE \
303 { \
304 *(StatusVar) = _SEH_GetExceptionCode(); \
305 } \
306 _SEH_END; \
307 \
308 if(!NT_SUCCESS(*(StatusVar))) \
309 { \
310 DPRINT1("ProbeAllInfoBuffer failed: 0x%x\n", *(StatusVar)); \
311 return *(StatusVar); \
312 } \
313 } \
314 } while(0)
315
316 #define DefaultSetInfoBufferCheck(Class, ClassList, Buffer, BufferLen, PrevMode, StatusVar) \
317 do { \
318 ULONG _Alignment; \
319 /* get the preferred alignment for the information class or return */ \
320 /* default alignment in case the class doesn't exist */ \
321 GetInfoClassAlignment(Class, \
322 ClassList, \
323 &_Alignment, \
324 SET); \
325 \
326 /* probe the ENTIRE buffers and return on failure */ \
327 ProbeSetInfoBuffer(Buffer, \
328 BufferLen, \
329 _Alignment, \
330 PrevMode, \
331 StatusVar); \
332 \
333 /* validate information class index and check buffer size */ \
334 CheckInfoClass(Class, \
335 BufferLen, \
336 ClassList, \
337 StatusVar, \
338 SET); \
339 } while(0)
340
341 #define DefaultQueryInfoBufferCheck(Class, ClassList, Buffer, BufferLen, RetLen, PrevMode, StatusVar) \
342 do { \
343 ULONG _Alignment; \
344 /* get the preferred alignment for the information class or return */ \
345 /* alignment in case the class doesn't exist */ \
346 GetInfoClassAlignment(Class, \
347 ClassList, \
348 &_Alignment, \
349 QUERY); \
350 \
351 /* probe the ENTIRE buffers and return on failure */ \
352 ProbeQueryInfoBuffer(Buffer, \
353 BufferLen, \
354 _Alignment, \
355 RetLen, \
356 PrevMode, \
357 StatusVar); \
358 \
359 /* validate information class index and check buffer size */ \
360 CheckInfoClass(Class, \
361 BufferLen, \
362 ClassList, \
363 StatusVar, \
364 QUERY); \
365 } while(0)
366
367 #endif /* __INCLUDE_INTERNAL_OBJMGR_H */