From 21baa4ddb6f7b397f5cd20dc2d64e7b7a94e30ec Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Jun 2006 06:12:09 +0000 Subject: [PATCH] - 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 --- reactos/include/ndk/obtypes.h | 4 +- reactos/ntoskrnl/ob/obhandle.c | 84 +++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/reactos/include/ndk/obtypes.h b/reactos/include/ndk/obtypes.h index 13dcf59e488..1b5d9b231fd 100644 --- a/reactos/include/ndk/obtypes.h +++ b/reactos/include/ndk/obtypes.h @@ -230,7 +230,9 @@ typedef NTSTATUS typedef NTSTATUS (NTAPI *OB_OKAYTOCLOSE_METHOD)( - VOID + IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle ); #else diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index e20726b97ff..feafdaab020 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -241,54 +241,86 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, ObjectType->TotalNumberOfHandles--; } -static NTSTATUS +/*++ +* @name ObpDeleteHandle +* +* The ObpDeleteHandle routine +* +* @param Handle +* . +* +* @return . +* +* @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); + /* 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_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_HANDLE_NOT_CLOSABLE; + } + + /* Destroy and unlock the handle entry */ + ExDestroyHandleByEntry(ObjectTable, HandleEntry, Handle); + + /* Now decrement the handle count */ ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess); - - KeLeaveCriticalRegion(); - - return STATUS_SUCCESS; + Status = STATUS_SUCCESS; } + + /* Leave the critical region and return the status */ KeLeaveCriticalRegion(); - return STATUS_INVALID_HANDLE; + return Status; } /*++