ReactOS  0.4.15-dev-3207-ga415bd4
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 
21 ULONG
24 {
25  if (PreviousMode == KernelMode)
26  {
27  /* For kernel, allow any valid attributes */
29  }
30  else
31  {
32  /* For user, mask out kernel-only attributes */
33  return (Attributes & OBJ_VALID_ATTRIBUTES) &
35  }
36 }
37 
39 ULONG
41 {
42  /* We have 4 locks total, this will return a 0-index slot */
43  return (((ULONG_PTR)ObjectHeader) >> 8) & 3;
44 }
45 
47 VOID
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 */
61  ExAcquireResourceExclusiveLite(&ObjectType->ObjectLocks[Slot], TRUE);
62 }
63 
65 VOID
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 
83 VOID
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 
142 VOID
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 
184 VOID
187 {
188  /* Update lock flag */
189  Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_SHARED;
190 
191  /* Acquire an shared directory lock */
194 
195  /* Update lock flag */
196  Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_SHARED;
197 }
198 
211 VOID
214 {
215  /* Update lock flag */
217 
218  /* Acquire an exclusive directory lock */
221 
222  /* Update lock flag */
224 }
225 
237 VOID
240 {
241  /* Release the lock */
243  Context->LockStateSignature = OBP_LOCK_STATE_RELEASED;
245 }
246 
257 VOID
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 
280 VOID
283 {
284  /* Acquire an exclusive directory lock and save its lock state */
286  Context->Directory = Directory;
287  Context->DirectoryLocked = TRUE;
288 }
289 
291 VOID
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 */
308  ObDereferenceObject(Context->Object);
309  Context->Object = NULL;
310  }
311 }
312 
322 VOID
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 
339 VOID
341 {
342  /* Sanity check */
344 
345  /* Enter a critical region and acquire the resource */
348 }
349 
351 VOID
353 {
354  /* Enter a critical region and acquire the resource */
357 
358  /* Sanity check */
360 }
361 
363 VOID
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 
378 PVOID
380 {
381  PVOID Buffer;
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 
415 VOID
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 
459 VOID
461 {
462  /* First release the attributes, then free them from the lookaside list */
463  ObpReleaseObjectCreateInformation(ObjectCreateInfo);
465 }
466 
467 #if DBG
469 VOID
470 ObpCalloutStart(IN PKIRQL CalloutIrql)
471 {
472  /* Save the callout IRQL */
473  *CalloutIrql = KeGetCurrentIrql();
474 }
475 
477 VOID
478 ObpCalloutEnd(IN KIRQL CalloutIrql,
479  IN PCHAR Procedure,
481  IN PVOID Object)
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);
491  DbgBreakPoint();
492  }
493 }
494 #else
496 VOID
498 {
499  /* No-op */
500  UNREFERENCED_PARAMETER(CalloutIrql);
501 }
502 
504 VOID
505 ObpCalloutEnd(IN KIRQL CalloutIrql,
506  IN PCHAR Procedure,
508  IN PVOID Object)
509 {
510  UNREFERENCED_PARAMETER(CalloutIrql);
511 }
512 #endif
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
signed char * PCHAR
Definition: retypes.h:7
ObjectType
Definition: metafile.c:80
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
#define IN
Definition: typedefs.h:39
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:416
#define OBJ_VALID_ATTRIBUTES
Definition: winternl.h:233
#define DbgPrint
Definition: hal.h:12
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST * PNPAGED_LOOKASIDE_LIST
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UCHAR KIRQL
Definition: env_spec_w32.h:591
FORCEINLINE PVOID ObpAllocateObjectCreateInfoBuffer(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:379
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:628
#define OBP_LOCK_STATE_RELEASED
Definition: ob_x.h:15
#define FALSE
Definition: types.h:117
VOID NTAPI DbgBreakPoint(VOID)
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:358
#define OBP_LOCK_STATE_INITIALIZED
Definition: ob_x.h:16
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 ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
Directory()
Definition: entries.h:140
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
Definition: bufpool.h:45
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define OB_NAME_TAG
Definition: tag.h:151
#define OBP_LOCK_STATE_POST_ACQUISITION_SHARED
Definition: ob_x.h:14
FORCEINLINE ULONG ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:40
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
#define ObDereferenceObject
Definition: obfuncs.h:203
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
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
Type
Definition: Type.h:6
FORCEINLINE VOID ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:66
#define PSLIST_ENTRY
Definition: rtltypes.h:134
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
struct _GENERAL_LOOKASIDE * L
Definition: ketypes.h:802
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
#define InterlockedDecrement
Definition: armddk.h:52
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1294
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 VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1103
#define OBP_LOCK_STATE_PRE_ACQUISITION_SHARED
Definition: ob_x.h:12
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
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
FORCEINLINE VOID ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:292
struct _GENERAL_LOOKASIDE * P
Definition: ketypes.h:801
#define OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE
Definition: ob_x.h:13
#define FORCEINLINE
Definition: wdftypes.h:67
#define NULL
Definition: types.h:112
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
enum _PP_NPAGED_LOOKASIDE_NUMBER PP_NPAGED_LOOKASIDE_NUMBER
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
signed int * PLONG
Definition: retypes.h:5
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define OBP_LOCK_STATE_PRE_ACQUISITION_EXCLUSIVE
Definition: ob_x.h:11
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
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