mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +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
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -19,42 +19,22 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS STDCALL internalQueryFileInfo (
|
||||||
NTSTATUS
|
IN PFILE_OBJECT FileObject,
|
||||||
STDCALL
|
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||||
NtQueryInformationFile (
|
|
||||||
HANDLE FileHandle,
|
|
||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
PVOID FileInformation,
|
IN ULONG Length,
|
||||||
ULONG Length,
|
OUT PVOID FileInformation,
|
||||||
FILE_INFORMATION_CLASS FileInformationClass
|
OUT PULONG ReturnedLength // FIXME: ReturnedLength not implemented
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
//This code is taken from old NtQueryInformationFile, now shared with IoQueryFileInformation
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
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);
|
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||||
DeviceObject = FileObject->DeviceObject;
|
DeviceObject = FileObject->DeviceObject;
|
||||||
|
@ -88,10 +68,49 @@ NtQueryInformationFile (
|
||||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
||||||
Status = Irp->IoStatus.Status;
|
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);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
IoQueryFileInformation (
|
IoQueryFileInformation (
|
||||||
|
@ -99,11 +118,22 @@ IoQueryFileInformation (
|
||||||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PVOID FileInformation,
|
OUT PVOID FileInformation,
|
||||||
OUT PULONG ReturnedLength
|
OUT PULONG ReturnedLength // FIXME: ReturnedLength not implemented
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
NTSTATUS Status;
|
||||||
return (STATUS_NOT_IMPLEMENTED);
|
|
||||||
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/ob.h>
|
#include <internal/ob.h>
|
||||||
|
#include <internal/id.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#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
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtQueryObject (
|
NtQueryObject (
|
||||||
|
@ -41,8 +70,100 @@ NtQueryObject (
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ResultLength
|
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