Free the capture buffer in ObReferenceObjectByName.
[reactos.git] / reactos / ntoskrnl / ob / namespc.c
index 34cb5d5..fe51c7a 100644 (file)
@@ -21,9 +21,11 @@ POBJECT_TYPE ObDirectoryType = NULL;
 POBJECT_TYPE ObTypeObjectType = NULL;
 
 PDIRECTORY_OBJECT NameSpaceRoot = NULL;
+PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
  /* FIXME: Move this somewhere else once devicemap support is in */
 PDEVICE_MAP ObSystemDeviceMap = NULL;
 
+
 static GENERIC_MAPPING ObpDirectoryMapping = {
        STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
        STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY,
@@ -36,6 +38,14 @@ static GENERIC_MAPPING ObpTypeMapping = {
        STANDARD_RIGHTS_EXECUTE,
        0x000F0001};
 
+NTSTATUS
+STDCALL
+ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+                  PUNICODE_STRING ObjectName,
+                  POBJECT_TYPE ObjectType,
+                  ULONG ObjectSize,
+                  POBJECT_HEADER *ObjectHeader);
+
 /* FUNCTIONS **************************************************************/
 
 /*
@@ -53,7 +63,9 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
 {
    PVOID Object = NULL;
    UNICODE_STRING RemainingPath;
+   UNICODE_STRING ObjectName;
    OBJECT_ATTRIBUTES ObjectAttributes;
+   OBJECT_CREATE_INFORMATION ObjectCreateInfo;
    NTSTATUS Status;
 
    PAGED_CODE();
@@ -63,21 +75,38 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
                              Attributes | OBJ_OPENIF,
                              NULL,
                              NULL);
-   Status = ObFindObject(&ObjectAttributes,
+    
+   /* Capture all the info */
+   DPRINT("Capturing Create Info\n");
+   Status = ObpCaptureObjectAttributes(&ObjectAttributes,
+                                       AccessMode,
+                                       ObjectType,
+                                       &ObjectCreateInfo,
+                                       &ObjectName);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+       return Status;
+     }
+     
+   Status = ObFindObject(&ObjectCreateInfo,
+                         &ObjectName,
                         &Object,
                         &RemainingPath,
                         ObjectType);
+
+   ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+   if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
    if (!NT_SUCCESS(Status))
      {
        return(Status);
      }
-CHECKPOINT;
-DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
+   DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
 
    if (RemainingPath.Buffer != NULL || Object == NULL)
      {
-CHECKPOINT;
-DPRINT("Object %p\n", Object);
+        DPRINT("Object %p\n", Object);
        *ObjectPtr = NULL;
        RtlFreeUnicodeString (&RemainingPath);
        return(STATUS_OBJECT_NAME_NOT_FOUND);
@@ -127,22 +156,41 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
 {
    UNICODE_STRING RemainingPath;
    PVOID Object = NULL;
+   UNICODE_STRING ObjectName;
+   OBJECT_CREATE_INFORMATION ObjectCreateInfo;
    NTSTATUS Status;
 
    PAGED_CODE();
 
    DPRINT("ObOpenObjectByName(...)\n");
 
-   Status = ObFindObject(ObjectAttributes,
+    /* Capture all the info */
+    DPRINT("Capturing Create Info\n");
+    Status = ObpCaptureObjectAttributes(ObjectAttributes,
+                                        AccessMode,
+                                        ObjectType,
+                                        &ObjectCreateInfo,
+                                        &ObjectName);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+       return Status;
+     }
+                                        
+   Status = ObFindObject(&ObjectCreateInfo,
+                         &ObjectName,
                         &Object,
                         &RemainingPath,
                         ObjectType);
+   ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+   if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
    if (!NT_SUCCESS(Status))
      {
        DPRINT("ObFindObject() failed (Status %lx)\n", Status);
        return Status;
      }
 
+   DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
    if (Object == NULL)
      {
        RtlFreeUnicodeString(&RemainingPath);
@@ -158,8 +206,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
       ObDereferenceObject(Object);
       return Status;
    }
-
-   Status = ObCreateHandle(PsGetCurrentProcess(),
+   
+   Status = ObpCreateHandle(PsGetCurrentProcess(),
                           Object,
                           DesiredAccess,
                           FALSE,
@@ -208,8 +256,7 @@ ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
 {
   KIRQL oldlvl;
 
-  RtlpCreateUnicodeString(&Header->Name, Name, NonPagedPool);
-  Header->Parent = Parent;
+  Header->NameInfo->Directory = Parent;
 
   KeAcquireSpinLock(&Parent->Lock, &oldlvl);
   InsertTailList(&Parent->head, &Header->Entry);
@@ -229,15 +276,33 @@ ObpRemoveEntryDirectory(POBJECT_HEADER Header)
 
   DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
 
-  KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
+  KeAcquireSpinLock(&(Header->NameInfo->Directory->Lock),&oldlvl);
   if (Header->Entry.Flink && Header->Entry.Blink)
   {
     RemoveEntryList(&(Header->Entry));
     Header->Entry.Flink = Header->Entry.Blink = NULL;
   }
-  KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
+  KeReleaseSpinLock(&(Header->NameInfo->Directory->Lock),oldlvl);
 }
 
+NTSTATUS
+STDCALL
+ObpCreateDirectory(OB_OPEN_REASON Reason,
+                   PVOID ObjectBody,
+                   PEPROCESS Process,
+                   ULONG HandleCount,
+                   ACCESS_MASK GrantedAccess)
+{
+    PDIRECTORY_OBJECT Directory = ObjectBody;
+    
+    if (Reason == ObCreateHandle)
+    {
+        InitializeListHead(&Directory->head);
+        KeInitializeSpinLock(&Directory->Lock);
+    }
+    
+    return STATUS_SUCCESS;
+}
 
 PVOID
 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
@@ -259,15 +324,15 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
      }
    if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
      {
-       return(BODY_TO_HEADER(DirectoryObject)->Parent);
+       return(BODY_TO_HEADER(DirectoryObject)->NameInfo->Directory);
      }
    while (current!=(&(DirectoryObject->head)))
      {
        current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
-       DPRINT("  Scanning: %S for: %S\n",current_obj->Name.Buffer, Name);
+       DPRINT("  Scanning: %S for: %S\n",current_obj->NameInfo->Name.Buffer, Name);
        if (Attributes & OBJ_CASE_INSENSITIVE)
          {
-            if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
+            if (_wcsicmp(current_obj->NameInfo->Name.Buffer, Name)==0)
               {
                  DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
                  return(HEADER_TO_BODY(current_obj));
@@ -275,7 +340,7 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
          }
        else
          {
-            if ( wcscmp(current_obj->Name.Buffer, Name)==0)
+            if ( wcscmp(current_obj->NameInfo->Name.Buffer, Name)==0)
               {
                  DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
                  return(HEADER_TO_BODY(current_obj));
@@ -349,191 +414,166 @@ ObpParseDirectory(PVOID Object,
   return STATUS_SUCCESS;
 }
 
-
-NTSTATUS STDCALL
-ObpCreateDirectory(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  PDIRECTORY_OBJECT DirectoryObject = (PDIRECTORY_OBJECT)ObjectBody;
-
-  DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  InitializeListHead(&DirectoryObject->head);
-  KeInitializeSpinLock(&DirectoryObject->Lock);
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ObInit(VOID)
-/*
- * FUNCTION: Initialize the object manager namespace
- */
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING Name;
-  SECURITY_DESCRIPTOR SecurityDescriptor;
-
-  /* Initialize the security descriptor cache */
-  ObpInitSdCache();
-
-  /* create 'directory' object type */
-  ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
-  ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
-  ObDirectoryType->TotalObjects = 0;
-  ObDirectoryType->TotalHandles = 0;
-  ObDirectoryType->PeakObjects = 0;
-  ObDirectoryType->PeakHandles = 0;
-  ObDirectoryType->PagedPoolCharge = 0;
-  ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
-  ObDirectoryType->Mapping = &ObpDirectoryMapping;
-  ObDirectoryType->Dump = NULL;
-  ObDirectoryType->Open = NULL;
-  ObDirectoryType->Close = NULL;
-  ObDirectoryType->Delete = NULL;
-  ObDirectoryType->Parse = ObpParseDirectory;
-  ObDirectoryType->Security = NULL;
-  ObDirectoryType->QueryName = NULL;
-  ObDirectoryType->OkayToClose = NULL;
-  ObDirectoryType->Create = ObpCreateDirectory;
-  ObDirectoryType->DuplicationNotify = NULL;
-
-  RtlInitUnicodeString(&ObDirectoryType->TypeName,
-                      L"Directory");
-
-  /* create 'type' object type*/
-  ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
-  ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T');
-  ObTypeObjectType->TotalObjects = 0;
-  ObTypeObjectType->TotalHandles = 0;
-  ObTypeObjectType->PeakObjects = 0;
-  ObTypeObjectType->PeakHandles = 0;
-  ObTypeObjectType->PagedPoolCharge = 0;
-  ObTypeObjectType->NonpagedPoolCharge = sizeof(TYPE_OBJECT);
-  ObTypeObjectType->Mapping = &ObpTypeMapping;
-  ObTypeObjectType->Dump = NULL;
-  ObTypeObjectType->Open = NULL;
-  ObTypeObjectType->Close = NULL;
-  ObTypeObjectType->Delete = NULL;
-  ObTypeObjectType->Parse = NULL;
-  ObTypeObjectType->Security = NULL;
-  ObTypeObjectType->QueryName = NULL;
-  ObTypeObjectType->OkayToClose = NULL;
-  ObTypeObjectType->Create = NULL;
-  ObTypeObjectType->DuplicationNotify = NULL;
-
-  RtlInitUnicodeString(&ObTypeObjectType->TypeName,
-                      L"ObjectType");
-
-  /* Create security descriptor */
-  RtlCreateSecurityDescriptor(&SecurityDescriptor,
-                             SECURITY_DESCRIPTOR_REVISION1);
-
-  RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
-                               SeAliasAdminsSid,
-                               FALSE);
-
-  RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
-                               SeLocalSystemSid,
-                               FALSE);
-
-  RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
-                              TRUE,
-                              SePublicDefaultDacl,
-                              FALSE);
-
-  /* Create root directory */
-  InitializeObjectAttributes(&ObjectAttributes,
-                            NULL,
-                            OBJ_PERMANENT,
-                            NULL,
-                            &SecurityDescriptor);
-  ObCreateObject(KernelMode,
-                ObDirectoryType,
-                &ObjectAttributes,
-                KernelMode,
-                NULL,
-                sizeof(DIRECTORY_OBJECT),
-                0,
-                0,
-                (PVOID*)&NameSpaceRoot);
-
-  /* Create '\ObjectTypes' directory */
-  RtlRosInitUnicodeStringFromLiteral(&Name,
-                      L"\\ObjectTypes");
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_PERMANENT,
-                            NULL,
-                            &SecurityDescriptor);
-  ObCreateObject(KernelMode,
-                ObDirectoryType,
-                &ObjectAttributes,
-                KernelMode,
-                NULL,
-                sizeof(DIRECTORY_OBJECT),
-                0,
-                0,
-                NULL);
-
-  ObpCreateTypeObject(ObDirectoryType);
-  ObpCreateTypeObject(ObTypeObjectType);
-
-  /* Create 'symbolic link' object type */
-  ObInitSymbolicLinkImplementation();
-
-  /* FIXME: Hack Hack! */
-  ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
-  RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING Name;
+    SECURITY_DESCRIPTOR SecurityDescriptor;
+    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+
+    /* Initialize the security descriptor cache */
+    ObpInitSdCache();
+
+    /* Create the Type Type */
+    DPRINT("Creating Type Type\n");
+    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+    RtlInitUnicodeString(&Name, L"Type");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
+    ObjectTypeInitializer.UseDefaultObject = TRUE;
+    ObjectTypeInitializer.MaintainTypeList = TRUE;
+    ObjectTypeInitializer.PoolType = NonPagedPool;
+    ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
+    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
+    ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
+  
+    /* Create the Directory Type */
+    DPRINT("Creating Directory Type\n");
+    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+    RtlInitUnicodeString(&Name, L"Directory");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
+    ObjectTypeInitializer.UseDefaultObject = FALSE;
+    ObjectTypeInitializer.OpenProcedure = ObpCreateDirectory;
+    ObjectTypeInitializer.ParseProcedure = ObpParseDirectory;
+    ObjectTypeInitializer.MaintainTypeList = FALSE;
+    ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
+    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DIRECTORY_OBJECT);
+    ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
+
+    /* Create security descriptor */
+    RtlCreateSecurityDescriptor(&SecurityDescriptor,
+                                SECURITY_DESCRIPTOR_REVISION1);
+    RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
+                                  SeAliasAdminsSid,
+                                  FALSE);
+    RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
+                                  SeLocalSystemSid,
+                                  FALSE);
+    RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
+                                 TRUE,
+                                 SePublicDefaultDacl,
+                                 FALSE);
+
+    /* Create root directory */
+    DPRINT("Creating Root Directory\n");    
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_PERMANENT,
+                               NULL,
+                               &SecurityDescriptor);
+    ObCreateObject(KernelMode,
+                   ObDirectoryType,
+                   &ObjectAttributes,
+                   KernelMode,
+                   NULL,
+                   sizeof(DIRECTORY_OBJECT),
+                   0,
+                   0,
+                   (PVOID*)&NameSpaceRoot);
+    ObInsertObject((PVOID)NameSpaceRoot,
+                   NULL,
+                   DIRECTORY_ALL_ACCESS,
+                   0,
+                   NULL,
+                   NULL);
+
+    /* Create '\ObjectTypes' directory */
+    RtlInitUnicodeString(&Name, L"\\ObjectTypes");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_PERMANENT,
+                               NULL,
+                               &SecurityDescriptor);
+    ObCreateObject(KernelMode,
+                   ObDirectoryType,
+                   &ObjectAttributes,
+                   KernelMode,
+                   NULL,
+                   sizeof(DIRECTORY_OBJECT),
+                   0,
+                   0,
+                   (PVOID*)&ObpTypeDirectoryObject);
+    ObInsertObject((PVOID)ObpTypeDirectoryObject,
+                   NULL,
+                   DIRECTORY_ALL_ACCESS,
+                   0,
+                   NULL,
+                   NULL);
+    
+    /* Insert the two objects we already created but couldn't add */
+    /* NOTE: Uses TypeList & Creator Info in OB 2.0 */
+    ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObTypeObjectType), NULL);
+    ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObDirectoryType), NULL);
+
+    /* Create 'symbolic link' object type */
+    ObInitSymbolicLinkImplementation();
+
+    /* FIXME: Hack Hack! */
+    ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
+    RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
 }
 
-
 NTSTATUS
-ObpCreateTypeObject(POBJECT_TYPE ObjectType)
+STDCALL
+ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
+                    PUNICODE_STRING TypeName,
+                    POBJECT_TYPE *ObjectType)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  WCHAR NameString[120];
-  PTYPE_OBJECT TypeObject = NULL;
-  UNICODE_STRING Name;
-  NTSTATUS Status;
-
-  DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType->TypeName);
-  wcscpy(NameString, L"\\ObjectTypes\\");
-  wcscat(NameString, ObjectType->TypeName.Buffer);
-  RtlInitUnicodeString(&Name,
-                      NameString);
-
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_PERMANENT,
-                            NULL,
-                            NULL);
-  Status = ObCreateObject(KernelMode,
-                         ObTypeObjectType,
-                         &ObjectAttributes,
-                         KernelMode,
-                         NULL,
-                         sizeof(TYPE_OBJECT),
-                         0,
-                         0,
-                         (PVOID*)&TypeObject);
-  if (NT_SUCCESS(Status))
+    POBJECT_HEADER Header;
+    POBJECT_TYPE LocalObjectType;
+    NTSTATUS Status;
+
+    DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
+    
+    /* Allocate the Object */
+    Status = ObpAllocateObject(NULL, 
+                               TypeName,
+                               ObTypeObjectType, 
+                               OBJECT_ALLOC_SIZE(sizeof(OBJECT_TYPE)),
+                               &Header);
+    if (!NT_SUCCESS(Status))
     {
-      TypeObject->ObjectType = ObjectType;
+        DPRINT1("ObpAllocateObject failed!\n");
+        return Status;
     }
-
-  return(STATUS_SUCCESS);
-}
+    
+    LocalObjectType = HEADER_TO_BODY(Header);
+    
+    /* Check if this is the first Object Type */
+    if (!ObTypeObjectType)
+    {
+        ObTypeObjectType = LocalObjectType;
+        Header->ObjectType = ObTypeObjectType;
+    }
+    
+    /* FIXME: Generate Tag */
+        
+    /* Set it up */
+    LocalObjectType->TypeInfo = *ObjectTypeInitializer;
+    LocalObjectType->Name = *TypeName;
+    
+    /* Insert it into the Object Directory */
+    if (ObpTypeDirectoryObject)
+    {
+        ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
+        ObReferenceObject(ObpTypeDirectoryObject);
+    }
+        
+    *ObjectType = LocalObjectType;
+    return Status;
+} 
 
 /* EOF */