NtQueryObject in early test version and reorganization of NtQueryInformationFile.

svn path=/trunk/; revision=1669
This commit is contained in:
Carl Nettelblad 2001-03-06 23:34:39 +00:00
parent 870a302f96
commit 29552067b3
2 changed files with 185 additions and 34 deletions

View file

@ -1,4 +1,4 @@
/* $Id: file.c,v 1.12 2001/01/28 17:37:48 ekohl Exp $
/* $Id: file.c,v 1.13 2001/03/06 23:34:39 cnettel Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -19,42 +19,22 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS
STDCALL
NtQueryInformationFile (
HANDLE FileHandle,
NTSTATUS STDCALL internalQueryFileInfo (
IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass
IN ULONG Length,
OUT PVOID FileInformation,
OUT PULONG ReturnedLength // FIXME: ReturnedLength not implemented
)
{
//This code is taken from old NtQueryInformationFile, now shared with IoQueryFileInformation
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
NTSTATUS Status;
KEVENT Event;
PIO_STACK_LOCATION StackPtr;
DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d Class %d)\n",
FileHandle,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass);
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
UserMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("FileObject %x\n", FileObject);
KeInitializeEvent(&Event,NotificationEvent,FALSE);
DeviceObject = FileObject->DeviceObject;
@ -88,10 +68,49 @@ NtQueryInformationFile (
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
Status = Irp->IoStatus.Status;
}
return Status;
}
NTSTATUS
STDCALL
NtQueryInformationFile (
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass
)
{
PFILE_OBJECT FileObject;
NTSTATUS Status;
DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d Class %d)\n",
FileHandle,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass);
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
UserMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("FileObject %x\n", FileObject);
Status = internalQueryFileInfo(FileObject, FileInformationClass, IoStatusBlock, Length, FileInformation, NULL);
// ObDereferenceObject(FileObject); FIXME: Why will a Dereference here make the OS impossible to boot. Incorrect deferring somewhere else?
return(Status);
}
NTSTATUS
STDCALL
IoQueryFileInformation (
@ -99,11 +118,22 @@ IoQueryFileInformation (
IN FILE_INFORMATION_CLASS FileInformationClass,
IN ULONG Length,
OUT PVOID FileInformation,
OUT PULONG ReturnedLength
OUT PULONG ReturnedLength // FIXME: ReturnedLength not implemented
)
{
UNIMPLEMENTED;
return (STATUS_NOT_IMPLEMENTED);
NTSTATUS Status;
Status = ObReferenceObjectByPointer(FileObject,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
KernelMode); // FIXME: Is KernelMode the correct choice here?
if (!NT_SUCCESS(Status))
{
return(Status);
}
// ObDereferenceObject(FileObject); For some reason, ObDereference is NOT a good thing here... wish I knew why
return internalQueryFileInfo(FileObject,FileInformationClass,NULL,Length,FileInformation,ReturnedLength);
}

View file

@ -1,4 +1,4 @@
/* $Id: ntobj.c,v 1.7 2000/10/22 16:36:53 ekohl Exp $
/* $Id: ntobj.c,v 1.8 2001/03/06 23:34:39 cnettel Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -13,6 +13,7 @@
#include <ddk/ntddk.h>
#include <internal/ob.h>
#include <internal/id.h>
#define NDEBUG
#include <internal/debug.h>
@ -32,6 +33,34 @@ NtSetInformationObject (
}
NTSTATUS
internalNameBuilder
(
POBJECT_HEADER ObjectHeader,
PUNICODE_STRING string)
/* So, what's the purpose of this function?
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
have any meaning (not files) */
{
NTSTATUS status;
if (ObjectHeader->Parent)
{
status = internalNameBuilder(BODY_TO_HEADER(ObjectHeader->Parent),string);
if (status != STATUS_SUCCESS)
{
return status;
}
}
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 (
@ -41,8 +70,100 @@ NtQueryObject (
IN ULONG Length,
OUT PULONG ResultLength
)
/*Very, very, very new implementation. Test it!
Probably we should add meaning to QueryName in POBJECT_TYPE, no matter if we know
the correct parameters or not. For FILE_OBJECTs, it would probably look like the code
for ObjectNameInformation below. You give it a POBJECT and a PUNICODE_STRING, and it
returns the full path in the PUNICODE_STRING
If we don't do it this way, we should anyway add switches and separate functions to handle
the different object types*/
{
UNIMPLEMENTED
POBJECT_NAME_INFORMATION nameinfo;
POBJECT_TYPE_INFORMATION typeinfo;
PFILE_NAME_INFORMATION filenameinfo;
PVOID Object;
NTSTATUS Status;
POBJECT_HEADER ObjectHeader;
PFILE_OBJECT fileob;
Status = ObReferenceObjectByHandle(
ObjectHandle,
0,
NULL,
KernelMode,
& Object,
NULL
);
if (Status != STATUS_SUCCESS)
{
return Status;
}
ObjectHeader = BODY_TO_HEADER(Object);
switch (ObjectInformationClass)
{
case ObjectNameInformation:
if (Length!=sizeof(OBJECT_NAME_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE;
nameinfo = (POBJECT_NAME_INFORMATION)ObjectInformation;
(*ResultLength)=Length;
if (ObjectHeader->Type==InternalFileType) // FIXME: Temporary QueryName implementation, or at least separate functions
{
fileob = (PFILE_OBJECT) Object;
Status = internalNameBuilder(BODY_TO_HEADER(fileob->DeviceObject->Vpb->RealDevice), &nameinfo->Name);
if (Status != STATUS_SUCCESS)
{
ObDereferenceObject(Object);
return Status;
}
filenameinfo = ExAllocatePool(NonPagedPool,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG));
IoQueryFileInformation(fileob,FileNameInformation,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG), filenameinfo,NULL);
Status = RtlAppendUnicodeToString(&(nameinfo->Name), filenameinfo->FileName);
ExFreePool( filenameinfo);
ObDereferenceObject(Object);
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);
ObDereferenceObject(Object);
return Status;
}
ObDereferenceObject(Object);
return STATUS_NOT_IMPLEMENTED;
case ObjectTypeInformation:
typeinfo = (POBJECT_TYPE_INFORMATION)ObjectInformation;
if (Length!=sizeof(OBJECT_TYPE_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE;
// FIXME: Is this supposed to only be the header's Name field?
// Can somebody check/verify this?
RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name);
if (Status != STATUS_SUCCESS)
{
ObDereferenceObject(Object);
return Status;
}
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;
ObDereferenceObject(Object);
return Status;
default:
ObDereferenceObject(Object);
return STATUS_NOT_IMPLEMENTED;
}
}