Fix OB Bug and port ObQueryNameString from my branch so Herve can get back to working on USB. Sorry for taking so long, hpoussin\!
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/object.c

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-06-13 22:27:09 UTC (rev 15902)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-06-14 03:33:21 UTC (rev 15903)
@@ -1022,6 +1022,8 @@
         if (BufferPos[0] == L'\\')
         {
             BufferPos++;
+            RemainingPath.Length -= 2;
+            RemainingPath.MaximumLength -= 2;
         }
         
         RtlMoveMemory(NewName, BufferPos, RemainingPath.MaximumLength);

Modified: trunk/reactos/ntoskrnl/ob/object.c
--- trunk/reactos/ntoskrnl/ob/object.c	2005-06-13 22:27:09 UTC (rev 15902)
+++ trunk/reactos/ntoskrnl/ob/object.c	2005-06-14 03:33:21 UTC (rev 15903)
@@ -15,6 +15,8 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+#define UNICODE_PATH_SEP L'\\'
+#define UNICODE_NO_PATH L"..."
 
 typedef struct _RETENTION_CHECK_PARAMS
 {
@@ -435,109 +437,204 @@
  *
  * @implemented
  */
-NTSTATUS STDCALL
-ObQueryNameString (IN PVOID Object,
-		   OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
-		   IN ULONG Length,
-		   OUT PULONG ReturnLength)
+NTSTATUS 
+STDCALL
+ObQueryNameString(IN  PVOID Object,
+                  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
+                  IN  ULONG Length,
+                  OUT PULONG ReturnLength)
 {
-  POBJECT_NAME_INFORMATION LocalInfo;
-  POBJECT_HEADER ObjectHeader;
-  ULONG LocalReturnLength;
-  NTSTATUS Status;
+    POBJECT_HEADER_NAME_INFO LocalInfo;
+    POBJECT_HEADER ObjectHeader;
+    PDIRECTORY_OBJECT ParentDirectory;
+    ULONG NameSize;
+    PWCH ObjectName;
+    NTSTATUS Status;
 
-  PAGED_CODE();
+    DPRINT1("ObQueryNameString: %x, %x\n", Object, ObjectNameInfo);
 
-  *ReturnLength = 0;
+    /* Get the Kernel Meta-Structures */
+    ObjectHeader = BODY_TO_HEADER(Object);
+    LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
+    DPRINT1("LocalInfo %x, Name Buffer %x, Name Size %x\n",
+            LocalInfo, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
 
-  if (Length < sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR))
-    return STATUS_INVALID_BUFFER_SIZE;
+    /* Check if a Query Name Procedure is available */
+    if (ObjectHeader->Type->TypeInfo.QueryNameProcedure) 
+    {  
+        /* Call the procedure */
+        DPRINT1("Calling Object's Procedure\n");
+        Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
+                                                                 ObjectNameInfo,
+                                                                 Length,
+                                                                 ReturnLength);
 
-  ObjectNameInfo->Name.MaximumLength = (USHORT)(Length - sizeof(OBJECT_NAME_INFORMATION));
-  ObjectNameInfo->Name.Length = 0;
-  ObjectNameInfo->Name.Buffer =
-    (PWCHAR)((ULONG_PTR)ObjectNameInfo + sizeof(OBJECT_NAME_INFORMATION));
-  ObjectNameInfo->Name.Buffer[0] = 0;
+        /* Return the status */
+        return Status;
+    }
 
-  ObjectHeader = BODY_TO_HEADER(Object);
+    /* Check if the object doesn't even have a name */
+    if (!LocalInfo || !LocalInfo->Name.Buffer) 
+    {
+        /* We're returning the name structure */
+        DPRINT1("Nameless Object\n");
+        *ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
 
-  if (ObjectHeader->Type != NULL &&
-      ObjectHeader->Type->TypeInfo.QueryNameProcedure != NULL)
-    {
-      DPRINT ("Calling %x\n", ObjectHeader->Type->TypeInfo.QueryNameProcedure);
-      Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure (Object,
-						    ObjectNameInfo,
-						    Length,
-						    ReturnLength);
+        /* Check if we were given enough space */
+        if (*ReturnLength > Length) 
+        {
+            DPRINT1("Not enough buffer space\n");
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+
+        /* Return an empty buffer */
+        ObjectNameInfo->Name.Length = 0;
+        ObjectNameInfo->Name.MaximumLength = 0;
+        ObjectNameInfo->Name.Buffer = NULL;
+
+        return STATUS_SUCCESS;
     }
-  else if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Name.Length > 0 && HEADER_TO_OBJECT_NAME(ObjectHeader)->Name.Buffer != NULL)
+
+    /* 
+     * Find the size needed for the name. We won't do
+     * this during the Name Creation loop because we want
+     * to let the caller know that the buffer isn't big
+     * enough right at the beginning, not work our way through
+     * and find out at the end
+     */
+    if (Object == NameSpaceRoot) 
     {
-      DPRINT ("Object does not have a 'QueryName' function\n");
+        /* Size of the '\' string */
+        DPRINT1("Object is Root\n");
+        NameSize = sizeof(UNICODE_PATH_SEP);
+    } 
+    else 
+    {
+        /* Get the Object Directory and add name of Object */
+        ParentDirectory = LocalInfo->Directory;
+        DPRINT1("LocalInfo->Name.Length %d\n", LocalInfo->Name.Length);
+        DPRINT1("LocalInfo->Name %S\n", LocalInfo->Name.Buffer);
+        NameSize = sizeof(UNICODE_PATH_SEP) + LocalInfo->Name.Length;
+        DPRINT1("Parent: %x, Size: %d\n", ParentDirectory, NameSize);
 
-      if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory == NameSpaceRoot)
-	{
-	  DPRINT ("Reached the root directory\n");
-	  ObjectNameInfo->Name.Length = 0;
-	  ObjectNameInfo->Name.Buffer[0] = 0;
-	  Status = STATUS_SUCCESS;
-	}
-      else if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory != NULL)
-	{
-	  LocalInfo = ExAllocatePool (NonPagedPool,
-				      sizeof(OBJECT_NAME_INFORMATION) +
-				      MAX_PATH * sizeof(WCHAR));
-	  if (LocalInfo == NULL)
-	    return STATUS_INSUFFICIENT_RESOURCES;
+        /* Loop inside the directory to get the top-most one (meaning root) */
+        while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory)) 
+        {
+            /* Get the Name Information */
+            LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
+            DPRINT1("LocalInfo %x, Name Buffer %x, Name Size %x\n",
+                    LocalInfo, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
 
-	  Status = ObQueryNameString (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
-				      LocalInfo,
-				      MAX_PATH * sizeof(WCHAR),
-				      &LocalReturnLength);
-	  if (!NT_SUCCESS (Status))
-	    {
-	      ExFreePool (LocalInfo);
-	      return Status;
-	    }
+            /* Add the size of the Directory Name */
+            if (LocalInfo && LocalInfo->Directory) 
+            {
+                /* Size of the '\' string + Directory Name */
+                NameSize += sizeof(UNICODE_PATH_SEP) + LocalInfo->Name.Length;
+                DPRINT1("Directory: %x. NameSize: %d\n", ParentDirectory, NameSize);
 
-	  Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
-						   &LocalInfo->Name);
+                /* Move to next parent Directory */
+                ParentDirectory = LocalInfo->Directory;
+            } 
+            else 
+            {
+                /* Directory with no name. We append "...\" */
+                DPRINT1("Nameless Directory\n");
+                NameSize += sizeof(UNICODE_NO_PATH) + sizeof(UNICODE_PATH_SEP);
+                break;
+            }
+        }
+    }
 
-	  ExFreePool (LocalInfo);
+    /* Finally, add the name of the structure and the null char */
+    *ReturnLength = NameSize + sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
+    DPRINT1("Final Length: %x\n", *ReturnLength);
 
-	  if (!NT_SUCCESS (Status))
-	    return Status;
-	}
+    /* Check if we were given enough space */
+    if (*ReturnLength > Length) 
+    {
+        DPRINT1("Not enough buffer space\n");
+        return STATUS_INFO_LENGTH_MISMATCH;
+    }
 
-      DPRINT ("Object path %wZ\n", &HEADER_TO_OBJECT_NAME(ObjectHeader)->Name);
-      Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
-					 L"\\");
-      if (!NT_SUCCESS (Status))
-	return Status;
+    /* 
+     * Now we will actually create the name. We work backwards because
+     * it's easier to start off from the Name we have and walk up the
+     * parent directories. We use the same logic as Name Length calculation.
+     */
+    LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
+    ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
+    DPRINT1("ObjectName : %x, NameInfo: %x LocalInfo %x\n", ObjectName, ObjectNameInfo, LocalInfo);
+    *--ObjectName = UNICODE_NULL;
 
-      Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
-					       &HEADER_TO_OBJECT_NAME(ObjectHeader)->Name);
-    }
-  else
+    if (Object == NameSpaceRoot) 
     {
-      DPRINT ("Object is unnamed\n");
+        /* This is already the Root Directory, return "\\" */
+        DPRINT1("Returning Root Dir\n");
+        *--ObjectName = UNICODE_PATH_SEP;
+        ObjectNameInfo->Name.Length = (USHORT)NameSize;
+        ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
+        ObjectNameInfo->Name.Buffer = ObjectName;
 
-      ObjectNameInfo->Name.MaximumLength = 0;
-      ObjectNameInfo->Name.Length = 0;
-      ObjectNameInfo->Name.Buffer = NULL;
+        return STATUS_SUCCESS;
+    } 
+    else 
+    {
+        /* Start by adding the Object's Name */
+        DPRINT1("LocalInfo %x, Name Buffer %x, Name Size %d\n",
+                LocalInfo, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
+        DPRINT1("ObjectName: %x, Length %d\n", ObjectName, LocalInfo->Name.Length);
+        ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
+        DPRINT1("ObjectName: %x\n", ObjectName);
+        RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
+        DPRINT1("Current Buffer: %S\n", ObjectName);
+        DPRINT1("Object Name: %S\n", LocalInfo->Name.Buffer);
 
-      Status = STATUS_SUCCESS;
-    }
+        /* Now parse the Parent directories until we reach the top */
+        ParentDirectory = LocalInfo->Directory;
+        DPRINT1("Parent: %x\n", ParentDirectory);
+        while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory)) 
+        {
+            /* Get the name information */
+            LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
+            DPRINT1("Scanning: %x\n", ParentDirectory);
 
-  if (NT_SUCCESS (Status))
-    {
-      ObjectNameInfo->Name.MaximumLength =
-	(ObjectNameInfo->Name.Length) ? ObjectNameInfo->Name.Length + sizeof(WCHAR) : 0;
-      *ReturnLength =
-	sizeof(OBJECT_NAME_INFORMATION) + ObjectNameInfo->Name.MaximumLength;
-      DPRINT ("Returned object path: %wZ\n", &ObjectNameInfo->Name);
+            /* Add the "\" */
+            DPRINT1("ObjectName: %x\n", ObjectName);
+            *(--ObjectName) = UNICODE_PATH_SEP;
+            DPRINT1("Current Buffer: %S\n", ObjectName);
+
+            /* Add the Parent Directory's Name */
+            if (LocalInfo && LocalInfo->Name.Buffer) 
+            {
+                /* Add the name */
+                ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
+                DPRINT1("ObjectName: %x, Length %d\n", ObjectName, LocalInfo->Name.Length);
+                RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
+                DPRINT1("Current Buffer: %S\n", ObjectName);
+
+                /* Move to next parent */
+                ParentDirectory = LocalInfo->Directory;
+            } 
+            else 
+            {
+                /* Directory without a name, we add "..." */
+                DPRINT1("Nameless Directory\n");
+                ObjectName -= sizeof(UNICODE_NO_PATH);
+                ObjectName = UNICODE_NO_PATH;
+                break;
+            }
+        }
+
+        /* Add Root Directory Name */
+        *(--ObjectName) = UNICODE_PATH_SEP;
+        DPRINT1("Current Buffer: %S\n", ObjectName);
+        ObjectNameInfo->Name.Length = (USHORT)NameSize;
+        ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
+        ObjectNameInfo->Name.Buffer = ObjectName;
+        DPRINT1("Complete: %wZ\n", ObjectNameInfo);
     }
 
-  return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS