ReactOS 0.4.16-dev-91-g764881a
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

NTSTATUS NTAPI ObpGetDosDevicesProtection (OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
 
VOID NTAPI ObpFreeDosDevicesProtection (OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
 
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()

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 * Initialize the \??\GLOBALROOT symbolic link
219 * pointing to the root directory \ .
220 */
221 RtlInitUnicodeString(&LinkName, L"GLOBALROOT");
224 &LinkName,
226 Handle,
227 &DosDevicesSD);
231 &TargetName);
232 if (NT_SUCCESS(Status)) NtClose(SymHandle);
233
234 /*
235 * Initialize the \??\Global symbolic link pointing to the global
236 * DosDevices directory \?? . It is used to access the global \??
237 * by user-mode components which, by default, use a per-session
238 * DosDevices directory.
239 */
240 RtlInitUnicodeString(&LinkName, L"Global");
242 &LinkName,
244 Handle,
245 &DosDevicesSD);
249 &RootName);
250 if (NT_SUCCESS(Status)) NtClose(SymHandle);
251
252 /* Close the directory handle */
254 if (!NT_SUCCESS(Status))
255 goto done;
256
257 /*
258 * Initialize the \DosDevices symbolic link pointing to the global
259 * DosDevices directory \?? , for backward compatibility with
260 * Windows NT-2000 systems.
261 */
262 RtlInitUnicodeString(&LinkName, L"\\DosDevices");
265 &LinkName,
267 NULL,
268 &DosDevicesSD);
272 &RootName);
273 if (NT_SUCCESS(Status)) NtClose(SymHandle);
274
275done:
276 ObpFreeDosDevicesProtection(&DosDevicesSD);
277
278 /* Return status */
279 return Status;
280}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
ULONG ObpProtectionMode
Definition: obinit.c:57
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
ULONG ObpLUIDDeviceMapsDisabled
Definition: devicemap.c:17
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
NTSTATUS NTAPI ObpGetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:40
ALIGNEDNAME ObpDosDevicesShortNameRoot
Definition: obname.c:24
VOID NTAPI ObpFreeDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:161
static PCWSTR TargetName
Definition: ping.c:67
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by ObInitSystem().

◆ ObpDeleteNameCheck()

VOID NTAPI ObpDeleteNameCheck ( IN PVOID  Object)

Definition at line 301 of file obname.c.

302{
303 POBJECT_HEADER ObjectHeader;
305 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
308
309 /* Get object structures */
310 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
311 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
312 ObjectType = ObjectHeader->Type;
313
314 /*
315 * Check if the handle count is 0, if the object is named,
316 * and if the object isn't a permanent object.
317 */
318 if (!(ObjectHeader->HandleCount) &&
319 (ObjectNameInfo) &&
320 (ObjectNameInfo->Name.Length) &&
321 (ObjectNameInfo->Directory) &&
322 !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
323 {
324 /* Setup a lookup context and lock it */
327
328 /* Do the lookup */
329 Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
330 &ObjectNameInfo->Name,
331 0,
332 FALSE,
333 &Context);
334 if (Object)
335 {
336 /* Lock the object */
337 ObpAcquireObjectLock(ObjectHeader);
338
339 /* Make sure we can still delete the object */
340 if (!(ObjectHeader->HandleCount) &&
341 !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
342 {
343 /* First delete it from the directory */
345
346 /* Check if this is a symbolic link */
348 {
349 /* Remove internal name */
351 }
352
353 /* Check if the kernel exclusive flag is set */
354 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
355 if ((ObjectNameInfo) &&
356 (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
357 {
358 /* Remove protection flag */
361 }
362
363 /* Get the directory */
364 Directory = ObjectNameInfo->Directory;
365 }
366
367 /* Release the lock */
368 ObpReleaseObjectLock(ObjectHeader);
369 }
370
371 /* Cleanup after lookup */
373
374 /* Remove another query reference since we added one on top */
375 ObpDereferenceNameInfo(ObjectNameInfo);
376
377 /* Check if we were inserted in a directory */
378 if (Directory)
379 {
380 /* We were, so first remove the extra reference we had added */
381 ObpDereferenceNameInfo(ObjectNameInfo);
382
383 /* Now dereference the object as well */
385 }
386 }
387 else
388 {
389 /* Remove the reference we added */
390 ObpDereferenceNameInfo(ObjectNameInfo);
391 }
392}
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:119
#define FALSE
Definition: types.h:117
#define InterlockedExchangeAdd
Definition: interlocked.h:181
ObjectType
Definition: metafile.c:81
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
BOOLEAN NTAPI ObpDeleteEntryDirectory(IN POBP_LOOKUP_CONTEXT Context)
VOID NTAPI ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:326
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 ObpAcquireLookupContextLock(IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_DIRECTORY Directory)
Locks an object directory lookup context for performing lookup operations (insertions/deletions) in a...
Definition: ob_x.h:281
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Initializes a new object directory lookup context. Used for lookup operations (insertions/deletions) ...
Definition: ob_x.h:258
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Releases an initialized object directory lookup context. Unlocks it if necessary, and dereferences th...
Definition: ob_x.h:323
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
base for all directory entries
Definition: entries.h:138
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
UNICODE_STRING Name
Definition: obtypes.h:433
UCHAR Flags
Definition: obtypes.h:497
LONG_PTR HandleCount
Definition: obtypes.h:490
POBJECT_TYPE Type
Definition: obtypes.h:493
int32_t * PLONG
Definition: typedefs.h:58
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define ObDereferenceObject
Definition: obfuncs.h:203

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

◆ ObpFreeDosDevicesProtection()

VOID NTAPI ObpFreeDosDevicesProtection ( OUT PSECURITY_DESCRIPTOR  SecurityDescriptor)

Definition at line 161 of file obname.c.

162{
163 PACL Dacl;
166
170 ASSERT(Dacl != NULL);
172}
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1605
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1647
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1650
#define TAG_DACL
Definition: tag.h:167
_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:191

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpGetDosDevicesProtection()

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) +
55 sizeof(ACE) + RtlLengthSid(SeWorldSid) +
59
60 /* Allocate the ACL */
62 if (Dacl == NULL)
63 {
65 }
66
67 /* Initialize the DACL */
70
71 /* Add the ACEs */
77
83
90
97
104
111 }
112 else
113 {
114 AclSize = sizeof(ACL) +
116 sizeof(ACE) + RtlLengthSid(SeWorldSid) +
118
119 /* Allocate the ACL */
121 if (Dacl == NULL)
122 {
124 }
125
126 /* Initialize the DACL */
129
130 /* Add the ACEs */
134 SeWorldSid);
136
142
147 SeWorldSid);
149 }
150
151 /* Attach the DACL to the SD */
154
155 return STATUS_SUCCESS;
156}
#define TRUE
Definition: types.h:120
#define GENERIC_READ
Definition: compat.h:135
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
struct _ACL ACL
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
struct _ACE ACE
#define GENERIC_ALL
Definition: nt_native.h:92
#define GENERIC_WRITE
Definition: nt_native.h:90
#define GENERIC_EXECUTE
Definition: nt_native.h:91
PSID SeLocalSystemSid
Definition: sid.c:38
PSID SeAliasAdminsSid
Definition: sid.c:41
PSID SeWorldSid
Definition: sid.c:25
PSID SeCreatorOwnerSid
Definition: sid.c:27
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: rtltypes.h:993
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpIsUnsecureName()

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

Definition at line 396 of file obname.c.

398{
399 BOOLEAN Unsecure;
400 PWSTR UnsecureBuffer;
401 UNICODE_STRING UnsecureName;
402
403 /* No unsecure names known, quit */
405 {
406 return FALSE;
407 }
408
409 /* By default, we have a secure name */
410 Unsecure = FALSE;
411 /* We will browse the whole string */
412 UnsecureBuffer = &ObpUnsecureGlobalNamesBuffer[0];
413 while (TRUE)
414 {
415 /* Initialize the unicode string */
416 RtlInitUnicodeString(&UnsecureName, UnsecureBuffer);
417 /* We're at the end of the multisz string! */
418 if (UnsecureName.Length == 0)
419 {
420 break;
421 }
422
423 /*
424 * Does the unsecure name prefix the object name?
425 * If so, that's an unsecure name, and return so
426 */
428 {
429 Unsecure = TRUE;
430 break;
431 }
432
433 /*
434 * Move to the next string. As a reminder, ObpUnsecureGlobalNamesBuffer is
435 * a multisz, so we move the string next to the current UNICODE_NULL char
436 */
437 UnsecureBuffer = (PWSTR)((ULONG_PTR)UnsecureBuffer + UnsecureName.Length + sizeof(UNICODE_NULL));
438 }
439
440 /* Return our findings */
441 return Unsecure;
442}
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2402
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define UNICODE_NULL
WCHAR ObpUnsecureGlobalNamesBuffer[128]
Definition: obname.c:32
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64

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 446 of file obname.c.

457{
459 POBJECT_HEADER ObjectHeader;
460 UNICODE_STRING ComponentName, RemainingName;
461 BOOLEAN Reparse = FALSE, SymLink = FALSE;
463 POBJECT_DIRECTORY ReferencedDirectory = NULL, ReferencedParentDirectory = NULL;
464 KIRQL CalloutIrql;
465 OB_PARSE_METHOD ParseRoutine;
467 KPROCESSOR_MODE AccessCheckMode;
469 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
470 ULONG MaxReparse = 30;
471 PDEVICE_MAP DeviceMap = NULL;
472 UNICODE_STRING LocalName;
473 PAGED_CODE();
475 "%s - Finding Object: %wZ. Expecting: %p\n",
478 InsertObject);
479
480 /* Initialize starting state */
481 ObpInitializeLookupContext(LookupContext);
482 *FoundObject = NULL;
484 Object = NULL;
485
486 /* Check if case-insensitivity is checked */
488 {
489 /* Check if the object type requests this */
490 if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
491 {
492 /* Add the flag to disable case sensitivity */
494 }
495 }
496
497 /* Check if this is a access checks are being forced */
498 AccessCheckMode = (Attributes & OBJ_FORCE_ACCESS_CHECK) ?
500
501 /* Check if we got a Root Directory */
502 if (RootHandle)
503 {
504 /* We did. Reference it */
506 0,
507 NULL,
510 NULL);
511 if (!NT_SUCCESS(Status)) return Status;
512
513 /* Get the header */
515
516 /* The name cannot start with a separator, unless this is a file */
517 if ((ObjectName->Buffer) &&
518 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
519 (ObjectHeader->Type != IoFileObjectType))
520 {
521 /* The syntax is bad, so fail this request */
524 }
525
526 /* Don't parse a Directory */
527 if (ObjectHeader->Type != ObpDirectoryObjectType)
528 {
529 /* Make sure the Object Type has a parse routine */
530 ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
531 if (!ParseRoutine)
532 {
533 /* We can't parse a name if we don't have a parse routine */
536 }
537
538 /* Set default parse count */
539 MaxReparse = 30;
540
541 /* Now parse */
542 while (TRUE)
543 {
544 /* Start with the full name */
546
547 /* Call the Parse Procedure */
548 ObpCalloutStart(&CalloutIrql);
549 Status = ParseRoutine(RootDirectory,
552 AccessCheckMode,
556 ParseContext,
557 SecurityQos,
558 &Object);
559 ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
560
561 /* Check for success or failure, so not reparse */
562 if ((Status != STATUS_REPARSE) &&
564 {
565 /* Check for failure */
566 if (!NT_SUCCESS(Status))
567 {
568 /* Parse routine might not have cleared this, do it */
569 Object = NULL;
570 }
571 else if (!Object)
572 {
573 /* Modify status to reflect failure inside Ob */
575 }
576
577 /* We're done, return the status and object */
578 *FoundObject = Object;
580 return Status;
581 }
582 else if ((!ObjectName->Length) ||
583 (!ObjectName->Buffer) ||
584 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
585 {
586 /* Reparsed to the root directory, so start over */
589
590 /* Don't use this anymore, since we're starting at root */
591 RootHandle = NULL;
592 goto ParseFromRoot;
593 }
594 else if (--MaxReparse)
595 {
596 /* Try reparsing again */
597 continue;
598 }
599 else
600 {
601 /* Reparsed too many times */
603
604 /* Return the object and normalized status */
605 *FoundObject = Object;
607 return Status;
608 }
609 }
610 }
611 else if (!(ObjectName->Length) || !(ObjectName->Buffer))
612 {
613 /* Just return the Root Directory if we didn't get a name */
615 0,
617 AccessMode);
619
620 /* Remove the first reference we added and return the object */
622 *FoundObject = Object;
623 return Status;
624 }
625
626 LocalName = *ObjectName;
627 }
628 else
629 {
630 /* We did not get a Root Directory, so use the root */
632
633 /* It must start with a path separator */
634 if (!(ObjectName->Length) ||
635 !(ObjectName->Buffer) ||
636 (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
637 {
638 /* This name is invalid, so fail */
640 }
641
642 /* Check if the name is only the path separator */
643 if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
644 {
645 /* So the caller only wants the root directory; do we have one? */
646 if (!RootDirectory)
647 {
648 /* This must be the first time we're creating it... right? */
649 if (InsertObject)
650 {
651 /* Yes, so return it to ObInsert so that it can create it */
652 Status = ObReferenceObjectByPointer(InsertObject,
653 0,
655 AccessMode);
656 if (NT_SUCCESS(Status)) *FoundObject = InsertObject;
657 return Status;
658 }
659 else
660 {
661 /* This should never really happen */
662 ASSERT(FALSE);
664 }
665 }
666 else
667 {
668 /* We do have the root directory, so just return it */
670 0,
672 AccessMode);
673 if (NT_SUCCESS(Status)) *FoundObject = RootDirectory;
674 return Status;
675 }
676 }
677 else
678 {
679ParseFromRoot:
680 LocalName = *ObjectName;
681
682 /* Deference the device map if we already have one */
683 if (DeviceMap != NULL)
684 {
685 ObfDereferenceDeviceMap(DeviceMap);
686 DeviceMap = NULL;
687 }
688
689 /* Check if this is a possible DOS name */
690 if (!((ULONG_PTR)(ObjectName->Buffer) & 7))
691 {
692 /*
693 * This could be one. Does it match the prefix?
694 * Note that as an optimization, the match is done as 64-bit
695 * compare since the prefix is "\??\" which is exactly 8 bytes.
696 *
697 * In the second branch, we test for "\??" which is also valid.
698 * This time, we use a 32-bit compare followed by a Unicode
699 * character compare (16-bit), since the sum is 6 bytes.
700 */
701 if ((ObjectName->Length >= ObpDosDevicesShortName.Length) &&
702 (*(PULONGLONG)(ObjectName->Buffer) ==
704 {
705 DeviceMap = ObpReferenceDeviceMap();
706 /* We have a local mapping, drop the ?? prefix */
707 if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
708 {
711 LocalName.Buffer += (ObpDosDevicesShortName.Length / sizeof(WCHAR));
712
713 /* We'll browse that local directory */
714 Directory = DeviceMap->DosDevicesDirectory;
715 }
716 }
717 else if ((ObjectName->Length == ObpDosDevicesShortName.Length -
718 sizeof(WCHAR)) &&
719 (*(PULONG)(ObjectName->Buffer) ==
721 (*((PWCHAR)(ObjectName->Buffer) + 2) ==
723 {
724 DeviceMap = ObpReferenceDeviceMap();
725
726 /* Caller is looking for the directory itself */
727 if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
728 {
730 0,
732 AccessMode);
733 if (NT_SUCCESS(Status))
734 {
735 *FoundObject = DeviceMap->DosDevicesDirectory;
736 }
737
738 ObfDereferenceDeviceMap(DeviceMap);
739 return Status;
740 }
741 }
742 }
743 }
744 }
745
746 /* Check if we were reparsing a symbolic link */
747 if (!SymLink)
748 {
749 /* Allow reparse */
750 Reparse = TRUE;
751 MaxReparse = 30;
752 }
753
754 /* Reparse */
755 while (Reparse && MaxReparse)
756 {
757 /* Get the name */
758 RemainingName = LocalName;
759
760 /* Disable reparsing again */
761 Reparse = FALSE;
762
763 /* Start parse loop */
764 while (TRUE)
765 {
766 /* Clear object */
767 Object = NULL;
768
769 /* Check if the name starts with a path separator */
770 if ((RemainingName.Length) &&
772 {
773 /* Skip the path separator */
774 RemainingName.Buffer++;
775 RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
776 }
777
778 /* Find the next Part Name */
779 ComponentName = RemainingName;
780 while (RemainingName.Length)
781 {
782 /* Break if we found the \ ending */
783 if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
784
785 /* Move on */
786 RemainingName.Buffer++;
787 RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
788 }
789
790 /* Get its size and make sure it's valid */
791 ComponentName.Length -= RemainingName.Length;
792 if (!ComponentName.Length)
793 {
794 /* Invalid size, fail */
796 break;
797 }
798
799 /* Check if we're in the root */
801
802 /* Check if this is a user-mode call that needs to traverse */
803 if ((AccessCheckMode != KernelMode) &&
805 {
806 /* We shouldn't have referenced a directory yet */
807 ASSERT(ReferencedDirectory == NULL);
808
809 /* Reference the directory */
811 ReferencedDirectory = Directory;
812
813 /* Check if we have a parent directory */
814 if (ParentDirectory)
815 {
816 /* Check for traverse access */
820 FALSE,
821 AccessCheckMode,
822 &Status))
823 {
824 /* We don't have it, fail */
825 break;
826 }
827 }
828 }
829
830 /* Check if we don't have a remaining name yet */
831 if (!RemainingName.Length)
832 {
833 /* Check if we don't have a referenced directory yet */
834 if (!ReferencedDirectory)
835 {
836 /* Reference it */
838 ReferencedDirectory = Directory;
839 }
840
841 /* Check if we are inserting an object */
842 if (InsertObject)
843 {
844 /* Lock the lookup context */
846 }
847 }
848
849 /* Do the lookup */
851 &ComponentName,
853 InsertObject ? FALSE : TRUE,
854 LookupContext);
855 if (!Object)
856 {
857 /* We didn't find it... do we still have a path? */
858 if (RemainingName.Length)
859 {
860 /* Then tell the caller the path wasn't found */
862 break;
863 }
864 else if (!InsertObject)
865 {
866 /* Otherwise, we have a path, but the name isn't valid */
868 break;
869 }
870
871 /* Check create access for the object */
877 &ComponentName,
878 FALSE,
879 AccessCheckMode,
880 &Status))
881 {
882 /* We don't have create access, fail */
883 break;
884 }
885
886 /* Get the object header */
887 ObjectHeader = OBJECT_TO_OBJECT_HEADER(InsertObject);
888
889 /*
890 * Deny object creation if:
891 * That's a section object or a symbolic link
892 * Which isn't in the same section that root directory
893 * That doesn't have the SeCreateGlobalPrivilege
894 * And that is not a known unsecure name
895 */
896 if (RootDirectory->SessionId != -1)
897 {
898 if (ObjectHeader->Type == MmSectionObjectType ||
899 ObjectHeader->Type == ObpSymbolicLinkObjectType)
900 {
901 if (RootDirectory->SessionId != PsGetCurrentProcessSessionId() &&
904 {
906 break;
907 }
908 }
909 }
910
911 /* Create Object Name */
913 ComponentName.Length,
915 if (!(NewName) ||
917 LookupContext,
918 ObjectHeader)))
919 {
920 /* Either couldn't allocate the name, or insert failed */
922
923 /* Fail due to memory reasons */
925 break;
926 }
927
928 /* Reference newly to be inserted object */
929 ObReferenceObject(InsertObject);
930
931 /* Get the name information */
932 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
933
934 /* Reference the directory */
936
937 /* Copy the Name */
939 ComponentName.Buffer,
940 ComponentName.Length);
941
942 /* Check if we had an old name */
943 if (ObjectNameInfo->Name.Buffer)
944 {
945 /* Free it */
946 ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
947 }
948
949 /* Write new one */
950 ObjectNameInfo->Name.Buffer = NewName;
951 ObjectNameInfo->Name.Length = ComponentName.Length;
952 ObjectNameInfo->Name.MaximumLength = ComponentName.Length;
953
954 /* Return Status and the Expected Object */
956 Object = InsertObject;
957
958 /* Get out of here */
959 break;
960 }
961
962ReparseObject:
963 /* We found it, so now get its header */
964 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
965
966 /*
967 * Check for a parse Procedure, but don't bother to parse for an insert
968 * unless it's a Symbolic Link, in which case we MUST parse
969 */
970 ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
971 if ((ParseRoutine) &&
972 (!(InsertObject) || (ParseRoutine == ObpParseSymbolicLink)))
973 {
974 /* Use the Root Directory next time */
975 Directory = NULL;
976
977 /* Increment the pointer count */
978 InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount, 1);
979
980 /* Cleanup from the first lookup */
981 ObpReleaseLookupContext(LookupContext);
982
983 /* Check if we have a referenced directory */
984 if (ReferencedDirectory)
985 {
986 /* We do, dereference it */
987 ObDereferenceObject(ReferencedDirectory);
988 ReferencedDirectory = NULL;
989 }
990
991 /* Check if we have a referenced parent directory */
992 if (ReferencedParentDirectory)
993 {
994 /* We do, dereference it */
995 ObDereferenceObject(ReferencedParentDirectory);
996 ReferencedParentDirectory = NULL;
997 }
998
999 /* Call the Parse Procedure */
1000 ObpCalloutStart(&CalloutIrql);
1001 Status = ParseRoutine(Object,
1002 ObjectType,
1004 AccessCheckMode,
1005 Attributes,
1006 ObjectName,
1008 ParseContext,
1009 SecurityQos,
1010 &Object);
1011 ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
1012
1013 /* Remove our extra reference */
1014 ObDereferenceObject(&ObjectHeader->Body);
1015
1016 /* Check if we have to reparse */
1017 if ((Status == STATUS_REPARSE) ||
1019 {
1020 /* Reparse again */
1021 Reparse = TRUE;
1022 --MaxReparse;
1023 if (MaxReparse == 0)
1024 {
1025 Object = NULL;
1026 break;
1027 }
1028
1029 /* Start over from root if we got sent back there */
1030 if ((Status == STATUS_REPARSE_OBJECT) ||
1031 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
1032 {
1033 /* Check if we got a root directory */
1034 if (RootHandle)
1035 {
1036 /* Stop using it, because we have a new directory now */
1038 RootHandle = NULL;
1039 }
1040
1041 /* Start at Root */
1044
1045 /* Check for reparse status */
1047 {
1048 /* Don't reparse again */
1049 Reparse = FALSE;
1050
1051 /* Did we actually get an object to which to reparse? */
1052 if (!Object)
1053 {
1054 /* We didn't, so set a failure status */
1056 }
1057 else
1058 {
1059 /* We did, so we're free to parse the new object */
1060 goto ReparseObject;
1061 }
1062 }
1063 else
1064 {
1065 /* This is a symbolic link */
1066 SymLink = TRUE;
1067 goto ParseFromRoot;
1068 }
1069 }
1071 {
1072 /* We got STATUS_REPARSE but are at the Root Directory */
1073 Object = NULL;
1075 Reparse = FALSE;
1076 }
1077 }
1078 else if (!NT_SUCCESS(Status))
1079 {
1080 /* Total failure */
1081 Object = NULL;
1082 }
1083 else if (!Object)
1084 {
1085 /* We didn't reparse but we didn't find the Object Either */
1087 }
1088
1089 /* Break out of the loop */
1090 break;
1091 }
1092 else
1093 {
1094 /* No parse routine...do we still have a remaining name? */
1095 if (!RemainingName.Length)
1096 {
1097 /* Are we creating an object? */
1098 if (!InsertObject)
1099 {
1100 /* Check if this is a user-mode call that needs to traverse */
1101 if ((AccessCheckMode != KernelMode) &&
1103 {
1104 /* Check if we can get it */
1108 FALSE,
1109 AccessCheckMode,
1110 &Status))
1111 {
1112 /* We don't have access, fail */
1113 Object = NULL;
1114 break;
1115 }
1116 }
1117
1118 /* Reference the Object */
1120 0,
1121 ObjectType,
1122 AccessMode);
1123 if (!NT_SUCCESS(Status)) Object = NULL;
1124 }
1125
1126 /* And get out of the reparse loop */
1127 break;
1128 }
1129 else
1130 {
1131 /* We still have a name; check if this is a directory object */
1132 if (ObjectHeader->Type == ObpDirectoryObjectType)
1133 {
1134 /* Check if we have a referenced parent directory */
1135 if (ReferencedParentDirectory)
1136 {
1137 /* Dereference it */
1138 ObDereferenceObject(ReferencedParentDirectory);
1139 }
1140
1141 /* Restart the lookup from this directory */
1142 ReferencedParentDirectory = ReferencedDirectory;
1144 Directory = Object;
1145 ReferencedDirectory = NULL;
1146 }
1147 else
1148 {
1149 /* We still have a name, but no parse routine for it */
1151 Object = NULL;
1152 break;
1153 }
1154 }
1155 }
1156 }
1157 }
1158
1159 /* Check if we failed */
1160 if (!NT_SUCCESS(Status))
1161 {
1162 /* Cleanup after lookup */
1163 ObpReleaseLookupContext(LookupContext);
1164 }
1165
1166 /* Check if we have a device map and dereference it if so */
1167 if (DeviceMap) ObfDereferenceDeviceMap(DeviceMap);
1168
1169 /* Check if we have a referenced directory and dereference it if so */
1170 if (ReferencedDirectory) ObDereferenceObject(ReferencedDirectory);
1171
1172 /* Check if we have a referenced parent directory */
1173 if (ReferencedParentDirectory)
1174 {
1175 /* We do, dereference it */
1176 ObDereferenceObject(ReferencedParentDirectory);
1177 }
1178
1179 /* Set the found object and check if we got one */
1180 *FoundObject = Object;
1181 if (!Object)
1182 {
1183 /* Nothing was found. Did we reparse or get success? */
1184 if ((Status == STATUS_REPARSE) || (NT_SUCCESS(Status)))
1185 {
1186 /* Set correct failure */
1188 }
1189 }
1190
1191 /* Check if we had a root directory */
1192 if (RootHandle) ObDereferenceObject(RootDirectory);
1193
1194 /* Return status to caller */
1196 "%s - Found Object: %p. Expected: %p\n",
1198 *FoundObject,
1199 InsertObject);
1200 return Status;
1201}
#define PAGED_CODE()
#define ObpDirectoryObjectType
Definition: ObTypes.c:118
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
static const LUID SeCreateGlobalPrivilege
Definition: authpackage.c:168
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define __FUNCTION__
Definition: types.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PDCB ParentDirectory
Definition: fatprocs.h:699
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
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
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define DIRECTORY_CREATE_SUBDIRECTORY
Definition: nt_native.h:1257
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_REPARSE_OBJECT
Definition: ntstatus.h:102
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
PDEVICE_MAP NTAPI ObpReferenceDeviceMap(VOID)
Definition: devicemap.c:325
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
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
#define OB_NAMESPACE_DEBUG
Definition: ob.h:18
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
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
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:431
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
BOOLEAN NTAPI ObpIsUnsecureName(IN PUNICODE_STRING ObjectName, IN BOOLEAN CaseInSensitive)
Definition: obname.c:396
ALIGNEDNAME ObpDosDevicesShortNamePrefix
Definition: obname.c:23
BOOLEAN ObpCaseInsensitive
Definition: obname.c:18
UNICODE_STRING ObpDosDevicesShortName
Definition: obname.c:25
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
POBJECT_DIRECTORY DosDevicesDirectory
Definition: obtypes.h:525
LONG_PTR PointerCount
Definition: obtypes.h:487
OB_PARSE_METHOD ParseProcedure
Definition: obtypes.h:370
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
$ULONG LowPart
Definition: ntbasedef.h:569
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
$ULONG HighPart
Definition: ntbasedef.h:570
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define OB_NAME_TAG
Definition: tag.h:118
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULARGE_INTEGER Alignment
Definition: ob.h:154
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObReferenceObject
Definition: obfuncs.h:204
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1178
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203

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 1207 of file obname.c.

1211{
1212 POBJECT_HEADER_NAME_INFO LocalInfo;
1213 POBJECT_HEADER ObjectHeader;
1215 ULONG NameSize;
1217 BOOLEAN ObjectIsNamed;
1219
1220 /* Get the Kernel Meta-Structures */
1221 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1222 LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1223
1224 /* Check if a Query Name Procedure is available */
1225 if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
1226 {
1227 /* Call the procedure inside SEH */
1228 ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0));
1229
1230 _SEH2_TRY
1231 {
1232 Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
1233 ObjectIsNamed,
1234 ObjectNameInfo,
1235 Length,
1237 KernelMode);
1238 }
1240 {
1241 /* Return the exception code */
1243 }
1244 _SEH2_END;
1245
1246 return Status;
1247 }
1248
1249 /* Check if the object doesn't even have a name */
1250 if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
1251 {
1253
1254 _SEH2_TRY
1255 {
1256 /* We're returning the name structure */
1258
1259 /* Check if we were given enough space */
1260 if (*ReturnLength > Length)
1261 {
1263 }
1264 else
1265 {
1266 /* Return an empty buffer */
1267 RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
1268 }
1269 }
1271 {
1272 /* Return the exception code */
1274 }
1275 _SEH2_END;
1276
1277 return Status;
1278 }
1279
1280 /*
1281 * Find the size needed for the name. We won't do
1282 * this during the Name Creation loop because we want
1283 * to let the caller know that the buffer isn't big
1284 * enough right at the beginning, not work our way through
1285 * and find out at the end
1286 */
1287 _SEH2_TRY
1288 {
1290 {
1291 /* Size of the '\' string */
1292 NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
1293 }
1294 else
1295 {
1296 /* Get the Object Directory and add name of Object */
1297 ParentDirectory = LocalInfo->Directory;
1298 NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
1299
1300 /* Loop inside the directory to get the top-most one (meaning root) */
1302 {
1303 /* Get the Name Information */
1304 LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1306
1307 /* Add the size of the Directory Name */
1308 if (LocalInfo && LocalInfo->Directory)
1309 {
1310 /* Size of the '\' string + Directory Name */
1311 NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
1312 LocalInfo->Name.Length;
1313
1314 /* Move to next parent Directory */
1315 ParentDirectory = LocalInfo->Directory;
1316 }
1317 else
1318 {
1319 /* Directory with no name. We append "...\" */
1320 NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
1321 break;
1322 }
1323 }
1324 }
1325
1326 /* Finally, add the name of the structure and the null char */
1327 *ReturnLength = NameSize +
1328 sizeof(OBJECT_NAME_INFORMATION) +
1329 sizeof(UNICODE_NULL);
1330
1331 /* Check if we were given enough space */
1333
1334 /*
1335 * Now we will actually create the name. We work backwards because
1336 * it's easier to start off from the Name we have and walk up the
1337 * parent directories. We use the same logic as Name Length calculation.
1338 */
1339 LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1340 ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
1342
1343 /* Check if the object is actually the Root directory */
1345 {
1346 /* This is already the Root Directory, return "\\" */
1348 ObjectNameInfo->Name.Length = (USHORT)NameSize;
1349 ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
1350 sizeof(UNICODE_NULL));
1351 ObjectNameInfo->Name.Buffer = ObjectName;
1353 }
1354 else
1355 {
1356 /* Start by adding the Object's Name */
1358 LocalInfo->Name.Length);
1360 LocalInfo->Name.Buffer,
1361 LocalInfo->Name.Length);
1362
1363 /* Now parse the Parent directories until we reach the top */
1364 ParentDirectory = LocalInfo->Directory;
1366 {
1367 /* Get the name information */
1368 LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1370
1371 /* Add the "\" */
1373
1374 /* Add the Parent Directory's Name */
1375 if (LocalInfo && LocalInfo->Name.Buffer)
1376 {
1377 /* Add the name */
1379 LocalInfo->Name.Length);
1381 LocalInfo->Name.Buffer,
1382 LocalInfo->Name.Length);
1383
1384 /* Move to next parent */
1385 ParentDirectory = LocalInfo->Directory;
1386 }
1387 else
1388 {
1389 /* Directory without a name, we add "..." */
1391 sizeof(L"...") +
1392 sizeof(UNICODE_NULL));
1393 RtlCopyMemory(ObjectName, L"...", sizeof(L"..."));
1394 break;
1395 }
1396 }
1397
1398 /* Add Root Directory Name */
1400 ObjectNameInfo->Name.Length = (USHORT)NameSize;
1401 ObjectNameInfo->Name.MaximumLength =
1402 (USHORT)(NameSize + sizeof(UNICODE_NULL));
1403 ObjectNameInfo->Name.Buffer = ObjectName;
1404 }
1405 }
1407 {
1408 /* Return the exception code */
1410 }
1411 _SEH2_END;
1412
1413 /* Return success */
1414 return Status;
1415}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
WCHAR * PWCH
Definition: ntbasedef.h:410
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
OB_QUERYNAME_METHOD QueryNameProcedure
Definition: obtypes.h:372
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

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

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