Preliminary fix for NtQueryObject().

svn path=/trunk/; revision=4808
This commit is contained in:
Eric Kohl 2003-06-01 15:09:34 +00:00
parent 05a9cdcf10
commit 813549499b

View file

@ -1,4 +1,4 @@
/* $Id: ntobj.c,v 1.11 2002/09/08 10:23:39 chorns Exp $ /* $Id: ntobj.c,v 1.12 2003/06/01 15:09:34 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -18,58 +18,66 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* FUNCTIONS ************************************************************/ /* FUNCTIONS ************************************************************/
NTSTATUS /**********************************************************************
STDCALL * NAME EXPORTED
NtSetInformationObject ( * NtSetInformationObject
IN HANDLE ObjectHandle, *
IN CINT ObjectInformationClass, * DESCRIPTION
IN PVOID ObjectInformation, *
IN ULONG Length * ARGUMENTS
) *
* RETURN VALUE
*
* REVISIONS
*/
NTSTATUS STDCALL
NtSetInformationObject (IN HANDLE ObjectHandle,
IN CINT ObjectInformationClass,
IN PVOID ObjectInformation,
IN ULONG Length)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
NTSTATUS NTSTATUS
internalNameBuilder internalNameBuilder(POBJECT_HEADER ObjectHeader,
( PUNICODE_STRING String)
POBJECT_HEADER ObjectHeader,
PUNICODE_STRING string)
/* So, what's the purpose of this function? /* So, what's the purpose of this function?
It will take any OBJECT_HEADER and traverse the Parent structure up to the root It will take any OBJECT_HEADER and traverse the Parent structure up to the root
and form the name, i.e. this will only work on objects where the Parent/Name fields and form the name, i.e. this will only work on objects where the Parent/Name fields
have any meaning (not files) */ have any meaning (not files) */
{ {
NTSTATUS status; NTSTATUS Status;
if (ObjectHeader->Parent)
{ if (ObjectHeader->Parent)
status = internalNameBuilder(BODY_TO_HEADER(ObjectHeader->Parent),string); {
if (status != STATUS_SUCCESS) Status = internalNameBuilder(BODY_TO_HEADER(ObjectHeader->Parent),
{ String);
return status; if (Status != STATUS_SUCCESS)
}
}
if (ObjectHeader->Name.Buffer)
{ {
status = RtlAppendUnicodeToString(string, L"\\"); return Status;
if (status != STATUS_SUCCESS) return status;
return RtlAppendUnicodeStringToString(string, &ObjectHeader->Name);
} }
return STATUS_SUCCESS; }
if (ObjectHeader->Name.Buffer)
{
Status = RtlAppendUnicodeToString(String,
L"\\");
if (Status != STATUS_SUCCESS)
return Status;
return RtlAppendUnicodeStringToString(String,
&ObjectHeader->Name);
}
return STATUS_SUCCESS;
} }
NTSTATUS
STDCALL
NtQueryObject (
IN HANDLE ObjectHandle,
IN CINT ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG Length,
OUT PULONG ResultLength
)
/*Very, very, very new implementation. Test it! /*Very, very, very new implementation. Test it!
Probably we should add meaning to QueryName in POBJECT_TYPE, no matter if we know Probably we should add meaning to QueryName in POBJECT_TYPE, no matter if we know
@ -79,95 +87,181 @@ NtQueryObject (
If we don't do it this way, we should anyway add switches and separate functions to handle If we don't do it this way, we should anyway add switches and separate functions to handle
the different object types*/ the different object types*/
/**********************************************************************
* NAME EXPORTED
* NtQueryObject
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*/
NTSTATUS STDCALL
NtQueryObject (IN HANDLE ObjectHandle,
IN CINT ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG Length,
OUT PULONG ReturnLength)
{ {
POBJECT_NAME_INFORMATION nameinfo; POBJECT_NAME_INFORMATION NameInfo;
POBJECT_TYPE_INFORMATION typeinfo; POBJECT_TYPE_INFORMATION typeinfo;
PFILE_NAME_INFORMATION filenameinfo; PFILE_NAME_INFORMATION filenameinfo;
PVOID Object; PVOID Object;
NTSTATUS Status; NTSTATUS Status;
POBJECT_HEADER ObjectHeader; POBJECT_HEADER ObjectHeader;
PFILE_OBJECT fileob; PFILE_OBJECT fileob;
Status = ObReferenceObjectByHandle(ObjectHandle, Status = ObReferenceObjectByHandle (ObjectHandle,
0, 0,
NULL, NULL,
KernelMode, KeGetPreviousMode(),
&Object, &Object,
NULL); NULL);
if (Status != STATUS_SUCCESS) if (!NT_SUCCESS (Status))
{ {
return Status; return Status;
} }
ObjectHeader = BODY_TO_HEADER(Object); ObjectHeader = BODY_TO_HEADER(Object);
switch (ObjectInformationClass) switch (ObjectInformationClass)
{ {
case ObjectNameInformation: case ObjectNameInformation:
if (Length!=sizeof(OBJECT_NAME_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE; #if 0
nameinfo = (POBJECT_NAME_INFORMATION)ObjectInformation; Status = ObQueryNameString (Object,
(*ResultLength)=Length; (POBJECT_NAME_INFORMATION)ObjectInformation,
Length,
if (ObjectHeader->Type==InternalFileType) // FIXME: Temporary QueryName implementation, or at least separate functions ReturnLength);
{ break;
fileob = (PFILE_OBJECT) Object; #endif
Status = internalNameBuilder(BODY_TO_HEADER(fileob->DeviceObject->Vpb->RealDevice), &nameinfo->Name);
if (Length < sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR))
if (Status != STATUS_SUCCESS) return STATUS_INVALID_BUFFER_SIZE;
{
ObDereferenceObject(Object); NameInfo = (POBJECT_NAME_INFORMATION)ObjectInformation;
return Status; *ReturnLength = 0;
}
filenameinfo = ExAllocatePool(NonPagedPool,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG)); NameInfo->Name.MaximumLength = sizeof(WCHAR);
IoQueryFileInformation(fileob,FileNameInformation,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG), filenameinfo,NULL); NameInfo->Name.Length = 0;
NameInfo->Name.Buffer = (PWCHAR)((ULONG_PTR)NameInfo + sizeof(OBJECT_NAME_INFORMATION));
Status = RtlAppendUnicodeToString(&(nameinfo->Name), filenameinfo->FileName); NameInfo->Name.Buffer[0] = 0;
ExFreePool( filenameinfo); // FIXME: Temporary QueryName implementation, or at least separate functions
ObDereferenceObject(Object); if (ObjectHeader->Type==InternalFileType)
return Status;
}
else
if (ObjectHeader->Name.Buffer) // If it's got a name there, we can probably just make the full path through Name and Parent
{ {
Status = internalNameBuilder(ObjectHeader, &nameinfo->Name); NameInfo->Name.MaximumLength = Length - sizeof(OBJECT_NAME_INFORMATION);
ObDereferenceObject(Object); fileob = (PFILE_OBJECT) Object;
return Status; Status = internalNameBuilder(BODY_TO_HEADER(fileob->DeviceObject->Vpb->RealDevice),
&NameInfo->Name);
if (Status != STATUS_SUCCESS)
{
NameInfo->Name.MaximumLength = 0;
break;
}
filenameinfo = ExAllocatePool (NonPagedPool,
MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
if (filenameinfo == NULL)
{
NameInfo->Name.MaximumLength = 0;
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Status = IoQueryFileInformation (fileob,
FileNameInformation,
MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
filenameinfo,
NULL);
if (Status != STATUS_SUCCESS)
{
NameInfo->Name.MaximumLength = 0;
ExFreePool (filenameinfo);
break;
}
Status = RtlAppendUnicodeToString (&(NameInfo->Name),
filenameinfo->FileName);
ExFreePool (filenameinfo);
if (NT_SUCCESS(Status))
{
NameInfo->Name.MaximumLength = NameInfo->Name.Length + sizeof(WCHAR);
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION) + NameInfo->Name.MaximumLength;
}
} }
ObDereferenceObject(Object); else if (ObjectHeader->Name.Buffer)
return STATUS_NOT_IMPLEMENTED; {
case ObjectTypeInformation: // If it's got a name there, we can probably just make the full path through Name and Parent
typeinfo = (POBJECT_TYPE_INFORMATION)ObjectInformation; NameInfo->Name.MaximumLength = Length - sizeof(OBJECT_NAME_INFORMATION);
if (Length!=sizeof(OBJECT_TYPE_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE;
Status = internalNameBuilder (ObjectHeader,
// FIXME: Is this supposed to only be the header's Name field? &NameInfo->Name);
// Can somebody check/verify this? if (NT_SUCCESS(Status))
RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name); {
NameInfo->Name.MaximumLength = NameInfo->Name.Length + sizeof(WCHAR);
if (Status != STATUS_SUCCESS) *ReturnLength = sizeof(OBJECT_NAME_INFORMATION) + NameInfo->Name.MaximumLength;
{ }
ObDereferenceObject(Object); }
return Status; else
} {
Status = STATUS_NOT_IMPLEMENTED;
RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->ObjectType->TypeName); }
//This should be info from the object header, not the object type, right? break;
typeinfo->TotalHandles = ObjectHeader-> HandleCount;
typeinfo->ReferenceCount = ObjectHeader -> RefCount; case ObjectTypeInformation:
typeinfo = (POBJECT_TYPE_INFORMATION)ObjectInformation;
ObDereferenceObject(Object); if (Length!=sizeof(OBJECT_TYPE_INFORMATION))
return Status; return STATUS_INVALID_BUFFER_SIZE;
default:
ObDereferenceObject(Object); // FIXME: Is this supposed to only be the header's Name field?
return STATUS_NOT_IMPLEMENTED; // Can somebody check/verify this?
RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name);
if (Status != STATUS_SUCCESS)
{
break;
}
RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->ObjectType->TypeName);
//This should be info from the object header, not the object type, right?
typeinfo->TotalHandles = ObjectHeader-> HandleCount;
typeinfo->ReferenceCount = ObjectHeader -> RefCount;
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
} }
ObDereferenceObject(Object);
return Status;
} }
/**********************************************************************
* NAME EXPORTED
* ObMakeTemporaryObject
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*/
VOID STDCALL VOID STDCALL
ObMakeTemporaryObject (PVOID ObjectBody) ObMakeTemporaryObject (IN PVOID ObjectBody)
{ {
POBJECT_HEADER ObjectHeader; POBJECT_HEADER ObjectHeader;
ObjectHeader = BODY_TO_HEADER(ObjectBody); ObjectHeader = BODY_TO_HEADER(ObjectBody);
ObjectHeader->Permanent = FALSE; ObjectHeader->Permanent = FALSE;
} }
@ -187,34 +281,29 @@ ObMakeTemporaryObject (PVOID ObjectBody)
*/ */
NTSTATUS NTSTATUS
STDCALL STDCALL
NtMakeTemporaryObject ( NtMakeTemporaryObject (IN HANDLE Handle)
HANDLE Handle
)
{ {
PVOID Object; POBJECT_HEADER ObjectHeader;
NTSTATUS Status; PVOID Object;
POBJECT_HEADER ObjectHeader; NTSTATUS Status;
Status = ObReferenceObjectByHandle(
Handle,
0,
NULL,
KernelMode,
& Object,
NULL
);
if (Status != STATUS_SUCCESS)
{
return Status;
}
ObjectHeader = BODY_TO_HEADER(Object); Status = ObReferenceObjectByHandle(Handle,
ObjectHeader->Permanent = FALSE; 0,
NULL,
ObDereferenceObject(Object); KernelMode,
& Object,
return STATUS_SUCCESS; NULL);
if (Status != STATUS_SUCCESS)
{
return Status;
}
ObjectHeader = BODY_TO_HEADER(Object);
ObjectHeader->Permanent = FALSE;
ObDereferenceObject(Object);
return STATUS_SUCCESS;
} }
/* EOF */ /* EOF */