mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
NtQueryObject in early test version and reorganization of NtQueryInformationFile.
svn path=/trunk/; revision=1669
This commit is contained in:
parent
870a302f96
commit
29552067b3
2 changed files with 185 additions and 34 deletions
|
@ -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,8 +68,47 @@ 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue