ReactOS  0.4.13-dev-52-g0efcfec
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 ObpCreateGlobalDosDevicesSD (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 133 of file obname.c.

134 {
136  UNICODE_STRING RootName, TargetName, LinkName;
137  HANDLE Handle, SymHandle;
138  PSECURITY_DESCRIPTOR DosDevicesSD = NULL;
140 
141  /* Create a custom security descriptor for the global DosDevices directory */
142  Status = ObpCreateGlobalDosDevicesSD(&DosDevicesSD);
143  if (!NT_SUCCESS(Status))
144  return Status;
145 
146  /* Create the global DosDevices directory \?? */
147  RtlInitUnicodeString(&RootName, L"\\GLOBAL??");
149  &RootName,
151  NULL,
152  DosDevicesSD);
156  ExFreePoolWithTag(DosDevicesSD, TAG_SD);
157  if (!NT_SUCCESS(Status)) return Status;
158 
159  /* Create the system device map */
161  if (!NT_SUCCESS(Status))
162  return Status;
163 
164  /*********************************************\
165  |*** HACK until we support device mappings ***|
166  |*** Add a symlink \??\ <--> \GLOBAL??\ ***|
167  \*********************************************/
168  RtlInitUnicodeString(&LinkName, L"\\??");
170  &LinkName,
172  NULL,
173  NULL);
174  Status = NtCreateSymbolicLinkObject(&SymHandle,
177  &RootName);
178  if (NT_SUCCESS(Status)) NtClose(SymHandle);
179  /*********************************************\
180  \*********************************************/
181 
182  // FIXME: Create a device mapping for the global \?? directory
183 
184  /*
185  * Initialize the \??\GLOBALROOT symbolic link
186  * pointing to the root directory \ .
187  */
188  RtlInitUnicodeString(&LinkName, L"GLOBALROOT");
191  &LinkName,
193  Handle,
194  NULL);
195  Status = NtCreateSymbolicLinkObject(&SymHandle,
198  &TargetName);
199  if (NT_SUCCESS(Status)) NtClose(SymHandle);
200 
201  /*
202  * Initialize the \??\Global symbolic link pointing to the global
203  * DosDevices directory \?? . It is used to access the global \??
204  * by user-mode components which, by default, use a per-session
205  * DosDevices directory.
206  */
207  RtlInitUnicodeString(&LinkName, L"Global");
209  &LinkName,
211  Handle,
212  NULL);
213  Status = NtCreateSymbolicLinkObject(&SymHandle,
216  &RootName);
217  if (NT_SUCCESS(Status)) NtClose(SymHandle);
218 
219  /* Close the directory handle */
220  NtClose(Handle);
221  if (!NT_SUCCESS(Status)) return Status;
222 
223  /*
224  * Initialize the \DosDevices symbolic link pointing to the global
225  * DosDevices directory \?? , for backward compatibility with
226  * Windows NT-2000 systems.
227  */
228  RtlCreateUnicodeString(&LinkName, L"\\DosDevices");
231  &LinkName,
233  NULL,
234  NULL);
235  Status = NtCreateSymbolicLinkObject(&SymHandle,
238  &RootName);
239  if (NT_SUCCESS(Status)) NtClose(SymHandle);
240 
241  /* Return status */
242  return Status;
243 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_PERMANENT
Definition: winternl.h:226
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
INIT_FUNCTION NTSTATUS NTAPI ObpCreateGlobalDosDevicesSD(OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
Definition: obname.c:40
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ObpCreateDeviceMap(IN HANDLE DirectoryHandle)
Definition: devicemap.c:20
#define TAG_SD
Definition: tag.h:176
_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:731
#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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ObInitSystem().

◆ ObpCreateGlobalDosDevicesSD()

INIT_FUNCTION NTSTATUS NTAPI ObpCreateGlobalDosDevicesSD ( OUT PSECURITY_DESCRIPTOR SecurityDescriptor)

Definition at line 40 of file obname.c.

41 {
43  PACL Dacl;
44  ULONG AclSize, SdSize;
46 
47  AclSize = sizeof(ACL) +
48  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
49  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
50  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
51  sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid) +
52  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
54 
55  SdSize = sizeof(SECURITY_DESCRIPTOR) + AclSize;
56 
57  /* Allocate the SD and ACL */
58  Sd = ExAllocatePoolWithTag(PagedPool, SdSize, TAG_SD);
59  if (Sd == NULL)
60  {
62  }
63 
64  /* Initialize the SD */
67  if (!NT_SUCCESS(Status))
68  return Status;
69 
70  Dacl = (PACL)((INT_PTR)Sd + sizeof(SECURITY_DESCRIPTOR));
71 
72  /* Initialize the DACL */
73  RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
74 
75  /* Add the ACEs */
79  SeWorldSid);
80 
85 
90  SeWorldSid);
91 
97 
101  GENERIC_ALL,
103 
105  ACL_REVISION,
107  GENERIC_ALL,
109 
110  /* Attach the DACL to the SD */
112  TRUE,
113  Dacl,
114  FALSE);
115  if (!NT_SUCCESS(Status))
116  goto done;
117 
118  *SecurityDescriptor = Sd;
119 
120 done:
121  if (!NT_SUCCESS(Status))
122  {
123  if (Sd != NULL)
125  }
126 
127  return Status;
128 }
#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)
int32_t INT_PTR
Definition: typedefs.h:62
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
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 TAG_SD
Definition: tag.h:176
struct _ACL * PACL
Definition: security.c:104
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
PSID SeWorldSid
Definition: sid.c:31
Status
Definition: gdiplustypes.h:24
#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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define GENERIC_EXECUTE
Definition: nt_native.h:91
Definition: rtltypes.h:988
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpDeleteNameCheck()

VOID NTAPI ObpDeleteNameCheck ( IN PVOID  Object)

Definition at line 264 of file obname.c.

265 {
266  POBJECT_HEADER ObjectHeader;
268  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
270  PVOID Directory = NULL;
271 
272  /* Get object structures */
273  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
274  ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
275  ObjectType = ObjectHeader->Type;
276 
277  /*
278  * Check if the handle count is 0, if the object is named,
279  * and if the object isn't a permanent object.
280  */
281  if (!(ObjectHeader->HandleCount) &&
282  (ObjectNameInfo) &&
283  (ObjectNameInfo->Name.Length) &&
284  (ObjectNameInfo->Directory) &&
285  !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
286  {
287  /* Setup a lookup context */
289 
290  /* Lock the directory */
292 
293  /* Do the lookup */
294  Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
295  &ObjectNameInfo->Name,
296  0,
297  FALSE,
298  &Context);
299  if (Object)
300  {
301  /* Lock the object */
302  ObpAcquireObjectLock(ObjectHeader);
303 
304  /* Make sure we can still delete the object */
305  if (!(ObjectHeader->HandleCount) &&
306  !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
307  {
308  /* First delete it from the directory */
310 
311  /* Check if this is a symbolic link */
313  {
314  /* Remove internal name */
316  }
317 
318  /* Check if the kernel exclusive is set */
319  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
320  if ((ObjectNameInfo) &&
321  (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
322  {
323  /* Remove protection flag */
324  InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences,
326  }
327 
328  /* Get the directory */
329  Directory = ObjectNameInfo->Directory;
330  }
331 
332  /* Release the lock */
333  ObpReleaseObjectLock(ObjectHeader);
334  }
335 
336  /* Cleanup after lookup */
338 
339  /* Remove another query reference since we added one on top */
340  ObpDereferenceNameInfo(ObjectNameInfo);
341 
342  /* Check if we were inserted in a directory */
343  if (Directory)
344  {
345  /* We were, so first remove the extra reference we had added */
346  ObpDereferenceNameInfo(ObjectNameInfo);
347 
348  /* Now dereference the object as well */
350  }
351  }
352  else
353  {
354  /* Remove the reference we added */
355  ObpDereferenceNameInfo(ObjectNameInfo);
356  }
357 }
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:123
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:255
VOID NTAPI ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:24
#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().

◆ ObpIsUnsecureName()

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

Definition at line 361 of file obname.c.

363 {
364  BOOLEAN Unsecure;
365  PWSTR UnsecureBuffer;
366  UNICODE_STRING UnsecureName;
367 
368  /* No unsecure names known, quit */
370  {
371  return FALSE;
372  }
373 
374  /* By default, we have a secure name */
375  Unsecure = FALSE;
376  /* We will browse the whole string */
377  UnsecureBuffer = &ObpUnsecureGlobalNamesBuffer[0];
378  while (TRUE)
379  {
380  /* Initialize the unicode string */
381  RtlInitUnicodeString(&UnsecureName, UnsecureBuffer);
382  /* We're at the end of the multisz string! */
383  if (UnsecureName.Length == 0)
384  {
385  break;
386  }
387 
388  /*
389  * Does the unsecure name prefix the object name?
390  * If so, that's an unsecure name, and return so
391  */
393  {
394  Unsecure = TRUE;
395  break;
396  }
397 
398  /*
399  * Move to the next string. As a reminder, ObpUnsecureGlobalNamesBuffer is
400  * a multisz, so we move the string next to the current UNICODE_NULL char
401  */
402  UnsecureBuffer = (PWSTR)((ULONG_PTR)UnsecureBuffer + UnsecureName.Length + sizeof(UNICODE_NULL));
403  }
404 
405  /* Return our findings */
406  return Unsecure;
407 }
#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 411 of file obname.c.

422 {
423  PVOID Object;
424  POBJECT_HEADER ObjectHeader;
425  UNICODE_STRING ComponentName, RemainingName;
426  BOOLEAN Reparse = FALSE, SymLink = FALSE;
428  POBJECT_DIRECTORY ReferencedDirectory = NULL, ReferencedParentDirectory = NULL;
429  KIRQL CalloutIrql;
430  OB_PARSE_METHOD ParseRoutine;
432  KPROCESSOR_MODE AccessCheckMode;
433  PWCHAR NewName;
434  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
435  ULONG MaxReparse = 30;
436  PAGED_CODE();
438  "%s - Finding Object: %wZ. Expecting: %p\n",
439  __FUNCTION__,
440  ObjectName,
441  InsertObject);
442 
443  /* Initialize starting state */
444  ObpInitializeLookupContext(LookupContext);
445  *FoundObject = NULL;
447  Object = NULL;
448 
449  /* Check if case-insensitivity is checked */
450  if (ObpCaseInsensitive)
451  {
452  /* Check if the object type requests this */
453  if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
454  {
455  /* Add the flag to disable case sensitivity */
457  }
458  }
459 
460  /* Check if this is a access checks are being forced */
461  AccessCheckMode = (Attributes & OBJ_FORCE_ACCESS_CHECK) ?
463 
464  /* Check if we got a Root Directory */
465  if (RootHandle)
466  {
467  /* We did. Reference it */
468  Status = ObReferenceObjectByHandle(RootHandle,
469  0,
470  NULL,
471  AccessMode,
472  (PVOID*)&RootDirectory,
473  NULL);
474  if (!NT_SUCCESS(Status)) return Status;
475 
476  /* Get the header */
477  ObjectHeader = OBJECT_TO_OBJECT_HEADER(RootDirectory);
478 
479  /* The name cannot start with a separator, unless this is a file */
480  if ((ObjectName->Buffer) &&
481  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
482  (ObjectHeader->Type != IoFileObjectType))
483  {
484  /* The syntax is bad, so fail this request */
487  }
488 
489  /* Don't parse a Directory */
490  if (ObjectHeader->Type != ObpDirectoryObjectType)
491  {
492  /* Make sure the Object Type has a parse routine */
493  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
494  if (!ParseRoutine)
495  {
496  /* We can't parse a name if we don't have a parse routine */
498  return STATUS_INVALID_HANDLE;
499  }
500 
501  /* Set default parse count */
502  MaxReparse = 30;
503 
504  /* Now parse */
505  while (TRUE)
506  {
507  /* Start with the full name */
509 
510  /* Call the Parse Procedure */
511  ObpCalloutStart(&CalloutIrql);
512  Status = ParseRoutine(RootDirectory,
513  ObjectType,
514  AccessState,
515  AccessCheckMode,
516  Attributes,
517  ObjectName,
518  &RemainingName,
519  ParseContext,
520  SecurityQos,
521  &Object);
522  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
523 
524  /* Check for success or failure, so not reparse */
525  if ((Status != STATUS_REPARSE) &&
527  {
528  /* Check for failure */
529  if (!NT_SUCCESS(Status))
530  {
531  /* Parse routine might not have cleared this, do it */
532  Object = NULL;
533  }
534  else if (!Object)
535  {
536  /* Modify status to reflect failure inside Ob */
538  }
539 
540  /* We're done, return the status and object */
541  *FoundObject = Object;
543  return Status;
544  }
545  else if ((!ObjectName->Length) ||
546  (!ObjectName->Buffer) ||
547  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
548  {
549  /* Reparsed to the root directory, so start over */
552 
553  /* Don't use this anymore, since we're starting at root */
554  RootHandle = NULL;
555  goto ParseFromRoot;
556  }
557  else if (--MaxReparse)
558  {
559  /* Try reparsing again */
560  continue;
561  }
562  else
563  {
564  /* Reparsed too many times */
566 
567  /* Return the object and normalized status */
568  *FoundObject = Object;
570  return Status;
571  }
572  }
573  }
574  else if (!(ObjectName->Length) || !(ObjectName->Buffer))
575  {
576  /* Just return the Root Directory if we didn't get a name */
578  0,
579  ObjectType,
580  AccessMode);
582 
583  /* Remove the first reference we added and return the object */
585  *FoundObject = Object;
586  return Status;
587  }
588  }
589  else
590  {
591  /* We did not get a Root Directory, so use the root */
593 
594  /* It must start with a path separator */
595  if (!(ObjectName->Length) ||
596  !(ObjectName->Buffer) ||
597  (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
598  {
599  /* This name is invalid, so fail */
601  }
602 
603  /* Check if the name is only the path separator */
604  if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
605  {
606  /* So the caller only wants the root directory; do we have one? */
607  if (!RootDirectory)
608  {
609  /* This must be the first time we're creating it... right? */
610  if (InsertObject)
611  {
612  /* Yes, so return it to ObInsert so that it can create it */
613  Status = ObReferenceObjectByPointer(InsertObject,
614  0,
615  ObjectType,
616  AccessMode);
617  if (NT_SUCCESS(Status)) *FoundObject = InsertObject;
618  return Status;
619  }
620  else
621  {
622  /* This should never really happen */
623  ASSERT(FALSE);
625  }
626  }
627  else
628  {
629  /* We do have the root directory, so just return it */
631  0,
632  ObjectType,
633  AccessMode);
634  if (NT_SUCCESS(Status)) *FoundObject = RootDirectory;
635  return Status;
636  }
637  }
638  else
639  {
640 ParseFromRoot:
641  /* FIXME: Check if we have a device map */
642 
643  /* Check if this is a possible DOS name */
644  if (!((ULONG_PTR)(ObjectName->Buffer) & 7))
645  {
646  /*
647  * This could be one. Does it match the prefix?
648  * Note that as an optimization, the match is done as 64-bit
649  * compare since the prefix is "\??\" which is exactly 8 bytes.
650  *
651  * In the second branch, we test for "\??" which is also valid.
652  * This time, we use a 32-bit compare followed by a Unicode
653  * character compare (16-bit), since the sum is 6 bytes.
654  */
655  if ((ObjectName->Length >= ObpDosDevicesShortName.Length) &&
656  (*(PULONGLONG)(ObjectName->Buffer) ==
658  {
659  /* FIXME! */
660  }
661  else if ((ObjectName->Length == ObpDosDevicesShortName.Length -
662  sizeof(WCHAR)) &&
663  (*(PULONG)(ObjectName->Buffer) ==
665  (*((PWCHAR)(ObjectName->Buffer) + 2) ==
667  {
668  /* FIXME! */
669  }
670  }
671  }
672  }
673 
674  /* Check if we were reparsing a symbolic link */
675  if (!SymLink)
676  {
677  /* Allow reparse */
678  Reparse = TRUE;
679  MaxReparse = 30;
680  }
681 
682  /* Reparse */
683  while (Reparse && MaxReparse)
684  {
685  /* Get the name */
687 
688  /* Disable reparsing again */
689  Reparse = FALSE;
690 
691  /* Start parse loop */
692  while (TRUE)
693  {
694  /* Clear object */
695  Object = NULL;
696 
697  /* Check if the name starts with a path separator */
698  if ((RemainingName.Length) &&
699  (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
700  {
701  /* Skip the path separator */
702  RemainingName.Buffer++;
703  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
704  }
705 
706  /* Find the next Part Name */
707  ComponentName = RemainingName;
708  while (RemainingName.Length)
709  {
710  /* Break if we found the \ ending */
711  if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
712 
713  /* Move on */
714  RemainingName.Buffer++;
715  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
716  }
717 
718  /* Get its size and make sure it's valid */
719  ComponentName.Length -= RemainingName.Length;
720  if (!ComponentName.Length)
721  {
722  /* Invalid size, fail */
724  break;
725  }
726 
727  /* Check if we're in the root */
729 
730  /* Check if this is a user-mode call that needs to traverse */
731  if ((AccessCheckMode != KernelMode) &&
733  {
734  /* We shouldn't have referenced a directory yet */
735  ASSERT(ReferencedDirectory == NULL);
736 
737  /* Reference the directory */
739  ReferencedDirectory = Directory;
740 
741  /* Check if we have a parent directory */
742  if (ParentDirectory)
743  {
744  /* Check for traverse access */
747  AccessState,
748  FALSE,
749  AccessCheckMode,
750  &Status))
751  {
752  /* We don't have it, fail */
753  break;
754  }
755  }
756  }
757 
758  /* Check if we don't have a remaining name yet */
759  if (!RemainingName.Length)
760  {
761  /* Check if we don't have a referenced directory yet */
762  if (!ReferencedDirectory)
763  {
764  /* Reference it */
766  ReferencedDirectory = Directory;
767  }
768 
769  /* Check if we are inserting an object */
770  if (InsertObject)
771  {
772  /* Lock the directory */
774  }
775  }
776 
777  /* Do the lookup */
779  &ComponentName,
780  Attributes,
781  InsertObject ? FALSE : TRUE,
782  LookupContext);
783  if (!Object)
784  {
785  /* We didn't find it... do we still have a path? */
786  if (RemainingName.Length)
787  {
788  /* Then tell the caller the path wasn't found */
790  break;
791  }
792  else if (!InsertObject)
793  {
794  /* Otherwise, we have a path, but the name isn't valid */
796  break;
797  }
798 
799  /* Check create access for the object */
804  AccessState,
805  &ComponentName,
806  FALSE,
807  AccessCheckMode,
808  &Status))
809  {
810  /* We don't have create access, fail */
811  break;
812  }
813 
814  /* Get the object header */
815  ObjectHeader = OBJECT_TO_OBJECT_HEADER(InsertObject);
816 
817  /*
818  * Deny object creation if:
819  * That's a section object or a symbolic link
820  * Which isn't in the same section that root directory
821  * That doesn't have the SeCreateGlobalPrivilege
822  * And that is not a known unsecure name
823  */
824  if (RootDirectory->SessionId != -1)
825  {
826  if (ObjectHeader->Type == MmSectionObjectType ||
827  ObjectHeader->Type == ObpSymbolicLinkObjectType)
828  {
829  if (RootDirectory->SessionId != PsGetCurrentProcessSessionId() &&
830  !SeSinglePrivilegeCheck(SeCreateGlobalPrivilege, AccessCheckMode) &&
832  {
834  break;
835  }
836  }
837  }
838 
839  /* Create Object Name */
841  ComponentName.Length,
842  OB_NAME_TAG);
843  if (!(NewName) ||
845  LookupContext,
846  ObjectHeader)))
847  {
848  /* Either couldn't allocate the name, or insert failed */
850 
851  /* Fail due to memory reasons */
853  break;
854  }
855 
856  /* Reference newly to be inserted object */
857  ObReferenceObject(InsertObject);
858 
859  /* Get the name information */
860  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
861 
862  /* Reference the directory */
864 
865  /* Copy the Name */
867  ComponentName.Buffer,
868  ComponentName.Length);
869 
870  /* Check if we had an old name */
871  if (ObjectNameInfo->Name.Buffer)
872  {
873  /* Free it */
874  ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
875  }
876 
877  /* Write new one */
878  ObjectNameInfo->Name.Buffer = NewName;
879  ObjectNameInfo->Name.Length = ComponentName.Length;
880  ObjectNameInfo->Name.MaximumLength = ComponentName.Length;
881 
882  /* Return Status and the Expected Object */
884  Object = InsertObject;
885 
886  /* Get out of here */
887  break;
888  }
889 
890 ReparseObject:
891  /* We found it, so now get its header */
892  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
893 
894  /*
895  * Check for a parse Procedure, but don't bother to parse for an insert
896  * unless it's a Symbolic Link, in which case we MUST parse
897  */
898  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
899  if ((ParseRoutine) &&
900  (!(InsertObject) || (ParseRoutine == ObpParseSymbolicLink)))
901  {
902  /* Use the Root Directory next time */
903  Directory = NULL;
904 
905  /* Increment the pointer count */
906  InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount, 1);
907 
908  /* Cleanup from the first lookup */
909  ObpReleaseLookupContext(LookupContext);
910 
911  /* Check if we have a referenced directory */
912  if (ReferencedDirectory)
913  {
914  /* We do, dereference it */
915  ObDereferenceObject(ReferencedDirectory);
916  ReferencedDirectory = NULL;
917  }
918 
919  /* Check if we have a referenced parent directory */
920  if (ReferencedParentDirectory)
921  {
922  /* We do, dereference it */
923  ObDereferenceObject(ReferencedParentDirectory);
924  ReferencedParentDirectory = NULL;
925  }
926 
927  /* Call the Parse Procedure */
928  ObpCalloutStart(&CalloutIrql);
929  Status = ParseRoutine(Object,
930  ObjectType,
931  AccessState,
932  AccessCheckMode,
933  Attributes,
934  ObjectName,
935  &RemainingName,
936  ParseContext,
937  SecurityQos,
938  &Object);
939  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
940 
941  /* Remove our extra reference */
942  ObDereferenceObject(&ObjectHeader->Body);
943 
944  /* Check if we have to reparse */
945  if ((Status == STATUS_REPARSE) ||
947  {
948  /* Reparse again */
949  Reparse = TRUE;
950  --MaxReparse;
951  if (MaxReparse == 0)
952  {
953  Object = NULL;
954  break;
955  }
956 
957  /* Start over from root if we got sent back there */
958  if ((Status == STATUS_REPARSE_OBJECT) ||
959  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
960  {
961  /* Check if we got a root directory */
962  if (RootHandle)
963  {
964  /* Stop using it, because we have a new directory now */
966  RootHandle = NULL;
967  }
968 
969  /* Start at Root */
972 
973  /* Check for reparse status */
975  {
976  /* Don't reparse again */
977  Reparse = FALSE;
978 
979  /* Did we actually get an object to which to reparse? */
980  if (!Object)
981  {
982  /* We didn't, so set a failure status */
984  }
985  else
986  {
987  /* We did, so we're free to parse the new object */
988  goto ReparseObject;
989  }
990  }
991  else
992  {
993  /* This is a symbolic link */
994  SymLink = TRUE;
995  goto ParseFromRoot;
996  }
997  }
999  {
1000  /* We got STATUS_REPARSE but are at the Root Directory */
1001  Object = NULL;
1003  Reparse = FALSE;
1004  }
1005  }
1006  else if (!NT_SUCCESS(Status))
1007  {
1008  /* Total failure */
1009  Object = NULL;
1010  }
1011  else if (!Object)
1012  {
1013  /* We didn't reparse but we didn't find the Object Either */
1015  }
1016 
1017  /* Break out of the loop */
1018  break;
1019  }
1020  else
1021  {
1022  /* No parse routine...do we still have a remaining name? */
1023  if (!RemainingName.Length)
1024  {
1025  /* Are we creating an object? */
1026  if (!InsertObject)
1027  {
1028  /* Check if this is a user-mode call that needs to traverse */
1029  if ((AccessCheckMode != KernelMode) &&
1031  {
1032  /* Check if we can get it */
1035  AccessState,
1036  FALSE,
1037  AccessCheckMode,
1038  &Status))
1039  {
1040  /* We don't have access, fail */
1041  Object = NULL;
1042  break;
1043  }
1044  }
1045 
1046  /* Reference the Object */
1048  0,
1049  ObjectType,
1050  AccessMode);
1051  if (!NT_SUCCESS(Status)) Object = NULL;
1052  }
1053 
1054  /* And get out of the reparse loop */
1055  break;
1056  }
1057  else
1058  {
1059  /* We still have a name; check if this is a directory object */
1060  if (ObjectHeader->Type == ObpDirectoryObjectType)
1061  {
1062  /* Check if we have a referenced parent directory */
1063  if (ReferencedParentDirectory)
1064  {
1065  /* Dereference it */
1066  ObDereferenceObject(ReferencedParentDirectory);
1067  }
1068 
1069  /* Restart the lookup from this directory */
1070  ReferencedParentDirectory = ReferencedDirectory;
1072  Directory = Object;
1073  ReferencedDirectory = NULL;
1074  }
1075  else
1076  {
1077  /* We still have a name, but no parse routine for it */
1079  Object = NULL;
1080  break;
1081  }
1082  }
1083  }
1084  }
1085  }
1086 
1087  /* Check if we failed */
1088  if (!NT_SUCCESS(Status))
1089  {
1090  /* Cleanup after lookup */
1091  ObpReleaseLookupContext(LookupContext);
1092  }
1093 
1094  /* Check if we have a device map and dereference it if so */
1095  //if (DeviceMap) ObfDereferenceDeviceMap(DeviceMap);
1096 
1097  /* Check if we have a referenced directory and dereference it if so */
1098  if (ReferencedDirectory) ObDereferenceObject(ReferencedDirectory);
1099 
1100  /* Check if we have a referenced parent directory */
1101  if (ReferencedParentDirectory)
1102  {
1103  /* We do, dereference it */
1104  ObDereferenceObject(ReferencedParentDirectory);
1105  }
1106 
1107  /* Set the found object and check if we got one */
1108  *FoundObject = Object;
1109  if (!Object)
1110  {
1111  /* Nothing was found. Did we reparse or get success? */
1112  if ((Status == STATUS_REPARSE) || (NT_SUCCESS(Status)))
1113  {
1114  /* Set correct failure */
1116  }
1117  }
1118 
1119  /* Check if we had a root directory */
1120  if (RootHandle) ObDereferenceObject(RootDirectory);
1121 
1122  /* Return status to caller */
1124  "%s - Found Object: %p. Expected: %p\n",
1125  __FUNCTION__,
1126  *FoundObject,
1127  InsertObject);
1128  return Status;
1129 }
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:361
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:46
#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:123
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:363
#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:2725
#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 1135 of file obname.c.

1139 {
1140  POBJECT_HEADER_NAME_INFO LocalInfo;
1141  POBJECT_HEADER ObjectHeader;
1143  ULONG NameSize;
1144  PWCH ObjectName;
1145  BOOLEAN ObjectIsNamed;
1147 
1148  /* Get the Kernel Meta-Structures */
1149  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1150  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1151 
1152  /* Check if a Query Name Procedure is available */
1153  if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
1154  {
1155  /* Call the procedure inside SEH */
1156  ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0));
1157 
1158  _SEH2_TRY
1159  {
1160  Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
1161  ObjectIsNamed,
1162  ObjectNameInfo,
1163  Length,
1164  ReturnLength,
1165  KernelMode);
1166  }
1168  {
1169  /* Return the exception code */
1171  }
1172  _SEH2_END;
1173 
1174  return Status;
1175  }
1176 
1177  /* Check if the object doesn't even have a name */
1178  if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
1179  {
1181 
1182  _SEH2_TRY
1183  {
1184  /* We're returning the name structure */
1186 
1187  /* Check if we were given enough space */
1188  if (*ReturnLength > Length)
1189  {
1191  }
1192  else
1193  {
1194  /* Return an empty buffer */
1195  RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
1196  }
1197  }
1199  {
1200  /* Return the exception code */
1202  }
1203  _SEH2_END;
1204 
1205  return Status;
1206  }
1207 
1208  /*
1209  * Find the size needed for the name. We won't do
1210  * this during the Name Creation loop because we want
1211  * to let the caller know that the buffer isn't big
1212  * enough right at the beginning, not work our way through
1213  * and find out at the end
1214  */
1215  _SEH2_TRY
1216  {
1218  {
1219  /* Size of the '\' string */
1220  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
1221  }
1222  else
1223  {
1224  /* Get the Object Directory and add name of Object */
1225  ParentDirectory = LocalInfo->Directory;
1226  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
1227 
1228  /* Loop inside the directory to get the top-most one (meaning root) */
1230  {
1231  /* Get the Name Information */
1232  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1234 
1235  /* Add the size of the Directory Name */
1236  if (LocalInfo && LocalInfo->Directory)
1237  {
1238  /* Size of the '\' string + Directory Name */
1239  NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
1240  LocalInfo->Name.Length;
1241 
1242  /* Move to next parent Directory */
1243  ParentDirectory = LocalInfo->Directory;
1244  }
1245  else
1246  {
1247  /* Directory with no name. We append "...\" */
1248  NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
1249  break;
1250  }
1251  }
1252  }
1253 
1254  /* Finally, add the name of the structure and the null char */
1255  *ReturnLength = NameSize +
1256  sizeof(OBJECT_NAME_INFORMATION) +
1257  sizeof(UNICODE_NULL);
1258 
1259  /* Check if we were given enough space */
1261 
1262  /*
1263  * Now we will actually create the name. We work backwards because
1264  * it's easier to start off from the Name we have and walk up the
1265  * parent directories. We use the same logic as Name Length calculation.
1266  */
1267  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1268  ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
1269  *--ObjectName = UNICODE_NULL;
1270 
1271  /* Check if the object is actually the Root directory */
1273  {
1274  /* This is already the Root Directory, return "\\" */
1276  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1277  ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
1278  sizeof(UNICODE_NULL));
1279  ObjectNameInfo->Name.Buffer = ObjectName;
1281  }
1282  else
1283  {
1284  /* Start by adding the Object's Name */
1286  LocalInfo->Name.Length);
1288  LocalInfo->Name.Buffer,
1289  LocalInfo->Name.Length);
1290 
1291  /* Now parse the Parent directories until we reach the top */
1292  ParentDirectory = LocalInfo->Directory;
1294  {
1295  /* Get the name information */
1296  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1298 
1299  /* Add the "\" */
1301 
1302  /* Add the Parent Directory's Name */
1303  if (LocalInfo && LocalInfo->Name.Buffer)
1304  {
1305  /* Add the name */
1307  LocalInfo->Name.Length);
1309  LocalInfo->Name.Buffer,
1310  LocalInfo->Name.Length);
1311 
1312  /* Move to next parent */
1313  ParentDirectory = LocalInfo->Directory;
1314  }
1315  else
1316  {
1317  /* Directory without a name, we add "..." */
1319  sizeof(L"...") +
1320  sizeof(UNICODE_NULL));
1321  RtlCopyMemory(ObjectName, L"...", sizeof(L"..."));
1322  break;
1323  }
1324  }
1325 
1326  /* Add Root Directory Name */
1328  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1329  ObjectNameInfo->Name.MaximumLength =
1330  (USHORT)(NameSize + sizeof(UNICODE_NULL));
1331  ObjectNameInfo->Name.Buffer = ObjectName;
1332  }
1333  }
1335  {
1336  /* Return the exception code */
1338  }
1339  _SEH2_END;
1340 
1341  /* Return success */
1342  return Status;
1343 }
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:2725

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

◆ ObpDosDevicesShortNamePrefix

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

Definition at line 23 of file obname.c.

Referenced by ObpLookupObjectName().

◆ ObpDosDevicesShortNameRoot

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

Definition at line 24 of file obname.c.

Referenced by ObpCreateDosDevicesDirectory(), and ObpLookupObjectName().

◆ 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.