[NTOSKRNL] Implement (with many FIXMEs) ObReferenceFileObjectForWrite() so that it can already do the job!

CORE-14003
This commit is contained in:
Pierre Schweitzer 2017-11-12 22:28:54 +01:00
parent 7eefe70294
commit 3b64f7f8fb
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
2 changed files with 117 additions and 0 deletions

View file

@ -384,6 +384,15 @@ ObpDeleteObjectType(
IN PVOID Object
);
NTSTATUS
NTAPI
ObReferenceFileObjectForWrite(
IN HANDLE Handle,
IN KPROCESSOR_MODE AccessMode,
OUT PFILE_OBJECT *FileObject,
OUT POBJECT_HANDLE_INFORMATION HandleInformation
);
//
// DOS Devices Functions
//

View file

@ -15,6 +15,8 @@
#define NDEBUG
#include <debug.h>
extern ULONG ObpAccessProtectCloseBit;
/* PRIVATE FUNCTIONS *********************************************************/
BOOLEAN
@ -195,6 +197,112 @@ ObFastReplaceObject(IN PEX_FAST_REF FastRef,
return OldObject;
}
NTSTATUS
NTAPI
ObReferenceFileObjectForWrite(IN HANDLE Handle,
IN KPROCESSOR_MODE AccessMode,
OUT PFILE_OBJECT *FileObject,
OUT POBJECT_HANDLE_INFORMATION HandleInformation)
{
NTSTATUS Status;
PHANDLE_TABLE HandleTable;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE_ENTRY HandleEntry;
ACCESS_MASK GrantedAccess, DesiredAccess;
/* Assume failure */
*FileObject = NULL;
/* Check if this is a special handle */
if (HandleToLong(Handle) < 0)
{
/* Make sure we have a valid kernel handle */
if (AccessMode != KernelMode || Handle == NtCurrentProcess() || Handle == NtCurrentThread())
{
return STATUS_INVALID_HANDLE;
}
/* Use the kernel handle table and get the actual handle value */
Handle = ObKernelHandleToHandle(Handle);
HandleTable = ObpKernelHandleTable;
}
else
{
/* Otherwise use this process's handle table */
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
ASSERT(HandleTable != NULL);
KeEnterCriticalRegion();
/* Get the handle entry */
HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
if (HandleEntry)
{
/* Get the object header and validate the type*/
ObjectHeader = ObpGetHandleObject(HandleEntry);
/* Get the desired access from the file object */
if (!NT_SUCCESS(IoComputeDesiredAccessFileObject((PFILE_OBJECT)&ObjectHeader->Body,
&DesiredAccess)))
{
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
else
{
/* Extract the granted access from the handle entry */
if (BooleanFlagOn(NtGlobalFlag, FLG_KERNEL_STACK_TRACE_DB))
{
/* FIXME: Translate granted access */
GrantedAccess = HandleEntry->GrantedAccess;
}
else
{
GrantedAccess = HandleEntry->GrantedAccess & ~ObpAccessProtectCloseBit;
}
/* FIXME: Get handle information for audit */
HandleInformation->GrantedAccess = GrantedAccess;
/* FIXME: Get handle attributes */
HandleInformation->HandleAttributes = 0;
/* Do granted and desired access match? */
if (GrantedAccess & DesiredAccess)
{
/* FIXME: Audit access if required */
/* Reference the object directly since we have its header */
InterlockedIncrement(&ObjectHeader->PointerCount);
/* Unlock the handle */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
KeLeaveCriticalRegion();
*FileObject = (PFILE_OBJECT)&ObjectHeader->Body;
/* Return success */
ASSERT(*FileObject != NULL);
return STATUS_SUCCESS;
}
/* No match, deny write access */
Status = STATUS_ACCESS_DENIED;
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
}
}
else
{
Status = STATUS_INVALID_HANDLE;
}
/* Return failure status */
KeLeaveCriticalRegion();
return Status;
}
/* PUBLIC FUNCTIONS *********************************************************/
LONG_PTR