ReactOS  0.4.15-dev-3297-g037c744
obdir.c
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/ob/obdir.c
5  * PURPOSE: Manages the Object Manager's Directory Implementation,
6  * such as functions for addition, deletion and lookup into
7  * the Object Manager's namespace. These routines are separate
8  * from the Namespace Implementation because they are largely
9  * independent and could be used for other namespaces.
10  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
11  * Thomas Weidenmueller (w3seek@reactos.org)
12  */
13 
14 /* INCLUDES ***************************************************************/
15 
16 #include <ntoskrnl.h>
17 #define NDEBUG
18 #include <debug.h>
19 
21 
22 /* PRIVATE FUNCTIONS ******************************************************/
23 
24 /*++
25 * @name ObpInsertEntryDirectory
26 *
27 * The ObpInsertEntryDirectory routine <FILLMEIN>.
28 *
29 * @param Parent
30 * <FILLMEIN>.
31 *
32 * @param Context
33 * <FILLMEIN>.
34 *
35 * @param ObjectHeader
36 * <FILLMEIN>.
37 *
38 * @return TRUE if the object was inserted, FALSE otherwise.
39 *
40 * @remarks None.
41 *
42 *--*/
43 BOOLEAN
44 NTAPI
47  IN POBJECT_HEADER ObjectHeader)
48 {
49  POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
50  POBJECT_DIRECTORY_ENTRY NewEntry;
51  POBJECT_HEADER_NAME_INFO HeaderNameInfo;
52 
53  /* Make sure we have a name */
54  ASSERT(ObjectHeader->NameInfoOffset != 0);
55 
56  /* Validate the context */
57  if ((Context->Object) ||
58  !(Context->DirectoryLocked) ||
59  (Parent != Context->Directory))
60  {
61  /* Invalid context */
62  DPRINT1("OB: ObpInsertEntryDirectory - invalid context %p %u\n",
63  Context, Context->DirectoryLocked);
64  ASSERT(FALSE);
65  return FALSE;
66  }
67 
68  /* Allocate a new Directory Entry */
70  sizeof(OBJECT_DIRECTORY_ENTRY),
71  OB_DIR_TAG);
72  if (!NewEntry) return FALSE;
73 
74  /* Save the hash */
75  NewEntry->HashValue = Context->HashValue;
76 
77  /* Get the Object Name Information */
78  HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
79 
80  /* Get the Allocated entry */
81  AllocatedEntry = &Parent->HashBuckets[Context->HashIndex];
82 
83  /* Set it */
84  NewEntry->ChainLink = *AllocatedEntry;
85  *AllocatedEntry = NewEntry;
86 
87  /* Associate the Object */
88  NewEntry->Object = &ObjectHeader->Body;
89 
90  /* Associate the Directory */
91  HeaderNameInfo->Directory = Parent;
92  return TRUE;
93 }
94 
95 /*++
96 * @name ObpGetShadowDirectory
97 *
98 * The ObpGetShadowDirectory routine <FILLMEIN>.
99 *
100 * @param Directory
101 * <FILLMEIN>.
102 *
103 * @return Pointer to the global DOS directory if any, or NULL otherwise.
104 *
105 * @remarks None.
106 *
107 *--*/
109 NTAPI
111 {
112  PDEVICE_MAP DeviceMap;
113  POBJECT_DIRECTORY GlobalDosDirectory = NULL;
114 
115  /* Acquire the device map lock */
117 
118  /* Get the global DOS directory if any */
119  DeviceMap = Directory->DeviceMap;
120  if (DeviceMap != NULL)
121  {
122  GlobalDosDirectory = DeviceMap->GlobalDosDevicesDirectory;
123  }
124 
125  /* Release the devicemap lock */
127 
128  return GlobalDosDirectory;
129 }
130 
131 /*++
132 * @name ObpLookupEntryDirectory
133 *
134 * The ObpLookupEntryDirectory routine <FILLMEIN>.
135 *
136 * @param Directory
137 * <FILLMEIN>.
138 *
139 * @param Name
140 * <FILLMEIN>.
141 *
142 * @param Attributes
143 * <FILLMEIN>.
144 *
145 * @param SearchShadow
146 * <FILLMEIN>.
147 *
148 * @param Context
149 * <FILLMEIN>.
150 *
151 * @return Pointer to the object which was found, or NULL otherwise.
152 *
153 * @remarks None.
154 *
155 *--*/
156 PVOID
157 NTAPI
161  IN UCHAR SearchShadow,
163 {
165  POBJECT_HEADER_NAME_INFO HeaderNameInfo;
166  POBJECT_HEADER ObjectHeader;
168  ULONG HashIndex;
169  LONG TotalChars;
170  WCHAR CurrentChar;
171  POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
172  POBJECT_DIRECTORY_ENTRY *LookupBucket;
173  POBJECT_DIRECTORY_ENTRY CurrentEntry;
174  PVOID FoundObject = NULL;
175  PWSTR Buffer;
176  POBJECT_DIRECTORY ShadowDirectory;
177 
178  PAGED_CODE();
179 
180  /* Check if we should search the shadow directory */
181  if (ObpLUIDDeviceMapsEnabled == 0) SearchShadow = FALSE;
182 
183  /* Fail if we don't have a directory or name */
184  if (!(Directory) || !(Name)) goto Quickie;
185 
186  /* Get name information */
187  TotalChars = Name->Length / sizeof(WCHAR);
188  Buffer = Name->Buffer;
189 
190  /* Set up case-sensitivity */
192 
193  /* Fail if the name is empty */
194  if (!(Buffer) || !(TotalChars)) goto Quickie;
195 
196  /* Create the Hash */
197  for (HashValue = 0; TotalChars; TotalChars--)
198  {
199  /* Go to the next Character */
200  CurrentChar = *Buffer++;
201 
202  /* Prepare the Hash */
203  HashValue += (HashValue << 1) + (HashValue >> 1);
204 
205  /* Create the rest based on the name */
206  if (CurrentChar < 'a') HashValue += CurrentChar;
207  else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
208  else HashValue += (CurrentChar - ('a'-'A'));
209  }
210 
211  /* Merge it with our number of hash buckets */
212  HashIndex = HashValue % 37;
213 
214  /* Save the result */
215  Context->HashValue = HashValue;
216  Context->HashIndex = (USHORT)HashIndex;
217 
218 DoItAgain:
219  /* Get the root entry and set it as our lookup bucket */
220  AllocatedEntry = &Directory->HashBuckets[HashIndex];
221  LookupBucket = AllocatedEntry;
222 
223  /* Check if the directory is already locked */
224  if (!Context->DirectoryLocked)
225  {
226  /* Lock it */
228  }
229 
230  /* Start looping */
231  while ((CurrentEntry = *AllocatedEntry))
232  {
233  /* Do the hashes match? */
234  if (CurrentEntry->HashValue == HashValue)
235  {
236  /* Make sure that it has a name */
237  ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object);
238 
239  /* Get the name information */
240  ASSERT(ObjectHeader->NameInfoOffset != 0);
241  HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
242 
243  /* Do the names match? */
244  if ((Name->Length == HeaderNameInfo->Name.Length) &&
245  (RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
246  {
247  break;
248  }
249  }
250 
251  /* Move to the next entry */
252  AllocatedEntry = &CurrentEntry->ChainLink;
253  }
254 
255  /* Check if we still have an entry */
256  if (CurrentEntry)
257  {
258  /* Set this entry as the first, to speed up incoming insertion */
259  if (AllocatedEntry != LookupBucket)
260  {
261  /* Check if the directory was locked or convert the lock */
262  if ((Context->DirectoryLocked) ||
264  {
265  /* Set the Current Entry */
266  *AllocatedEntry = CurrentEntry->ChainLink;
267 
268  /* Link to the old Hash Entry */
269  CurrentEntry->ChainLink = *LookupBucket;
270 
271  /* Set the new Hash Entry */
272  *LookupBucket = CurrentEntry;
273  }
274  }
275 
276  /* Save the found object */
277  FoundObject = CurrentEntry->Object;
278  goto Quickie;
279  }
280  else
281  {
282  /* Check if the directory was locked */
283  if (!Context->DirectoryLocked)
284  {
285  /* Release the lock */
287  }
288 
289  /* Check if we should scan the shadow directory */
290  if ((SearchShadow) && (Directory->DeviceMap))
291  {
292  ShadowDirectory = ObpGetShadowDirectory(Directory);
293  /* A global DOS directory was found, loop it again */
294  if (ShadowDirectory != NULL)
295  {
296  Directory = ShadowDirectory;
297  goto DoItAgain;
298  }
299  }
300  }
301 
302 Quickie:
303  /* Check if we inserted an object */
304  if (FoundObject)
305  {
306  /* Get the object name information */
307  ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
308  ObpReferenceNameInfo(ObjectHeader);
309 
310  /* Reference the object being looked up */
311  ObReferenceObject(FoundObject);
312 
313  /* Check if the directory was locked */
314  if (!Context->DirectoryLocked)
315  {
316  /* Release the lock */
318  }
319  }
320 
321  /* Release any object previously looked up and replace it with the new one */
323  Context->Object = FoundObject;
324 
325  /* Return the object we found */
326  return FoundObject;
327 }
328 
329 /*++
330 * @name ObpDeleteEntryDirectory
331 *
332 * The ObpDeleteEntryDirectory routine <FILLMEIN>.
333 *
334 * @param Context
335 * <FILLMEIN>.
336 *
337 * @return TRUE if the object was deleted, FALSE otherwise.
338 *
339 * @remarks None.
340 *
341 *--*/
342 BOOLEAN
343 NTAPI
345 {
347  POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
348  POBJECT_DIRECTORY_ENTRY CurrentEntry;
349 
350  /* Get the Directory */
351  Directory = Context->Directory;
352  if (!Directory) return FALSE;
353 
354  /* Get the Entry */
355  AllocatedEntry = &Directory->HashBuckets[Context->HashIndex];
356  CurrentEntry = *AllocatedEntry;
357 
358  /* Unlink the Entry */
359  *AllocatedEntry = CurrentEntry->ChainLink;
360  CurrentEntry->ChainLink = NULL;
361 
362  /* Free it */
363  ExFreePoolWithTag(CurrentEntry, OB_DIR_TAG);
364 
365  /* Return */
366  return TRUE;
367 }
368 
369 /* FUNCTIONS **************************************************************/
370 
371 /*++
372 * @name NtOpenDirectoryObject
373 * @implemented NT4
374 *
375 * The NtOpenDirectoryObject routine opens a namespace directory object.
376 *
377 * @param DirectoryHandle
378 * Variable which receives the directory handle.
379 *
380 * @param DesiredAccess
381 * Desired access to the directory.
382 *
383 * @param ObjectAttributes
384 * Structure describing the directory.
385 *
386 * @return STATUS_SUCCESS or appropriate error value.
387 *
388 * @remarks None.
389 *
390 *--*/
391 NTSTATUS
392 NTAPI
396 {
400  PAGED_CODE();
401 
402  /* Check if we need to do any probing */
403  if (PreviousMode != KernelMode)
404  {
405  _SEH2_TRY
406  {
407  /* Probe the return handle */
409  }
411  {
412  /* Return the exception code */
414  }
415  _SEH2_END;
416  }
417 
418  /* Open the directory object */
421  PreviousMode,
422  NULL,
424  NULL,
425  &Directory);
426  if (NT_SUCCESS(Status))
427  {
428  _SEH2_TRY
429  {
430  /* Write back the handle to the caller */
432  }
434  {
435  /* Get the exception code */
437  }
438  _SEH2_END;
439  }
440 
441  /* Return the status to the caller */
442  return Status;
443 }
444 
445 /*++
446 * @name NtQueryDirectoryObject
447 * @implemented NT4
448 *
449 * The NtQueryDirectoryObject routine reads information from a directory in
450 * the system namespace.
451 *
452 * @param DirectoryHandle
453 * Handle obtained with NtOpenDirectoryObject which
454 * must grant DIRECTORY_QUERY access to the directory object.
455 *
456 * @param Buffer
457 * Buffer to hold the data read.
458 *
459 * @param BufferLength
460 * Size of the buffer in bytes.
461 *
462 * @param ReturnSingleEntry
463 * When TRUE, only 1 entry is written in DirObjInformation;
464 * otherwise as many as will fit in the buffer.
465 *
466 * @param RestartScan
467 * If TRUE start reading at index 0.
468 * If FALSE start reading at the index specified by *ObjectIndex.
469 *
470 * @param Context
471 * Zero based index into the directory, interpretation
472 * depends on RestartScan.
473 *
474 * @param ReturnLength
475 * Caller supplied storage for the number of bytes
476 * written (or NULL).
477 *
478 * @return STATUS_SUCCESS or appropriate error value.
479 *
480 * @remarks Although you can iterate over the directory by calling this
481 * function multiple times, the directory is unlocked between
482 * calls. This means that another thread can change the directory
483 * and so iterating doesn't guarantee a consistent picture of the
484 * directory. Best thing is to retrieve all directory entries in
485 * one call.
486 *
487 *--*/
488 NTSTATUS
489 NTAPI
491  OUT PVOID Buffer,
497 {
500  ULONG SkipEntries = 0;
502  PVOID LocalBuffer;
503  POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
505  ULONG Count, CurrentEntry;
506  ULONG Hash;
508  POBJECT_HEADER ObjectHeader;
509  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
511  PWSTR p;
512  OBP_LOOKUP_CONTEXT LookupContext;
513  PAGED_CODE();
514 
515  /* Initialize lookup */
516  ObpInitializeLookupContext(&LookupContext);
517 
518  /* Check if we need to do any probing */
519  if (PreviousMode != KernelMode)
520  {
521  _SEH2_TRY
522  {
523  /* Probe the buffer (assuming it will hold Unicode characters) */
525 
526  /* Probe the context and copy it unless scan-restart was requested */
528  if (!RestartScan) SkipEntries = *Context;
529 
530  /* Probe the return length if the caller specified one */
532  }
534  {
535  /* Return the exception code */
537  }
538  _SEH2_END;
539  }
540  else if (!RestartScan)
541  {
542  /* This is kernel mode, save the context without probing, if needed */
543  SkipEntries = *Context;
544  }
545 
546  /* Allocate a buffer */
547  LocalBuffer = ExAllocatePoolWithTag(PagedPool,
549  BufferLength,
550  OB_NAME_TAG);
551  if (!LocalBuffer) return STATUS_INSUFFICIENT_RESOURCES;
552  RtlZeroMemory(LocalBuffer, BufferLength);
553 
554  /* Get a reference to directory */
558  PreviousMode,
559  (PVOID*)&Directory,
560  NULL);
561  if (!NT_SUCCESS(Status))
562  {
563  /* Free the buffer and fail */
564  ExFreePoolWithTag(LocalBuffer, OB_NAME_TAG);
565  return Status;
566  }
567 
568  /* Lock the directory in shared mode */
569  ObpAcquireDirectoryLockShared(Directory, &LookupContext);
570 
571  /* Start at position 0 */
572  DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer;
574 
575  /* Start with 0 entries */
576  Count = 0;
577  CurrentEntry = 0;
578 
579  /* Set default status and start looping */
581  for (Hash = 0; Hash < 37; Hash++)
582  {
583  /* Get this entry and loop all of them */
584  Entry = Directory->HashBuckets[Hash];
585  while (Entry)
586  {
587  /* Check if we should process this entry */
588  if (SkipEntries == CurrentEntry++)
589  {
590  /* Get the header data */
591  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Entry->Object);
592  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
593 
594  /* Get the object name */
595  if (ObjectNameInfo)
596  {
597  /* Use the one we have */
598  Name = ObjectNameInfo->Name;
599  }
600  else
601  {
602  /* Otherwise, use an empty one */
603  RtlInitEmptyUnicodeString(&Name, NULL, 0);
604  }
605 
606  /* Calculate the length for this entry */
608  Name.Length + sizeof(UNICODE_NULL) +
609  ObjectHeader->Type->Name.Length + sizeof(UNICODE_NULL);
610 
611  /* Make sure this entry won't overflow */
612  if ((TotalLength + Length) > BufferLength)
613  {
614  /* Check if the caller wanted only an entry */
615  if (ReturnSingleEntry)
616  {
617  /* Then we'll fail and ask for more buffer */
618  TotalLength += Length;
620  }
621  else
622  {
623  /* Otherwise, we'll say we're done for now */
625  }
626 
627  /* Decrease the entry since we didn't process */
628  CurrentEntry--;
629  goto Quickie;
630  }
631 
632  /* Now fill in the buffer */
633  DirectoryInfo->Name.Length = Name.Length;
634  DirectoryInfo->Name.MaximumLength = Name.Length +
635  sizeof(UNICODE_NULL);
636  DirectoryInfo->Name.Buffer = Name.Buffer;
637  DirectoryInfo->TypeName.Length = ObjectHeader->
638  Type->Name.Length;
639  DirectoryInfo->TypeName.MaximumLength = ObjectHeader->
640  Type->Name.Length +
641  sizeof(UNICODE_NULL);
642  DirectoryInfo->TypeName.Buffer = ObjectHeader->
643  Type->Name.Buffer;
644 
645  /* Set success */
647 
648  /* Increase statistics */
649  TotalLength += Length;
650  DirectoryInfo++;
651  Count++;
652 
653  /* If the caller only wanted an entry, bail out */
654  if (ReturnSingleEntry) goto Quickie;
655 
656  /* Increase the key by one */
657  SkipEntries++;
658  }
659 
660  /* Move to the next directory */
661  Entry = Entry->ChainLink;
662  }
663  }
664 
665 Quickie:
666  /* Make sure we got success */
667  if (NT_SUCCESS(Status))
668  {
669  /* Clear the current pointer and set it */
670  RtlZeroMemory(DirectoryInfo, sizeof(OBJECT_DIRECTORY_INFORMATION));
671  DirectoryInfo++;
672 
673  /* Set the buffer here now and loop entries */
674  p = (PWSTR)DirectoryInfo;
675  DirectoryInfo = LocalBuffer;
676  while (Count--)
677  {
678  /* Copy the name buffer */
680  DirectoryInfo->Name.Buffer,
681  DirectoryInfo->Name.Length);
682 
683  /* Now fixup the pointers */
684  DirectoryInfo->Name.Buffer = (PVOID)((ULONG_PTR)Buffer +
685  ((ULONG_PTR)p -
686  (ULONG_PTR)LocalBuffer));
687 
688  /* Advance in buffer and NULL-terminate */
689  p = (PVOID)((ULONG_PTR)p + DirectoryInfo->Name.Length);
690  *p++ = UNICODE_NULL;
691 
692  /* Now copy the type name buffer */
694  DirectoryInfo->TypeName.Buffer,
695  DirectoryInfo->TypeName.Length);
696 
697  /* Now fixup the pointers */
698  DirectoryInfo->TypeName.Buffer = (PVOID)((ULONG_PTR)Buffer +
699  ((ULONG_PTR)p -
700  (ULONG_PTR)LocalBuffer));
701 
702  /* Advance in buffer and NULL-terminate */
703  p = (PVOID)((ULONG_PTR)p + DirectoryInfo->TypeName.Length);
704  *p++ = UNICODE_NULL;
705 
706  /* Move to the next entry */
707  DirectoryInfo++;
708  }
709 
710  /* Set the key */
711  *Context = CurrentEntry;
712  }
713 
714  _SEH2_TRY
715  {
716  /* Copy the buffer */
718  LocalBuffer,
721 
722  /* Check if the caller requested the return length and return it*/
724  }
726  {
727  /* Get the exception code */
729  }
730  _SEH2_END;
731 
732  /* Unlock the directory */
733  ObpReleaseDirectoryLock(Directory, &LookupContext);
734 
735  /* Dereference the directory and free our buffer */
737  ExFreePoolWithTag(LocalBuffer, OB_NAME_TAG);
738 
739  /* Return status to caller */
740  return Status;
741 }
742 
743 /*++
744 * @name NtCreateDirectoryObject
745 * @implemented NT4
746 *
747 * The NtOpenDirectoryObject routine creates or opens a directory object.
748 *
749 * @param DirectoryHandle
750 * Variable which receives the directory handle.
751 *
752 * @param DesiredAccess
753 * Desired access to the directory.
754 *
755 * @param ObjectAttributes
756 * Structure describing the directory.
757 *
758 * @return STATUS_SUCCESS or appropriate error value.
759 *
760 * @remarks None.
761 *
762 *--*/
763 NTSTATUS
764 NTAPI
768 {
770  HANDLE NewHandle;
773  PAGED_CODE();
774 
775  /* Check if we need to do any probing */
776  if (PreviousMode != KernelMode)
777  {
778  _SEH2_TRY
779  {
780  /* Probe the return handle */
782  }
784  {
785  /* Return the exception code */
787  }
788  _SEH2_END;
789  }
790 
791  /* Create the object */
795  PreviousMode,
796  NULL,
797  sizeof(OBJECT_DIRECTORY),
798  0,
799  0,
800  (PVOID*)&Directory);
801  if (!NT_SUCCESS(Status)) return Status;
802 
803  /* Setup the object */
806  Directory->SessionId = -1;
807 
808  /* Insert it into the handle table */
810  NULL,
812  0,
813  NULL,
814  &NewHandle);
815 
816  /* Enter SEH to protect write */
817  _SEH2_TRY
818  {
819  /* Return the handle back to the caller */
820  *DirectoryHandle = NewHandle;
821  }
823  {
824  /* Get the exception code */
826  }
827  _SEH2_END;
828 
829  /* Return status to caller */
830  return Status;
831 }
832 
833 /* EOF */
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2528
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
static int Hash(const char *)
Definition: reader.c:2257
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2297
struct _Entry Entry
Definition: kefuncs.h:627
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING Name
Definition: obtypes.h:433
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2294
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2037
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
UCHAR NameInfoOffset
Definition: obtypes.h:494
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:728
_In_ ULONG TotalLength
Definition: usbdlib.h:158
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
PVOID Object
Definition: obtypes.h:401
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c: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
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
struct _OBJECT_DIRECTORY_INFORMATION * POBJECT_DIRECTORY_INFORMATION
#define OB_DIR_TAG
Definition: tag.h:152
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory(IN POBJECT_DIRECTORY Directory)
Definition: obdir.c:110
struct NameRec_ * Name
Definition: cdprocs.h:459
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
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN UCHAR SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:158
unsigned char BOOLEAN
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
#define ExInitializePushLock
Definition: ex.h:1011
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2304
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
POBJECT_DIRECTORY GlobalDosDevicesDirectory
Definition: obtypes.h:526
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
int Count
Definition: noreturn.cpp:7
#define OB_NAME_TAG
Definition: tag.h:151
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
#define ObDereferenceObject
Definition: obfuncs.h:203
ULONG HashValue
Definition: obtypes.h:403
Type
Definition: Type.h:6
Definition: obtypes.h:398
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
_SEH2_END
Definition: create.c:4400
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
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2931
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
FORCEINLINE VOID ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:292
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
FORCEINLINE BOOLEAN ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock)
Definition: ex.h:1137
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:344
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
base for all directory entries
Definition: entries.h:138
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
UNICODE_STRING Name
Definition: obtypes.h:383
GLfloat GLfloat p
Definition: glext.h:8902
POBJECT_TYPE Type
Definition: obtypes.h:493
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
ULONG ACCESS_MASK
Definition: nt_native.h:40
base of all file and directory entries
Definition: entries.h:82
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define PAGED_CODE()
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68