ReactOS  0.4.14-dev-554-g2f8d847
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  PAGED_CODE();
178 
179  /* Check if we should search the shadow directory */
180  if (ObpLUIDDeviceMapsEnabled == 0) SearchShadow = FALSE;
181 
182  /* Fail if we don't have a directory or name */
183  if (!(Directory) || !(Name)) goto Quickie;
184 
185  /* Get name information */
186  TotalChars = Name->Length / sizeof(WCHAR);
187  Buffer = Name->Buffer;
188 
189  /* Set up case-sensitivity */
191 
192  /* Fail if the name is empty */
193  if (!(Buffer) || !(TotalChars)) goto Quickie;
194 
195  /* Create the Hash */
196  for (HashValue = 0; TotalChars; TotalChars--)
197  {
198  /* Go to the next Character */
199  CurrentChar = *Buffer++;
200 
201  /* Prepare the Hash */
202  HashValue += (HashValue << 1) + (HashValue >> 1);
203 
204  /* Create the rest based on the name */
205  if (CurrentChar < 'a') HashValue += CurrentChar;
206  else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
207  else HashValue += (CurrentChar - ('a'-'A'));
208  }
209 
210  /* Merge it with our number of hash buckets */
211  HashIndex = HashValue % 37;
212 
213  /* Save the result */
214  Context->HashValue = HashValue;
215  Context->HashIndex = (USHORT)HashIndex;
216 
217 DoItAgain:
218  /* Get the root entry and set it as our lookup bucket */
219  AllocatedEntry = &Directory->HashBuckets[HashIndex];
220  LookupBucket = AllocatedEntry;
221 
222  /* Check if the directory is already locked */
223  if (!Context->DirectoryLocked)
224  {
225  /* Lock it */
227  }
228 
229  /* Start looping */
230  while ((CurrentEntry = *AllocatedEntry))
231  {
232  /* Do the hashes match? */
233  if (CurrentEntry->HashValue == HashValue)
234  {
235  /* Make sure that it has a name */
236  ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object);
237 
238  /* Get the name information */
239  ASSERT(ObjectHeader->NameInfoOffset != 0);
240  HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
241 
242  /* Do the names match? */
243  if ((Name->Length == HeaderNameInfo->Name.Length) &&
244  (RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
245  {
246  break;
247  }
248  }
249 
250  /* Move to the next entry */
251  AllocatedEntry = &CurrentEntry->ChainLink;
252  }
253 
254  /* Check if we still have an entry */
255  if (CurrentEntry)
256  {
257  /* Set this entry as the first, to speed up incoming insertion */
258  if (AllocatedEntry != LookupBucket)
259  {
260  /* Check if the directory was locked or convert the lock */
261  if ((Context->DirectoryLocked) ||
263  {
264  /* Set the Current Entry */
265  *AllocatedEntry = CurrentEntry->ChainLink;
266 
267  /* Link to the old Hash Entry */
268  CurrentEntry->ChainLink = *LookupBucket;
269 
270  /* Set the new Hash Entry */
271  *LookupBucket = CurrentEntry;
272  }
273  }
274 
275  /* Save the found object */
276  FoundObject = CurrentEntry->Object;
277  goto Quickie;
278  }
279  else
280  {
281  /* Check if the directory was locked */
282  if (!Context->DirectoryLocked)
283  {
284  /* Release the lock */
286  }
287 
288  /* Check if we should scan the shadow directory */
289  if ((SearchShadow) && (Directory->DeviceMap))
290  {
291  ShadowDirectory = ObpGetShadowDirectory(Directory);
292  /* A global DOS directory was found, loop it again */
293  if (ShadowDirectory != NULL)
294  {
295  Directory = ShadowDirectory;
296  goto DoItAgain;
297  }
298  }
299  }
300 
301 Quickie:
302  /* Check if we inserted an object */
303  if (FoundObject)
304  {
305  /* Get the object name information */
306  ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
307  ObpReferenceNameInfo(ObjectHeader);
308 
309  /* Reference the object being looked up */
310  ObReferenceObject(FoundObject);
311 
312  /* Check if the directory was locked */
313  if (!Context->DirectoryLocked)
314  {
315  /* Release the lock */
317  }
318  }
319 
320  /* Check if we found an object already */
321  if (Context->Object)
322  {
323  /* We already did a lookup, so remove this object's query reference */
324  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
325  HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
326  ObpDereferenceNameInfo(HeaderNameInfo);
327 
328  /* Also dereference the object itself */
329  ObDereferenceObject(Context->Object);
330  }
331 
332  /* Return the object we found */
333  Context->Object = FoundObject;
334  return FoundObject;
335 }
336 
337 /*++
338 * @name ObpDeleteEntryDirectory
339 *
340 * The ObpDeleteEntryDirectory routine <FILLMEIN>.
341 *
342 * @param Context
343 * <FILLMEIN>.
344 *
345 * @return TRUE if the object was deleted, FALSE otherwise.
346 *
347 * @remarks None.
348 *
349 *--*/
350 BOOLEAN
351 NTAPI
353 {
355  POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
356  POBJECT_DIRECTORY_ENTRY CurrentEntry;
357 
358  /* Get the Directory */
359  Directory = Context->Directory;
360  if (!Directory) return FALSE;
361 
362  /* Get the Entry */
363  AllocatedEntry = &Directory->HashBuckets[Context->HashIndex];
364  CurrentEntry = *AllocatedEntry;
365 
366  /* Unlink the Entry */
367  *AllocatedEntry = CurrentEntry->ChainLink;
368  CurrentEntry->ChainLink = NULL;
369 
370  /* Free it */
371  ExFreePoolWithTag(CurrentEntry, OB_DIR_TAG);
372 
373  /* Return */
374  return TRUE;
375 }
376 
377 /* FUNCTIONS **************************************************************/
378 
379 /*++
380 * @name NtOpenDirectoryObject
381 * @implemented NT4
382 *
383 * The NtOpenDirectoryObject routine opens a namespace directory object.
384 *
385 * @param DirectoryHandle
386 * Variable which receives the directory handle.
387 *
388 * @param DesiredAccess
389 * Desired access to the directory.
390 *
391 * @param ObjectAttributes
392 * Structure describing the directory.
393 *
394 * @return STATUS_SUCCESS or appropriate error value.
395 *
396 * @remarks None.
397 *
398 *--*/
399 NTSTATUS
400 NTAPI
404 {
408  PAGED_CODE();
409 
410  /* Check if we need to do any probing */
411  if (PreviousMode != KernelMode)
412  {
413  _SEH2_TRY
414  {
415  /* Probe the return handle */
417  }
419  {
420  /* Return the exception code */
422  }
423  _SEH2_END;
424  }
425 
426  /* Open the directory object */
429  PreviousMode,
430  NULL,
432  NULL,
433  &Directory);
434  if (NT_SUCCESS(Status))
435  {
436  _SEH2_TRY
437  {
438  /* Write back the handle to the caller */
440  }
442  {
443  /* Get the exception code */
445  }
446  _SEH2_END;
447  }
448 
449  /* Return the status to the caller */
450  return Status;
451 }
452 
453 /*++
454 * @name NtQueryDirectoryObject
455 * @implemented NT4
456 *
457 * The NtQueryDirectoryObject routine reads information from a directory in
458 * the system namespace.
459 *
460 * @param DirectoryHandle
461 * Handle obtained with NtOpenDirectoryObject which
462 * must grant DIRECTORY_QUERY access to the directory object.
463 *
464 * @param Buffer
465 * Buffer to hold the data read.
466 *
467 * @param BufferLength
468 * Size of the buffer in bytes.
469 *
470 * @param ReturnSingleEntry
471 * When TRUE, only 1 entry is written in DirObjInformation;
472 * otherwise as many as will fit in the buffer.
473 *
474 * @param RestartScan
475 * If TRUE start reading at index 0.
476 * If FALSE start reading at the index specified by *ObjectIndex.
477 *
478 * @param Context
479 * Zero based index into the directory, interpretation
480 * depends on RestartScan.
481 *
482 * @param ReturnLength
483 * Caller supplied storage for the number of bytes
484 * written (or NULL).
485 *
486 * @return STATUS_SUCCESS or appropriate error value.
487 *
488 * @remarks Although you can iterate over the directory by calling this
489 * function multiple times, the directory is unlocked between
490 * calls. This means that another thread can change the directory
491 * and so iterating doesn't guarantee a consistent picture of the
492 * directory. Best thing is to retrieve all directory entries in
493 * one call.
494 *
495 *--*/
496 NTSTATUS
497 NTAPI
499  OUT PVOID Buffer,
505 {
508  ULONG SkipEntries = 0;
510  PVOID LocalBuffer;
511  POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
513  ULONG Count, CurrentEntry;
514  ULONG Hash;
516  POBJECT_HEADER ObjectHeader;
517  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
519  PWSTR p;
520  OBP_LOOKUP_CONTEXT LookupContext;
521  PAGED_CODE();
522 
523  /* Initialize lookup */
524  ObpInitializeLookupContext(&LookupContext);
525 
526  /* Check if we need to do any probing */
527  if (PreviousMode != KernelMode)
528  {
529  _SEH2_TRY
530  {
531  /* Probe the buffer (assuming it will hold Unicode characters) */
533 
534  /* Probe the context and copy it unless scan-restart was requested */
536  if (!RestartScan) SkipEntries = *Context;
537 
538  /* Probe the return length if the caller specified one */
540  }
542  {
543  /* Return the exception code */
545  }
546  _SEH2_END;
547  }
548  else if (!RestartScan)
549  {
550  /* This is kernel mode, save the context without probing, if needed */
551  SkipEntries = *Context;
552  }
553 
554  /* Allocate a buffer */
555  LocalBuffer = ExAllocatePoolWithTag(PagedPool,
557  BufferLength,
558  OB_NAME_TAG);
559  if (!LocalBuffer) return STATUS_INSUFFICIENT_RESOURCES;
560  RtlZeroMemory(LocalBuffer, BufferLength);
561 
562  /* Get a reference to directory */
566  PreviousMode,
567  (PVOID*)&Directory,
568  NULL);
569  if (!NT_SUCCESS(Status))
570  {
571  /* Free the buffer and fail */
572  ExFreePoolWithTag(LocalBuffer, OB_NAME_TAG);
573  return Status;
574  }
575 
576  /* Lock directory in shared mode */
577  ObpAcquireDirectoryLockShared(Directory, &LookupContext);
578 
579  /* Start at position 0 */
580  DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer;
582 
583  /* Start with 0 entries */
584  Count = 0;
585  CurrentEntry = 0;
586 
587  /* Set default status and start looping */
589  for (Hash = 0; Hash < 37; Hash++)
590  {
591  /* Get this entry and loop all of them */
592  Entry = Directory->HashBuckets[Hash];
593  while (Entry)
594  {
595  /* Check if we should process this entry */
596  if (SkipEntries == CurrentEntry++)
597  {
598  /* Get the header data */
599  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Entry->Object);
600  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
601 
602  /* Get the object name */
603  if (ObjectNameInfo)
604  {
605  /* Use the one we have */
606  Name = ObjectNameInfo->Name;
607  }
608  else
609  {
610  /* Otherwise, use an empty one */
611  RtlInitEmptyUnicodeString(&Name, NULL, 0);
612  }
613 
614  /* Calculate the length for this entry */
616  Name.Length + sizeof(UNICODE_NULL) +
617  ObjectHeader->Type->Name.Length + sizeof(UNICODE_NULL);
618 
619  /* Make sure this entry won't overflow */
620  if ((TotalLength + Length) > BufferLength)
621  {
622  /* Check if the caller wanted only an entry */
623  if (ReturnSingleEntry)
624  {
625  /* Then we'll fail and ask for more buffer */
626  TotalLength += Length;
628  }
629  else
630  {
631  /* Otherwise, we'll say we're done for now */
633  }
634 
635  /* Decrease the entry since we didn't process */
636  CurrentEntry--;
637  goto Quickie;
638  }
639 
640  /* Now fill in the buffer */
641  DirectoryInfo->Name.Length = Name.Length;
642  DirectoryInfo->Name.MaximumLength = Name.Length +
643  sizeof(UNICODE_NULL);
644  DirectoryInfo->Name.Buffer = Name.Buffer;
645  DirectoryInfo->TypeName.Length = ObjectHeader->
646  Type->Name.Length;
647  DirectoryInfo->TypeName.MaximumLength = ObjectHeader->
648  Type->Name.Length +
649  sizeof(UNICODE_NULL);
650  DirectoryInfo->TypeName.Buffer = ObjectHeader->
651  Type->Name.Buffer;
652 
653  /* Set success */
655 
656  /* Increase statistics */
657  TotalLength += Length;
658  DirectoryInfo++;
659  Count++;
660 
661  /* If the caller only wanted an entry, bail out */
662  if (ReturnSingleEntry) goto Quickie;
663 
664  /* Increase the key by one */
665  SkipEntries++;
666  }
667 
668  /* Move to the next directory */
669  Entry = Entry->ChainLink;
670  }
671  }
672 
673 Quickie:
674  /* Make sure we got success */
675  if (NT_SUCCESS(Status))
676  {
677  /* Clear the current pointer and set it */
678  RtlZeroMemory(DirectoryInfo, sizeof(OBJECT_DIRECTORY_INFORMATION));
679  DirectoryInfo++;
680 
681  /* Set the buffer here now and loop entries */
682  p = (PWSTR)DirectoryInfo;
683  DirectoryInfo = LocalBuffer;
684  while (Count--)
685  {
686  /* Copy the name buffer */
688  DirectoryInfo->Name.Buffer,
689  DirectoryInfo->Name.Length);
690 
691  /* Now fixup the pointers */
692  DirectoryInfo->Name.Buffer = (PVOID)((ULONG_PTR)Buffer +
693  ((ULONG_PTR)p -
694  (ULONG_PTR)LocalBuffer));
695 
696  /* Advance in buffer and NULL-terminate */
697  p = (PVOID)((ULONG_PTR)p + DirectoryInfo->Name.Length);
698  *p++ = UNICODE_NULL;
699 
700  /* Now copy the type name buffer */
702  DirectoryInfo->TypeName.Buffer,
703  DirectoryInfo->TypeName.Length);
704 
705  /* Now fixup the pointers */
706  DirectoryInfo->TypeName.Buffer = (PVOID)((ULONG_PTR)Buffer +
707  ((ULONG_PTR)p -
708  (ULONG_PTR)LocalBuffer));
709 
710  /* Advance in buffer and NULL-terminate */
711  p = (PVOID)((ULONG_PTR)p + DirectoryInfo->TypeName.Length);
712  *p++ = UNICODE_NULL;
713 
714  /* Move to the next entry */
715  DirectoryInfo++;
716  }
717 
718  /* Set the key */
719  *Context = CurrentEntry;
720  }
721 
722  _SEH2_TRY
723  {
724  /* Copy the buffer */
726  LocalBuffer,
729 
730  /* Check if the caller requested the return length and return it*/
732  }
734  {
735  /* Get the exception code */
737  }
738  _SEH2_END;
739 
740  /* Unlock the directory */
741  ObpReleaseDirectoryLock(Directory, &LookupContext);
742 
743  /* Dereference the directory and free our buffer */
745  ExFreePoolWithTag(LocalBuffer, OB_NAME_TAG);
746 
747  /* Return status to caller */
748  return Status;
749 }
750 
751 /*++
752 * @name NtCreateDirectoryObject
753 * @implemented NT4
754 *
755 * The NtOpenDirectoryObject routine creates or opens a directory object.
756 *
757 * @param DirectoryHandle
758 * Variable which receives the directory handle.
759 *
760 * @param DesiredAccess
761 * Desired access to the directory.
762 *
763 * @param ObjectAttributes
764 * Structure describing the directory.
765 *
766 * @return STATUS_SUCCESS or appropriate error value.
767 *
768 * @remarks None.
769 *
770 *--*/
771 NTSTATUS
772 NTAPI
776 {
778  HANDLE NewHandle;
781  PAGED_CODE();
782 
783  /* Check if we need to do any probing */
784  if (PreviousMode != KernelMode)
785  {
786  _SEH2_TRY
787  {
788  /* Probe the return handle */
790  }
792  {
793  /* Return the exception code */
795  }
796  _SEH2_END;
797  }
798 
799  /* Create the object */
803  PreviousMode,
804  NULL,
805  sizeof(OBJECT_DIRECTORY),
806  0,
807  0,
808  (PVOID*)&Directory);
809  if (!NT_SUCCESS(Status)) return Status;
810 
811  /* Setup the object */
814  Directory->SessionId = -1;
815 
816  /* Insert it into the handle table */
818  NULL,
820  0,
821  NULL,
822  &NewHandle);
823 
824  /* Enter SEH to protect write */
825  _SEH2_TRY
826  {
827  /* Return the handle back to the caller */
828  *DirectoryHandle = NewHandle;
829  }
831  {
832  /* Get the exception code */
834  }
835  _SEH2_END;
836 
837  /* Return status to caller */
838  return Status;
839 }
840 
841 /* 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:2529
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:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Type
Definition: Type.h:6
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2298
struct _Entry Entry
Definition: kefuncs.h:640
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
uint16_t * PWSTR
Definition: typedefs.h:54
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:401
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:2295
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2039
static HANDLE DirectoryHandle
Definition: ObType.c:48
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#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:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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:145
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:498
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
#define PAGED_CODE()
Definition: video.h:57
FORCEINLINE VOID ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:210
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
#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:496
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory(IN POBJECT_DIRECTORY Directory)
Definition: obdir.c:110
struct NameRec_ * Name
Definition: cdprocs.h:464
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE VOID ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:174
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
smooth NULL
Definition: ftsmooth.c:416
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
#define ExInitializePushLock
Definition: ex.h:999
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2261
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
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define OB_NAME_TAG
Definition: tag.h:151
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
ULONG HashValue
Definition: obtypes.h:403
Definition: obtypes.h:398
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:773
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
_SEH2_END
Definition: create.c:4424
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
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:2932
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
unsigned short USHORT
Definition: pedump.c:61
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
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:1125
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
unsigned int * PULONG
Definition: retypes.h:1
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:352
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
struct tagContext Context
Definition: acpixf.h:1030
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:261
#define ULONG_PTR
Definition: config.h:101
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
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 OUT PSTR Buffer
Definition: progress.h:34
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3734
return STATUS_SUCCESS
Definition: btrfs.c:2938
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
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
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68