Handles are no longer used to create type objects.
[reactos.git] / reactos / ntoskrnl / ob / namespc.c
index 4b78890..1abe482 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id: namespc.c,v 1.30 2002/03/06 12:40:47 ekohl Exp $
+ *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
  * FILE:           ntoskrnl/ob/namespc.c
 
 /* INCLUDES ***************************************************************/
 
-#include <windows.h>
-#include <wstring.h>
+#include <limits.h>
 #include <ddk/ntddk.h>
 #include <internal/ob.h>
 #include <internal/io.h>
-#include <internal/string.h>
+#include <internal/pool.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 /* GLOBALS ****************************************************************/
 
 POBJECT_TYPE ObDirectoryType = NULL;
+POBJECT_TYPE ObTypeObjectType = NULL;
 
-static struct
-{
-   OBJECT_HEADER hdr;
-//   DIRECTORY_OBJECT directory;
-   LIST_ENTRY head;
-   KSPIN_LOCK Lock;
-} namespc_root = {{0,},};
+PDIRECTORY_OBJECT NameSpaceRoot = NULL;
 
-/* FUNCTIONS **************************************************************/
+static GENERIC_MAPPING ObpDirectoryMapping = {
+       STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
+       STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY,
+       STANDARD_RIGHTS_EXECUTE|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
+       DIRECTORY_ALL_ACCESS};
 
-NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle,
-                              ACCESS_MASK DesiredAccess,
-                              POBJECT_ATTRIBUTES ObjectAttributes)
-{
-   return(ZwOpenDirectoryObject(DirectoryHandle,
-                               DesiredAccess,
-                               ObjectAttributes));
-}
+static GENERIC_MAPPING ObpTypeMapping = {
+       STANDARD_RIGHTS_READ,
+       STANDARD_RIGHTS_WRITE,
+       STANDARD_RIGHTS_EXECUTE,
+       0x000F0001};
 
-NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,
-                              ACCESS_MASK DesiredAccess,
-                              POBJECT_ATTRIBUTES ObjectAttributes)
-/*
- * FUNCTION: Opens a namespace directory object
- * ARGUMENTS:
- *       DirectoryHandle (OUT) = Variable which receives the directory handle
- *       DesiredAccess = Desired access to the directory
- *       ObjectAttributes = Structure describing the directory
- * RETURNS: Status
- * NOTES: Undocumented
- */
+/* FUNCTIONS **************************************************************/
+
+NTSTATUS STDCALL
+ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
+                       ULONG Attributes,
+                       PACCESS_STATE PassedAccessState,
+                       ACCESS_MASK DesiredAccess,
+                       POBJECT_TYPE ObjectType,
+                       KPROCESSOR_MODE AccessMode,
+                       PVOID ParseContext,
+                       PVOID* ObjectPtr)
 {
-   PVOID Object;
+   PVOID Object = NULL;
+   UNICODE_STRING RemainingPath;
+   OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
-   PWSTR Ignored;
-   
-   *DirectoryHandle = 0;
-   
-   Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored);
+
+   InitializeObjectAttributes(&ObjectAttributes,
+                             ObjectPath,
+                             Attributes,
+                             NULL,
+                             NULL);
+   Status = ObFindObject(&ObjectAttributes,
+                        &Object,
+                        &RemainingPath,
+                        ObjectType);
    if (!NT_SUCCESS(Status))
      {
        return(Status);
      }
-       
-   if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)
-     { 
+CHECKPOINT;
+DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
+
+   if (RemainingPath.Buffer != NULL || Object == NULL)
+     {
+CHECKPOINT;
+DPRINT("Object %p\n", Object);
+       *ObjectPtr = NULL;
+       RtlFreeUnicodeString (&RemainingPath);
        return(STATUS_UNSUCCESSFUL);
      }
-   
-   *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object,
-                                    DesiredAccess,FALSE);
-   CHECKPOINT;
+   *ObjectPtr = Object;
+   RtlFreeUnicodeString (&RemainingPath);
    return(STATUS_SUCCESS);
 }
 
-NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle,
-                               OUT POBJDIR_INFORMATION DirObjInformation, 
-                               IN ULONG                BufferLength, 
-                               IN BOOLEAN              GetNextIndex, 
-                               IN BOOLEAN              IgnoreInputIndex, 
-                               IN OUT PULONG           ObjectIndex,
-                               OUT PULONG              DataWritten OPTIONAL)
-{
-   return(ZwQueryDirectoryObject(DirObjHandle,
-                                DirObjInformation,
-                                BufferLength,
-                                GetNextIndex,
-                                IgnoreInputIndex,
-                                ObjectIndex,
-                                DataWritten));
-}
 
-NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,
-                               OUT POBJDIR_INFORMATION DirObjInformation, 
-                               IN ULONG                BufferLength, 
-                               IN BOOLEAN              GetNextIndex, 
-                               IN BOOLEAN              IgnoreInputIndex, 
-                               IN OUT PULONG           ObjectIndex,
-                               OUT PULONG              DataWritten OPTIONAL)
-/*
- * FUNCTION: Reads information from a namespace directory
- * ARGUMENTS:
- *        DirObjInformation (OUT) = Buffer to hold the data read
- *        BufferLength = Size of the buffer in bytes
- *        GetNextIndex = If TRUE then set ObjectIndex to the index of the
- *                       next object
- *                       If FALSE then set ObjectIndex to the number of
- *                       objects in the directory
- *        IgnoreInputIndex = If TRUE start reading at index 0
- *                           If FALSE start reading at the index specified
- *                           by object index
- *        ObjectIndex = Zero based index into the directory, interpretation
- *                      depends on IgnoreInputIndex and GetNextIndex
- *        DataWritten (OUT) = Caller supplied storage for the number of bytes
- *                            written (or NULL)
- * RETURNS: Status
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     ObOpenObjectByName
+ *     
+ * DESCRIPTION
+ *     Obtain a handle to an existing object.
+ *     
+ * ARGUMENTS
+ *     ObjectAttributes
+ *             ...
+ *     ObjectType
+ *             ...
+ *     ParseContext
+ *             ...
+ *     AccessMode
+ *             ...
+ *     DesiredAccess
+ *             ...
+ *     PassedAccessState
+ *             ...
+ *     Handle
+ *             Handle to close.
+ *
+ * RETURN VALUE
+ *     Status.
  */
+NTSTATUS STDCALL
+ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
+                  IN POBJECT_TYPE ObjectType,
+                  IN OUT PVOID ParseContext,
+                  IN KPROCESSOR_MODE AccessMode,
+                  IN ACCESS_MASK DesiredAccess,
+                  IN PACCESS_STATE PassedAccessState,
+                  OUT PHANDLE Handle)
 {
-   PDIRECTORY_OBJECT dir = NULL;
-   ULONG EntriesToRead;
-   PLIST_ENTRY current_entry;
-   POBJECT_HEADER current;
-   ULONG i=0;
-   ULONG EntriesToSkip;
+   UNICODE_STRING RemainingPath;
+   PVOID Object = NULL;
    NTSTATUS Status;
-   
-   DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);
-   DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));
-   
-//   assert_irql(PASSIVE_LEVEL);
-   
-   Status = ObReferenceObjectByHandle(DirObjHandle,
-                                     DIRECTORY_QUERY,
-                                     ObDirectoryType,
-                                     UserMode,
-                                     (PVOID*)&dir,
-                                     NULL);
-   if (Status != STATUS_SUCCESS)
-     {
-       return(Status);
-     }
-   
-   EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);
-   *DataWritten = 0;
-   
-   DPRINT("EntriesToRead %d\n",EntriesToRead);
-   
-   current_entry = dir->head.Flink;
-   
-   /*
-    * Optionally, skip over some entries at the start of the directory
-    */
-   if (!IgnoreInputIndex)
-     {
-       CHECKPOINT;
-       
-       EntriesToSkip = *ObjectIndex;
-       while ( i<EntriesToSkip && current_entry!=NULL)
-         {
-            current_entry = current_entry->Flink;
-         }
-     }
-   
-   DPRINT("DirObjInformation %x\n",DirObjInformation);
-   
-   /*
-    * Read the maximum entries possible into the buffer
-    */
-   while ( i<EntriesToRead && current_entry!=(&(dir->head)))
-     {
-       current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
-       DPRINT("Scanning %w\n",current->Name.Buffer);
-       DirObjInformation[i].ObjectName.Buffer = 
-                      ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);
-       DirObjInformation[i].ObjectName.Length = current->Name.Length;
-       DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;
-       DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
-              DirObjInformation[i].ObjectName.Buffer);
-       RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
-                            &(current->Name));
-       i++;
-       current_entry = current_entry->Flink;
-       (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);
-       CHECKPOINT;
-     }
-   CHECKPOINT;
-   
-   /*
-    * Optionally, count the number of entries in the directory
-    */
-   if (GetNextIndex)
+
+   DPRINT("ObOpenObjectByName()\n");
+
+   Status = ObFindObject(ObjectAttributes,
+                        &Object,
+                        &RemainingPath,
+                        ObjectType);
+   if (!NT_SUCCESS(Status))
      {
-       *ObjectIndex=i;
+       return Status;
      }
-   else
+
+   if (RemainingPath.Buffer != NULL ||
+       Object == NULL)
      {
-       while ( current_entry!=(&(dir->head)) )
-         {
-            current_entry=current_entry->Flink;
-            i++;
-         }
-       *ObjectIndex=i;
+       RtlFreeUnicodeString(&RemainingPath);
+       return STATUS_UNSUCCESSFUL;
      }
-   return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
-                                ULONG Attributes,
-                                PACCESS_STATE PassedAccessState,
-                                ACCESS_MASK DesiredAccess,
-                                POBJECT_TYPE ObjectType,
-                                KPROCESSOR_MODE AccessMode,
-                                PVOID ParseContext,
-                                PVOID* ObjectPtr)
-{
-   UNIMPLEMENTED;
-}
 
-NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,
-                           PVOID* Object, PWSTR* UnparsedSection)
-{
-   NTSTATUS Status;
-   
-   DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",
-         ObjectAttributes,Object);
-   DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",
-         ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);
-   DPRINT("ObjectAttributes->ObjectName->Length %d\n",
-         ObjectAttributes->ObjectName->Length);
-   
-   *Object = NULL;
-   Status = ObLookupObject(ObjectAttributes->RootDirectory, 
-                          ObjectAttributes->ObjectName->Buffer, 
+   Status = ObCreateHandle(PsGetCurrentProcess(),
                           Object,
-                          UnparsedSection);
-   DPRINT("*Object %x\n",*Object);
-   DPRINT("ObjectAttributes->ObjectName->Length %d\n",
-         ObjectAttributes->ObjectName->Length);
-   return(Status);
-}
+                          DesiredAccess,
+                          FALSE,
+                          Handle);
 
-void ObInit(void)
-/*
- * FUNCTION: Initialize the object manager namespace
- */
-{
-   ANSI_STRING AnsiString;
-   
-   ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   ObDirectoryType->TotalObjects = 0;
-   ObDirectoryType->TotalHandles = 0;
-   ObDirectoryType->MaxObjects = ULONG_MAX;
-   ObDirectoryType->MaxHandles = ULONG_MAX;
-   ObDirectoryType->PagedPoolCharge = 0;
-   ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
-   ObDirectoryType->Dump = NULL;
-   ObDirectoryType->Open = NULL;
-   ObDirectoryType->Close = NULL;
-   ObDirectoryType->Delete = NULL;
-   ObDirectoryType->Parse = NULL;
-   ObDirectoryType->Security = NULL;
-   ObDirectoryType->QueryName = NULL;
-   ObDirectoryType->OkayToClose = NULL;
-   
-   RtlInitAnsiString(&AnsiString,"Directory");
-   RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName,
-                               &AnsiString,TRUE);
-   
-   ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr);
-   InitializeListHead(&namespc_root.head);
-}
+   ObDereferenceObject(Object);
+   RtlFreeUnicodeString(&RemainingPath);
 
-NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle,
-                                ACCESS_MASK DesiredAccess,
-                                POBJECT_ATTRIBUTES ObjectAttributes)
-{
-   return(ZwCreateDirectoryObject(DirectoryHandle,
-                                 DesiredAccess,
-                                 ObjectAttributes));
+   return Status;
 }
 
-NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,
-                                ACCESS_MASK DesiredAccess,
-                                POBJECT_ATTRIBUTES ObjectAttributes)
+
+VOID
+ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
+                    POBJECT_HEADER Header,
+                    PWSTR Name)
 /*
- * FUNCTION: Creates or opens a directory object (a container for other
- * objects)
+ * FUNCTION: Add an entry to a namespace directory
  * ARGUMENTS:
- *        DirectoryHandle (OUT) = Caller supplied storage for the handle
- *                                of the directory
- *        DesiredAccess = Access desired to the directory
- *        ObjectAttributes = Object attributes initialized with
- *                           InitializeObjectAttributes
- * RETURNS: Status
+ *         Parent = directory to add in
+ *         Header = Header of the object to add the entry for
+ *         Name = Name to give the entry
  */
 {
-   PDIRECTORY_OBJECT dir;
-   
-   dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes,
-                              ObDirectoryType);
-   
-   /*
-    * Initialize the object body
-    */
-   InitializeListHead(&dir->head);
-   KeInitializeSpinLock(&(dir->Lock));
-   
-   return(STATUS_SUCCESS);
+  KIRQL oldlvl;
+
+  RtlCreateUnicodeString(&Header->Name, Name);
+  Header->Parent = Parent;
+
+  KeAcquireSpinLock(&Parent->Lock, &oldlvl);
+  InsertTailList(&Parent->head, &Header->Entry);
+  KeReleaseSpinLock(&Parent->Lock, oldlvl);
 }
 
-VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
-                               PUNICODE_STRING ObjectName,
-                               ULONG Attributes,
-                               HANDLE RootDirectory,
-                               PSECURITY_DESCRIPTOR SecurityDescriptor)
+VOID
+ObpRemoveEntryDirectory(POBJECT_HEADER Header)
 /*
- * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a 
- * subsequent call to ZwCreateXXX or ZwOpenXXX
+ * FUNCTION: Remove an entry from a namespace directory
  * ARGUMENTS:
- *        InitializedAttributes (OUT) = Caller supplied storage for the
- *                                      object attributes
- *        ObjectName = Full path name for object
- *        Attributes = Attributes for the object
- *        RootDirectory = Where the object should be placed or NULL
- *        SecurityDescriptor = Ignored
- * 
- * NOTE:
- *     Either ObjectName is a fully qualified pathname or a path relative
- *     to RootDirectory
+ *         Header = Header of the object to remove
  */
 {
-   DPRINT("InitializeObjectAttributes(InitializedAttributes %x "
-         "ObjectName %x Attributes %x RootDirectory %x)\n",
-         InitializedAttributes,ObjectName,Attributes,RootDirectory);
-   InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);
-   InitializedAttributes->RootDirectory=RootDirectory;
-   InitializedAttributes->ObjectName=ObjectName;
-   InitializedAttributes->Attributes=Attributes;
-   InitializedAttributes->SecurityDescriptor=SecurityDescriptor;
-   InitializedAttributes->SecurityQualityOfService=NULL;
+  KIRQL oldlvl;
+
+  DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
+
+  KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
+  RemoveEntryList(&(Header->Entry));
+  KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
 }
 
-static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name)
-/*
- * FUNCTION: Looks up an entry within a namespace directory
- * ARGUMENTS:
- *        dir = Directory to lookup in
- *        name = Entry name to find
- * RETURNS: A pointer to the object body if found
- *          NULL otherwise
- */
+PVOID
+ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
+                     PWSTR Name,
+                     ULONG Attributes)
 {
-   LIST_ENTRY* current = dir->head.Flink;
+   PLIST_ENTRY current = DirectoryObject->head.Flink;
    POBJECT_HEADER current_obj;
+
+   DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
    
-   DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);
-   
-   if (name[0]==0)
+   if (Name[0]==0)
      {
-       return(dir);
+       return(DirectoryObject);
      }
-   if (name[0]=='.'&&name[1]==0)
+   if (Name[0]=='.' && Name[1]==0)
      {
-       return(dir);
+       return(DirectoryObject);
      }
-   if (name[0]=='.'&&name[1]=='.'&&name[2]==0)
+   if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
      {
-       return(BODY_TO_HEADER(dir)->Parent);
+       return(BODY_TO_HEADER(DirectoryObject)->Parent);
      }
-   while (current!=(&(dir->head)))
+   while (current!=(&(DirectoryObject->head)))
      {
        current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
-       DPRINT("Scanning %w\n",current_obj->Name.Buffer);
-       if ( wcscmp(current_obj->Name.Buffer, name)==0)
+       DPRINT("Scanning %S %S\n",current_obj->Name.Buffer, Name);
+       if (Attributes & OBJ_CASE_INSENSITIVE)
          {
-            return(HEADER_TO_BODY(current_obj));
+            if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
+              {
+                 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
+                 return(HEADER_TO_BODY(current_obj));
+              }
+         }
+       else
+         {
+            if ( wcscmp(current_obj->Name.Buffer, Name)==0)
+              {
+                 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
+                 return(HEADER_TO_BODY(current_obj));
+              }
          }
        current = current->Flink;
      }
@@ -389,150 +243,204 @@ static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name)
    return(NULL);
 }
 
-VOID ObRemoveEntry(POBJECT_HEADER Header)
-{
-   KIRQL oldlvl;
-   
-   DPRINT("ObRemoveEntry(Header %x)\n",Header);
-   
-   KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
-   RemoveEntryList(&(Header->Entry));
-   KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
-}
-
-VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)
-/*
- * FUNCTION: Add an entry to a namespace directory
- * ARGUMENTS:
- *         parent = directory to add in
- *         name = Name to give the entry
- *         Object = Header of the object to add the entry for
- */
-{
-   DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer,
-         Object->Name.Buffer);
-   
-   /*
-    * Insert ourselves in our parents list
-    */
-   InsertTailList(&parent->head,&Object->Entry);
-}
-
-NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,
-                        PWSTR* UnparsedSection)
-/*
- * FUNCTION: Lookup an object within the system namespc
- * ARGUMENTS:
- *         root = Directory to start lookup from
- *         _string = Pathname to lookup
- * RETURNS: On success a pointer to the object body
- *          On failure NULL
- */
+NTSTATUS STDCALL
+ObpParseDirectory(PVOID Object,
+                 PVOID * NextObject,
+                 PUNICODE_STRING FullPath,
+                 PWSTR * Path,
+                 POBJECT_TYPE ObjectType,
+                 ULONG Attributes)
 {
-   PWSTR current;
-   PWSTR next;
-   PDIRECTORY_OBJECT current_dir = NULL;
-   NTSTATUS Status;
+   PWSTR end;
+   PVOID FoundObject;
    
-   DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, "
-         "UnparsedSection %x)\n",rootdir,string,string,Object,
-         UnparsedSection);
-                         
+   DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
+         Object,Path,*Path);
    
-   *UnparsedSection = NULL;
-   *Object = NULL;
+   *NextObject = NULL;
    
-   if (rootdir==NULL)
+   if ((*Path) == NULL)
      {
-       current_dir = HEADER_TO_BODY(&(namespc_root.hdr));
+       return STATUS_UNSUCCESSFUL;
      }
-   else
-     {
-       ObReferenceObjectByHandle(rootdir,DIRECTORY_TRAVERSE,NULL,
-                                 UserMode,(PVOID*)&current_dir,NULL);
-     }
-  
-   /*
-    * Bit of a hack this
-    */
-   if (string[0]==0)
-   {
-      *Object=current_dir;
-      return(STATUS_SUCCESS);
-   }
-
-   if (string[0]!='\\')
+   
+   end = wcschr((*Path)+1, '\\');
+   if (end != NULL)
      {
-        DbgPrint("(%s:%d) Non absolute pathname passed to %s\n",__FILE__,
-               __LINE__,__FUNCTION__);
-       return(STATUS_UNSUCCESSFUL);
+       *end = 0;
      }
-      
-   next = &string[0];
-   current = next+1;
    
-   while (next!=NULL && 
-         BODY_TO_HEADER(current_dir)->ObjectType==ObDirectoryType)
-     {         
-       *next = '\\';
-       current = next+1;
-       next = wcschr(next+1,'\\');
-       if (next!=NULL)
-         {
-            *next=0;
-         }
-
-       DPRINT("current %w current[5] %x next %x ",current,current[5],next);
-       if (next!=NULL)
-         {
-            DPRINT("(next+1) %w",next+1);
-         }
-       DPRINT("\n",0);
-       
-       current_dir=(PDIRECTORY_OBJECT)ObDirLookup(current_dir,current);
-       if (current_dir==NULL)
-         {
-             DbgPrint("(%s:%d) Path component not found\n",__FILE__,
-                    __LINE__);
-            return(STATUS_UNSUCCESSFUL);                    
-         }
-       
-       if (BODY_TO_HEADER(current_dir)->ObjectType==IoSymbolicLinkType)
+   FoundObject = ObpFindEntryDirectory(Object, (*Path)+1, Attributes);
+   
+   if (FoundObject == NULL)
+     {
+       if (end != NULL)
          {
-            current_dir = IoOpenSymlink(current_dir);     
+            *end = '\\';
          }
-       
+       return STATUS_UNSUCCESSFUL;
      }
-   DPRINT("next %x\n",next);
-   DPRINT("current %x current %w\n",current,current);
-   if (next==NULL)
+   
+   ObReferenceObjectByPointer(FoundObject,
+                             STANDARD_RIGHTS_REQUIRED,
+                             NULL,
+                             UserMode);
+   
+   if (end != NULL)
      {
-       if (current_dir==NULL)
-         {
-            Status = STATUS_UNSUCCESSFUL;
-         }
-       else
-         {
-            Status = STATUS_SUCCESS;
-         }
+       *end = '\\';
+       *Path = end;
      }
    else
      {
-       CHECKPOINT;
-       *next = '\\';
-       *UnparsedSection = next;
-       if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType)
-         {
-            Status = STATUS_FS_QUERY_REQUIRED;
-         }
-       else
-         {
-            Status = STATUS_UNSUCCESSFUL;
-         }     
+       *Path = NULL;
      }
-   CHECKPOINT;
-   *Object = current_dir;
    
-   return(Status);
+   *NextObject = FoundObject;
+   
+   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
+ObInit(VOID)
+/*
+ * FUNCTION: Initialize the object manager namespace
+ */
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING Name;
+
+  /* create 'directory' object type */
+  ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+  
+  ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
+  ObDirectoryType->TotalObjects = 0;
+  ObDirectoryType->TotalHandles = 0;
+  ObDirectoryType->MaxObjects = ULONG_MAX;
+  ObDirectoryType->MaxHandles = ULONG_MAX;
+  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->MaxObjects = ULONG_MAX;
+  ObTypeObjectType->MaxHandles = ULONG_MAX;
+  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 root directory */
+  ObCreateObject(NULL,
+                STANDARD_RIGHTS_REQUIRED,
+                NULL,
+                ObDirectoryType,
+                (PVOID*)&NameSpaceRoot);
+
+  /* create '\ObjectTypes' directory */
+  RtlInitUnicodeString(&Name,
+                      L"\\ObjectTypes");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &Name,
+                            OBJ_PERMANENT,
+                            NULL,
+                            NULL);
+  ObCreateObject(NULL,
+                STANDARD_RIGHTS_REQUIRED,
+                &ObjectAttributes,
+                ObDirectoryType,
+                NULL);
+
+  ObpCreateTypeObject(ObDirectoryType);
+  ObpCreateTypeObject(ObTypeObjectType);
+}
+
+
+NTSTATUS
+ObpCreateTypeObject(POBJECT_TYPE ObjectType)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  WCHAR NameString[120];
+  PTYPE_OBJECT TypeObject = NULL;
+  UNICODE_STRING Name;
+  NTSTATUS Status;
+
+  DPRINT("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(NULL,
+                         STANDARD_RIGHTS_REQUIRED,
+                         &ObjectAttributes,
+                         ObTypeObjectType,
+                         (PVOID*)&TypeObject);
+  if (NT_SUCCESS(Status))
+    {
+      TypeObject->ObjectType = ObjectType;
+    }
+
+  return(STATUS_SUCCESS);
 }
+
+
+/* EOF */