Object Manager Patch. This patch continues the work done in the previous patch and makes the following changes in order to support OB 2.0 (it basically temporarily fixes a highly incorrect implementation so that caller code will be ready to work with the OB 2.0 without change):

1) The documented Object Create Information Structure and semantics implemented. All Object Attributes and passed data from user-mode is now probed and saved into this object create structure when ObCreateObject is called.
2) ObCreateObject does NOT PERFORM ANY OTHER OPERATION EXCEPT CREATING THE OBJECT ANYMORE. ObCreateObject will NOT insert the Object into the tree and other operations. These are now done correctly by ObInsertObject. Therefore, the biggest hurdle was changing pieces of code which assumed ObCreateObject would be enough.
3) ObInsertObject uses the captured create info for all operations isntead of the Object Attributes.
4) ObFindObject now uses the captured info as well.
5) The OBject name and directory are now stored in the documented Object Name Information, always allocated and freed from non paged pool.

HACKS:
5) Because the registry code is horribly broken and doesn't use ObFindObjectByName, the old ObFindObject had to be temporarily duplicated into CmpFindObject.
7) Win32k used ObInsertObject in CsrInsertObject as a way to create a handle inside csrss. However, OBInsertObject now does more then this. As a temporary hack, ObpCreateHandle is exported from the kernel and called from win32k. A fix needs to be done for this, but I don't know the design of win32k+csrss well enough to find a solution.
8) SEH has been commented out in some places of the new probing code because it breaks smss and explorer. These need to be investigated (seh did not exist in the previous code, so this is not really a hack)
9) Named objects with a parent directory are NOT allowed. However because of bugs in kernel32, the new check has been temporarily disabled. (this check did not exist in the previous code, so this is not really a hack)

The next patch will add a proper ObFindObject which will support a more complete Parse Procedure with context and security information. This is needed for proper registry access (requested by Eric Kohl) and for proper functionality of the Desktop/File creation, which should use the Parse routine, and not the Create Handle Routine. This will also make it possible to remove some previous hacks and pave the way for a fixed Iop/IoCreateFile
Modified: trunk/reactos/include/ddk/obfuncs.h
Modified: trunk/reactos/ntoskrnl/cm/cm.h
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/cm/registry.c
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/io/driver.c
Modified: trunk/reactos/ntoskrnl/io/file.c
Modified: trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/ob/ntobj.c
Modified: trunk/reactos/ntoskrnl/ob/object.c
Modified: trunk/reactos/ntoskrnl/rtl/nls.c
Modified: trunk/reactos/ntoskrnl/se/sd.c
Modified: trunk/reactos/ntoskrnl/se/semgr.c
Modified: trunk/reactos/ntoskrnl/se/token.c
Modified: trunk/reactos/subsys/system/services/database.c
Modified: trunk/reactos/subsys/win32k/ntuser/csr.c
Modified: trunk/reactos/w32api/include/ddk/winddk.h

Modified: trunk/reactos/include/ddk/obfuncs.h
--- trunk/reactos/include/ddk/obfuncs.h	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/include/ddk/obfuncs.h	2005-05-18 19:26:47 UTC (rev 15395)
@@ -63,6 +63,15 @@
                         PSECURITY_DESCRIPTOR SecurityDescriptor,
                         PULONG BufferLength);
 
+typedef struct _OBJECT_HEADER_NAME_INFO
+{
+    struct _DIRECTORY_OBJECT *Directory;
+    UNICODE_STRING Name;
+    ULONG QueryReferences;
+    ULONG Reserved2;
+    ULONG DbgReferenceCount;
+} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
+
 typedef struct _OBJECT_CREATE_INFORMATION 
 {
     ULONG Attributes;

Modified: trunk/reactos/ntoskrnl/cm/cm.h
--- trunk/reactos/ntoskrnl/cm/cm.h	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/cm/cm.h	2005-05-18 19:26:47 UTC (rev 15395)
@@ -744,4 +744,11 @@
 CmiSaveTempHive (PREGISTRY_HIVE Hive,
 		 HANDLE FileHandle);
 
+/* TEMPORARY HACK UNTIL PROPER PARSE ROUTINES SOON. DO NOT REMOVE -- Alex */         
+NTSTATUS
+CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+	     PVOID* ReturnedObject,
+	     PUNICODE_STRING RemainingPath,
+	     POBJECT_TYPE ObjectType);
+
 #endif /*__INCLUDE_CM_H*/

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -30,6 +30,138 @@
 
 /* FUNCTIONS ****************************************************************/
 
+/* TEMPORARY HACK UNTIL PROPER PARSE ROUTINES SOON. DO NOT REMOVE -- Alex */
+NTSTATUS
+CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+	     PVOID* ReturnedObject,
+	     PUNICODE_STRING RemainingPath,
+	     POBJECT_TYPE ObjectType)
+{
+  PVOID NextObject;
+  PVOID CurrentObject;
+  PVOID RootObject;
+  POBJECT_HEADER CurrentHeader;
+  NTSTATUS Status;
+  PWSTR current;
+  UNICODE_STRING PathString;
+  ULONG Attributes;
+  PUNICODE_STRING ObjectName;
+
+  PAGED_CODE();
+
+  DPRINT("CmpFindObject(ObjectAttributes %x, ReturnedObject %x, "
+	 "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
+  DPRINT("ObjectAttributes->ObjectName %wZ\n",
+	 ObjectAttributes->ObjectName);
+
+  RtlInitUnicodeString (RemainingPath, NULL);
+
+  if (ObjectAttributes->RootDirectory == NULL)
+    {
+      ObReferenceObjectByPointer(NameSpaceRoot,
+				 DIRECTORY_TRAVERSE,
+				 NULL,
+				 UserMode);
+      CurrentObject = NameSpaceRoot;
+    }
+  else
+    {
+      Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
+					 0,
+					 NULL,
+					 UserMode,
+					 &CurrentObject,
+					 NULL);
+      if (!NT_SUCCESS(Status))
+	{
+	  return Status;
+	}
+    }
+
+  ObjectName = ObjectAttributes->ObjectName;
+  if (ObjectName->Length == 0 ||
+      ObjectName->Buffer[0] == UNICODE_NULL)
+    {
+      *ReturnedObject = CurrentObject;
+      return STATUS_SUCCESS;
+    }
+
+  if (ObjectAttributes->RootDirectory == NULL &&
+      ObjectName->Buffer[0] != L'\\')
+    {
+      ObDereferenceObject (CurrentObject);
+      return STATUS_UNSUCCESSFUL;
+    }
+
+  /* Create a zero-terminated copy of the object name */
+  PathString.Length = ObjectName->Length;
+  PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
+  PathString.Buffer = ExAllocatePool (NonPagedPool,
+				      PathString.MaximumLength);
+  if (PathString.Buffer == NULL)
+    {
+      ObDereferenceObject (CurrentObject);
+      return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+  RtlCopyMemory (PathString.Buffer,
+		 ObjectName->Buffer,
+		 ObjectName->Length);
+  PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+  current = PathString.Buffer;
+
+  RootObject = CurrentObject;
+  Attributes = ObjectAttributes->Attributes;
+  if (ObjectType == ObSymbolicLinkType)
+    Attributes |= OBJ_OPENLINK;
+
+  while (TRUE)
+    {
+	DPRINT("current %S\n",current);
+	CurrentHeader = BODY_TO_HEADER(CurrentObject);
+
+	DPRINT("Current ObjectType %wZ\n",
+	       &CurrentHeader->ObjectType->TypeName);
+
+	if (CurrentHeader->ObjectType->TypeInfo.ParseProcedure == NULL)
+	  {
+	     DPRINT("Current object can't parse\n");
+	     break;
+	  }
+	Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject,
+						  &NextObject,
+						  &PathString,
+						  &current,
+						  Attributes);
+	if (Status == STATUS_REPARSE)
+	  {
+	     /* reparse the object path */
+	     NextObject = NameSpaceRoot;
+	     current = PathString.Buffer;
+
+	     ObReferenceObjectByPointer(NextObject,
+					DIRECTORY_TRAVERSE,
+					NULL,
+					UserMode);
+	  }
+
+	if (NextObject == NULL)
+	  {
+	     break;
+	  }
+	ObDereferenceObject(CurrentObject);
+	CurrentObject = NextObject;
+    }
+
+  if (current)
+     RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
+  RtlFreeUnicodeString (&PathString);
+  *ReturnedObject = CurrentObject;
+
+  return STATUS_SUCCESS;
+}
+
 /*
  * @implemented
  */
@@ -199,13 +331,13 @@
 	 KeyHandle,
 	 ObjectAttributes->RootDirectory);
 
-  Status = ObFindObject(ObjectAttributes,
+  Status = CmpFindObject(ObjectAttributes,
 			&Object,
 			&RemainingPath,
 			CmiKeyType);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT("ObFindObject failed, Status: 0x%x\n", Status);
+      DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
       return(Status);
     }
 
@@ -379,7 +511,7 @@
 
   PAGED_CODE();
 
-  DPRINT1("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
+  DPRINT("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
 
   PreviousMode = ExGetPreviousMode();
 
@@ -418,7 +550,7 @@
   ExReleaseResourceLite(&CmiRegistryLock);
   KeLeaveCriticalRegion();
 
-  DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
+  DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
 
   /* Dereference the object */
   ObDereferenceObject(KeyObject);
@@ -1146,14 +1278,14 @@
 	  return(STATUS_BUFFER_OVERFLOW);*/
 
   RemainingPath.Buffer = NULL;
-  Status = ObFindObject(ObjectAttributes,
+  Status = CmpFindObject(ObjectAttributes,
 			&Object,
 			&RemainingPath,
 			CmiKeyType);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT("ObFindObject() returned 0x%08lx\n", Status);
-	  Status = STATUS_INVALID_HANDLE; /* Because ObFindObject returns STATUS_UNSUCCESSFUL */
+      DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
+	  Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject returns STATUS_UNSUCCESSFUL */
 	  hKey = *KeyHandle; /* Preserve hkResult value */
 	  goto openkey_cleanup;
     }

Modified: trunk/reactos/ntoskrnl/cm/registry.c
--- trunk/reactos/ntoskrnl/cm/registry.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/cm/registry.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -702,7 +702,7 @@
   DPRINT("CmiConnectHive(%p, %p) called.\n",
 	 KeyObjectAttributes, RegistryHive);
 
-  Status = ObFindObject(KeyObjectAttributes,
+  Status = CmpFindObject(KeyObjectAttributes,
 			(PVOID*)&ParentKey,
 			&RemainingPath,
 			CmiKeyType);
@@ -746,6 +746,7 @@
 			  0,
 			  0,
 			  (PVOID*)&NewKey);
+                            
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
@@ -753,7 +754,14 @@
       RtlFreeUnicodeString(&RemainingPath);
       return Status;
     }
-
+    DPRINT("Inserting Key into Object Tree\n");
+    Status =  ObInsertObject((PVOID)NewKey,
+                             NULL,
+                             KEY_ALL_ACCESS,
+                             0,
+                             NULL,
+                             NULL);
+DPRINT("Status %x\n", Status);
   NewKey->RegistryHive = RegistryHive;
   NewKey->KeyCellOffset = RegistryHive->HiveHeader->RootKeyOffset;
   NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset, NULL);

Modified: trunk/reactos/ntoskrnl/cm/regobj.c
--- trunk/reactos/ntoskrnl/cm/regobj.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/cm/regobj.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -176,6 +176,15 @@
 	  RtlFreeUnicodeString(&KeyName);
 	  return(Status);
 	}
+    DPRINT("Inserting Key into Object Tree\n");
+    Status =  ObInsertObject((PVOID)FoundObject,
+                             NULL,
+                             KEY_ALL_ACCESS,
+                             0,
+                             NULL,
+                             NULL);
+    DPRINT("Status %x\n", Status);
+
       /* Add the keep-alive reference */
       ObReferenceObject(FoundObject);
 
@@ -503,7 +512,7 @@
   else
     {
       /* KeyObject is the root key */
-      Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->Parent,
+      Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->NameInfo->Directory,
 				  LocalInfo,
 				  MAX_PATH * sizeof(WCHAR),
 				  &LocalReturnLength);

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/include/internal/io.h	2005-05-18 19:26:47 UTC (rev 15395)
@@ -385,11 +385,6 @@
    PVOID* SystemArgument2);
 
 NTSTATUS STDCALL
-IopCreateFile(PVOID ObjectBody,
-	      PVOID Parent,
-	      PWSTR RemainingPath,
-	      POBJECT_ATTRIBUTES ObjectAttributes);
-NTSTATUS STDCALL
 IopCreateDevice(PVOID ObjectBody,
 		PVOID Parent,
 		PWSTR RemainingPath,
@@ -553,7 +548,7 @@
 IopCreateFile(PVOID ObjectBody,
               PVOID Parent,
               PWSTR RemainingPath,
-              POBJECT_ATTRIBUTES ObjectAttributes);
+              POBJECT_CREATE_INFORMATION ObjectAttributes);
 
 VOID
 STDCALL

Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
--- trunk/reactos/ntoskrnl/include/internal/ob.h	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h	2005-05-18 19:26:47 UTC (rev 15395)
@@ -29,14 +29,14 @@
  * PURPOSE: Header for every object managed by the object manager
  */
 {
-   UNICODE_STRING Name;
+   POBJECT_HEADER_NAME_INFO NameInfo;
    LIST_ENTRY Entry;
    LONG RefCount;
    LONG HandleCount;
    BOOLEAN Permanent;
    BOOLEAN Inherit;
-   struct _DIRECTORY_OBJECT* Parent;
    POBJECT_TYPE ObjectType;
+   POBJECT_CREATE_INFORMATION ObjectCreateInfo;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
 
    /*
@@ -133,7 +133,8 @@
 VOID ObCreateHandleTable(struct _EPROCESS* Parent,
 			 BOOLEAN Inherit,
 			 struct _EPROCESS* Process);
-NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+NTSTATUS ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+            PUNICODE_STRING ObjectName,
 		      PVOID* ReturnedObject,
 		      PUNICODE_STRING RemainingPath,
 		      POBJECT_TYPE ObjectType);
@@ -148,7 +149,7 @@
 
 NTSTATUS
 STDCALL
-ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, 
+ObpCreateTypeObject(struct _OBJECT_TYPE_INITIALIZER *ObjectTypeInitializer, 
                     PUNICODE_STRING TypeName, 
                     POBJECT_TYPE *ObjectType);
 
@@ -224,18 +225,22 @@
 } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
 
 NTSTATUS
-ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+STDCALL
+ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
+                     IN PUNICODE_STRING ObjectName,
+                     IN KPROCESSOR_MODE AccessMode);
+                     
+NTSTATUS
+STDCALL
+ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
                            IN KPROCESSOR_MODE AccessMode,
-                           IN POOL_TYPE PoolType,
-                           IN BOOLEAN CaptureIfKernel,
-                           OUT PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes  OPTIONAL,
-                           OUT PUNICODE_STRING ObjectName  OPTIONAL);
+                           IN POBJECT_TYPE ObjectType,
+                           IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+                           OUT PUNICODE_STRING ObjectName);
 
 VOID
-ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes  OPTIONAL,
-                           IN PUNICODE_STRING ObjectName  OPTIONAL,
-                           IN KPROCESSOR_MODE AccessMode,
-                           IN BOOLEAN CaptureIfKernel);
+STDCALL
+ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo);
 
 /* object information classes */
 

Modified: trunk/reactos/ntoskrnl/io/driver.c
--- trunk/reactos/ntoskrnl/io/driver.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/io/driver.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -218,6 +218,17 @@
    {
       return Status;
    }
+   
+   Status = ObInsertObject(Object,
+                           NULL,
+                           FILE_ALL_ACCESS,
+                           0,
+                           NULL,
+                           NULL);
+   if (!NT_SUCCESS(Status))
+   {
+      return Status;
+   }  
 
    if (Status == STATUS_OBJECT_EXISTS)
    {

Modified: trunk/reactos/ntoskrnl/io/file.c
--- trunk/reactos/ntoskrnl/io/file.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/io/file.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -47,7 +47,7 @@
 IopCreateFile(PVOID ObjectBody,
               PVOID Parent,
               PWSTR RemainingPath,
-              POBJECT_ATTRIBUTES ObjectAttributes)
+              POBJECT_CREATE_INFORMATION ObjectCreateInfo)
 {
   PDEVICE_OBJECT DeviceObject;
   PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
@@ -73,8 +73,8 @@
       ParentObjectType != IoFileObjectType)
     {
       DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n",
-        &BODY_TO_HEADER(Parent)->Name,
-        BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer,
+        &BODY_TO_HEADER(Parent)->NameInfo->Name,
+        BODY_TO_HEADER(Parent)->ObjectType->Name.Buffer,
         RemainingPath);
       return(STATUS_UNSUCCESSFUL);
     }
@@ -852,6 +852,7 @@
    if (CreateDisposition == FILE_OPEN ||
        CreateDisposition == FILE_OPEN_IF)
    {
+
       Status = ObOpenObjectByName(ObjectAttributes,
                            NULL,
       NULL,
@@ -859,6 +860,7 @@
       DesiredAccess,
       NULL,
       &LocalHandle);
+
       if (NT_SUCCESS(Status))
       {
          Status = ObReferenceObjectByHandle(LocalHandle,
@@ -1012,7 +1014,7 @@
     */
    Status = IofCallDriver(FileObject->DeviceObject, Irp );
    DPRINT("Status :%x\n", Status);
-
+   
    if (Status == STATUS_PENDING)
      {
  KeWaitForSingleObject(&FileObject->Event,

Modified: trunk/reactos/ntoskrnl/mm/section.c
--- trunk/reactos/ntoskrnl/mm/section.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/mm/section.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -2099,6 +2099,16 @@
       DbgPrint("Failed to create PhysicalMemory section\n");
       KEBUGCHECK(0);
    }
+   Status = ObInsertObject(PhysSection,
+                           NULL,
+                           SECTION_ALL_ACCESS,
+                           0,
+                           NULL,
+                           NULL);
+   if (!NT_SUCCESS(Status))
+   {
+      ObDereferenceObject(PhysSection);
+   }
    PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY;
 
    return(STATUS_SUCCESS);
@@ -2239,7 +2249,6 @@
    {
       return(Status);
    }
-
    /*
     * Initialize it
     */
@@ -3140,6 +3149,7 @@
                                       UserMode,
                                       (PVOID*)(PVOID)&FileObject,
                                       NULL);
+
    if (!NT_SUCCESS(Status))
    {
       return Status;

Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
--- trunk/reactos/ntoskrnl/ntoskrnl.def	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/ntoskrnl.def	2005-05-18 19:26:47 UTC (rev 15395)
@@ -823,6 +823,7 @@
 ;ObCheckCreateObjectAccess@28
 ;ObCheckObjectAccess@20
 ObCreateObject@36
+ObpCreateHandle ; FIXME! See win32k/ntuser/csr.c!
 ObFindHandleForObject@20
 ObGetObjectPointerCount@4
 ObGetObjectSecurity@12

Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
--- trunk/reactos/ntoskrnl/ob/dirobj.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/ob/dirobj.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -253,7 +253,7 @@
           EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, Entry);
 
           /* calculate the size of the required buffer space for this entry */
-          Name = (EntryHeader->Name.Length != 0 ? &EntryHeader->Name : NULL);
+          Name = (EntryHeader->NameInfo->Name.Length != 0 ? &EntryHeader->NameInfo->Name : NULL);
           Type = &EntryHeader->ObjectType->Name;
           EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
                       ((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) +
@@ -440,8 +440,8 @@
   PAGED_CODE();
 
   DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
-	 "DesiredAccess %x, ObjectAttributes %x\n",
-	 DirectoryHandle, DesiredAccess, ObjectAttributes);
+         "DesiredAccess %x, ObjectAttributes %x\n",
+          DirectoryHandle, DesiredAccess, ObjectAttributes);
 
   PreviousMode = ExGetPreviousMode();
 

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -46,6 +46,14 @@
 
 PHANDLE_TABLE ObpKernelHandleTable = NULL;
 
+/* TEMPORARY HACK. DO NOT REMOVE -- Alex */
+NTSTATUS
+STDCALL
+ExpDesktopCreate(PVOID ObjectBody,
+                 PVOID Parent,
+                 PWSTR RemainingPath,
+                 POBJECT_CREATE_INFORMATION ObjectCreateInformation);
+
 /* FUNCTIONS ***************************************************************/
 
 static VOID
@@ -64,7 +72,7 @@
 
   if(NewHandleCount == 0)
   {
-    if(ObjectHeader->Parent != NULL && !ObjectHeader->Permanent)
+    if(ObjectHeader->NameInfo->Directory != NULL && !ObjectHeader->Permanent)
     {
       /* delete the object from the namespace when the last handle got closed.
          Only do this if it's actually been inserted into the namespace and
@@ -925,27 +933,221 @@
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 ObInsertObject(IN PVOID Object,
-	       IN PACCESS_STATE PassedAccessState OPTIONAL,
-	       IN ACCESS_MASK DesiredAccess,
-	       IN ULONG AdditionalReferences,
-	       OUT PVOID* ReferencedObject OPTIONAL,
-	       OUT PHANDLE Handle)
+               IN PACCESS_STATE PassedAccessState OPTIONAL,
+               IN ACCESS_MASK DesiredAccess,
+               IN ULONG AdditionalReferences,
+               OUT PVOID* ReferencedObject OPTIONAL,
+               OUT PHANDLE Handle)
 {
-  POBJECT_HEADER ObjectHeader;
-  ACCESS_MASK Access;
+    POBJECT_CREATE_INFORMATION ObjectCreateInfo;
+    POBJECT_HEADER Header;
+    POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+    PVOID FoundObject = NULL;
+    POBJECT_HEADER FoundHeader = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
+    UNICODE_STRING RemainingPath;
+    BOOLEAN ObjectAttached = FALSE; 
+    PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
+    SECURITY_SUBJECT_CONTEXT SubjectContext;
 
-  PAGED_CODE();
+    PAGED_CODE();
+    
+    /* Get the Header and Create Info */
+    DPRINT("ObInsertObject: %x\n", Object);
+    Header = BODY_TO_HEADER(Object);
+    ObjectCreateInfo = Header->ObjectCreateInfo;
+    ObjectNameInfo = Header->NameInfo;
+    
+    /* First try to find the Object */
+    if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
+    {
+        DPRINT("Object has a name. Trying to find it: %wZ.\n", &ObjectNameInfo->Name);
+        Status = ObFindObject(ObjectCreateInfo,
+                              &ObjectNameInfo->Name,
+                              &FoundObject,
+                              &RemainingPath,
+                              NULL);
+        DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
+            return Status;
+        }
+        
+        if (FoundObject)
+        {
+            DPRINT("Getting header: %x\n", FoundObject);
+            FoundHeader = BODY_TO_HEADER(FoundObject);
+        }
+        
+        if (FoundHeader && RemainingPath.Buffer == NULL)
+        {
+            DPRINT("Object exists\n");
+            if (FoundHeader->ObjectType != Header->ObjectType
+                || !(ObjectCreateInfo->Attributes & OBJ_OPENIF))
+            {
+                ObDereferenceObject(FoundObject);
+                return STATUS_OBJECT_NAME_COLLISION;
+            }
+            return STATUS_OBJECT_EXISTS;
+        }
+    }
+    else
+    {
+        DPRINT("No name, empty remaining path\n");
+        RtlInitUnicodeString(&RemainingPath, NULL);
+    }
 
-  Access = DesiredAccess;
-  ObjectHeader = BODY_TO_HEADER(Object);
+    if (FoundHeader && FoundHeader->ObjectType == ObDirectoryType &&
+        RemainingPath.Buffer)
+    {
+        DPRINT("Adding to Object Directory\n");
+        ObpAddEntryDirectory(FoundObject, Header, NULL);
+        ObjectAttached = TRUE;
+        
+        /* The name was changed so let's update it */
+        /* FIXME: TEMPORARY HACK This will go in ObFindObject in the next commit */
+        PVOID NewName;
+        PWSTR BufferPos = RemainingPath.Buffer;
+        
+        NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength);
+        ObjectNameInfo = Header->NameInfo;
+        
+        if (BufferPos[0] == L'\\')
+        {
+            BufferPos++;
+        }
+        
+        RtlMoveMemory(NewName, BufferPos, RemainingPath.MaximumLength);
+        if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer);
+        ObjectNameInfo->Name.Buffer = NewName;
+        ObjectNameInfo->Name.Length = RemainingPath.Length;
+        ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength;
+        DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
+    }
 
-  return(ObpCreateHandle(PsGetCurrentProcess(),
-			Object,
-			Access,
-			ObjectHeader->Inherit,
-			Handle));
+    if ((Header->ObjectType == IoFileObjectType) ||
+        (Header->ObjectType == ExDesktopObjectType) ||
+        (Header->ObjectType->TypeInfo.OpenProcedure != NULL))
+    {    
+        DPRINT("About to call Open Routine\n");
+        if (Header->ObjectType == IoFileObjectType)
+        {
+            /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
+            DPRINT("Calling IopCreateFile: %x\n", FoundObject);
+            Status = IopCreateFile(HEADER_TO_BODY(Header),
+                                   FoundObject,
+                                   RemainingPath.Buffer,            
+                                   ObjectCreateInfo);
+            DPRINT("Called IopCreateFile: %x\n", Status);
+                                   
+        }
+        else if (Header->ObjectType == ExDesktopObjectType)
+        {
+            /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
+            DPRINT("Calling ExpDesktopCreate\n");
+            Status = ExpDesktopCreate(HEADER_TO_BODY(Header),
+                                      FoundObject,
+                                      RemainingPath.Buffer,            
+                                      ObjectCreateInfo);
+        }
+        else if (Header->ObjectType->TypeInfo.OpenProcedure != NULL)
+        {
+            DPRINT("Calling %x\n", Header->ObjectType->TypeInfo.OpenProcedure);
+            Status = Header->ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
+                                                                HEADER_TO_BODY(Header),
+                                                                NULL,
+                                                                0,
+                                                                0);
+        }
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("Create Failed\n");
+            if (ObjectAttached == TRUE)
+            {
+                ObpRemoveEntryDirectory(Header);
+            }
+            if (FoundObject)
+            {
+                ObDereferenceObject(FoundObject);
+            }
+            RtlFreeUnicodeString(&RemainingPath);
+            return Status;
+        }
+    }
+
+    RtlFreeUnicodeString(&RemainingPath);
+  
+    DPRINT("Security Assignment in progress\n");  
+    SeCaptureSubjectContext(&SubjectContext);
+
+    /* Build the new security descriptor */
+    Status = SeAssignSecurity((FoundHeader != NULL) ? FoundHeader->SecurityDescriptor : NULL,
+			    (ObjectCreateInfo != NULL) ? ObjectCreateInfo->SecurityDescriptor : NULL,
+			    &NewSecurityDescriptor,
+			    (Header->ObjectType == ObDirectoryType),
+			    &SubjectContext,
+			    &Header->ObjectType->TypeInfo.GenericMapping,
+			    PagedPool);
+
+    if (NT_SUCCESS(Status))
+    {
+        DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
+
+        if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL)
+        {
+            /* Call the security method */
+            Status = Header->ObjectType->TypeInfo.SecurityProcedure(HEADER_TO_BODY(Header),
+                                                                    AssignSecurityDescriptor,
+                                                                    0,
+                                                                    NewSecurityDescriptor,
+                                                                    NULL);
+        }
+        else
+        {
+            /* Assign the security descriptor to the object header */
+            Status = ObpAddSecurityDescriptor(NewSecurityDescriptor,
+                                              &Header->SecurityDescriptor);
+            DPRINT("Object security descriptor %p\n", Header->SecurityDescriptor);
+        }
+
+        /* Release the new security descriptor */
+        SeDeassignSecurity(&NewSecurityDescriptor);
+    }
+
+    DPRINT("Security Complete\n");
+    SeReleaseSubjectContext(&SubjectContext);
+
+    /* We can delete the Create Info now */
+    Header->ObjectCreateInfo = NULL;
+    ObpReleaseCapturedAttributes(ObjectCreateInfo);
+    ExFreePool(ObjectCreateInfo);
+    
+    /* Create the Handle */
+    /* HACKHACK: Because of ROS's incorrect startup, this can be called
+     * without a valid Process until I finalize the startup patch,
+     * so don't create a handle if this is the case. We also don't create
+     * a handle if Handle is NULL when the Registry Code calls it, because
+     * the registry code totally bastardizes the Ob and needs to be fixed
+     */
+    DPRINT("Creating handle\n");
+    if (Handle != NULL)
+    {
+        Status = ObpCreateHandle(PsGetCurrentProcess(),
+                                 HEADER_TO_BODY(Header),
+                                 DesiredAccess,
+                                 Header->Inherit,
+                                 Handle);
+        DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
+                 *Handle, Header->RefCount, Header->HandleCount);
+    }
+    
+    DPRINT("Status %x\n", Status);
+    return Status;
 }
 
 

Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c	2005-05-18 19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/ob/namespc.c	2005-05-18 19:26:47 UTC (rev 15395)
@@ -40,7 +40,8 @@
 
 NTSTATUS
 STDCALL
-ObpAllocateObject(POBJECT_ATTRIBUTES ObjectAttributes,
+ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+                  PUNICODE_STRING ObjectName,
                   POBJECT_TYPE ObjectType,
                   ULONG ObjectSize,
                   POBJECT_HEADER *ObjectHeader);
@@ -62,7 +63,9 @@
 {
    PVOID Object = NULL;
    UNICODE_STRING RemainingPath;
+   UNICODE_STRING ObjectName;
    OBJECT_ATTRIBUTES ObjectAttributes;
+   OBJECT_CREATE_INFORMATION ObjectCreateInfo;
    NTSTATUS Status;
 
    PAGED_CODE();
@@ -72,10 +75,26 @@
 			      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);
+
    if (!NT_SUCCESS(Status))
      {
 	return(Status);
@@ -136,13 +155,29 @@
 {
    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);
@@ -152,9 +187,12 @@
 	return Status;
      }
 
+    DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
    if (Object == NULL)
      {
        RtlFreeUnicodeString(&RemainingPath);
+       ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+       if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
        return STATUS_UNSUCCESSFUL;
      }
    if (RemainingPath.Buffer != NULL)
@@ -165,9 +203,11 @@
          Status =STATUS_OBJECT_PATH_NOT_FOUND;
       RtlFreeUnicodeString(&RemainingPath);
       ObDereferenceObject(Object);
+      ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+      if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
       return Status;
    }
-
+   
    Status = ObpCreateHandle(PsGetCurrentProcess(),
 			   Object,
 			   DesiredAccess,
@@ -176,6 +216,8 @@
 
    ObDereferenceObject(Object);
    RtlFreeUnicodeString(&RemainingPath);
+   ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+   if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
 
    return Status;
 }
@@ -217,8 +259,7 @@
 {
   KIRQL oldlvl;
 
-  RtlpCreateUnicodeString(&Header->Name, Name, NonPagedPool);
-  Header->Parent = Parent;
+  Header->NameInfo->Directory = Parent;
 
   KeAcquireSpinLock(&Parent->Lock, &oldlvl);
   InsertTailList(&Parent->head, &Header->Entry);
@@ -238,13 +279,13 @@
 
   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
@@ -286,15 +327,15 @@
      }
    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));
@@ -302,7 +343,7 @@
 	  }
 	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));
@@ -389,7 +430,7 @@
     ObpInitSdCache();
 
     /* Create the Type Type */
-    DPRINT1("Creating Type Type\n");
+    DPRINT("Creating Type Type\n");
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Type");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
@@ -402,7 +443,7 @@
     ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
   
     /* Create the Directory Type */
-    DPRINT1("Creating Directory Type\n");
+    DPRINT("Creating Directory Type\n");
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Directory");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
@@ -430,7 +471,7 @@
                                  FALSE);
 
     /* Create root directory */
-    DPRINT1("Creating Root Directory\n");    
+    DPRINT("Creating Root Directory\n");    
[truncated at 1000 lines; 1272 more skipped]