mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:35:41 +00:00
- Add function documentation header to ObpDeleteHandle, comment and re-format the function, and simplify the code to reduce some code duplication.
- Call the OkayToClose Procedure, if one is present, to allow the object owner a chance to disallow closing this handle. I believe this is required for properly protecting Winsta/Desktop handles (instead of using the regular protection mode, since that one can be bypassed). Thomas, get to work! svn path=/trunk/; revision=22246
This commit is contained in:
parent
18ed42b8a4
commit
21baa4ddb6
2 changed files with 61 additions and 27 deletions
|
@ -230,7 +230,9 @@ typedef NTSTATUS
|
|||
|
||||
typedef NTSTATUS
|
||||
(NTAPI *OB_OKAYTOCLOSE_METHOD)(
|
||||
VOID
|
||||
IN PEPROCESS Process OPTIONAL,
|
||||
IN PVOID Object,
|
||||
IN HANDLE Handle
|
||||
);
|
||||
|
||||
#else
|
||||
|
|
|
@ -241,54 +241,86 @@ ObpDecrementHandleCount(IN PVOID ObjectBody,
|
|||
ObjectType->TotalNumberOfHandles--;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
/*++
|
||||
* @name ObpDeleteHandle
|
||||
*
|
||||
* The ObpDeleteHandle routine <FILLMEIN>
|
||||
*
|
||||
* @param Handle
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return <FILLMEIN>.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObpDeleteHandle(HANDLE Handle)
|
||||
{
|
||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||
PVOID Body;
|
||||
POBJECT_TYPE ObjectType;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
PHANDLE_TABLE ObjectTable;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
|
||||
NTSTATUS Status = STATUS_INVALID_HANDLE;
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("ObpDeleteHandle(Handle %p)\n",Handle);
|
||||
|
||||
/*
|
||||
* Get the object table of the current process/
|
||||
* NOTE: We might actually be attached to the system process
|
||||
*/
|
||||
ObjectTable = PsGetCurrentProcess()->ObjectTable;
|
||||
|
||||
/* Enter a critical region while touching the handle locks */
|
||||
KeEnterCriticalRegion();
|
||||
|
||||
HandleEntry = ExMapHandleToPointer(ObjectTable,
|
||||
Handle);
|
||||
if(HandleEntry != NULL)
|
||||
/* Get the entry for this handle */
|
||||
HandleEntry = ExMapHandleToPointer(ObjectTable, Handle);
|
||||
if(HandleEntry)
|
||||
{
|
||||
if(HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
||||
{
|
||||
ExUnlockHandleTableEntry(ObjectTable,
|
||||
HandleEntry);
|
||||
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
return STATUS_HANDLE_NOT_CLOSABLE;
|
||||
}
|
||||
|
||||
/* Get the object data */
|
||||
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||
ObjectType = ObjectHeader->Type;
|
||||
Body = &ObjectHeader->Body;
|
||||
GrantedAccess = HandleEntry->GrantedAccess;
|
||||
|
||||
/* destroy and unlock the handle entry */
|
||||
ExDestroyHandleByEntry(ObjectTable,
|
||||
HandleEntry,
|
||||
Handle);
|
||||
|
||||
ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess);
|
||||
|
||||
/* Check if the object has an Okay To Close procedure */
|
||||
if (ObjectType->TypeInfo.OkayToCloseProcedure)
|
||||
{
|
||||
/* Call it and check if it's not letting us close it */
|
||||
if (!ObjectType->TypeInfo.OkayToCloseProcedure(PsGetCurrentProcess(),
|
||||
Body,
|
||||
Handle))
|
||||
{
|
||||
/* Fail */
|
||||
ExUnlockHandleTableEntry(ObjectTable, HandleEntry);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_HANDLE_NOT_CLOSABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* The callback allowed us to close it, but does the handle itself? */
|
||||
if(HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
||||
{
|
||||
/* Fail */
|
||||
ExUnlockHandleTableEntry(ObjectTable, HandleEntry);
|
||||
KeLeaveCriticalRegion();
|
||||
return STATUS_INVALID_HANDLE;
|
||||
return STATUS_HANDLE_NOT_CLOSABLE;
|
||||
}
|
||||
|
||||
/* Destroy and unlock the handle entry */
|
||||
ExDestroyHandleByEntry(ObjectTable, HandleEntry, Handle);
|
||||
|
||||
/* Now decrement the handle count */
|
||||
ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Leave the critical region and return the status */
|
||||
KeLeaveCriticalRegion();
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*++
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue