ReactOS  0.4.14-dev-49-gfb4591c
obname.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ob/obname.c
5  * PURPOSE: Manages all functions related to the Object Manager name-
6  * space, such as finding objects or querying their names.
7  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
8  * Eric Kohl
9  * Thomas Weidenmueller (w3seek@reactos.org)
10  */
11 
12 /* INCLUDES ******************************************************************/
13 
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <debug.h>
17 
21 
22 /* DOS Device Prefix \??\ and \?? */
26 {
30 };
31 
34 
35 /* PRIVATE FUNCTIONS *********************************************************/
36 
37 INIT_FUNCTION
39 NTAPI
41 {
42  PACL Dacl;
43  ULONG AclSize;
45 
46  /* Initialize the SD */
49 
50  if (ObpProtectionMode & 1)
51  {
52  AclSize = sizeof(ACL) +
53  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
54  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
55  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
56  sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid) +
57  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
59 
60  /* Allocate the ACL */
61  Dacl = ExAllocatePoolWithTag(PagedPool, AclSize, 'lcaD');
62  if (Dacl == NULL)
63  {
65  }
66 
67  /* Initialize the DACL */
68  Status = RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
70 
71  /* Add the ACEs */
75  SeWorldSid);
77 
83 
88  SeWorldSid);
90 
97 
101  GENERIC_ALL,
104 
106  ACL_REVISION,
108  GENERIC_ALL,
111  }
112  else
113  {
114  AclSize = sizeof(ACL) +
115  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid) +
116  sizeof(ACE) + RtlLengthSid(SeWorldSid) +
117  sizeof(ACE) + RtlLengthSid(SeLocalSystemSid);
118 
119  /* Allocate the ACL */
120  Dacl = ExAllocatePoolWithTag(PagedPool, AclSize, 'lcaD');
121  if (Dacl == NULL)
122  {
124  }
125 
126  /* Initialize the DACL */
127  Status = RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
129 
130  /* Add the ACEs */
132  ACL_REVISION,
134  SeWorldSid);
136 
138  ACL_REVISION,
139  GENERIC_ALL,
142 
144  ACL_REVISION,
146  GENERIC_ALL,
147  SeWorldSid);
149  }
150 
151  /* Attach the DACL to the SD */
154 
155  return STATUS_SUCCESS;
156 }
157 
158 INIT_FUNCTION
159 VOID
160 NTAPI
162 {
163  PACL Dacl;
166 
170  ASSERT(Dacl != NULL);
171  ExFreePoolWithTag(Dacl, 'lcaD');
172 }
173 
174 INIT_FUNCTION
175 NTSTATUS
176 NTAPI
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);
228  Status = NtCreateSymbolicLinkObject(&SymHandle,
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);
246  Status = NtCreateSymbolicLinkObject(&SymHandle,
249  &RootName);
250  if (NT_SUCCESS(Status)) NtClose(SymHandle);
251 
252  /* Close the directory handle */
253  NtClose(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  RtlCreateUnicodeString(&LinkName, L"\\DosDevices");
265  &LinkName,
267  NULL,
268  &DosDevicesSD);
269  Status = NtCreateSymbolicLinkObject(&SymHandle,
272  &RootName);
273  if (NT_SUCCESS(Status)) NtClose(SymHandle);
274 
275 done:
276  ObpFreeDosDevicesProtection(&DosDevicesSD);
277 
278  /* Return status */
279  return Status;
280 }
281 
282 /*++
283 * @name ObpDeleteNameCheck
284 *
285 * The ObpDeleteNameCheck routine checks if a named object should be
286 * removed from the object directory namespace.
287 *
288 * @param Object
289 * Pointer to the object to check for possible removal.
290 *
291 * @return None.
292 *
293 * @remarks An object is removed if the following 4 criteria are met:
294 * 1) The object has 0 handles open
295 * 2) The object is in the directory namespace and has a name
296 * 3) The object is not permanent
297 *
298 *--*/
299 VOID
300 NTAPI
302 {
303  POBJECT_HEADER ObjectHeader;
305  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
307  PVOID Directory = NULL;
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 */
326 
327  /* Lock the directory */
329 
330  /* Do the lookup */
331  Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
332  &ObjectNameInfo->Name,
333  0,
334  FALSE,
335  &Context);
336  if (Object)
337  {
338  /* Lock the object */
339  ObpAcquireObjectLock(ObjectHeader);
340 
341  /* Make sure we can still delete the object */
342  if (!(ObjectHeader->HandleCount) &&
343  !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
344  {
345  /* First delete it from the directory */
347 
348  /* Check if this is a symbolic link */
350  {
351  /* Remove internal name */
353  }
354 
355  /* Check if the kernel exclusive is set */
356  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
357  if ((ObjectNameInfo) &&
358  (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
359  {
360  /* Remove protection flag */
361  InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences,
363  }
364 
365  /* Get the directory */
366  Directory = ObjectNameInfo->Directory;
367  }
368 
369  /* Release the lock */
370  ObpReleaseObjectLock(ObjectHeader);
371  }
372 
373  /* Cleanup after lookup */
375 
376  /* Remove another query reference since we added one on top */
377  ObpDereferenceNameInfo(ObjectNameInfo);
378 
379  /* Check if we were inserted in a directory */
380  if (Directory)
381  {
382  /* We were, so first remove the extra reference we had added */
383  ObpDereferenceNameInfo(ObjectNameInfo);
384 
385  /* Now dereference the object as well */
387  }
388  }
389  else
390  {
391  /* Remove the reference we added */
392  ObpDereferenceNameInfo(ObjectNameInfo);
393  }
394 }
395 
396 BOOLEAN
397 NTAPI
400 {
401  BOOLEAN Unsecure;
402  PWSTR UnsecureBuffer;
403  UNICODE_STRING UnsecureName;
404 
405  /* No unsecure names known, quit */
407  {
408  return FALSE;
409  }
410 
411  /* By default, we have a secure name */
412  Unsecure = FALSE;
413  /* We will browse the whole string */
414  UnsecureBuffer = &ObpUnsecureGlobalNamesBuffer[0];
415  while (TRUE)
416  {
417  /* Initialize the unicode string */
418  RtlInitUnicodeString(&UnsecureName, UnsecureBuffer);
419  /* We're at the end of the multisz string! */
420  if (UnsecureName.Length == 0)
421  {
422  break;
423  }
424 
425  /*
426  * Does the unsecure name prefix the object name?
427  * If so, that's an unsecure name, and return so
428  */
430  {
431  Unsecure = TRUE;
432  break;
433  }
434 
435  /*
436  * Move to the next string. As a reminder, ObpUnsecureGlobalNamesBuffer is
437  * a multisz, so we move the string next to the current UNICODE_NULL char
438  */
439  UnsecureBuffer = (PWSTR)((ULONG_PTR)UnsecureBuffer + UnsecureName.Length + sizeof(UNICODE_NULL));
440  }
441 
442  /* Return our findings */
443  return Unsecure;
444 }
445 
446 NTSTATUS
447 NTAPI
453  IN OUT PVOID ParseContext,
455  IN PVOID InsertObject OPTIONAL,
457  OUT POBP_LOOKUP_CONTEXT LookupContext,
458  OUT PVOID *FoundObject)
459 {
460  PVOID Object;
461  POBJECT_HEADER ObjectHeader;
462  UNICODE_STRING ComponentName, RemainingName;
463  BOOLEAN Reparse = FALSE, SymLink = FALSE;
465  POBJECT_DIRECTORY ReferencedDirectory = NULL, ReferencedParentDirectory = NULL;
466  KIRQL CalloutIrql;
467  OB_PARSE_METHOD ParseRoutine;
469  KPROCESSOR_MODE AccessCheckMode;
470  PWCHAR NewName;
471  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
472  ULONG MaxReparse = 30;
473  PDEVICE_MAP DeviceMap = NULL;
474  UNICODE_STRING LocalName;
475  PAGED_CODE();
477  "%s - Finding Object: %wZ. Expecting: %p\n",
478  __FUNCTION__,
479  ObjectName,
480  InsertObject);
481 
482  /* Initialize starting state */
483  ObpInitializeLookupContext(LookupContext);
484  *FoundObject = NULL;
486  Object = NULL;
487 
488  /* Check if case-insensitivity is checked */
489  if (ObpCaseInsensitive)
490  {
491  /* Check if the object type requests this */
492  if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
493  {
494  /* Add the flag to disable case sensitivity */
496  }
497  }
498 
499  /* Check if this is a access checks are being forced */
500  AccessCheckMode = (Attributes & OBJ_FORCE_ACCESS_CHECK) ?
502 
503  /* Check if we got a Root Directory */
504  if (RootHandle)
505  {
506  /* We did. Reference it */
507  Status = ObReferenceObjectByHandle(RootHandle,
508  0,
509  NULL,
510  AccessMode,
511  (PVOID*)&RootDirectory,
512  NULL);
513  if (!NT_SUCCESS(Status)) return Status;
514 
515  /* Get the header */
516  ObjectHeader = OBJECT_TO_OBJECT_HEADER(RootDirectory);
517 
518  /* The name cannot start with a separator, unless this is a file */
519  if ((ObjectName->Buffer) &&
520  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
521  (ObjectHeader->Type != IoFileObjectType))
522  {
523  /* The syntax is bad, so fail this request */
526  }
527 
528  /* Don't parse a Directory */
529  if (ObjectHeader->Type != ObpDirectoryObjectType)
530  {
531  /* Make sure the Object Type has a parse routine */
532  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
533  if (!ParseRoutine)
534  {
535  /* We can't parse a name if we don't have a parse routine */
537  return STATUS_INVALID_HANDLE;
538  }
539 
540  /* Set default parse count */
541  MaxReparse = 30;
542 
543  /* Now parse */
544  while (TRUE)
545  {
546  /* Start with the full name */
548 
549  /* Call the Parse Procedure */
550  ObpCalloutStart(&CalloutIrql);
551  Status = ParseRoutine(RootDirectory,
552  ObjectType,
553  AccessState,
554  AccessCheckMode,
555  Attributes,
556  ObjectName,
557  &RemainingName,
558  ParseContext,
559  SecurityQos,
560  &Object);
561  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
562 
563  /* Check for success or failure, so not reparse */
564  if ((Status != STATUS_REPARSE) &&
566  {
567  /* Check for failure */
568  if (!NT_SUCCESS(Status))
569  {
570  /* Parse routine might not have cleared this, do it */
571  Object = NULL;
572  }
573  else if (!Object)
574  {
575  /* Modify status to reflect failure inside Ob */
577  }
578 
579  /* We're done, return the status and object */
580  *FoundObject = Object;
582  return Status;
583  }
584  else if ((!ObjectName->Length) ||
585  (!ObjectName->Buffer) ||
586  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
587  {
588  /* Reparsed to the root directory, so start over */
591 
592  /* Don't use this anymore, since we're starting at root */
593  RootHandle = NULL;
594  goto ParseFromRoot;
595  }
596  else if (--MaxReparse)
597  {
598  /* Try reparsing again */
599  continue;
600  }
601  else
602  {
603  /* Reparsed too many times */
605 
606  /* Return the object and normalized status */
607  *FoundObject = Object;
609  return Status;
610  }
611  }
612  }
613  else if (!(ObjectName->Length) || !(ObjectName->Buffer))
614  {
615  /* Just return the Root Directory if we didn't get a name */
617  0,
618  ObjectType,
619  AccessMode);
621 
622  /* Remove the first reference we added and return the object */
624  *FoundObject = Object;
625  return Status;
626  }
627 
628  LocalName = *ObjectName;
629  }
630  else
631  {
632  /* We did not get a Root Directory, so use the root */
634 
635  /* It must start with a path separator */
636  if (!(ObjectName->Length) ||
637  !(ObjectName->Buffer) ||
638  (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
639  {
640  /* This name is invalid, so fail */
642  }
643 
644  /* Check if the name is only the path separator */
645  if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
646  {
647  /* So the caller only wants the root directory; do we have one? */
648  if (!RootDirectory)
649  {
650  /* This must be the first time we're creating it... right? */
651  if (InsertObject)
652  {
653  /* Yes, so return it to ObInsert so that it can create it */
654  Status = ObReferenceObjectByPointer(InsertObject,
655  0,
656  ObjectType,
657  AccessMode);
658  if (NT_SUCCESS(Status)) *FoundObject = InsertObject;
659  return Status;
660  }
661  else
662  {
663  /* This should never really happen */
664  ASSERT(FALSE);
666  }
667  }
668  else
669  {
670  /* We do have the root directory, so just return it */
672  0,
673  ObjectType,
674  AccessMode);
675  if (NT_SUCCESS(Status)) *FoundObject = RootDirectory;
676  return Status;
677  }
678  }
679  else
680  {
681 ParseFromRoot:
682  LocalName = *ObjectName;
683 
684  /* Deference the device map if we already have one */
685  if (DeviceMap != NULL)
686  {
687  ObfDereferenceDeviceMap(DeviceMap);
688  DeviceMap = NULL;
689  }
690 
691  /* Check if this is a possible DOS name */
692  if (!((ULONG_PTR)(ObjectName->Buffer) & 7))
693  {
694  /*
695  * This could be one. Does it match the prefix?
696  * Note that as an optimization, the match is done as 64-bit
697  * compare since the prefix is "\??\" which is exactly 8 bytes.
698  *
699  * In the second branch, we test for "\??" which is also valid.
700  * This time, we use a 32-bit compare followed by a Unicode
701  * character compare (16-bit), since the sum is 6 bytes.
702  */
703  if ((ObjectName->Length >= ObpDosDevicesShortName.Length) &&
704  (*(PULONGLONG)(ObjectName->Buffer) ==
706  {
707  DeviceMap = ObpReferenceDeviceMap();
708  /* We have a local mapping, drop the ?? prefix */
709  if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
710  {
711  LocalName.Length -= ObpDosDevicesShortName.Length;
713  LocalName.Buffer += (ObpDosDevicesShortName.Length / sizeof(WCHAR));
714 
715  /* We'll browse that local directory */
716  Directory = DeviceMap->DosDevicesDirectory;
717  }
718  }
719  else if ((ObjectName->Length == ObpDosDevicesShortName.Length -
720  sizeof(WCHAR)) &&
721  (*(PULONG)(ObjectName->Buffer) ==
723  (*((PWCHAR)(ObjectName->Buffer) + 2) ==
725  {
726  DeviceMap = ObpReferenceDeviceMap();
727 
728  /* Caller is looking for the directory itself */
729  if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
730  {
732  0,
733  ObjectType,
734  AccessMode);
735  if (NT_SUCCESS(Status))
736  {
737  *FoundObject = DeviceMap->DosDevicesDirectory;
738  }
739 
740  ObfDereferenceDeviceMap(DeviceMap);
741  return Status;
742  }
743  }
744  }
745  }
746  }
747 
748  /* Check if we were reparsing a symbolic link */
749  if (!SymLink)
750  {
751  /* Allow reparse */
752  Reparse = TRUE;
753  MaxReparse = 30;
754  }
755 
756  /* Reparse */
757  while (Reparse && MaxReparse)
758  {
759  /* Get the name */
760  RemainingName = LocalName;
761 
762  /* Disable reparsing again */
763  Reparse = FALSE;
764 
765  /* Start parse loop */
766  while (TRUE)
767  {
768  /* Clear object */
769  Object = NULL;
770 
771  /* Check if the name starts with a path separator */
772  if ((RemainingName.Length) &&
773  (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
774  {
775  /* Skip the path separator */
776  RemainingName.Buffer++;
777  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
778  }
779 
780  /* Find the next Part Name */
781  ComponentName = RemainingName;
782  while (RemainingName.Length)
783  {
784  /* Break if we found the \ ending */
785  if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
786 
787  /* Move on */
788  RemainingName.Buffer++;
789  RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
790  }
791 
792  /* Get its size and make sure it's valid */
793  ComponentName.Length -= RemainingName.Length;
794  if (!ComponentName.Length)
795  {
796  /* Invalid size, fail */
798  break;
799  }
800 
801  /* Check if we're in the root */
803 
804  /* Check if this is a user-mode call that needs to traverse */
805  if ((AccessCheckMode != KernelMode) &&
807  {
808  /* We shouldn't have referenced a directory yet */
809  ASSERT(ReferencedDirectory == NULL);
810 
811  /* Reference the directory */
813  ReferencedDirectory = Directory;
814 
815  /* Check if we have a parent directory */
816  if (ParentDirectory)
817  {
818  /* Check for traverse access */
821  AccessState,
822  FALSE,
823  AccessCheckMode,
824  &Status))
825  {
826  /* We don't have it, fail */
827  break;
828  }
829  }
830  }
831 
832  /* Check if we don't have a remaining name yet */
833  if (!RemainingName.Length)
834  {
835  /* Check if we don't have a referenced directory yet */
836  if (!ReferencedDirectory)
837  {
838  /* Reference it */
840  ReferencedDirectory = Directory;
841  }
842 
843  /* Check if we are inserting an object */
844  if (InsertObject)
845  {
846  /* Lock the directory */
848  }
849  }
850 
851  /* Do the lookup */
853  &ComponentName,
854  Attributes,
855  InsertObject ? FALSE : TRUE,
856  LookupContext);
857  if (!Object)
858  {
859  /* We didn't find it... do we still have a path? */
860  if (RemainingName.Length)
861  {
862  /* Then tell the caller the path wasn't found */
864  break;
865  }
866  else if (!InsertObject)
867  {
868  /* Otherwise, we have a path, but the name isn't valid */
870  break;
871  }
872 
873  /* Check create access for the object */
878  AccessState,
879  &ComponentName,
880  FALSE,
881  AccessCheckMode,
882  &Status))
883  {
884  /* We don't have create access, fail */
885  break;
886  }
887 
888  /* Get the object header */
889  ObjectHeader = OBJECT_TO_OBJECT_HEADER(InsertObject);
890 
891  /*
892  * Deny object creation if:
893  * That's a section object or a symbolic link
894  * Which isn't in the same section that root directory
895  * That doesn't have the SeCreateGlobalPrivilege
896  * And that is not a known unsecure name
897  */
898  if (RootDirectory->SessionId != -1)
899  {
900  if (ObjectHeader->Type == MmSectionObjectType ||
901  ObjectHeader->Type == ObpSymbolicLinkObjectType)
902  {
903  if (RootDirectory->SessionId != PsGetCurrentProcessSessionId() &&
904  !SeSinglePrivilegeCheck(SeCreateGlobalPrivilege, AccessCheckMode) &&
906  {
908  break;
909  }
910  }
911  }
912 
913  /* Create Object Name */
915  ComponentName.Length,
916  OB_NAME_TAG);
917  if (!(NewName) ||
919  LookupContext,
920  ObjectHeader)))
921  {
922  /* Either couldn't allocate the name, or insert failed */
924 
925  /* Fail due to memory reasons */
927  break;
928  }
929 
930  /* Reference newly to be inserted object */
931  ObReferenceObject(InsertObject);
932 
933  /* Get the name information */
934  ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
935 
936  /* Reference the directory */
938 
939  /* Copy the Name */
941  ComponentName.Buffer,
942  ComponentName.Length);
943 
944  /* Check if we had an old name */
945  if (ObjectNameInfo->Name.Buffer)
946  {
947  /* Free it */
948  ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
949  }
950 
951  /* Write new one */
952  ObjectNameInfo->Name.Buffer = NewName;
953  ObjectNameInfo->Name.Length = ComponentName.Length;
954  ObjectNameInfo->Name.MaximumLength = ComponentName.Length;
955 
956  /* Return Status and the Expected Object */
958  Object = InsertObject;
959 
960  /* Get out of here */
961  break;
962  }
963 
964 ReparseObject:
965  /* We found it, so now get its header */
966  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
967 
968  /*
969  * Check for a parse Procedure, but don't bother to parse for an insert
970  * unless it's a Symbolic Link, in which case we MUST parse
971  */
972  ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
973  if ((ParseRoutine) &&
974  (!(InsertObject) || (ParseRoutine == ObpParseSymbolicLink)))
975  {
976  /* Use the Root Directory next time */
977  Directory = NULL;
978 
979  /* Increment the pointer count */
980  InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount, 1);
981 
982  /* Cleanup from the first lookup */
983  ObpReleaseLookupContext(LookupContext);
984 
985  /* Check if we have a referenced directory */
986  if (ReferencedDirectory)
987  {
988  /* We do, dereference it */
989  ObDereferenceObject(ReferencedDirectory);
990  ReferencedDirectory = NULL;
991  }
992 
993  /* Check if we have a referenced parent directory */
994  if (ReferencedParentDirectory)
995  {
996  /* We do, dereference it */
997  ObDereferenceObject(ReferencedParentDirectory);
998  ReferencedParentDirectory = NULL;
999  }
1000 
1001  /* Call the Parse Procedure */
1002  ObpCalloutStart(&CalloutIrql);
1003  Status = ParseRoutine(Object,
1004  ObjectType,
1005  AccessState,
1006  AccessCheckMode,
1007  Attributes,
1008  ObjectName,
1009  &RemainingName,
1010  ParseContext,
1011  SecurityQos,
1012  &Object);
1013  ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
1014 
1015  /* Remove our extra reference */
1016  ObDereferenceObject(&ObjectHeader->Body);
1017 
1018  /* Check if we have to reparse */
1019  if ((Status == STATUS_REPARSE) ||
1021  {
1022  /* Reparse again */
1023  Reparse = TRUE;
1024  --MaxReparse;
1025  if (MaxReparse == 0)
1026  {
1027  Object = NULL;
1028  break;
1029  }
1030 
1031  /* Start over from root if we got sent back there */
1032  if ((Status == STATUS_REPARSE_OBJECT) ||
1033  (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
1034  {
1035  /* Check if we got a root directory */
1036  if (RootHandle)
1037  {
1038  /* Stop using it, because we have a new directory now */
1040  RootHandle = NULL;
1041  }
1042 
1043  /* Start at Root */
1046 
1047  /* Check for reparse status */
1049  {
1050  /* Don't reparse again */
1051  Reparse = FALSE;
1052 
1053  /* Did we actually get an object to which to reparse? */
1054  if (!Object)
1055  {
1056  /* We didn't, so set a failure status */
1058  }
1059  else
1060  {
1061  /* We did, so we're free to parse the new object */
1062  goto ReparseObject;
1063  }
1064  }
1065  else
1066  {
1067  /* This is a symbolic link */
1068  SymLink = TRUE;
1069  goto ParseFromRoot;
1070  }
1071  }
1073  {
1074  /* We got STATUS_REPARSE but are at the Root Directory */
1075  Object = NULL;
1077  Reparse = FALSE;
1078  }
1079  }
1080  else if (!NT_SUCCESS(Status))
1081  {
1082  /* Total failure */
1083  Object = NULL;
1084  }
1085  else if (!Object)
1086  {
1087  /* We didn't reparse but we didn't find the Object Either */
1089  }
1090 
1091  /* Break out of the loop */
1092  break;
1093  }
1094  else
1095  {
1096  /* No parse routine...do we still have a remaining name? */
1097  if (!RemainingName.Length)
1098  {
1099  /* Are we creating an object? */
1100  if (!InsertObject)
1101  {
1102  /* Check if this is a user-mode call that needs to traverse */
1103  if ((AccessCheckMode != KernelMode) &&
1105  {
1106  /* Check if we can get it */
1109  AccessState,
1110  FALSE,
1111  AccessCheckMode,
1112  &Status))
1113  {
1114  /* We don't have access, fail */
1115  Object = NULL;
1116  break;
1117  }
1118  }
1119 
1120  /* Reference the Object */
1122  0,
1123  ObjectType,
1124  AccessMode);
1125  if (!NT_SUCCESS(Status)) Object = NULL;
1126  }
1127 
1128  /* And get out of the reparse loop */
1129  break;
1130  }
1131  else
1132  {
1133  /* We still have a name; check if this is a directory object */
1134  if (ObjectHeader->Type == ObpDirectoryObjectType)
1135  {
1136  /* Check if we have a referenced parent directory */
1137  if (ReferencedParentDirectory)
1138  {
1139  /* Dereference it */
1140  ObDereferenceObject(ReferencedParentDirectory);
1141  }
1142 
1143  /* Restart the lookup from this directory */
1144  ReferencedParentDirectory = ReferencedDirectory;
1146  Directory = Object;
1147  ReferencedDirectory = NULL;
1148  }
1149  else
1150  {
1151  /* We still have a name, but no parse routine for it */
1153  Object = NULL;
1154  break;
1155  }
1156  }
1157  }
1158  }
1159  }
1160 
1161  /* Check if we failed */
1162  if (!NT_SUCCESS(Status))
1163  {
1164  /* Cleanup after lookup */
1165  ObpReleaseLookupContext(LookupContext);
1166  }
1167 
1168  /* Check if we have a device map and dereference it if so */
1169  if (DeviceMap) ObfDereferenceDeviceMap(DeviceMap);
1170 
1171  /* Check if we have a referenced directory and dereference it if so */
1172  if (ReferencedDirectory) ObDereferenceObject(ReferencedDirectory);
1173 
1174  /* Check if we have a referenced parent directory */
1175  if (ReferencedParentDirectory)
1176  {
1177  /* We do, dereference it */
1178  ObDereferenceObject(ReferencedParentDirectory);
1179  }
1180 
1181  /* Set the found object and check if we got one */
1182  *FoundObject = Object;
1183  if (!Object)
1184  {
1185  /* Nothing was found. Did we reparse or get success? */
1186  if ((Status == STATUS_REPARSE) || (NT_SUCCESS(Status)))
1187  {
1188  /* Set correct failure */
1190  }
1191  }
1192 
1193  /* Check if we had a root directory */
1194  if (RootHandle) ObDereferenceObject(RootDirectory);
1195 
1196  /* Return status to caller */
1198  "%s - Found Object: %p. Expected: %p\n",
1199  __FUNCTION__,
1200  *FoundObject,
1201  InsertObject);
1202  return Status;
1203 }
1204 
1205 /* PUBLIC FUNCTIONS *********************************************************/
1206 
1207 NTSTATUS
1208 NTAPI
1210  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1211  IN ULONG Length,
1213 {
1214  POBJECT_HEADER_NAME_INFO LocalInfo;
1215  POBJECT_HEADER ObjectHeader;
1217  ULONG NameSize;
1218  PWCH ObjectName;
1219  BOOLEAN ObjectIsNamed;
1221 
1222  /* Get the Kernel Meta-Structures */
1223  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1224  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1225 
1226  /* Check if a Query Name Procedure is available */
1227  if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
1228  {
1229  /* Call the procedure inside SEH */
1230  ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0));
1231 
1232  _SEH2_TRY
1233  {
1234  Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
1235  ObjectIsNamed,
1236  ObjectNameInfo,
1237  Length,
1238  ReturnLength,
1239  KernelMode);
1240  }
1242  {
1243  /* Return the exception code */
1245  }
1246  _SEH2_END;
1247 
1248  return Status;
1249  }
1250 
1251  /* Check if the object doesn't even have a name */
1252  if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
1253  {
1255 
1256  _SEH2_TRY
1257  {
1258  /* We're returning the name structure */
1260 
1261  /* Check if we were given enough space */
1262  if (*ReturnLength > Length)
1263  {
1265  }
1266  else
1267  {
1268  /* Return an empty buffer */
1269  RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
1270  }
1271  }
1273  {
1274  /* Return the exception code */
1276  }
1277  _SEH2_END;
1278 
1279  return Status;
1280  }
1281 
1282  /*
1283  * Find the size needed for the name. We won't do
1284  * this during the Name Creation loop because we want
1285  * to let the caller know that the buffer isn't big
1286  * enough right at the beginning, not work our way through
1287  * and find out at the end
1288  */
1289  _SEH2_TRY
1290  {
1292  {
1293  /* Size of the '\' string */
1294  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
1295  }
1296  else
1297  {
1298  /* Get the Object Directory and add name of Object */
1299  ParentDirectory = LocalInfo->Directory;
1300  NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
1301 
1302  /* Loop inside the directory to get the top-most one (meaning root) */
1304  {
1305  /* Get the Name Information */
1306  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1308 
1309  /* Add the size of the Directory Name */
1310  if (LocalInfo && LocalInfo->Directory)
1311  {
1312  /* Size of the '\' string + Directory Name */
1313  NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
1314  LocalInfo->Name.Length;
1315 
1316  /* Move to next parent Directory */
1317  ParentDirectory = LocalInfo->Directory;
1318  }
1319  else
1320  {
1321  /* Directory with no name. We append "...\" */
1322  NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
1323  break;
1324  }
1325  }
1326  }
1327 
1328  /* Finally, add the name of the structure and the null char */
1329  *ReturnLength = NameSize +
1330  sizeof(OBJECT_NAME_INFORMATION) +
1331  sizeof(UNICODE_NULL);
1332 
1333  /* Check if we were given enough space */
1335 
1336  /*
1337  * Now we will actually create the name. We work backwards because
1338  * it's easier to start off from the Name we have and walk up the
1339  * parent directories. We use the same logic as Name Length calculation.
1340  */
1341  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1342  ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
1343  *--ObjectName = UNICODE_NULL;
1344 
1345  /* Check if the object is actually the Root directory */
1347  {
1348  /* This is already the Root Directory, return "\\" */
1350  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1351  ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
1352  sizeof(UNICODE_NULL));
1353  ObjectNameInfo->Name.Buffer = ObjectName;
1355  }
1356  else
1357  {
1358  /* Start by adding the Object's Name */
1360  LocalInfo->Name.Length);
1362  LocalInfo->Name.Buffer,
1363  LocalInfo->Name.Length);
1364 
1365  /* Now parse the Parent directories until we reach the top */
1366  ParentDirectory = LocalInfo->Directory;
1368  {
1369  /* Get the name information */
1370  LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
1372 
1373  /* Add the "\" */
1375 
1376  /* Add the Parent Directory's Name */
1377  if (LocalInfo && LocalInfo->Name.Buffer)
1378  {
1379  /* Add the name */
1381  LocalInfo->Name.Length);
1383  LocalInfo->Name.Buffer,
1384  LocalInfo->Name.Length);
1385 
1386  /* Move to next parent */
1387  ParentDirectory = LocalInfo->Directory;
1388  }
1389  else
1390  {
1391  /* Directory without a name, we add "..." */
1393  sizeof(L"...") +
1394  sizeof(UNICODE_NULL));
1395  RtlCopyMemory(ObjectName, L"...", sizeof(L"..."));
1396  break;
1397  }
1398  }
1399 
1400  /* Add Root Directory Name */
1402  ObjectNameInfo->Name.Length = (USHORT)NameSize;
1403  ObjectNameInfo->Name.MaximumLength =
1404  (USHORT)(NameSize + sizeof(UNICODE_NULL));
1405  ObjectNameInfo->Name.Buffer = ObjectName;
1406  }
1407  }
1409  {
1410  /* Return the exception code */
1412  }
1413  _SEH2_END;
1414 
1415  /* Return success */
1416  return Status;
1417 }
1418 
1419 /* EOF */
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ObjectType
Definition: metafile.c:80
UNICODE_STRING ObpDosDevicesShortName
Definition: obname.c:25
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
INIT_FUNCTION VOID NTAPI ObpFreeDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:161
#define GENERIC_ALL
Definition: nt_native.h:92
#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
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
LONG_PTR HandleCount
Definition: obtypes.h:490
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1595
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
_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
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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: obname.c:448
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
uint16_t * PWSTR
Definition: typedefs.h:54
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
INIT_FUNCTION NTSTATUS NTAPI ObpGetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:40
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301
struct _ACE ACE
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
BOOLEAN NTAPI ObpIsUnsecureName(IN PUNICODE_STRING ObjectName, IN BOOLEAN CaseInSensitive)
Definition: obname.c:398
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
UNICODE_STRING Name
Definition: obtypes.h:433
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
$ULONG LowPart
Definition: ntbasedef.h:576
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OBJ_PERMANENT
Definition: winternl.h:226
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
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1595
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
_SEH2_TRY
Definition: create.c:4250
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
UCHAR KIRQL
Definition: env_spec_w32.h:591
while(1)
Definition: macro.lex.yy.c:740
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define UNICODE_NULL
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2292
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STATUS_REPARSE_OBJECT
Definition: ntstatus.h:102
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:429
struct _ACL ACL
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
UCHAR Flags
Definition: obtypes.h:497
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
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 InterlockedExchangeAdd
Definition: interlocked.h:181
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
_In_ HANDLE Handle
Definition: extypes.h:390
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
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
POBJECT_TYPE MmSectionObjectType
Definition: section.c:136
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
static IUnknown Object
Definition: main.c:512
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#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
WCHAR * PWCH
Definition: ntbasedef.h:417
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
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
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
PSID SeAliasAdminsSid
Definition: sid.c:47
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:437
static const WCHAR L[]
Definition: oid.c:1250
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
ULONG ObpUnsecureGlobalNamesLength
Definition: obname.c:33
PSID SeCreatorOwnerSid
Definition: sid.c:33
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
WCHAR TargetName[256]
Definition: arping.c:27
#define GENERIC_READ
Definition: compat.h:124
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
PSID SeWorldSid
Definition: sid.c:31
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
INIT_FUNCTION NTSTATUS NTAPI ObpCreateDosDevicesDirectory(VOID)
Definition: obname.c:177
#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
VOID NTAPI ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:326
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:773
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
_SEH2_END
Definition: create.c:4424
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:124
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
ULONG ObpProtectionMode
Definition: obinit.c:56
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
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
#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
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
IN PDCB ParentDirectory
Definition: fatprocs.h:689
#define ACL_REVISION
Definition: setypes.h:39
PSID SeLocalSystemSid
Definition: sid.c:44
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
ALIGNEDNAME ObpDosDevicesShortNamePrefix
Definition: obname.c:23
OB_QUERYNAME_METHOD QueryNameProcedure
Definition: obtypes.h:372
base for all directory entries
Definition: entries.h:138
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG ObpLUIDDeviceMapsDisabled
Definition: devicemap.c:17
POBJECT_DIRECTORY DosDevicesDirectory
Definition: obtypes.h:525
#define INHERIT_ONLY_ACE
Definition: setypes.h:717
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PDEVICE_MAP NTAPI ObpReferenceDeviceMap(VOID)
Definition: devicemap.c:325
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
WCHAR ObpUnsecureGlobalNamesBuffer[128]
Definition: obname.c:32
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:281
POBJECT_TYPE Type
Definition: obtypes.h:493
#define GENERIC_EXECUTE
Definition: nt_native.h:91
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3734
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define __FUNCTION__
Definition: types.h:112
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
Definition: rtltypes.h:988
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714
BOOLEAN NTAPI ObpDeleteEntryDirectory(IN POBP_LOOKUP_CONTEXT Context)
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68