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