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