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