ReactOS  0.4.13-dev-563-g0561610
obname.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for obname.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

INIT_FUNCTION NTSTATUS NTAPI ObpGetDosDevicesProtection (OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
 
INIT_FUNCTION VOID NTAPI ObpFreeDosDevicesProtection (OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
 
INIT_FUNCTION NTSTATUS NTAPI ObpCreateDosDevicesDirectory (VOID)
 
VOID NTAPI ObpDeleteNameCheck (IN PVOID Object)
 
BOOLEAN NTAPI ObpIsUnsecureName (IN PUNICODE_STRING ObjectName, IN BOOLEAN CaseInSensitive)
 
NTSTATUS NTAPI ObpLookupObjectName (IN HANDLE RootHandle OPTIONAL, IN OUT PUNICODE_STRING ObjectName, IN ULONG Attributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, IN PVOID InsertObject OPTIONAL, IN OUT PACCESS_STATE AccessState, OUT POBP_LOOKUP_CONTEXT LookupContext, OUT PVOID *FoundObject)
 
NTSTATUS NTAPI ObQueryNameString (IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
 

Variables

BOOLEAN ObpCaseInsensitive = TRUE
 
POBJECT_DIRECTORY ObpRootDirectoryObject
 
POBJECT_DIRECTORY ObpTypeDirectoryObject
 
ALIGNEDNAME ObpDosDevicesShortNamePrefix = {{L'\\',L'?',L'?',L'\\'}}
 
ALIGNEDNAME ObpDosDevicesShortNameRoot = {{L'\\',L'?',L'?',L'\0'}}
 
UNICODE_STRING ObpDosDevicesShortName
 
WCHAR ObpUnsecureGlobalNamesBuffer [128] = {0}
 
ULONG ObpUnsecureGlobalNamesLength = sizeof(ObpUnsecureGlobalNamesBuffer)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file obname.c.

Function Documentation

◆ ObpCreateDosDevicesDirectory()

INIT_FUNCTION NTSTATUS NTAPI ObpCreateDosDevicesDirectory ( VOID  )

Definition at line 177 of file obname.c.

178 {
180  UNICODE_STRING RootName, TargetName, LinkName;
181  HANDLE Handle, SymHandle;
182  SECURITY_DESCRIPTOR DosDevicesSD;
184 
185  /*
186  * Enable LUID mappings only if not explicitely disabled
187  * and if protection mode is set
188  */
191  else
193 
194  /* Create a custom security descriptor for the global DosDevices directory */
195  Status = ObpGetDosDevicesProtection(&DosDevicesSD);
196  if (!NT_SUCCESS(Status))
197  return Status;
198 
199  /* Create the global DosDevices directory \?? */
200  RtlInitUnicodeString(&RootName, L"\\GLOBAL??");
202  &RootName,
204  NULL,
205  &DosDevicesSD);
209  if (!NT_SUCCESS(Status))
210  goto done;
211 
212  /* Create the system device map */
214  if (!NT_SUCCESS(Status))
215  goto done;
216 
217  /*********************************************\
218  |*** HACK until we support device mappings ***|
219  |*** Add a symlink \??\ <--> \GLOBAL??\ ***|
220  \*********************************************/
221  RtlInitUnicodeString(&LinkName, L"\\??");
223  &LinkName,
225  NULL,
226  &DosDevicesSD);
227  Status = NtCreateSymbolicLinkObject(&SymHandle,
230  &RootName);
231  if (NT_SUCCESS(Status)) NtClose(SymHandle);
232  /*********************************************\
233  \*********************************************/
234 
235  // FIXME: Create a device mapping for the global \?? directory
236 
237  /*
238  * Initialize the \??\GLOBALROOT symbolic link
239  * pointing to the root directory \ .
240  */
241  RtlInitUnicodeString(&LinkName, L"GLOBALROOT");
244  &LinkName,
246  Handle,
247  &DosDevicesSD);
248  Status = NtCreateSymbolicLinkObject(&SymHandle,
251  &TargetName);
252  if (NT_SUCCESS(Status)) NtClose(SymHandle);
253 
254  /*
255  * Initialize the \??\Global symbolic link pointing to the global
256  * DosDevices directory \?? . It is used to access the global \??
257  * by user-mode components which, by default, use a per-session
258  * DosDevices directory.
259  */
260  RtlInitUnicodeString(&LinkName, L"Global");
262  &LinkName,
264  Handle,
265  &DosDevicesSD);
266  Status = NtCreateSymbolicLinkObject(&SymHandle,
269  &RootName);
270  if (NT_SUCCESS(Status)) NtClose(SymHandle);
271 
272  /* Close the directory handle */
273  NtClose(Handle);
274  if (!NT_SUCCESS(Status))
275  goto done;
276 
277  /*
278  * Initialize the \DosDevices symbolic link pointing to the global
279  * DosDevices directory \?? , for backward compatibility with
280  * Windows NT-2000 systems.
281  */
282  RtlCreateUnicodeString(&LinkName, L"\\DosDevices");
285  &LinkName,
287  NULL,
288  &DosDevicesSD);
289  Status = NtCreateSymbolicLinkObject(&SymHandle,
292  &RootName);
293  if (NT_SUCCESS(Status)) NtClose(SymHandle);
294 
295 done:
296  ObpFreeDosDevicesProtection(&DosDevicesSD);
297 
298  /* Return status */
299  return Status;
300 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
INIT_FUNCTION VOID NTAPI ObpFreeDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:161
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
INIT_FUNCTION NTSTATUS NTAPI ObpGetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:40
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
#define OBJ_PERMANENT
Definition: winternl.h:226
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ALIGNEDNAME ObpDosDevicesShortNameRoot
Definition: obname.c:24
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static const WCHAR L[]
Definition: oid.c:1250
WCHAR TargetName[256]
Definition: arping.c:27
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:773
ULONG ObpProtectionMode
Definition: obinit.c:56
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG ObpLUIDDeviceMapsDisabled
Definition: devicemap.c:17

Referenced by ObInitSystem().

◆ ObpDeleteNameCheck()

VOID NTAPI ObpDeleteNameCheck ( IN PVOID  Object)

Definition at line 321 of file obname.c.

322 {
323  POBJECT_HEADER ObjectHeader;
325  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
327  PVOID Directory = NULL;
328 
329  /* Get object structures */
330  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
331  ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
332  ObjectType = ObjectHeader->Type;
333 
334  /*
335  * Check if the handle count is 0, if the object is named,
336  * and if the object isn't a permanent object.
337  */
338  if (!(ObjectHeader->HandleCount) &&
339  (ObjectNameInfo) &&
340  (ObjectNameInfo->Name.Length) &&
341  (ObjectNameInfo->Directory) &&
342  !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
343  {
344  /* Setup a lookup context */
346 
347  /* Lock the directory */
349 
350  /* Do the lookup */
351  Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
352  &ObjectNameInfo->Name,
353  0,
354  FALSE,
355  &Context);
356  if (Object)
357  {
358  /* Lock the object */
359  ObpAcquireObjectLock(ObjectHeader);
360 
361  /* Make sure we can still delete the object */
362  if (!(ObjectHeader->HandleCount) &&
363  !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
364  {
365  /* First delete it from the directory */
367 
368  /* Check if this is a symbolic link */
370  {
371  /* Remove internal name */
373  }
374 
375  /* Check if the kernel exclusive is set */
376  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
377  if ((ObjectNameInfo) &&
378  (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
379  {
380  /* Remove protection flag */
381  InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences,
383  }
384 
385  /* Get the directory */
386  Directory = ObjectNameInfo->Directory;
387  }
388 
389  /* Release the lock */
390  ObpReleaseObjectLock(ObjectHeader);
391  }
392 
393  /* Cleanup after lookup */
395 
396  /* Remove another query reference since we added one on top */
397  ObpDereferenceNameInfo(ObjectNameInfo);
398 
399  /* Check if we were inserted in a directory */
400  if (Directory)
401  {
402  /* We were, so first remove the extra reference we had added */
403  ObpDereferenceNameInfo(ObjectNameInfo);
404 
405  /* Now dereference the object as well */
407  }
408  }
409  else
410  {
411  /* Remove the reference we added */
412  ObpDereferenceNameInfo(ObjectNameInfo);
413  }
414 }
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
ObjectType
Definition: metafile.c:80
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
LONG_PTR HandleCount
Definition: obtypes.h:490
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
UNICODE_STRING Name
Definition: obtypes.h:433
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
smooth NULL
Definition: ftsmooth.c:416
UCHAR Flags
Definition: obtypes.h:497
#define InterlockedExchangeAdd
Definition: interlocked.h:181
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:190
static IUnknown Object
Definition: main.c:512
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
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:255
VOID NTAPI ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:325
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:124
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
struct tagContext Context
Definition: acpixf.h:1012
base for all directory entries
Definition: entries.h:138
POBJECT_TYPE Type
Definition: obtypes.h:493
signed int * PLONG
Definition: retypes.h:5
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
BOOLEAN NTAPI ObpDeleteEntryDirectory(IN POBP_LOOKUP_CONTEXT Context)

Referenced by ObInsertObject(), ObpDecrementHandleCount(), and ObpSetPermanentObject().

◆ ObpFreeDosDevicesProtection()

INIT_FUNCTION VOID NTAPI ObpFreeDosDevicesProtection ( OUT PSECURITY_DESCRIPTOR  SecurityDescriptor)

Definition at line 161 of file obname.c.

162 {
163  PACL Dacl;
166 
170  ASSERT(Dacl != NULL);
171  ExFreePoolWithTag(Dacl, 'lcaD');
172 }
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1595
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
LONG NTSTATUS
Definition: precomp.h:26
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1595
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
Status
Definition: gdiplustypes.h:24
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpGetDosDevicesProtection()

INIT_FUNCTION NTSTATUS NTAPI ObpGetDosDevicesProtection ( OUT PSECURITY_DESCRIPTOR  SecurityDescriptor)

Definition at line 40 of file obname.c.

41 {
42  PACL Dacl;
43  ULONG AclSize;
45 
46  /* Initialize the SD */
49 
50  if (ObpProtectionMode & 1)
51  {
52  AclSize = sizeof(ACL) +
53  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
54  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
55  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
56  sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid) +
57  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
59 
60  /* Allocate the ACL */
61  Dacl = ExAllocatePoolWithTag(PagedPool, AclSize, 'lcaD');
62  if (Dacl == NULL)
63  {
65  }
66 
67  /* Initialize the DACL */
68  Status = RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
70 
71  /* Add the ACEs */
75  SeWorldSid);
77 
83 
88  SeWorldSid);
90 
97 
101  GENERIC_ALL,
104 
106  ACL_REVISION,
108  GENERIC_ALL,
111  }
112  else
113  {
114  AclSize = sizeof(ACL) +
115  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
116  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
117  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid);
118 
119  /* Allocate the ACL */
120  Dacl = ExAllocatePoolWithTag(PagedPool, AclSize, 'lcaD');
121  if (Dacl == NULL)
122  {
124  }
125 
126  /* Initialize the DACL */
127  Status = RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
129 
130  /* Add the ACEs */
132  ACL_REVISION,
134  SeWorldSid);
136 
138  ACL_REVISION,
139  GENERIC_ALL,
142 
144  ACL_REVISION,
146  GENERIC_ALL,
147  SeWorldSid);
149  }
150 
151  /* Attach the DACL to the SD */
154 
155  return STATUS_SUCCESS;
156 }
#define GENERIC_ALL
Definition: nt_native.h:92
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
struct _ACE ACE
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
struct _ACL ACL
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
PSID SeAliasAdminsSid
Definition: sid.c:47
PSID SeCreatorOwnerSid
Definition: sid.c:33
#define GENERIC_READ
Definition: compat.h:124
PSID SeWorldSid
Definition: sid.c:31
Status
Definition: gdiplustypes.h:24
ULONG ObpProtectionMode
Definition: obinit.c:56
#define ACL_REVISION
Definition: setypes.h:39
PSID SeLocalSystemSid
Definition: sid.c:44
unsigned int ULONG
Definition: retypes.h:1
#define INHERIT_ONLY_ACE
Definition: setypes.h:717
#define GENERIC_EXECUTE
Definition: nt_native.h:91
return STATUS_SUCCESS
Definition: btrfs.c:2777
Definition: rtltypes.h:988
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpIsUnsecureName()

BOOLEAN NTAPI ObpIsUnsecureName ( IN PUNICODE_STRING  ObjectName,
IN BOOLEAN  CaseInSensitive 
)

Definition at line 418 of file obname.c.

420 {
421  BOOLEAN Unsecure;
422  PWSTR UnsecureBuffer;
423  UNICODE_STRING UnsecureName;
424 
425  /* No unsecure names known, quit */
427  {
428  return FALSE;
429  }
430 
431  /* By default, we have a secure name */
432  Unsecure = FALSE;
433  /* We will browse the whole string */
434  UnsecureBuffer = &ObpUnsecureGlobalNamesBuffer[0];
435  while (TRUE)
436  {
437  /* Initialize the unicode string */
438  RtlInitUnicodeString(&UnsecureName, UnsecureBuffer);
439  /* We're at the end of the multisz string! */
440  if (UnsecureName.Length == 0)
441  {
442  break;
443  }
444 
445  /*
446  * Does the unsecure name prefix the object name?
447  * If so, that's an unsecure name, and return so
448  */
450  {
451  Unsecure = TRUE;
452  break;
453  }
454 
455  /*
456  * Move to the next string. As a reminder, ObpUnsecureGlobalNamesBuffer is
457  * a multisz, so we move the string next to the current UNICODE_NULL char
458  */
459  UnsecureBuffer = (PWSTR)((ULONG_PTR)UnsecureBuffer + UnsecureName.Length + sizeof(UNICODE_NULL));
460  }
461 
462  /* Return our findings */
463  return Unsecure;
464 }
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:54
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2276
unsigned char BOOLEAN
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
WCHAR ObpUnsecureGlobalNamesBuffer[128]
Definition: obname.c:32

Referenced by ObpLookupObjectName().

◆ ObpLookupObjectName()

NTSTATUS NTAPI ObpLookupObjectName ( IN HANDLE RootHandle  OPTIONAL,
IN OUT PUNICODE_STRING  ObjectName,
IN ULONG  Attributes,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode,
IN OUT PVOID  ParseContext,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos  OPTIONAL,
IN PVOID InsertObject  OPTIONAL,
IN OUT PACCESS_STATE  AccessState,
OUT POBP_LOOKUP_CONTEXT  LookupContext,
OUT PVOID FoundObject 
)

Definition at line 468 of file obname.c.

479 {
480  PVOID Object;
481  POBJECT_HEADER ObjectHeader;
482  UNICODE_STRING ComponentName, RemainingName;
483  BOOLEAN Reparse = FALSE, SymLink = FALSE;
485  POBJECT_DIRECTORY ReferencedDirectory = NULL, ReferencedParentDirectory = NULL;
486  KIRQL CalloutIrql;
487  OB_PARSE_METHOD ParseRoutine;
489  KPROCESSOR_MODE AccessCheckMode;
490  PWCHAR NewName;
491  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
492  ULONG MaxReparse = 30;
493  PAGED_CODE();
495  "%s - Finding Object: %wZ. Expecting: %p\n",
496  __FUNCTION__,
497  ObjectName,
498  InsertObject);
499 
500  /* Initialize starting state */
501  ObpInitializeLookupContext(LookupContext);
502  *FoundObject = NULL;
504  Object = NULL;
505 
506  /* Check if case-insensitivity is checked */
507  if (ObpCaseInsensitive)
508  {
509  /* Check if the object type requests this */
510  if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
511  {
512  /* Add the flag to disable case sensitivity */
514  }
515  }
516 
517  /* Check if this is a access checks are being forced */
518  AccessCheckMode = (Attributes & OBJ_FORCE_ACCESS_CHECK) ?
520 
521  /* Check if we got a Root Directory */
522  if (RootHandle)
523  {
524  /* We did. Reference it */
525  Status = ObReferenceObjectByHandle(RootHandle,
526  0,
527  NULL,
528  AccessMode,
529  (PVOID*)&RootDirectory,
530  NULL);
531  if (!NT_SUCCESS(Status)) return Status;
532 
533  /* Get the header */
534  ObjectHeader = OBJECT_TO_OBJECT_HEADER(RootDirectory);
535 
536  /* The name cannot start with a separator, unless this is a file */
537  if ((ObjectName->Buffer) &&
538  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
539  (ObjectHeader->Type != IoFileObjectType))
540  {
541  /* The syntax is bad, so fail this request */
544  }
545 
546  /* Don't parse a Directory */
547  if (ObjectHeader->Type != ObpDirectoryObjectType)
548  {
549  /* Make sure the Object Type has a parse routine */
550  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
551  if (!ParseRoutine)
552  {
553  /* We can't parse a name if we don't have a parse routine */
555  return STATUS_INVALID_HANDLE;
556  }
557 
558  /* Set default parse count */
559  MaxReparse = 30;
560 
561  /* Now parse */
562  while (TRUE)
563  {
564  /* Start with the full name */
566 
567  /* Call the Parse Procedure */
568  ObpCalloutStart(&CalloutIrql);
569  Status = ParseRoutine(RootDirectory,
570  ObjectType,
571  AccessState,
572  AccessCheckMode,
573  Attributes,
574  ObjectName,
575  &RemainingName,
576  ParseContext,
577  SecurityQos,
578  &Object);
579  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
580 
581  /* Check for success or failure, so not reparse */
582  if ((Status != STATUS_REPARSE) &&
584  {
585  /* Check for failure */
586  if (!NT_SUCCESS(Status))
587  {
588  /* Parse routine might not have cleared this, do it */
589  Object = NULL;
590  }
591  else if (!Object)
592  {
593  /* Modify status to reflect failure inside Ob */
595  }
596 
597  /* We're done, return the status and object */
598  *FoundObject = Object;
600  return Status;
601  }
602  else if ((!ObjectName->Length) ||
603  (!ObjectName->Buffer) ||
604  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
605  {
606  /* Reparsed to the root directory, so start over */
609 
610  /* Don't use this anymore, since we're starting at root */
611  RootHandle = NULL;
612  goto ParseFromRoot;
613  }
614  else if (--MaxReparse)
615  {
616  /* Try reparsing again */
617  continue;
618  }
619  else
620  {
621  /* Reparsed too many times */
623 
624  /* Return the object and normalized status */
625  *FoundObject = Object;
627  return Status;
628  }
629  }
630  }
631  else if (!(ObjectName->Length) || !(ObjectName->Buffer))
632  {
633  /* Just return the Root Directory if we didn't get a name */
635  0,
636  ObjectType,
637  AccessMode);
639 
640  /* Remove the first reference we added and return the object */
642  *FoundObject = Object;
643  return Status;
644  }
645  }
646  else
647  {
648  /* We did not get a Root Directory, so use the root */
650 
651  /* It must start with a path separator */
652  if (!(ObjectName->Length) ||
653  !(ObjectName->Buffer) ||
654  (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
655  {
656  /* This name is invalid, so fail */
658  }
659 
660  /* Check if the name is only the path separator */
661  if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
662  {
663  /* So the caller only wants the root directory; do we have one? */
664  if (!RootDirectory)
665  {
666  /* This must be the first time we're creating it... right? */
667  if (InsertObject)
668  {
669  /* Yes, so return it to ObInsert so that it can create it */
670  Status = ObReferenceObjectByPointer(InsertObject,
671  0,
672  ObjectType,
673  AccessMode);
674  if (NT_SUCCESS(Status)) *FoundObject = InsertObject;
675  return Status;
676  }
677  else
678  {
679  /* This should never really happen */
680  ASSERT(FALSE);
682  }
683  }
684  else
685  {
686  /* We do have the root directory, so just return it */
688  0,
689  ObjectType,
690  AccessMode);
691  if (NT_SUCCESS(Status)) *FoundObject = RootDirectory;
692  return Status;
693  }
694  }
695  else
696  {
697 ParseFromRoot:
698  /* FIXME: Check if we have a device map */
699 
700  /* Check if this is a possible DOS name */
701  if (!((ULONG_PTR)(ObjectName->Buffer) & 7))
702  {
703  /*
704  * This could be one. Does it match the prefix?
705  * Note that as an optimization, the match is done as 64-bit
706  * compare since the prefix is "\??\" which is exactly 8 bytes.
707  *
708  * In the second branch, we test for "\??" which is also valid.
709  * This time, we use a 32-bit compare followed by a Unicode
710  * character compare (16-bit), since the sum is 6 bytes.
711  */
712  if ((ObjectName->Length >= ObpDosDevicesShortName.Length) &&
713  (*(PULONGLONG)(ObjectName->Buffer) ==
715  {
716  /* FIXME! */
717  }
718  else if ((ObjectName->Length == ObpDosDevicesShortName.Length -
719  sizeof(WCHAR)) &&
720  (*(PULONG)(ObjectName->Buffer) ==
722  (*((PWCHAR)(ObjectName->Buffer) + 2) ==
724  {
725  /* FIXME! */
726  }
727  }
728  }
729  }
730 
731  /* Check if we were reparsing a symbolic link */
732  if (!SymLink)
733  {
734  /* Allow reparse */
735  Reparse = TRUE;
736  MaxReparse = 30;
737  }
738 
739  /* Reparse */
740  while (Reparse && MaxReparse)
741  {
742  /* Get the name */
744 
745  /* Disable reparsing again */
746  Reparse = FALSE;
747 
748  /* Start parse loop */
749  while (TRUE)
750  {
751  /* Clear object */
752  Object = NULL;
753 
754  /* Check if the name starts with a path separator */
755  if ((RemainingName.Length) &&
756  (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
757  {
758  /* Skip the path separator */
759  RemainingName.Buffer++;
760  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
761  }
762 
763  /* Find the next Part Name */
764  ComponentName = RemainingName;
765  while (RemainingName.Length)
766  {
767  /* Break if we found the \ ending */
768  if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
769 
770  /* Move on */
771  RemainingName.Buffer++;
772  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
773  }
774 
775  /* Get its size and make sure it's valid */
776  ComponentName.Length -= RemainingName.Length;
777  if (!ComponentName.Length)
778  {
779  /* Invalid size, fail */
781  break;
782  }
783 
784  /* Check if we're in the root */
786 
787  /* Check if this is a user-mode call that needs to traverse */
788  if ((AccessCheckMode != KernelMode) &&
790  {
791  /* We shouldn't have referenced a directory yet */
792  ASSERT(ReferencedDirectory == NULL);
793 
794  /* Reference the directory */
796  ReferencedDirectory = Directory;
797 
798  /* Check if we have a parent directory */
799  if (ParentDirectory)
800  {
801  /* Check for traverse access */
804  AccessState,
805  FALSE,
806  AccessCheckMode,
807  &Status))
808  {
809  /* We don't have it, fail */
810  break;
811  }
812  }
813  }
814 
815  /* Check if we don't have a remaining name yet */
816  if (!RemainingName.Length)
817  {
818  /* Check if we don't have a referenced directory yet */
819  if (!ReferencedDirectory)
820  {
821  /* Reference it */
823  ReferencedDirectory = Directory;
824  }
825 
826  /* Check if we are inserting an object */
827  if (InsertObject)
828  {
829  /* Lock the directory */
831  }
832  }
833 
834  /* Do the lookup */
836  &ComponentName,
837  Attributes,
838  InsertObject ? FALSE : TRUE,
839  LookupContext);
840  if (!Object)
841  {
842  /* We didn't find it... do we still have a path? */
843  if (RemainingName.Length)
844  {
845  /* Then tell the caller the path wasn't found */
847  break;
848  }
849  else if (!InsertObject)
850  {
851  /* Otherwise, we have a path, but the name isn't valid */
853  break;
854  }
855 
856  /* Check create access for the object */
861  AccessState,
862  &ComponentName,
863  FALSE,
864  AccessCheckMode,
865  &Status))
866  {
867  /* We don't have create access, fail */
868  break;
869  }
870 
871  /* Get the object header */
872  ObjectHeader = OBJECT_TO_OBJECT_HEADER(InsertObject);
873 
874  /*
875  * Deny object creation if:
876  * That's a section object or a symbolic link
877  * Which isn't in the same section that root directory
878  * That doesn't have the SeCreateGlobalPrivilege
879  * And that is not a known unsecure name
880  */
881  if (RootDirectory->SessionId != -1)
882  {
883  if (ObjectHeader->Type == MmSectionObjectType ||
884  ObjectHeader->Type == ObpSymbolicLinkObjectType)
885  {
886  if (RootDirectory->SessionId != PsGetCurrentProcessSessionId() &&
887  !SeSinglePrivilegeCheck(SeCreateGlobalPrivilege, AccessCheckMode) &&
889  {
891  break;
892  }
893  }
894  }
895 
896  /* Create Object Name */
898  ComponentName.Length,
899  OB_NAME_TAG);
900  if (!(NewName) ||
902  LookupContext,
903  ObjectHeader)))
904  {
905  /* Either couldn't allocate the name, or insert failed */
907 
908  /* Fail due to memory reasons */
910  break;
911  }
912 
913  /* Reference newly to be inserted object */
914  ObReferenceObject(InsertObject);
915 
916  /* Get the name information */
917  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
918 
919  /* Reference the directory */
921 
922  /* Copy the Name */
924  ComponentName.Buffer,
925  ComponentName.Length);
926 
927  /* Check if we had an old name */
928  if (ObjectNameInfo->Name.Buffer)
929  {
930  /* Free it */
931  ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
932  }
933 
934  /* Write new one */
935  ObjectNameInfo->Name.Buffer = NewName;
936  ObjectNameInfo->Name.Length = ComponentName.Length;
937  ObjectNameInfo->Name.MaximumLength = ComponentName.Length;
938 
939  /* Return Status and the Expected Object */
941  Object = InsertObject;
942 
943  /* Get out of here */
944  break;
945  }
946 
947 ReparseObject:
948  /* We found it, so now get its header */
949  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
950 
951  /*
952  * Check for a parse Procedure, but don't bother to parse for an insert
953  * unless it's a Symbolic Link, in which case we MUST parse
954  */
955  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
956  if ((ParseRoutine) &&
957  (!(InsertObject) || (ParseRoutine == ObpParseSymbolicLink)))
958  {
959  /* Use the Root Directory next time */
960  Directory = NULL;
961 
962  /* Increment the pointer count */
963  InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount, 1);
964 
965  /* Cleanup from the first lookup */
966  ObpReleaseLookupContext(LookupContext);
967 
968  /* Check if we have a referenced directory */
969  if (ReferencedDirectory)
970  {
971  /* We do, dereference it */
972  ObDereferenceObject(ReferencedDirectory);
973  ReferencedDirectory = NULL;
974  }
975 
976  /* Check if we have a referenced parent directory */
977  if (ReferencedParentDirectory)
978  {
979  /* We do, dereference it */
980  ObDereferenceObject(ReferencedParentDirectory);
981  ReferencedParentDirectory = NULL;
982  }
983 
984  /* Call the Parse Procedure */
985  ObpCalloutStart(&CalloutIrql);
986  Status = ParseRoutine(Object,
987  ObjectType,
988  AccessState,
989  AccessCheckMode,
990  Attributes,
991  ObjectName,
992  &RemainingName,
993  ParseContext,
994  SecurityQos,
995  &Object);
996  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
997 
998  /* Remove our extra reference */
999  ObDereferenceObject(&ObjectHeader->Body);
1000 
1001  /* Check if we have to reparse */
1002  if ((Status == STATUS_REPARSE) ||
1004  {
1005  /* Reparse again */
1006  Reparse = TRUE;
1007  --MaxReparse;
1008  if (MaxReparse == 0)
1009  {
1010  Object = NULL;
1011  break;
1012  }
1013 
1014  /* Start over from root if we got sent back there */
1015  if ((Status == STATUS_REPARSE_OBJECT) ||
1016  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
1017  {
1018  /* Check if we got a root directory */
1019  if (RootHandle)
1020  {
1021  /* Stop using it, because we have a new directory now */
1023  RootHandle = NULL;
1024  }
1025 
1026  /* Start at Root */
1029 
1030  /* Check for reparse status */
1032  {
1033  /* Don't reparse again */
1034  Reparse = FALSE;
1035 
1036  /* Did we actually get an object to which to reparse? */
1037  if (!Object)
1038  {
1039  /* We didn't, so set a failure status */
1041  }
1042  else
1043  {
1044  /* We did, so we're free to parse the new object */
1045  goto ReparseObject;
1046  }
1047  }
1048  else
1049  {
1050  /* This is a symbolic link */
1051  SymLink = TRUE;
1052  goto ParseFromRoot;
1053  }
1054  }
1056  {
1057  /* We got STATUS_REPARSE but are at the Root Directory */
1058  Object = NULL;
1060  Reparse = FALSE;
1061  }
1062  }
1063  else if (!NT_SUCCESS(Status))
1064  {
1065  /* Total failure */
1066  Object = NULL;
1067  }
1068  else if (!Object)
1069  {
1070  /* We didn't reparse but we didn't find the Object Either */
1072  }
1073 
1074  /* Break out of the loop */
1075  break;
1076  }
1077  else
1078  {
1079  /* No parse routine...do we still have a remaining name? */
1080  if (!RemainingName.Length)
1081  {
1082  /* Are we creating an object? */
1083  if (!InsertObject)
1084  {
1085  /* Check if this is a user-mode call that needs to traverse */
1086  if ((AccessCheckMode != KernelMode) &&
1088  {
1089  /* Check if we can get it */
1092  AccessState,
1093  FALSE,
1094  AccessCheckMode,
1095  &Status))
1096  {
1097  /* We don't have access, fail */
1098  Object = NULL;
1099  break;
1100  }
1101  }
1102 
1103  /* Reference the Object */
1105  0,
1106  ObjectType,
1107  AccessMode);
1108  if (!NT_SUCCESS(Status)) Object = NULL;
1109  }
1110 
1111  /* And get out of the reparse loop */
1112  break;
1113  }
1114  else
1115  {
1116  /* We still have a name; check if this is a directory object */
1117  if (ObjectHeader->Type == ObpDirectoryObjectType)
1118  {
1119  /* Check if we have a referenced parent directory */
1120  if (ReferencedParentDirectory)
1121  {
1122  /* Dereference it */
1123  ObDereferenceObject(ReferencedParentDirectory);
1124  }
1125 
1126  /* Restart the lookup from this directory */
1127  ReferencedParentDirectory = ReferencedDirectory;
1129  Directory = Object;
1130  ReferencedDirectory = NULL;
1131  }
1132  else
1133  {
1134  /* We still have a name, but no parse routine for it */
1136  Object = NULL;
1137  break;
1138  }
1139  }
1140  }
1141  }
1142  }
1143 
1144  /* Check if we failed */
1145  if (!NT_SUCCESS(Status))
1146  {
1147  /* Cleanup after lookup */
1148  ObpReleaseLookupContext(LookupContext);
1149  }
1150 
1151  /* Check if we have a device map and dereference it if so */
1152  //if (DeviceMap) ObfDereferenceDeviceMap(DeviceMap);
1153 
1154  /* Check if we have a referenced directory and dereference it if so */
1155  if (ReferencedDirectory) ObDereferenceObject(ReferencedDirectory);
1156 
1157  /* Check if we have a referenced parent directory */
1158  if (ReferencedParentDirectory)
1159  {
1160  /* We do, dereference it */
1161  ObDereferenceObject(ReferencedParentDirectory);
1162  }
1163 
1164  /* Set the found object and check if we got one */
1165  *FoundObject = Object;
1166  if (!Object)
1167  {
1168  /* Nothing was found. Did we reparse or get success? */
1169  if ((Status == STATUS_REPARSE) || (NT_SUCCESS(Status)))
1170  {
1171  /* Set correct failure */
1173  }
1174  }
1175 
1176  /* Check if we had a root directory */
1177  if (RootHandle) ObDereferenceObject(RootDirectory);
1178 
1179  /* Return status to caller */
1181  "%s - Found Object: %p. Expected: %p\n",
1182  __FUNCTION__,
1183  *FoundObject,
1184  InsertObject);
1185  return Status;
1186 }
ObjectType
Definition: metafile.c:80
UNICODE_STRING ObpDosDevicesShortName
Definition: obname.c:25
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BOOLEAN ObpCaseInsensitive
Definition: obname.c:18
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
BOOLEAN NTAPI ObpIsUnsecureName(IN PUNICODE_STRING ObjectName, IN BOOLEAN CaseInSensitive)
Definition: obname.c:418
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING Name
Definition: obtypes.h:433
$ULONG LowPart
Definition: ntbasedef.h:576
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1124
BOOLEAN NTAPI ObpCheckTraverseAccess(IN PVOID Object, IN ACCESS_MASK TraverseAccess, IN PACCESS_STATE AccessState OPTIONAL, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS AccessStatus)
Definition: obsecure.c:267
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULARGE_INTEGER Alignment
Definition: ob.h:144
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
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
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define STATUS_REPARSE_OBJECT
Definition: ntstatus.h:102
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
unsigned char BOOLEAN
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:429
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
NTSTATUS(NTAPI * OB_PARSE_METHOD)(_In_ PVOID ParseObject, _In_ PVOID ObjectType, _Inout_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE AccessMode, _In_ ULONG Attributes, _Inout_ PUNICODE_STRING CompleteName, _Inout_ PUNICODE_STRING RemainingName, _Inout_opt_ PVOID Context, _In_opt_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _Out_ PVOID *Object)
Definition: obtypes.h:215
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
#define OB_NAME_TAG
Definition: tag.h:151
#define ObpDirectoryObjectType
Definition: ObTypes.c:123
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
$ULONG HighPart
Definition: ntbasedef.h:577
#define DIRECTORY_CREATE_SUBDIRECTORY
Definition: nt_native.h:1257
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:190
OB_PARSE_METHOD ParseProcedure
Definition: obtypes.h:370
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
ALIGNEDNAME ObpDosDevicesShortNameRoot
Definition: obname.c:24
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
static IUnknown Object
Definition: main.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const LUID SeCreateGlobalPrivilege
Definition: authpackage.c:168
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOLEAN NTAPI ObCheckCreateObjectAccess(IN PVOID Object, IN ACCESS_MASK CreateAccess, IN PACCESS_STATE AccessState, IN PUNICODE_STRING ComponentName, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS AccessStatus)
Definition: obsecure.c:203
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:437
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
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define OB_NAMESPACE_DEBUG
Definition: ob.h:18
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:255
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:124
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS NTAPI ObpParseSymbolicLink(IN PVOID ParsedObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING FullPath, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *NextObject)
Definition: oblink.c:430
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
unsigned int * PULONG
Definition: retypes.h:1
LONG_PTR PointerCount
Definition: obtypes.h:487
IN PDCB ParentDirectory
Definition: fatprocs.h:689
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
#define ObReferenceObject
Definition: obfuncs.h:204
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
unsigned int ULONG
Definition: retypes.h:1
ALIGNEDNAME ObpDosDevicesShortNamePrefix
Definition: obname.c:23
base for all directory entries
Definition: entries.h:138
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:281
POBJECT_TYPE Type
Definition: obtypes.h:493
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3718
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define __FUNCTION__
Definition: types.h:112
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806

Referenced by ObInsertObject(), ObOpenObjectByName(), and ObReferenceObjectByName().

◆ ObQueryNameString()

NTSTATUS NTAPI ObQueryNameString ( IN PVOID  Object,
OUT POBJECT_NAME_INFORMATION  ObjectNameInfo,
IN ULONG  Length,
OUT PULONG  ReturnLength 
)

Definition at line 1192 of file obname.c.

1196 {
1197  POBJECT_HEADER_NAME_INFO LocalInfo;
1198  POBJECT_HEADER ObjectHeader;
1200  ULONG NameSize;
1201  PWCH ObjectName;
1202  BOOLEAN ObjectIsNamed;
1204 
1205  /* Get the Kernel Meta-Structures */
1206  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1207  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1208 
1209  /* Check if a Query Name Procedure is available */
1210  if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
1211  {
1212  /* Call the procedure inside SEH */
1213  ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0));
1214 
1215  _SEH2_TRY
1216  {
1217  Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
1218  ObjectIsNamed,
1219  ObjectNameInfo,
1220  Length,
1221  ReturnLength,
1222  KernelMode);
1223  }
1225  {
1226  /* Return the exception code */
1228  }
1229  _SEH2_END;
1230 
1231  return Status;
1232  }
1233 
1234  /* Check if the object doesn't even have a name */
1235  if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
1236  {
1238 
1239  _SEH2_TRY
1240  {
1241  /* We're returning the name structure */
1243 
1244  /* Check if we were given enough space */
1245  if (*ReturnLength > Length)
1246  {
1248  }
1249  else
1250  {
1251  /* Return an empty buffer */
1252  RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
1253  }
1254  }
1256  {
1257  /* Return the exception code */
1259  }
1260  _SEH2_END;
1261 
1262  return Status;
1263  }
1264 
1265  /*
1266  * Find the size needed for the name. We won't do
1267  * this during the Name Creation loop because we want
1268  * to let the caller know that the buffer isn't big
1269  * enough right at the beginning, not work our way through
1270  * and find out at the end
1271  */
1272  _SEH2_TRY
1273  {
1275  {
1276  /* Size of the '\' string */
1277  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
1278  }
1279  else
1280  {
1281  /* Get the Object Directory and add name of Object */
1282  ParentDirectory = LocalInfo->Directory;
1283  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
1284 
1285  /* Loop inside the directory to get the top-most one (meaning root) */
1287  {
1288  /* Get the Name Information */
1289  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1291 
1292  /* Add the size of the Directory Name */
1293  if (LocalInfo && LocalInfo->Directory)
1294  {
1295  /* Size of the '\' string + Directory Name */
1296  NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
1297  LocalInfo->Name.Length;
1298 
1299  /* Move to next parent Directory */
1300  ParentDirectory = LocalInfo->Directory;
1301  }
1302  else
1303  {
1304  /* Directory with no name. We append "...\" */
1305  NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
1306  break;
1307  }
1308  }
1309  }
1310 
1311  /* Finally, add the name of the structure and the null char */
1312  *ReturnLength = NameSize +
1313  sizeof(OBJECT_NAME_INFORMATION) +
1314  sizeof(UNICODE_NULL);
1315 
1316  /* Check if we were given enough space */
1318 
1319  /*
1320  * Now we will actually create the name. We work backwards because
1321  * it's easier to start off from the Name we have and walk up the
1322  * parent directories. We use the same logic as Name Length calculation.
1323  */
1324  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1325  ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
1326  *--ObjectName = UNICODE_NULL;
1327 
1328  /* Check if the object is actually the Root directory */
1330  {
1331  /* This is already the Root Directory, return "\\" */
1333  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1334  ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
1335  sizeof(UNICODE_NULL));
1336  ObjectNameInfo->Name.Buffer = ObjectName;
1338  }
1339  else
1340  {
1341  /* Start by adding the Object's Name */
1343  LocalInfo->Name.Length);
1345  LocalInfo->Name.Buffer,
1346  LocalInfo->Name.Length);
1347 
1348  /* Now parse the Parent directories until we reach the top */
1349  ParentDirectory = LocalInfo->Directory;
1351  {
1352  /* Get the name information */
1353  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1355 
1356  /* Add the "\" */
1358 
1359  /* Add the Parent Directory's Name */
1360  if (LocalInfo && LocalInfo->Name.Buffer)
1361  {
1362  /* Add the name */
1364  LocalInfo->Name.Length);
1366  LocalInfo->Name.Buffer,
1367  LocalInfo->Name.Length);
1368 
1369  /* Move to next parent */
1370  ParentDirectory = LocalInfo->Directory;
1371  }
1372  else
1373  {
1374  /* Directory without a name, we add "..." */
1376  sizeof(L"...") +
1377  sizeof(UNICODE_NULL));
1378  RtlCopyMemory(ObjectName, L"...", sizeof(L"..."));
1379  break;
1380  }
1381  }
1382 
1383  /* Add Root Directory Name */
1385  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1386  ObjectNameInfo->Name.MaximumLength =
1387  (USHORT)(NameSize + sizeof(UNICODE_NULL));
1388  ObjectNameInfo->Name.Buffer = ObjectName;
1389  }
1390  }
1392  {
1393  /* Return the exception code */
1395  }
1396  _SEH2_END;
1397 
1398  /* Return success */
1399  return Status;
1400 }
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
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_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING Name
Definition: obtypes.h:433
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
while(1)
Definition: macro.lex.yy.c:740
#define UNICODE_NULL
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static IUnknown Object
Definition: main.c:512
WCHAR * PWCH
Definition: ntbasedef.h:417
static const WCHAR L[]
Definition: oid.c:1250
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
unsigned short USHORT
Definition: pedump.c:61
IN PDCB ParentDirectory
Definition: fatprocs.h:689
unsigned int ULONG
Definition: retypes.h:1
OB_QUERYNAME_METHOD QueryNameProcedure
Definition: obtypes.h:372
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
POBJECT_TYPE Type
Definition: obtypes.h:493
return STATUS_SUCCESS
Definition: btrfs.c:2777

Referenced by FltpGetObjectName(), IoGetDeviceProperty(), IopLogWorker(), IopQueryNameInternal(), IoRegisterDeviceInterface(), MmGetFileNameForFileObject(), MountMgrVolumeMountPointChanged(), NtQueryObject(), PopFlushVolumeWorker(), and SeInitializeProcessAuditName().

Variable Documentation

◆ ObpCaseInsensitive

BOOLEAN ObpCaseInsensitive = TRUE

Definition at line 18 of file obname.c.

Referenced by ObpLookupObjectName().

◆ ObpDosDevicesShortName

UNICODE_STRING ObpDosDevicesShortName
Initial value:
=
{
}
uint16_t * PWSTR
Definition: typedefs.h:54
ALIGNEDNAME ObpDosDevicesShortNamePrefix
Definition: obname.c:23

Definition at line 25 of file obname.c.

Referenced by ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

◆ ObpDosDevicesShortNamePrefix

ALIGNEDNAME ObpDosDevicesShortNamePrefix = {{L'\\',L'?',L'?',L'\\'}}

Definition at line 23 of file obname.c.

Referenced by ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

◆ ObpDosDevicesShortNameRoot

ALIGNEDNAME ObpDosDevicesShortNameRoot = {{L'\\',L'?',L'?',L'\0'}}

Definition at line 24 of file obname.c.

Referenced by ObpCreateDosDevicesDirectory(), and ObpLookupObjectName().

◆ ObpRootDirectoryObject

POBJECT_DIRECTORY ObpRootDirectoryObject

◆ ObpTypeDirectoryObject

POBJECT_DIRECTORY ObpTypeDirectoryObject

Definition at line 20 of file obname.c.

Referenced by ObCreateObjectType(), and ObInitSystem().

◆ ObpUnsecureGlobalNamesBuffer

WCHAR ObpUnsecureGlobalNamesBuffer[128] = {0}

Definition at line 32 of file obname.c.

Referenced by ObpIsUnsecureName().

◆ ObpUnsecureGlobalNamesLength

ULONG ObpUnsecureGlobalNamesLength = sizeof(ObpUnsecureGlobalNamesBuffer)

Definition at line 33 of file obname.c.