ReactOS 0.4.15-dev-7934-g1dc8d80
ob_x.h
Go to the documentation of this file.
1/*
2* PROJECT: ReactOS Kernel
3* LICENSE: GPL - See COPYING in the top level directory
4* FILE: ntoskrnl/include/internal/ob_x.h
5* PURPOSE: Internal Inlined Functions for the Object Manager
6* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7*/
8
9#include "ex.h"
10
11#define OBP_LOCK_STATE_PRE_ACQUISITION_EXCLUSIVE 0xAAAA1234
12#define OBP_LOCK_STATE_PRE_ACQUISITION_SHARED 0xBBBB1234
13#define OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE 0xCCCC1234
14#define OBP_LOCK_STATE_POST_ACQUISITION_SHARED 0xDDDD1234
15#define OBP_LOCK_STATE_RELEASED 0xEEEE1234
16#define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234
17
18#define OBP_NAME_LOOKASIDE_MAX_SIZE 248
19
24{
26 {
27 /* For kernel, allow any valid attributes */
29 }
30 else
31 {
32 /* For user, mask out kernel-only attributes */
35 }
36}
37
41{
42 /* We have 4 locks total, this will return a 0-index slot */
43 return (((ULONG_PTR)ObjectHeader) >> 8) & 3;
44}
45
47VOID
49{
50 ULONG Slot;
51 POBJECT_TYPE ObjectType = ObjectHeader->Type;
52
53 /* Sanity check */
55
56 /* Pick a slot */
57 Slot = ObpSelectObjectLockSlot(ObjectHeader);
58
59 /* Enter a critical region and acquire the resource */
62}
63
65VOID
67{
68 ULONG Slot;
69 POBJECT_TYPE ObjectType = ObjectHeader->Type;
70
71 /* Sanity check */
73
74 /* Pick a slot */
75 Slot = ObpSelectObjectLockSlot(ObjectHeader);
76
77 /* Enter a critical region and acquire the resource */
79 ExAcquireResourceSharedLite(&ObjectType->ObjectLocks[Slot], TRUE);
80}
81
83VOID
85{
86 ULONG Slot;
87 POBJECT_TYPE ObjectType = ObjectHeader->Type;
88
89 /* Pick a slot */
90 Slot = ObpSelectObjectLockSlot(ObjectHeader);
91
92 /* Release the resource and leave a critical region */
93 ExReleaseResourceLite(&ObjectType->ObjectLocks[Slot]);
95
96 /* Sanity check */
98}
99
103{
104 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
105 ULONG NewValue, References;
106
107 /* Make sure we have name information at all */
108 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
109 if (!ObjectNameInfo) return NULL;
110
111 /* Get the number of references */
112 References = ObjectNameInfo->QueryReferences;
113 for (;;)
114 {
115 /* Check if the count is 0 and fail if so */
116 if (!References) return NULL;
117
118 /* Increment the number of references */
119 NewValue = InterlockedCompareExchange((PLONG)&ObjectNameInfo->
120 QueryReferences,
121 References + 1,
122 References);
123 if (NewValue == References) break;
124
125 /* We failed, try again */
126 References = NewValue;
127 }
128
129 /* Check for magic flag */
130 if (ObjectNameInfo->QueryReferences & 0x80000000)
131 {
132 /* FIXME: Unhandled*/
133 DbgPrint("OB: Unhandled path\n");
134 ASSERT(FALSE);
135 }
136
137 /* Return the name information */
138 return ObjectNameInfo;
139}
140
142VOID
144{
146
147 /* Bail out if there's no info at all */
148 if (!HeaderNameInfo) return;
149
150 /* Remove a query reference and check if it was the last one */
151 if (!InterlockedDecrement((PLONG)&HeaderNameInfo->QueryReferences))
152 {
153 /* Check if we have a name */
154 if (HeaderNameInfo->Name.Buffer)
155 {
156 /* We can get rid of the object name now */
157 ExFreePoolWithTag(HeaderNameInfo->Name.Buffer, OB_NAME_TAG);
158 RtlInitEmptyUnicodeString(&HeaderNameInfo->Name, NULL, 0);
159 }
160
161 /* Check if the object has a directory associated to it */
162 Directory = HeaderNameInfo->Directory;
163 if (Directory)
164 {
165 /* Delete the directory */
166 HeaderNameInfo->Directory = NULL;
168 }
169 }
170}
171
184VOID
187{
188 /* Update lock flag */
190
191 /* Acquire an shared directory lock */
194
195 /* Update lock flag */
197}
198
211VOID
214{
215 /* Update lock flag */
217
218 /* Acquire an exclusive directory lock */
221
222 /* Update lock flag */
224}
225
237VOID
240{
241 /* Release the lock */
243 Context->LockStateSignature = OBP_LOCK_STATE_RELEASED;
245}
246
257VOID
259{
260 /* Initialize a null context */
261 Context->Object = NULL;
262 Context->Directory = NULL;
263 Context->DirectoryLocked = FALSE;
264 Context->LockStateSignature = OBP_LOCK_STATE_INITIALIZED;
265}
266
280VOID
283{
284 /* Acquire an exclusive directory lock and save its lock state */
286 Context->Directory = Directory;
287 Context->DirectoryLocked = TRUE;
288}
289
291VOID
293{
294 POBJECT_HEADER ObjectHeader;
295 POBJECT_HEADER_NAME_INFO HeaderNameInfo;
296
297 /* Check if we had an object */
298 if (Context->Object)
299 {
300 /* Get the object name information */
301 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
302 HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
303
304 /* Release the name information */
305 ObpDereferenceNameInfo(HeaderNameInfo);
306
307 /* Dereference the object */
309 Context->Object = NULL;
310 }
311}
312
322VOID
324{
325 /* Check if we came back with the directory locked */
326 if (Context->DirectoryLocked)
327 {
328 /* Release the directory lock */
330 Context->Directory = NULL;
331 Context->DirectoryLocked = FALSE;
332 }
333
334 /* Clear the context */
336}
337
339VOID
341{
342 /* Sanity check */
344
345 /* Enter a critical region and acquire the resource */
348}
349
351VOID
353{
354 /* Enter a critical region and acquire the resource */
357
358 /* Sanity check */
360}
361
363VOID
365{
366 /* Check if we have a security descriptor */
367 if (ObjectCreateInfo->SecurityDescriptor)
368 {
369 /* Release it */
370 SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
371 ObjectCreateInfo->ProbeMode,
372 TRUE);
373 ObjectCreateInfo->SecurityDescriptor = NULL;
374 }
375}
376
378PVOID
380{
383 PKPRCB Prcb = KeGetCurrentPrcb();
384
385 /* Get the P list first */
387
388 /* Attempt allocation */
389 List->L.TotalAllocates++;
390 Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
391 if (!Buffer)
392 {
393 /* Let the balancer know that the P list failed */
394 List->L.AllocateMisses++;
395
396 /* Try the L List */
398 List->L.TotalAllocates++;
399 Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
400 if (!Buffer)
401 {
402 /* Let the balancer know the L list failed too */
403 List->L.AllocateMisses++;
404
405 /* Allocate it */
406 Buffer = List->L.Allocate(List->L.Type, List->L.Size, List->L.Tag);
407 }
408 }
409
410 /* Return buffer */
411 return Buffer;
412}
413
415VOID
418{
420 PKPRCB Prcb = KeGetCurrentPrcb();
421
422 /* Use the P List */
424 List->L.TotalFrees++;
425
426 /* Check if the Free was within the Depth or not */
427 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
428 {
429 /* Let the balancer know */
430 List->L.FreeMisses++;
431
432 /* Use the L List */
434 List->L.TotalFrees++;
435
436 /* Check if the Free was within the Depth or not */
437 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
438 {
439 /* All lists failed, use the pool */
440 List->L.FreeMisses++;
441 List->L.Free(Buffer);
442 }
443 else
444 {
445 /* The free was within the Depth */
446 InterlockedPushEntrySList(&List->L.ListHead,
448 }
449 }
450 else
451 {
452 /* The free was within the Depth */
453 InterlockedPushEntrySList(&List->L.ListHead,
455 }
456}
457
459VOID
461{
462 /* First release the attributes, then free them from the lookaside list */
463 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
465}
466
467#if DBG
469VOID
470ObpCalloutStart(IN PKIRQL CalloutIrql)
471{
472 /* Save the callout IRQL */
473 *CalloutIrql = KeGetCurrentIrql();
474}
475
477VOID
478ObpCalloutEnd(IN KIRQL CalloutIrql,
479 IN PCHAR Procedure,
482{
483 /* Detect IRQL change */
484 if (CalloutIrql != KeGetCurrentIrql())
485 {
486 /* Print error */
487 DbgPrint("OB: ObjectType: %wZ Procedure: %s Object: %p\n",
488 &ObjectType->Name, Procedure, Object);
489 DbgPrint(" Returned at %x IRQL, but was called at %x IRQL\n",
490 KeGetCurrentIrql(), CalloutIrql);
492 }
493}
494#else
496VOID
498{
499 /* No-op */
500 UNREFERENCED_PARAMETER(CalloutIrql);
501}
502
504VOID
506 IN PCHAR Procedure,
509{
510 UNREFERENCED_PARAMETER(CalloutIrql);
511}
512#endif
Type
Definition: Type.h:7
#define InterlockedDecrement
Definition: armddk.h:52
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1296
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1036
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1105
#define DbgPrint
Definition: hal.h:12
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_VALID_ATTRIBUTES
Definition: winternl.h:233
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
ObjectType
Definition: metafile.c:81
#define KernelMode
Definition: asm.h:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1146
enum _PP_NPAGED_LOOKASIDE_NUMBER PP_NPAGED_LOOKASIDE_NUMBER
@ LookasideCreateInfoList
Definition: mmtypes.h:171
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Locks a directory for exclusive access. Used for writing/reading members of the directory object.
Definition: ob_x.h:212
#define OBP_LOCK_STATE_PRE_ACQUISITION_EXCLUSIVE
Definition: ob_x.h:11
#define OBP_LOCK_STATE_RELEASED
Definition: ob_x.h:15
FORCEINLINE VOID ObpAcquireLookupContextLock(IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_DIRECTORY Directory)
Locks an object directory lookup context for performing lookup operations (insertions/deletions) in a...
Definition: ob_x.h:281
#define OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE
Definition: ob_x.h:13
FORCEINLINE VOID ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Locks a directory for shared access. Used for reading members of the directory object.
Definition: ob_x.h:185
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Initializes a new object directory lookup context. Used for lookup operations (insertions/deletions) ...
Definition: ob_x.h:258
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
FORCEINLINE VOID ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:66
#define OBP_LOCK_STATE_POST_ACQUISITION_SHARED
Definition: ob_x.h:14
#define OBP_LOCK_STATE_PRE_ACQUISITION_SHARED
Definition: ob_x.h:12
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
#define OBP_LOCK_STATE_INITIALIZED
Definition: ob_x.h:16
FORCEINLINE PVOID ObpAllocateObjectCreateInfoBuffer(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:379
FORCEINLINE VOID ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:292
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
FORCEINLINE VOID ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Unlocks a previously shared or exclusively locked directory.
Definition: ob_x.h:238
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Releases an initialized object directory lookup context. Unlocks it if necessary, and dereferences th...
Definition: ob_x.h:323
FORCEINLINE ULONG ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:40
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:416
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:358
base for all directory entries
Definition: entries.h:138
Directory()
Definition: entries.h:140
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:693
struct _GENERAL_LOOKASIDE * P
Definition: ketypes.h:871
struct _GENERAL_LOOKASIDE * L
Definition: ketypes.h:872
#define OB_NAME_TAG
Definition: tag.h:118
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define FORCEINLINE
Definition: wdftypes.h:67
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST * PNPAGED_LOOKASIDE_LIST
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392
#define PSLIST_ENTRY
Definition: rtltypes.h:134
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103