ReactOS  0.4.13-dev-464-g6b95727
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 773 of file obdir.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2982
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
#define ExInitializePushLock
Definition: ex.h:999
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 _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
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
_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
base for all directory entries
Definition: entries.h:138
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3718

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 401 of file obdir.c.

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 }
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
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2982
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
_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
base for all directory entries
Definition: entries.h:138
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3718

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 498 of file obdir.c.

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 }
#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
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
uint16_t * PWSTR
Definition: typedefs.h:54
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
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
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2982
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_In_ ULONG TotalLength
Definition: usbdlib.h:145
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:64
_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
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
#define UNICODE_NULL
_In_ ULONG BufferLength
Definition: usbdlib.h:225
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
smooth NULL
Definition: ftsmooth.c:416
POBJECT_TYPE ObpDirectoryObjectType
Definition: obdir.c:20
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_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
Definition: obtypes.h:398
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
struct tagContext Context
Definition: acpixf.h:1012
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
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3718
return STATUS_SUCCESS
Definition: btrfs.c:2777
base of all file and directory entries
Definition: entries.h:82
UNICODE_STRING TypeName
Definition: obtypes.h:279

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

◆ ObpDeleteEntryDirectory()

BOOLEAN NTAPI ObpDeleteEntryDirectory ( POBP_LOOKUP_CONTEXT  Context)

Definition at line 352 of file obdir.c.

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

◆ 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
smooth NULL
Definition: ftsmooth.c:416
POBJECT_DIRECTORY GlobalDosDevicesDirectory
Definition: obtypes.h:526
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:716
PVOID Object
Definition: obtypes.h:401
#define OB_DIR_TAG
Definition: tag.h:152
ULONG HashValue
Definition: obtypes.h:403
Definition: obtypes.h:398
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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  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  /* Get the root entry and set it as our lookup bucket */
218  AllocatedEntry = &Directory->HashBuckets[HashIndex];
219  LookupBucket = AllocatedEntry;
220 
221 DoItAgain:
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 }
#define TRUE
Definition: types.h:120
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
uint16_t * PWSTR
Definition: typedefs.h:54
UNICODE_STRING Name
Definition: obtypes.h:433
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2039
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
UCHAR NameInfoOffset
Definition: obtypes.h:494
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
PVOID Object
Definition: obtypes.h:401
#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 OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
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)
Definition: ob_x.h:174
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2245
Definition: bufpool.h:45
__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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
unsigned short USHORT
Definition: pedump.c:61
FORCEINLINE BOOLEAN ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock)
Definition: ex.h:1125
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
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)

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().