Thread/Process Termination/Repeaing Rewrite + Fixes
[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 struct
20 {
21 CSHORT Type;
22 CSHORT Size;
23 } COMMON_BODY_HEADER, *PCOMMON_BODY_HEADER;
24
25 typedef PVOID POBJECT;
26
27
28 typedef struct _OBJECT_TYPE
29 {
30 /*
31 * PURPOSE: Tag to be used when allocating objects of this type
32 */
33 ULONG Tag;
34
35 /*
36 * PURPOSE: Name of the type
37 */
38 UNICODE_STRING TypeName;
39
40 /*
41 * PURPOSE: Total number of objects of this type
42 */
43 ULONG TotalObjects;
44
45 /*
46 * PURPOSE: Total number of handles of this type
47 */
48 ULONG TotalHandles;
49
50 /*
51 * PURPOSE: Peak objects of this type
52 */
53 ULONG PeakObjects;
54
55 /*
56 * PURPOSE: Peak handles of this type
57 */
58 ULONG PeakHandles;
59
60 /*
61 * PURPOSE: Paged pool charge
62 */
63 ULONG PagedPoolCharge;
64
65 /*
66 * PURPOSE: Nonpaged pool charge
67 */
68 ULONG NonpagedPoolCharge;
69
70 /*
71 * PURPOSE: Mapping of generic access rights
72 */
73 PGENERIC_MAPPING Mapping;
74
75 /*
76 * PURPOSE: Dumps the object
77 * NOTE: To be defined
78 */
79 VOID STDCALL_FUNC (*Dump)(VOID);
80
81 /*
82 * PURPOSE: Opens the object
83 * NOTE: To be defined
84 */
85 VOID STDCALL_FUNC (*Open)(VOID);
86
87 /*
88 * PURPOSE: Called to close an object if OkayToClose returns true
89 */
90 VOID STDCALL_FUNC (*Close)(PVOID ObjectBody,
91 ULONG HandleCount);
92
93 /*
94 * PURPOSE: Called to delete an object when the last reference is removed
95 */
96 VOID STDCALL_FUNC (*Delete)(PVOID ObjectBody);
97
98 /*
99 * PURPOSE: Called when an open attempts to open a file apparently
100 * residing within the object
101 * RETURNS
102 * STATUS_SUCCESS NextObject was found
103 * STATUS_UNSUCCESSFUL NextObject not found
104 * STATUS_REPARSE Path changed, restart parsing the path
105 */
106 NTSTATUS STDCALL_FUNC (*Parse)(PVOID ParsedObject,
107 PVOID *NextObject,
108 PUNICODE_STRING FullPath,
109 PWSTR *Path,
110 ULONG Attributes);
111
112 /*
113 * PURPOSE: Called to set, query, delete or assign a security-descriptor
114 * to the object
115 * RETURNS
116 * STATUS_SUCCESS NextObject was found
117 */
118 NTSTATUS STDCALL_FUNC (*Security)(PVOID ObjectBody,
119 SECURITY_OPERATION_CODE OperationCode,
120 SECURITY_INFORMATION SecurityInformation,
121 PSECURITY_DESCRIPTOR SecurityDescriptor,
122 PULONG BufferLength);
123
124 /*
125 * PURPOSE: Called to query the name of the object
126 * RETURNS
127 * STATUS_SUCCESS NextObject was found
128 */
129 NTSTATUS STDCALL_FUNC (*QueryName)(PVOID ObjectBody,
130 POBJECT_NAME_INFORMATION ObjectNameInfo,
131 ULONG Length,
132 PULONG ReturnLength);
133
134 /*
135 * PURPOSE: Called when a process asks to close the object
136 */
137 VOID STDCALL_FUNC (*OkayToClose)(VOID);
138
139 NTSTATUS STDCALL_FUNC (*Create)(PVOID ObjectBody,
140 PVOID Parent,
141 PWSTR RemainingPath,
142 struct _OBJECT_ATTRIBUTES* ObjectAttributes);
143
144 VOID STDCALL_FUNC (*DuplicationNotify)(PEPROCESS DuplicateTo,
145 PEPROCESS DuplicateFrom,
146 PVOID Object);
147 } OBJECT_TYPE;
148
149
150
151 typedef struct _OBJECT_HEADER
152 /*
153 * PURPOSE: Header for every object managed by the object manager
154 */
155 {
156 UNICODE_STRING Name;
157 LIST_ENTRY Entry;
158 LONG RefCount;
159 LONG HandleCount;
160 BOOLEAN Permanent;
161 BOOLEAN Inherit;
162 struct _DIRECTORY_OBJECT* Parent;
163 POBJECT_TYPE ObjectType;
164 PSECURITY_DESCRIPTOR SecurityDescriptor;
165
166 /*
167 * PURPOSE: Object type
168 * NOTE: This overlaps the first member of the object body
169 */
170 CSHORT Type;
171
172 /*
173 * PURPOSE: Object size
174 * NOTE: This overlaps the second member of the object body
175 */
176 CSHORT Size;
177
178
179 } OBJECT_HEADER, *POBJECT_HEADER;
180
181
182 typedef struct _DIRECTORY_OBJECT
183 {
184 CSHORT Type;
185 CSHORT Size;
186
187 /*
188 * PURPOSE: Head of the list of our subdirectories
189 */
190 LIST_ENTRY head;
191 KSPIN_LOCK Lock;
192 } DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
193
194 typedef struct _SYMLINK_OBJECT
195 {
196 CSHORT Type;
197 CSHORT Size;
198 UNICODE_STRING TargetName;
199 LARGE_INTEGER CreateTime;
200 } SYMLINK_OBJECT, *PSYMLINK_OBJECT;
201
202
203 typedef struct _TYPE_OBJECT
204 {
205 CSHORT Type;
206 CSHORT Size;
207
208 /* pointer to object type data */
209 POBJECT_TYPE ObjectType;
210 } TYPE_OBJECT, *PTYPE_OBJECT;
211
212
213 /*
214 * Enumeration of object types
215 */
216 enum
217 {
218 OBJTYP_INVALID,
219 OBJTYP_TYPE,
220 OBJTYP_DIRECTORY,
221 OBJTYP_SYMLNK,
222 OBJTYP_DEVICE,
223 OBJTYP_THREAD,
224 OBJTYP_FILE,
225 OBJTYP_PROCESS,
226 OBJTYP_SECTION,
227 OBJTYP_MAX,
228 };
229
230 #define HEADER_TO_BODY(objhdr) \
231 (PVOID)((ULONG_PTR)objhdr + sizeof(OBJECT_HEADER) - sizeof(COMMON_BODY_HEADER))
232
233 #define BODY_TO_HEADER(objbdy) \
234 CONTAINING_RECORD(&(((PCOMMON_BODY_HEADER)objbdy)->Type), OBJECT_HEADER, Type)
235
236 #define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER))
237
238 #define HANDLE_TO_EX_HANDLE(handle) \
239 (LONG)(((LONG)(handle) >> 2) - 1)
240 #define EX_HANDLE_TO_HANDLE(exhandle) \
241 (HANDLE)(((exhandle) + 1) << 2)
242
243 extern PDIRECTORY_OBJECT NameSpaceRoot;
244 extern POBJECT_TYPE ObSymbolicLinkType;
245
246 VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
247 POBJECT_HEADER Header,
248 PWSTR Name);
249 VOID ObpRemoveEntryDirectory(POBJECT_HEADER Header);
250
251 VOID
252 ObInitSymbolicLinkImplementation(VOID);
253
254
255 NTSTATUS ObCreateHandle(struct _EPROCESS* Process,
256 PVOID ObjectBody,
257 ACCESS_MASK GrantedAccess,
258 BOOLEAN Inherit,
259 PHANDLE Handle);
260 VOID ObCreateHandleTable(struct _EPROCESS* Parent,
261 BOOLEAN Inherit,
262 struct _EPROCESS* Process);
263 NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
264 PVOID* ReturnedObject,
265 PUNICODE_STRING RemainingPath,
266 POBJECT_TYPE ObjectType);
267 VOID ObDeleteHandleTable(struct _EPROCESS* Process);
268
269 NTSTATUS
270 ObDeleteHandle(PEPROCESS Process,
271 HANDLE Handle);
272
273 NTSTATUS
274 ObpQueryHandleAttributes(HANDLE Handle,
275 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
276
277 NTSTATUS
278 ObpSetHandleAttributes(HANDLE Handle,
279 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
280
281 NTSTATUS
282 ObpCreateTypeObject(POBJECT_TYPE ObjectType);
283
284 ULONG
285 ObGetObjectHandleCount(PVOID Object);
286 NTSTATUS
287 ObDuplicateObject(PEPROCESS SourceProcess,
288 PEPROCESS TargetProcess,
289 HANDLE SourceHandle,
290 PHANDLE TargetHandle,
291 ACCESS_MASK DesiredAccess,
292 BOOLEAN InheritHandle,
293 ULONG Options);
294
295 ULONG
296 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
297
298 VOID
299 STDCALL
300 ObQueryDeviceMapInformation(PEPROCESS Process, PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo);
301
302 VOID FASTCALL
303 ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent);
304
305 VOID
306 STDCALL
307 ObKillProcess(PEPROCESS Process);
308 /* Security descriptor cache functions */
309
310 NTSTATUS
311 ObpInitSdCache(VOID);
312
313 NTSTATUS
314 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD,
315 OUT PSECURITY_DESCRIPTOR *DestinationSD);
316
317 NTSTATUS
318 ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
319
320 VOID
321 ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
322
323 VOID
324 ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
325
326 /* Secure object information functions */
327
328 typedef struct _CAPTURED_OBJECT_ATTRIBUTES
329 {
330 HANDLE RootDirectory;
331 ULONG Attributes;
332 PSECURITY_DESCRIPTOR SecurityDescriptor;
333 PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
334 } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
335
336 NTSTATUS
337 ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
338 IN KPROCESSOR_MODE AccessMode,
339 IN POOL_TYPE PoolType,
340 IN BOOLEAN CaptureIfKernel,
341 OUT PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes OPTIONAL,
342 OUT PUNICODE_STRING ObjectName OPTIONAL);
343
344 VOID
345 ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes OPTIONAL,
346 IN PUNICODE_STRING ObjectName OPTIONAL,
347 IN KPROCESSOR_MODE AccessMode,
348 IN BOOLEAN CaptureIfKernel);
349
350 /* object information classes */
351
352 #define ICIF_QUERY 0x1
353 #define ICIF_SET 0x2
354 #define ICIF_QUERY_SIZE_VARIABLE 0x4
355 #define ICIF_SET_SIZE_VARIABLE 0x8
356 #define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
357
358 typedef struct _INFORMATION_CLASS_INFO
359 {
360 ULONG RequiredSizeQUERY;
361 ULONG RequiredSizeSET;
362 ULONG AlignmentSET;
363 ULONG AlignmentQUERY;
364 ULONG Flags;
365 } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
366
367 #define ICI_SQ_SAME(Size, Alignment, Flags) \
368 { Size, Size, Alignment, Alignment, Flags }
369
370 #define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \
371 { SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags }
372
373 #define CheckInfoClass(Class, BufferLen, ClassList, StatusVar, Mode) \
374 do { \
375 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
376 { \
377 if(!(ClassList[Class].Flags & ICIF_##Mode)) \
378 { \
379 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
380 } \
381 else if(ClassList[Class].RequiredSize##Mode > 0 && \
382 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
383 { \
384 if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
385 (BufferLen) != ClassList[Class].RequiredSize##Mode) \
386 { \
387 *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
388 } \
389 } \
390 } \
391 else \
392 { \
393 *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
394 } \
395 } while(0)
396
397
398 #define GetInfoClassAlignment(Class, ClassList, AlignmentVar, Mode) \
399 do { \
400 if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
401 { \
402 *(AlignmentVar) = ClassList[Class].Alignment##Mode; \
403 } \
404 else \
405 { \
406 *(AlignmentVar) = sizeof(ULONG); \
407 } \
408 } while(0)
409
410 #define ProbeQueryInfoBuffer(Buffer, BufferLen, Alignment, RetLen, PrevMode, StatusVar) \
411 do { \
412 if(PrevMode == UserMode) \
413 { \
414 _SEH_TRY \
415 { \
416 ProbeForWrite(Buffer, \
417 BufferLen, \
418 Alignment); \
419 if(RetLen != NULL) \
420 { \
421 ProbeForWrite(RetLen, \
422 sizeof(ULONG), \
423 1); \
424 } \
425 } \
426 _SEH_HANDLE \
427 { \
428 *(StatusVar) = _SEH_GetExceptionCode(); \
429 } \
430 _SEH_END; \
431 \
432 if(!NT_SUCCESS(*(StatusVar))) \
433 { \
434 DPRINT1("ProbeQueryInfoBuffer failed: 0x%x\n", *(StatusVar)); \
435 return *(StatusVar); \
436 } \
437 } \
438 } while(0)
439
440 #define ProbeSetInfoBuffer(Buffer, BufferLen, Alignment, PrevMode, StatusVar) \
441 do { \
442 if(PrevMode == UserMode) \
443 { \
444 _SEH_TRY \
445 { \
446 ProbeForRead(Buffer, \
447 BufferLen, \
448 Alignment); \
449 } \
450 _SEH_HANDLE \
451 { \
452 *(StatusVar) = _SEH_GetExceptionCode(); \
453 } \
454 _SEH_END; \
455 \
456 if(!NT_SUCCESS(*(StatusVar))) \
457 { \
458 DPRINT1("ProbeAllInfoBuffer failed: 0x%x\n", *(StatusVar)); \
459 return *(StatusVar); \
460 } \
461 } \
462 } while(0)
463
464 #define DefaultSetInfoBufferCheck(Class, ClassList, Buffer, BufferLen, PrevMode, StatusVar) \
465 do { \
466 ULONG _Alignment; \
467 /* get the preferred alignment for the information class or return */ \
468 /* default alignment in case the class doesn't exist */ \
469 GetInfoClassAlignment(Class, \
470 ClassList, \
471 &_Alignment, \
472 SET); \
473 \
474 /* probe the ENTIRE buffers and return on failure */ \
475 ProbeSetInfoBuffer(Buffer, \
476 BufferLen, \
477 _Alignment, \
478 PrevMode, \
479 StatusVar); \
480 \
481 /* validate information class index and check buffer size */ \
482 CheckInfoClass(Class, \
483 BufferLen, \
484 ClassList, \
485 StatusVar, \
486 SET); \
487 } while(0)
488
489 #define DefaultQueryInfoBufferCheck(Class, ClassList, Buffer, BufferLen, RetLen, PrevMode, StatusVar) \
490 do { \
491 ULONG _Alignment; \
492 /* get the preferred alignment for the information class or return */ \
493 /* alignment in case the class doesn't exist */ \
494 GetInfoClassAlignment(Class, \
495 ClassList, \
496 &_Alignment, \
497 QUERY); \
498 \
499 /* probe the ENTIRE buffers and return on failure */ \
500 ProbeQueryInfoBuffer(Buffer, \
501 BufferLen, \
502 _Alignment, \
503 RetLen, \
504 PrevMode, \
505 StatusVar); \
506 \
507 /* validate information class index and check buffer size */ \
508 CheckInfoClass(Class, \
509 BufferLen, \
510 ClassList, \
511 StatusVar, \
512 QUERY); \
513 } while(0)
514
515 #endif /* __INCLUDE_INTERNAL_OBJMGR_H */