2e4f8ac1c0aa8df20a704140e3a14d35fcca984f
[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 enum _OB_OPEN_REASON
20 {
21 ObCreateHandle,
22 ObOpenHandle,
23 ObDuplicateHandle,
24 ObInheritHandle,
25 ObMaxOpenReason
26 } OB_OPEN_REASON;
27
28 /* TEMPORARY HACK */
29 typedef NTSTATUS
30 (STDCALL *OB_CREATE_METHOD)(
31 PVOID ObjectBody,
32 PVOID Parent,
33 PWSTR RemainingPath,
34 struct _OBJECT_ATTRIBUTES* ObjectAttributes);
35
36 /* Object Callbacks */
37 typedef NTSTATUS
38 (STDCALL *OB_OPEN_METHOD)(
39 OB_OPEN_REASON Reason,
40 PVOID ObjectBody,
41 PEPROCESS Process,
42 ULONG HandleCount,
43 ACCESS_MASK GrantedAccess);
44
45 typedef NTSTATUS
46 (STDCALL *OB_PARSE_METHOD)(
47 PVOID Object,
48 PVOID *NextObject,
49 PUNICODE_STRING FullPath,
50 PWSTR *Path,
51 ULONG Attributes);
52
53 typedef VOID
54 (STDCALL *OB_DELETE_METHOD)(
55 PVOID DeletedObject);
56
57 typedef VOID
58 (STDCALL *OB_CLOSE_METHOD)(
59 PVOID ClosedObject,
60 ULONG HandleCount);
61
62 typedef VOID
63 (STDCALL *OB_DUMP_METHOD)(
64 VOID);
65
66 typedef NTSTATUS
67 (STDCALL *OB_OKAYTOCLOSE_METHOD)(
68 VOID);
69
70 typedef NTSTATUS
71 (STDCALL *OB_QUERYNAME_METHOD)(
72 PVOID ObjectBody,
73 POBJECT_NAME_INFORMATION ObjectNameInfo,
74 ULONG Length,
75 PULONG ReturnLength);
76
77 typedef PVOID
78 (STDCALL *OB_FIND_METHOD)(
79 PVOID WinStaObject,
80 PWSTR Name,
81 ULONG Attributes);
82
83 typedef NTSTATUS
84 (STDCALL *OB_SECURITY_METHOD)(
85 PVOID ObjectBody,
86 SECURITY_OPERATION_CODE OperationCode,
87 SECURITY_INFORMATION SecurityInformation,
88 PSECURITY_DESCRIPTOR SecurityDescriptor,
89 PULONG BufferLength);
90
91 typedef struct _OBJECT_HEADER_NAME_INFO
92 {
93 struct _DIRECTORY_OBJECT *Directory;
94 UNICODE_STRING Name;
95 ULONG QueryReferences;
96 ULONG Reserved2;
97 ULONG DbgReferenceCount;
98 } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
99
100 typedef struct _OBJECT_CREATE_INFORMATION
101 {
102 ULONG Attributes;
103 HANDLE RootDirectory;
104 PVOID ParseContext;
105 KPROCESSOR_MODE ProbeMode;
106 ULONG PagedPoolCharge;
107 ULONG NonPagedPoolCharge;
108 ULONG SecurityDescriptorCharge;
109 PSECURITY_DESCRIPTOR SecurityDescriptor;
110 PSECURITY_QUALITY_OF_SERVICE SecurityQos;
111 SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
112 } OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
113
114 typedef struct _OBJECT_TYPE_INITIALIZER
115 {
116 WORD Length;
117 UCHAR UseDefaultObject;
118 UCHAR CaseInsensitive;
119 ULONG InvalidAttributes;
120 GENERIC_MAPPING GenericMapping;
121 ULONG ValidAccessMask;
122 UCHAR SecurityRequired;
123 UCHAR MaintainHandleCount;
124 UCHAR MaintainTypeList;
125 POOL_TYPE PoolType;
126 ULONG DefaultPagedPoolCharge;
127 ULONG DefaultNonPagedPoolCharge;
128 OB_DUMP_METHOD DumpProcedure;
129 OB_OPEN_METHOD OpenProcedure;
130 OB_CLOSE_METHOD CloseProcedure;
131 OB_DELETE_METHOD DeleteProcedure;
132 OB_PARSE_METHOD ParseProcedure;
133 OB_SECURITY_METHOD SecurityProcedure;
134 OB_QUERYNAME_METHOD QueryNameProcedure;
135 OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
136 } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
137
138 typedef struct _OBJECT_TYPE
139 {
140 ERESOURCE Mutex; /* Used to lock the Object Type */
141 LIST_ENTRY TypeList; /* Links all the Types Together for Debugging */
142 UNICODE_STRING Name; /* Name of the Type */
143 PVOID DefaultObject; /* What Object to use during a Wait (ie, FileObjects wait on FileObject->Event) */
144 ULONG Index; /* Index of this Type in the Object Directory */
145 ULONG TotalNumberOfObjects; /* Total number of objects of this type */
146 ULONG TotalNumberOfHandles; /* Total number of handles of this type */
147 ULONG HighWaterNumberOfObjects; /* Peak number of objects of this type */
148 ULONG HighWaterNumberOfHandles; /* Peak number of handles of this type */
149 OBJECT_TYPE_INITIALIZER TypeInfo; /* Information captured during type creation */
150 ULONG Key; /* Key to use when allocating objects of this type */
151 ERESOURCE ObjectLocks[4]; /* Locks for locking the Objects */
152 } OBJECT_TYPE;
153
154 typedef struct _OBJECT_HANDLE_COUNT_ENTRY
155 {
156 struct _EPROCESS *Process;
157 ULONG HandleCount;
158 } OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;
159
160 typedef struct _OBJECT_HANDLE_COUNT_DATABASE
161 {
162 ULONG CountEntries;
163 POBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1];
164 } OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;
165
166 typedef struct _OBJECT_HEADER_HANDLE_INFO
167 {
168 union {
169 POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase;
170 OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
171 };
172 } OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
173
174 typedef struct _OBJECT_HEADER_CREATOR_INFO
175 {
176 LIST_ENTRY TypeList;
177 PVOID CreatorUniqueProcess;
178 USHORT CreatorBackTraceIndex;
179 USHORT Reserved;
180 } OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
181
182 typedef PVOID POBJECT;
183
184 typedef struct _QUAD
185 {
186 union {
187 LONGLONG UseThisFieldToCopy;
188 float DoNotUseThisField;
189 };
190 } QUAD, *PQUAD;
191
192 #define OB_FLAG_CREATE_INFO 0x01 // has OBJECT_CREATE_INFO
193 #define OB_FLAG_KERNEL_MODE 0x02 // created by kernel
194 #define OB_FLAG_CREATOR_INFO 0x04 // has OBJECT_CREATOR_INFO
195 #define OB_FLAG_EXCLUSIVE 0x08 // OBJ_EXCLUSIVE
196 #define OB_FLAG_PERMANENT 0x10 // OBJ_PERMANENT
197 #define OB_FLAG_SECURITY 0x20 // has security descriptor
198 #define OB_FLAG_SINGLE_PROCESS 0x40 // no HandleDBList
199
200 /* Will be moved to public headers once "Entry" is gone */
201 typedef struct _OBJECT_HEADER
202 {
203 LIST_ENTRY Entry;
204 LONG PointerCount;
205 union {
206 LONG HandleCount;
207 PVOID NextToFree;
208 };
209 POBJECT_TYPE Type;
210 UCHAR NameInfoOffset;
211 UCHAR HandleInfoOffset;
212 UCHAR QuotaInfoOffset;
213 UCHAR Flags;
214 union {
215 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
216 PVOID QuotaBlockCharged;
217 };
218 PSECURITY_DESCRIPTOR SecurityDescriptor;
219 QUAD Body;
220 } OBJECT_HEADER, *POBJECT_HEADER;
221
222 typedef struct _DIRECTORY_OBJECT
223 {
224 CSHORT Type;
225 CSHORT Size;
226
227 /*
228 * PURPOSE: Head of the list of our subdirectories
229 */
230 LIST_ENTRY head;
231 KSPIN_LOCK Lock;
232 } DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
233
234 typedef struct _SYMLINK_OBJECT
235 {
236 CSHORT Type;
237 CSHORT Size;
238 UNICODE_STRING TargetName;
239 LARGE_INTEGER CreateTime;
240 } SYMLINK_OBJECT, *PSYMLINK_OBJECT;
241
242 /*
243 * Enumeration of object types
244 */
245 enum
246 {
247 OBJTYP_INVALID,
248 OBJTYP_TYPE,
249 OBJTYP_DIRECTORY,
250 OBJTYP_SYMLNK,
251 OBJTYP_DEVICE,
252 OBJTYP_THREAD,
253 OBJTYP_FILE,
254 OBJTYP_PROCESS,
255 OBJTYP_SECTION,
256 OBJTYP_MAX,
257 };
258
259 #define BODY_TO_HEADER(objbdy) \
260 CONTAINING_RECORD((objbdy), OBJECT_HEADER, Body)
261
262 #define HEADER_TO_OBJECT_NAME(objhdr) ((POBJECT_HEADER_NAME_INFO) \
263 (!(objhdr)->NameInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->NameInfoOffset)))
264
265 #define HEADER_TO_HANDLE_INFO(objhdr) ((POBJECT_HEADER_HANDLE_INFO) \
266 (!(objhdr)->HandleInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->HandleInfoOffset)))
267
268 #define HEADER_TO_CREATOR_INFO(objhdr) ((POBJECT_HEADER_CREATOR_INFO) \
269 (!((objhdr)->Flags & OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(objhdr) - sizeof(OBJECT_HEADER_CREATOR_INFO))))
270
271 #define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER))
272
273 #define HANDLE_TO_EX_HANDLE(handle) \
274 (LONG)(((LONG)(handle) >> 2) - 1)
275 #define EX_HANDLE_TO_HANDLE(exhandle) \
276 (HANDLE)(((exhandle) + 1) << 2)
277
278 extern PDIRECTORY_OBJECT NameSpaceRoot;
279 extern POBJECT_TYPE ObSymbolicLinkType;
280 extern PHANDLE_TABLE ObpKernelHandleTable;
281
282 #define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
283 #define ObIsKernelHandle(Handle, ProcessorMode) \
284 (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) && \
285 ((ProcessorMode) == KernelMode))
286 #define ObKernelHandleToHandle(Handle) \
287 (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
288
289 VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
290 POBJECT_HEADER Header,
291 PWSTR Name);
292 VOID ObpRemoveEntryDirectory(POBJECT_HEADER Header);
293
294 VOID
295 ObInitSymbolicLinkImplementation(VOID);
296
297
298 NTSTATUS ObpCreateHandle(struct _EPROCESS* Process,
299 PVOID ObjectBody,
300 ACCESS_MASK GrantedAccess,
301 BOOLEAN Inherit,
302 PHANDLE Handle);
303 VOID ObCreateHandleTable(struct _EPROCESS* Parent,
304 BOOLEAN Inherit,
305 struct _EPROCESS* Process);
306 NTSTATUS ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
307 PUNICODE_STRING ObjectName,
308 PVOID* ReturnedObject,
309 PUNICODE_STRING RemainingPath,
310 POBJECT_TYPE ObjectType);
311
312 NTSTATUS
313 ObpQueryHandleAttributes(HANDLE Handle,
314 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
315
316 NTSTATUS
317 ObpSetHandleAttributes(HANDLE Handle,
318 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
319
320 NTSTATUS
321 STDCALL
322 ObpCreateTypeObject(struct _OBJECT_TYPE_INITIALIZER *ObjectTypeInitializer,
323 PUNICODE_STRING TypeName,
324 POBJECT_TYPE *ObjectType);
325
326 ULONG
327 ObGetObjectHandleCount(PVOID Object);
328 NTSTATUS
329 ObDuplicateObject(PEPROCESS SourceProcess,
330 PEPROCESS TargetProcess,
331 HANDLE SourceHandle,
332 PHANDLE TargetHandle,
333 ACCESS_MASK DesiredAccess,
334 BOOLEAN InheritHandle,
335 ULONG Options);
336
337 ULONG
338 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
339
340 VOID
341 STDCALL
342 ObQueryDeviceMapInformation(PEPROCESS Process, PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo);
343
344 VOID FASTCALL
345 ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent);
346
347 VOID
348 STDCALL
349 ObKillProcess(PEPROCESS Process);
350 /* Security descriptor cache functions */
351
352 NTSTATUS
353 ObpInitSdCache(VOID);
354
355 NTSTATUS
356 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD,
357 OUT PSECURITY_DESCRIPTOR *DestinationSD);
358
359 NTSTATUS
360 ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
361
362 VOID
363 ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
364
365 VOID
366 ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
367
368 VOID
369 FASTCALL
370 ObInitializeFastReference(IN PEX_FAST_REF FastRef,
371 PVOID Object);
372
373 PVOID
374 FASTCALL
375 ObFastReplaceObject(IN PEX_FAST_REF FastRef,
376 PVOID Object);
377
378 PVOID
379 FASTCALL
380 ObFastReferenceObject(IN PEX_FAST_REF FastRef);
381
382 VOID
383 FASTCALL
384 ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
385 PVOID Object);
386
387 /* Secure object information functions */
388
389 typedef struct _CAPTURED_OBJECT_ATTRIBUTES
390 {
391 HANDLE RootDirectory;
392 ULONG Attributes;
393 PSECURITY_DESCRIPTOR SecurityDescriptor;
394 PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
395 } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
396
397 NTSTATUS
398 STDCALL
399 ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
400 IN PUNICODE_STRING ObjectName,
401 IN KPROCESSOR_MODE AccessMode);
402
403 NTSTATUS
404 STDCALL
405 ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
406 IN KPROCESSOR_MODE AccessMode,
407 IN POBJECT_TYPE ObjectType,
408 IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
409 OUT PUNICODE_STRING ObjectName);
410
411 VOID
412 STDCALL
413 ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo);
414
415 /* object information classes */
416
417 #define ICIF_QUERY 0x1
418 #define ICIF_SET 0x2
419 #define ICIF_QUERY_SIZE_VARIABLE 0x4
420 #define ICIF_SET_SIZE_VARIABLE 0x8
421 #define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
422
423 typedef struct _INFORMATION_CLASS_INFO
424 {
425 ULONG RequiredSizeQUERY;
426 ULONG RequiredSizeSET;
427 ULONG AlignmentSET;
428 ULONG AlignmentQUERY;
429 ULONG Flags;
430 } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
431
432 #define ICI_SQ_SAME(Size, Alignment, Flags) \
433 { Size, Size, Alignment, Alignment, Flags }
434
435 #define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \
436 { SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags }
437
438 #define CheckInfoClass(Class, BufferLen, ClassList, StatusVar, Mode) \
439 do { \
440 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
441 { \
442 if(!(ClassList[Class].Flags & ICIF_##Mode)) \
443 { \
444 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
445 } \
446 else if(ClassList[Class].RequiredSize##Mode > 0 && \
447 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
448 { \
449 if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
450 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
451 { \
452 *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
453 } \
454 } \
455 } \
456 else \
457 { \
458 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
459 } \
460 } while(0)
461
462
463 #define GetInfoClassAlignment(Class, ClassList, AlignmentVar, Mode) \
464 do { \
465 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
466 { \
467 *(AlignmentVar) = ClassList[Class].Alignment##Mode; \
468 } \
469 else \
470 { \
471 *(AlignmentVar) = sizeof(ULONG); \
472 } \
473 } while(0)
474
475 #define ProbeQueryInfoBuffer(Buffer, BufferLen, Alignment, RetLen, PrevMode, StatusVar) \
476 do { \
477 if(PrevMode == UserMode) \
478 { \
479 _SEH_TRY \
480 { \
481 ProbeForWrite(Buffer, \
482 BufferLen, \
483 Alignment); \
484 if(RetLen != NULL) \
485 { \
486 ProbeForWrite(RetLen, \
487 sizeof(ULONG), \
488 1); \
489 } \
490 } \
491 _SEH_HANDLE \
492 { \
493 *(StatusVar) = _SEH_GetExceptionCode(); \
494 } \
495 _SEH_END; \
496 \
497 if(!NT_SUCCESS(*(StatusVar))) \
498 { \
499 DPRINT1("ProbeQueryInfoBuffer failed: 0x%x\n", *(StatusVar)); \
500 return *(StatusVar); \
501 } \
502 } \
503 } while(0)
504
505 #define ProbeSetInfoBuffer(Buffer, BufferLen, Alignment, PrevMode, StatusVar) \
506 do { \
507 if(PrevMode == UserMode) \
508 { \
509 _SEH_TRY \
510 { \
511 ProbeForRead(Buffer, \
512 BufferLen, \
513 Alignment); \
514 } \
515 _SEH_HANDLE \
516 { \
517 *(StatusVar) = _SEH_GetExceptionCode(); \
518 } \
519 _SEH_END; \
520 \
521 if(!NT_SUCCESS(*(StatusVar))) \
522 { \
523 DPRINT1("ProbeAllInfoBuffer failed: 0x%x\n", *(StatusVar)); \
524 return *(StatusVar); \
525 } \
526 } \
527 } while(0)
528
529 #define DefaultSetInfoBufferCheck(Class, ClassList, Buffer, BufferLen, PrevMode, StatusVar) \
530 do { \
531 ULONG _Alignment; \
532 /* get the preferred alignment for the information class or return */ \
533 /* default alignment in case the class doesn't exist */ \
534 GetInfoClassAlignment(Class, \
535 ClassList, \
536 &_Alignment, \
537 SET); \
538 \
539 /* probe the ENTIRE buffers and return on failure */ \
540 ProbeSetInfoBuffer(Buffer, \
541 BufferLen, \
542 _Alignment, \
543 PrevMode, \
544 StatusVar); \
545 \
546 /* validate information class index and check buffer size */ \
547 CheckInfoClass(Class, \
548 BufferLen, \
549 ClassList, \
550 StatusVar, \
551 SET); \
552 } while(0)
553
554 #define DefaultQueryInfoBufferCheck(Class, ClassList, Buffer, BufferLen, RetLen, PrevMode, StatusVar) \
555 do { \
556 ULONG _Alignment; \
557 /* get the preferred alignment for the information class or return */ \
558 /* alignment in case the class doesn't exist */ \
559 GetInfoClassAlignment(Class, \
560 ClassList, \
561 &_Alignment, \
562 QUERY); \
563 \
564 /* probe the ENTIRE buffers and return on failure */ \
565 ProbeQueryInfoBuffer(Buffer, \
566 BufferLen, \
567 _Alignment, \
568 RetLen, \
569 PrevMode, \
570 StatusVar); \
571 \
572 /* validate information class index and check buffer size */ \
573 CheckInfoClass(Class, \
574 BufferLen, \
575 ClassList, \
576 StatusVar, \
577 QUERY); \
578 } while(0)
579
580 #endif /* __INCLUDE_INTERNAL_OBJMGR_H */