ReactOS  0.4.15-dev-4569-g032c50f
obdir.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for obdir.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI ObpInsertEntryDirectory (IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
 
POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory (IN POBJECT_DIRECTORY Directory)
 
PVOID NTAPI ObpLookupEntryDirectory (IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN UCHAR SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
 
BOOLEAN NTAPI ObpDeleteEntryDirectory (POBP_LOOKUP_CONTEXT Context)
 
NTSTATUS NTAPI NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
 
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)
 
NTSTATUS NTAPI NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
 

Variables

POBJECT_TYPE ObpDirectoryObjectType = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file obdir.c.

Function Documentation

◆ NtCreateDirectoryObject()

NTSTATUS NTAPI NtCreateDirectoryObject ( OUT PHANDLE  DirectoryHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes 
)

Definition at line 765 of file obdir.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
_SEH2_TRY
Definition: create.c:4226
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
#define ExInitializePushLock
Definition: ex.h:1011
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:951
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_SEH2_END
Definition: create.c:4400
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:2934
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define NULL
Definition: types.h:112
base for all directory entries
Definition: entries.h:138
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define PAGED_CODE()

Referenced by BaseInitializeStaticServerData(), CsrCreateSessionObjectDirectory(), CsrParseServerCommandLine(), ExpCreateSystemRootLink(), ExpInitializeCallbacks(), IopCreateRootDirectories(), NlsInit(), ObInitSystem(), ObpCreateDosDevicesDirectory(), SmpConfigureObjectDirectories(), SmpInitializeKnownDllsInternal(), and SmpLoadDataFromRegistry().

◆ NtOpenDirectoryObject()

NTSTATUS NTAPI NtOpenDirectoryObject ( OUT PHANDLE  DirectoryHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes 
)

Definition at line 393 of file obdir.c.

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 }
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:2531
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
_SEH2_TRY
Definition: create.c:4226
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_SEH2_END
Definition: create.c:4400
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define NULL
Definition: types.h:112
base for all directory entries
Definition: entries.h:138
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define PAGED_CODE()

Referenced by BaseGetNamedObjectDirectory(), CreateWindowStationW(), ListDirectory(), NtOpenObject(), OpenWindowStationW(), QueryDosDeviceW(), ResolveArcNameNtSymLink(), ScmCheckDriver(), ScmGetDriverStatus(), and SmpInitializeDosDevices().

◆ NtQueryDirectoryObject()

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 at line 490 of file obdir.c.

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 }
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
static int Hash(const char *)
Definition: reader.c:2257
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#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:629
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
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
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
_In_ ULONG TotalLength
Definition: usbdlib.h:158
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
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
#define UNICODE_NULL
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
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
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:113
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ObDereferenceObject
Definition: obfuncs.h:203
Type
Definition: Type.h:6
Definition: obtypes.h:398
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
_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
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define NULL
Definition: types.h:112
struct tagContext Context
Definition: acpixf.h:1034
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
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
base of all file and directory entries
Definition: entries.h:82
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define PAGED_CODE()

Referenced by CEnumNTDirectory::EnumerateNext(), ListDirectory(), QueryDosDeviceW(), ScmCheckDriver(), ScmGetDriverStatus(), and SmpTranslateSystemPartitionInformation().

◆ ObpDeleteEntryDirectory()

BOOLEAN NTAPI ObpDeleteEntryDirectory ( POBP_LOOKUP_CONTEXT  Context)

Definition at line 344 of file obdir.c.

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 }
#define TRUE
Definition: types.h:120
#define OB_DIR_TAG
Definition: tag.h:114
#define FALSE
Definition: types.h:117
Definition: obtypes.h:398
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
#define NULL
Definition: types.h:112
base for all directory entries
Definition: entries.h:138
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3885
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ ObpGetShadowDirectory()

POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory ( IN POBJECT_DIRECTORY  Directory)

Definition at line 110 of file obdir.c.

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 }
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
POBJECT_DIRECTORY GlobalDosDevicesDirectory
Definition: obtypes.h:526
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
base for all directory entries
Definition: entries.h:138
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24

Referenced by ObpLookupEntryDirectory().

◆ ObpInsertEntryDirectory()

BOOLEAN NTAPI ObpInsertEntryDirectory ( IN POBJECT_DIRECTORY  Parent,
IN POBP_LOOKUP_CONTEXT  Context,
IN POBJECT_HEADER  ObjectHeader 
)

Definition at line 45 of file obdir.c.

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 }
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
#define TRUE
Definition: types.h:120
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
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
PVOID Object
Definition: obtypes.h:401
#define OB_DIR_TAG
Definition: tag.h:114
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
ULONG HashValue
Definition: obtypes.h:403
Definition: obtypes.h:398
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
#define DPRINT1
Definition: precomp.h:8

Referenced by ObCreateObjectType(), ObInitSystem(), and ObpLookupObjectName().

◆ ObpLookupEntryDirectory()

PVOID NTAPI ObpLookupEntryDirectory ( IN POBJECT_DIRECTORY  Directory,
IN PUNICODE_STRING  Name,
IN ULONG  Attributes,
IN UCHAR  SearchShadow,
IN POBP_LOOKUP_CONTEXT  Context 
)

Definition at line 158 of file obdir.c.

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 }
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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
UNICODE_STRING Name
Definition: obtypes.h:433
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2037
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
UCHAR NameInfoOffset
Definition: obtypes.h:494
PVOID Object
Definition: obtypes.h:401
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 OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory(IN POBJECT_DIRECTORY Directory)
Definition: obdir.c:110
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
unsigned char BOOLEAN
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2304
Definition: bufpool.h:45
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
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
FORCEINLINE VOID ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:292
unsigned short USHORT
Definition: pedump.c:61
FORCEINLINE BOOLEAN ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock)
Definition: ex.h:1137
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
#define NULL
Definition: types.h:112
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define PAGED_CODE()
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by ObCreateObjectType(), ObInitSystem(), ObpDeleteNameCheck(), ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

Variable Documentation

◆ ObpDirectoryObjectType

POBJECT_TYPE ObpDirectoryObjectType = NULL

Definition at line 20 of file obdir.c.

Referenced by NtCreateDirectoryObject(), NtOpenDirectoryObject(), and NtQueryDirectoryObject().