Author: ion Date: Tue Jun 6 10:12:09 2006 New Revision: 22246
URL: http://svn.reactos.ru/svn/reactos?rev=22246&view=rev Log: - 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!
Modified: trunk/reactos/include/ndk/obtypes.h trunk/reactos/ntoskrnl/ob/obhandle.c
Modified: trunk/reactos/include/ndk/obtypes.h URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ndk/obtypes.h?rev=22... ============================================================================== --- trunk/reactos/include/ndk/obtypes.h (original) +++ trunk/reactos/include/ndk/obtypes.h Tue Jun 6 10:12:09 2006 @@ -230,7 +230,9 @@
typedef NTSTATUS (NTAPI *OB_OKAYTOCLOSE_METHOD)( - VOID + IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle );
#else
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c Tue Jun 6 10:12:09 2006 @@ -241,54 +241,86 @@ 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; - - PAGED_CODE(); - - DPRINT("ObpDeleteHandle(Handle %p)\n",Handle); - + NTSTATUS Status = STATUS_INVALID_HANDLE; + PAGED_CODE(); + + /* + * 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) - { - if(HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) - { - ExUnlockHandleTableEntry(ObjectTable, - HandleEntry); - - KeLeaveCriticalRegion(); - - return STATUS_HANDLE_NOT_CLOSABLE; - } - + /* Get the entry for this handle */ + HandleEntry = ExMapHandleToPointer(ObjectTable, Handle); + if(HandleEntry) + { + /* 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; }
/*++