mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:32:57 +00:00
- Fix ExChangeHandle not to send NULL but the actual context to the callback function (fix by Thomas Weidenmueller <w3seek@reactos.org>)
- Re-implement NtSetInformationObject based on ExChangeHandle and using ObpSetHandleAttributes as a callback. - Re-implement NtQueryObject's ObjectHandleInformation case to simply return the information that's already in HandleAttributes; there is no point in querying for it all over again. - Fix NtSetInformationObject not to allow a user-mode call to modify kernel-mdoe handle attributes. Add FIXME for Inheritance permissions check. - Fix NtQueryObject to properly return OBJ_PERMANENT and OBJ_EXCLUSIVE; these flags are not stored in Handle Attributes. - Fix NtQueryObject not to attempt referencing the handle if the caller specified AllTypesInformation, because then a handle is not needed. svn path=/trunk/; revision=22228
This commit is contained in:
parent
7c2e312093
commit
02d0bb9dbd
4 changed files with 203 additions and 182 deletions
|
@ -916,7 +916,7 @@ ExChangeHandle(IN PHANDLE_TABLE HandleTable,
|
||||||
{
|
{
|
||||||
Ret = ChangeHandleCallback(HandleTable,
|
Ret = ChangeHandleCallback(HandleTable,
|
||||||
HandleTableEntry,
|
HandleTableEntry,
|
||||||
NULL);
|
Context);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(HandleTable,
|
||||||
HandleTableEntry);
|
HandleTableEntry);
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
#ifndef __INCLUDE_INTERNAL_OBJMGR_H
|
#ifndef __INCLUDE_INTERNAL_OBJMGR_H
|
||||||
#define __INCLUDE_INTERNAL_OBJMGR_H
|
#define __INCLUDE_INTERNAL_OBJMGR_H
|
||||||
|
|
||||||
|
typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
|
||||||
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information;
|
||||||
|
} OBP_SET_HANDLE_ATTRIBUTES_CONTEXT, *POBP_SET_HANDLE_ATTRIBUTES_CONTEXT;
|
||||||
|
|
||||||
#define GENERIC_ACCESS (GENERIC_READ | \
|
#define GENERIC_ACCESS (GENERIC_READ | \
|
||||||
GENERIC_WRITE | \
|
GENERIC_WRITE | \
|
||||||
GENERIC_EXECUTE | \
|
GENERIC_EXECUTE | \
|
||||||
|
@ -100,18 +106,12 @@ ObFindObject(
|
||||||
IN PVOID Insert
|
IN PVOID Insert
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
BOOLEAN
|
||||||
NTAPI
|
|
||||||
ObpQueryHandleAttributes(
|
|
||||||
HANDLE Handle,
|
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpSetHandleAttributes(
|
ObpSetHandleAttributes(
|
||||||
HANDLE Handle,
|
IN PHANDLE_TABLE HandleTable,
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
|
IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||||
|
IN PVOID Context
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -154,129 +154,51 @@ ObpDecrementHandleCount(PVOID ObjectBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpQueryHandleAttributes(HANDLE Handle,
|
ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||||
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo =
|
||||||
PEPROCESS Process, CurrentProcess;
|
(POBP_SET_HANDLE_ATTRIBUTES_CONTEXT)Context;
|
||||||
KAPC_STATE ApcState;
|
POBJECT_HEADER ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
|
||||||
BOOLEAN AttachedToProcess = FALSE;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObpQueryHandleAttributes(Handle %p)\n", Handle);
|
/* Don't allow operations on kernel objects */
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
if ((ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) &&
|
||||||
|
(SetHandleInfo->PreviousMode != KernelMode))
|
||||||
KeEnterCriticalRegion();
|
|
||||||
|
|
||||||
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
|
||||||
{
|
{
|
||||||
Process = PsInitialSystemProcess;
|
/* Fail */
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (Process != CurrentProcess)
|
/* Check if making the handle inheritable */
|
||||||
{
|
if (SetHandleInfo->Information.Inherit)
|
||||||
KeStackAttachProcess(&Process->Pcb,
|
{
|
||||||
&ApcState);
|
/* Set the flag. FIXME: Need to check if this is allowed */
|
||||||
AttachedToProcess = TRUE;
|
HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Process = CurrentProcess;
|
/* Otherwise this implies we're removing the flag */
|
||||||
|
HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
|
/* Check if making the handle protected */
|
||||||
Handle);
|
if (SetHandleInfo->Information.ProtectFromClose)
|
||||||
if (HandleTableEntry != NULL)
|
|
||||||
{
|
{
|
||||||
HandleInfo->Inherit = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
|
/* Set the flag */
|
||||||
HandleInfo->ProtectFromClose = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
|
HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
|
||||||
HandleTableEntry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Status = STATUS_INVALID_HANDLE;
|
|
||||||
|
|
||||||
if (AttachedToProcess)
|
|
||||||
{
|
|
||||||
KeUnstackDetachProcess(&ApcState);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
ObpSetHandleAttributes(HANDLE Handle,
|
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
|
||||||
{
|
|
||||||
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
|
||||||
PEPROCESS Process, CurrentProcess;
|
|
||||||
KAPC_STATE ApcState;
|
|
||||||
BOOLEAN AttachedToProcess = FALSE;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
DPRINT("ObpSetHandleAttributes(Handle %p)\n", Handle);
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
|
||||||
|
|
||||||
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
|
||||||
{
|
|
||||||
Process = PsInitialSystemProcess;
|
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
|
||||||
|
|
||||||
if (Process != CurrentProcess)
|
|
||||||
{
|
|
||||||
KeStackAttachProcess(&Process->Pcb,
|
|
||||||
&ApcState);
|
|
||||||
AttachedToProcess = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Process = CurrentProcess;
|
/* Otherwise, remove it */
|
||||||
|
HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
|
/* Return success */
|
||||||
Handle);
|
return TRUE;
|
||||||
if (HandleTableEntry != NULL)
|
|
||||||
{
|
|
||||||
if (HandleInfo->Inherit)
|
|
||||||
HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
|
||||||
else
|
|
||||||
HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
|
||||||
|
|
||||||
if (HandleInfo->ProtectFromClose)
|
|
||||||
HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
|
|
||||||
else
|
|
||||||
HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
|
|
||||||
|
|
||||||
/* FIXME: Do we need to set anything in the object header??? */
|
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
|
||||||
HandleTableEntry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Status = STATUS_INVALID_HANDLE;
|
|
||||||
|
|
||||||
if (AttachedToProcess)
|
|
||||||
{
|
|
||||||
KeUnstackDetachProcess(&ApcState);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
|
|
|
@ -790,95 +790,157 @@ NtQueryObject(IN HANDLE ObjectHandle,
|
||||||
OUT PULONG ResultLength OPTIONAL)
|
OUT PULONG ResultLength OPTIONAL)
|
||||||
{
|
{
|
||||||
OBJECT_HANDLE_INFORMATION HandleInfo;
|
OBJECT_HANDLE_INFORMATION HandleInfo;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader = NULL;
|
||||||
|
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
|
||||||
|
POBJECT_BASIC_INFORMATION BasicInfo;
|
||||||
ULONG InfoLength;
|
ULONG InfoLength;
|
||||||
PVOID Object;
|
PVOID Object = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
/* FIXME: Needs SEH */
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
KeGetPreviousMode(),
|
|
||||||
&Object,
|
|
||||||
&HandleInfo);
|
|
||||||
if (!NT_SUCCESS (Status)) return Status;
|
|
||||||
|
|
||||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
/*
|
||||||
|
* Make sure this isn't a generic type query, since the caller doesn't
|
||||||
|
* have to give a handle for it
|
||||||
|
*/
|
||||||
|
if (ObjectInformationClass != ObjectAllTypesInformation)
|
||||||
|
{
|
||||||
|
/* Reference the object */
|
||||||
|
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
KeGetPreviousMode(),
|
||||||
|
&Object,
|
||||||
|
&HandleInfo);
|
||||||
|
if (!NT_SUCCESS (Status)) return Status;
|
||||||
|
|
||||||
|
/* Get the object header */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the information class */
|
||||||
switch (ObjectInformationClass)
|
switch (ObjectInformationClass)
|
||||||
{
|
{
|
||||||
case ObjectBasicInformation:
|
/* Basic info */
|
||||||
InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
|
case ObjectBasicInformation:
|
||||||
if (Length != sizeof(OBJECT_BASIC_INFORMATION))
|
|
||||||
{
|
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
POBJECT_BASIC_INFORMATION BasicInfo;
|
|
||||||
|
|
||||||
|
/* Validate length */
|
||||||
|
InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
|
||||||
|
if (Length != sizeof(OBJECT_BASIC_INFORMATION))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the basic information */
|
||||||
BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation;
|
BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation;
|
||||||
BasicInfo->Attributes = HandleInfo.HandleAttributes;
|
BasicInfo->Attributes = HandleInfo.HandleAttributes;
|
||||||
BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
|
BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
|
||||||
BasicInfo->HandleCount = ObjectHeader->HandleCount;
|
BasicInfo->HandleCount = ObjectHeader->HandleCount;
|
||||||
BasicInfo->PointerCount = ObjectHeader->PointerCount;
|
BasicInfo->PointerCount = ObjectHeader->PointerCount;
|
||||||
|
|
||||||
|
/* Permanent/Exclusive Flags are NOT in Handle attributes! */
|
||||||
|
if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
|
||||||
|
{
|
||||||
|
/* Set the flag */
|
||||||
|
BasicInfo->Attributes |= OBJ_EXCLUSIVE;
|
||||||
|
}
|
||||||
|
if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
|
||||||
|
{
|
||||||
|
/* Set the flag */
|
||||||
|
BasicInfo->Attributes |= OBJ_PERMANENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy quota information */
|
||||||
BasicInfo->PagedPoolUsage = 0; /* FIXME*/
|
BasicInfo->PagedPoolUsage = 0; /* FIXME*/
|
||||||
BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
|
BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
|
||||||
|
|
||||||
|
/* Copy name information */
|
||||||
BasicInfo->NameInformationLength = 0; /* FIXME*/
|
BasicInfo->NameInformationLength = 0; /* FIXME*/
|
||||||
BasicInfo->TypeInformationLength = 0; /* FIXME*/
|
BasicInfo->TypeInformationLength = 0; /* FIXME*/
|
||||||
|
|
||||||
|
/* Copy security information */
|
||||||
BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
|
BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
|
||||||
|
|
||||||
|
/* Check if this is a symlink */
|
||||||
if (ObjectHeader->Type == ObSymbolicLinkType)
|
if (ObjectHeader->Type == ObSymbolicLinkType)
|
||||||
{
|
{
|
||||||
|
/* Return the creation time */
|
||||||
BasicInfo->CreateTime.QuadPart =
|
BasicInfo->CreateTime.QuadPart =
|
||||||
((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
|
((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Otherwise return 0 */
|
||||||
BasicInfo->CreateTime.QuadPart = (ULONGLONG)0;
|
BasicInfo->CreateTime.QuadPart = (ULONGLONG)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Break out with success */
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case ObjectNameInformation:
|
/* Name information */
|
||||||
Status = ObQueryNameString(Object,
|
case ObjectNameInformation:
|
||||||
(POBJECT_NAME_INFORMATION)ObjectInformation,
|
|
||||||
Length,
|
|
||||||
&InfoLength);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ObjectTypeInformation:
|
/* Call the helper and break out */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = ObQueryNameString(Object,
|
||||||
break;
|
(POBJECT_NAME_INFORMATION)
|
||||||
|
ObjectInformation,
|
||||||
|
Length,
|
||||||
|
&InfoLength);
|
||||||
|
break;
|
||||||
|
|
||||||
case ObjectAllTypesInformation:
|
/* Information about this type */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
case ObjectTypeInformation:
|
||||||
break;
|
DPRINT1("NOT IMPLEMENTED!\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
case ObjectHandleInformation:
|
/* Information about all types */
|
||||||
InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
|
case ObjectAllTypesInformation:
|
||||||
if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
|
DPRINT1("NOT IMPLEMENTED!\n");
|
||||||
{
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = ObpQueryHandleAttributes(
|
|
||||||
ObjectHandle,
|
|
||||||
(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
/* Information about the handle flags */
|
||||||
Status = STATUS_INVALID_INFO_CLASS;
|
case ObjectHandleInformation:
|
||||||
break;
|
|
||||||
|
/* Validate length */
|
||||||
|
InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
|
||||||
|
if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the structure */
|
||||||
|
HandleFlags = (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
|
||||||
|
ObjectInformation;
|
||||||
|
|
||||||
|
/* Set the flags */
|
||||||
|
HandleFlags->Inherit = (HandleInfo.HandleAttributes &
|
||||||
|
EX_HANDLE_ENTRY_INHERITABLE) != 0;
|
||||||
|
HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
|
||||||
|
EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
|
||||||
|
|
||||||
|
/* Break out with success */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Anything else */
|
||||||
|
default:
|
||||||
|
/* Fail it */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject (Object);
|
/* Derefernece the object if we had referenced it */
|
||||||
|
if (Object) ObDereferenceObject (Object);
|
||||||
if (ResultLength != NULL) *ResultLength = InfoLength;
|
|
||||||
|
|
||||||
|
/* Return the length and status */
|
||||||
|
if (ResultLength) *ResultLength = InfoLength;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,29 +974,66 @@ NtSetInformationObject(IN HANDLE ObjectHandle,
|
||||||
IN PVOID ObjectInformation,
|
IN PVOID ObjectInformation,
|
||||||
IN ULONG Length)
|
IN ULONG Length)
|
||||||
{
|
{
|
||||||
PVOID Object;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
NTSTATUS Status;
|
OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context;
|
||||||
|
PVOID ObjectTable;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Validate the information class */
|
||||||
if (ObjectInformationClass != ObjectHandleInformation)
|
if (ObjectInformationClass != ObjectHandleInformation)
|
||||||
|
{
|
||||||
|
/* Invalid class */
|
||||||
return STATUS_INVALID_INFO_CLASS;
|
return STATUS_INVALID_INFO_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate the length */
|
||||||
if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
|
if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
|
||||||
|
{
|
||||||
|
/* Invalid length */
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
/* Save the previous mode and actual information */
|
||||||
0,
|
Context.PreviousMode = ExGetPreviousMode();
|
||||||
NULL,
|
Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
|
||||||
KeGetPreviousMode(),
|
ObjectInformation;
|
||||||
&Object,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS (Status)) return Status;
|
|
||||||
|
|
||||||
Status = ObpSetHandleAttributes(ObjectHandle,
|
/* Check if this is a kernel handle */
|
||||||
(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
|
if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode))
|
||||||
ObjectInformation);
|
{
|
||||||
|
/* Get the actual handle */
|
||||||
|
ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
|
||||||
|
ObjectTable = ObpKernelHandleTable;
|
||||||
|
|
||||||
ObDereferenceObject (Object);
|
/* Check if we're not in the system process */
|
||||||
|
if (PsGetCurrentProcess() != PsInitialSystemProcess)
|
||||||
|
{
|
||||||
|
/* Attach to it */
|
||||||
|
KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use the current table */
|
||||||
|
ObjectTable = PsGetCurrentProcess()->ObjectTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the handle attributes */
|
||||||
|
if (!ExChangeHandle(ObjectTable,
|
||||||
|
ObjectHandle,
|
||||||
|
ObpSetHandleAttributes,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
/* Some failure */
|
||||||
|
Status = STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* De-attach if we were attached, and return status */
|
||||||
|
if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue