Author: ion Date: Sat Jun 10 04:41:16 2006 New Revision: 22294
URL: http://svn.reactos.ru/svn/reactos?rev=22294&view=rev Log: - Update sweep callback to send the handle number. Patch by Thomas Weidenmueller (w3seek@reactos.org) - Export ObCloseHandle since it's implemented now - Implement ObpCreateUnnamedHandle and ObpIncrementUnnamedHandleCount as optimizations for ObInsertObject with unnamed objects.
Modified: trunk/reactos/ntoskrnl/ex/handle.c trunk/reactos/ntoskrnl/include/internal/ex.h trunk/reactos/ntoskrnl/ntoskrnl.def trunk/reactos/ntoskrnl/ob/obhandle.c
Modified: trunk/reactos/ntoskrnl/ex/handle.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/handle.c?rev=222... ============================================================================== --- trunk/reactos/ntoskrnl/ex/handle.c (original) +++ trunk/reactos/ntoskrnl/ex/handle.c Sat Jun 10 04:41:16 2006 @@ -168,6 +168,7 @@ IN PVOID Context OPTIONAL) { PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; + LONG ExHandle = 0;
PAGED_CODE();
@@ -209,12 +210,18 @@ if(curee->Object != NULL && SweepHandleCallback != NULL) { curee->ObAttributes |= EX_HANDLE_ENTRY_LOCKED; - SweepHandleCallback(HandleTable, curee->Object, curee->GrantedAccess, Context); + SweepHandleCallback(curee, EX_HANDLE_TO_HANDLE(ExHandle), Context); } + + ExHandle++; } } - } - } + else + break; + } + } + else + break; }
ExReleaseHandleLock(HandleTable);
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ex... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h Sat Jun 10 04:41:16 2006 @@ -160,9 +160,8 @@ EX_HANDLE_ENTRY_AUDITONCLOSE)
typedef VOID (STDCALL PEX_SWEEP_HANDLE_CALLBACK)( - PHANDLE_TABLE HandleTable, - PVOID Object, - ULONG GrantedAccess, + PHANDLE_TABLE_ENTRY HandleTableEntry, + HANDLE Handle, PVOID Context );
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.def?rev=22... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl.def (original) +++ trunk/reactos/ntoskrnl/ntoskrnl.def Sat Jun 10 04:41:16 2006 @@ -836,7 +836,7 @@ ObAssignSecurity@16 ;ObCheckCreateObjectAccess@28 ;ObCheckObjectAccess@20 -;ObCloseHandle@4 +ObCloseHandle@8 ObCreateObject@36 ObCreateObjectType@16 ObDereferenceObject@4
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 Sat Jun 10 04:41:16 2006 @@ -382,6 +382,270 @@ ObjectHeader->HandleCount, ObjectHeader->PointerCount); return STATUS_SUCCESS; +} + +/*++ +* @name ObpIncrementUnnamedHandleCount +* +* The ObpIncrementUnnamedHandleCount routine <FILLMEIN> +* +* @param Object +* <FILLMEIN>. +* +* @param AccessState +* <FILLMEIN>. +* +* @param AccessMode +* <FILLMEIN>. +* +* @param HandleAttributes +* <FILLMEIN>. +* +* @param Process +* <FILLMEIN>. +* +* @param OpenReason +* <FILLMEIN>. +* +* @return <FILLMEIN>. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +ObpIncrementUnnamedHandleCount(IN PVOID Object, + IN PACCESS_MASK DesiredAccess, + IN KPROCESSOR_MODE AccessMode, + IN ULONG HandleAttributes, + IN PEPROCESS Process) +{ + POBJECT_HEADER ObjectHeader; + POBJECT_TYPE ObjectType; + ULONG ProcessHandleCount; + NTSTATUS Status; + + /* Get the object header and type */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + ObjectType = ObjectHeader->Type; + OBTRACE("OBTRACE - %s - Incrementing count for: %p. UNNAMED. HC LC %lx %lx\n", + __FUNCTION__, + Object, + ObjectHeader->HandleCount, + ObjectHeader->PointerCount); + + /* Charge quota and remove the creator info flag */ + Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType); + if (!NT_SUCCESS(Status)) return Status; + + /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */ + if (*DesiredAccess & MAXIMUM_ALLOWED) + { + /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */ + *DesiredAccess &= ~MAXIMUM_ALLOWED; + *DesiredAccess |= GENERIC_ALL; + } + + /* Check if we have to map the GENERIC mask */ + if (*DesiredAccess & GENERIC_ACCESS) + { + /* Map it to the correct access masks */ + RtlMapGenericMask(DesiredAccess, + &ObjectType->TypeInfo.GenericMapping); + } + + /* Increase the handle count */ + if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1) + { + /* + * FIXME: Is really needed? Perhaps we should instead take + * advantage of the AddtionalReferences parameter to add the + * bias when required. This might be the source of the mysterious + * ReactOS bug where ObInsertObject *requires* an immediate dereference + * even in a success case. + * Will have to think more about this when doing the Increment/Create + * split later. + */ + ObReferenceObject(Object); + } + + /* FIXME: Use the Handle Database */ + ProcessHandleCount = 0; + + /* Check if we have an open procedure */ + if (ObjectType->TypeInfo.OpenProcedure) + { + /* Call it */ + ObjectType->TypeInfo.OpenProcedure(ObCreateHandle, + Process, + Object, + *DesiredAccess, + ProcessHandleCount); + } + + /* Increase total number of handles */ + ObjectType->TotalNumberOfHandles++; + OBTRACE("OBTRACE - %s - Incremented count for: %p. UNNAMED HC LC %lx %lx\n", + __FUNCTION__, + Object, + ObjectHeader->HandleCount, + ObjectHeader->PointerCount); + return STATUS_SUCCESS; +} + +/*++ +* @name ObpCreateUnnamedHandle +* +* The ObpCreateUnnamedHandle routine <FILLMEIN> +* +* @param Object +* <FILLMEIN>. +* +* @param DesiredAccess +* <FILLMEIN>. +* +* @param AdditionalReferences +* <FILLMEIN>. +* +* @param HandleAttributes +* <FILLMEIN>. +* +* @param AccessMode +* <FILLMEIN>. +* +* @param ReturnedObject +* <FILLMEIN>. +* +* @param ReturnedHandle +* <FILLMEIN>. +* +* @return <FILLMEIN>. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +ObpCreateUnnamedHandle(IN PVOID Object, + IN ACCESS_MASK DesiredAccess, + IN ULONG AdditionalReferences, + IN ULONG HandleAttributes, + IN KPROCESSOR_MODE AccessMode, + OUT PVOID *ReturnedObject, + OUT PHANDLE ReturnedHandle) +{ + HANDLE_TABLE_ENTRY NewEntry; + POBJECT_HEADER ObjectHeader; + HANDLE Handle; + KAPC_STATE ApcState; + BOOLEAN AttachedToProcess = FALSE; + PVOID HandleTable; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the object header and type */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + OBTRACE("OBTRACE - %s - Creating handle for: %p. UNNAMED. HC LC %lx %lx\n", + __FUNCTION__, + Object, + ObjectHeader->HandleCount, + ObjectHeader->PointerCount); + + /* Check if this is a kernel handle */ + if ((HandleAttributes & OBJ_KERNEL_HANDLE) && (AccessMode == KernelMode)) + { + /* Set the handle table */ + HandleTable = ObpKernelHandleTable; + + /* Check if we're not in the system process */ + if (PsGetCurrentProcess() != PsInitialSystemProcess) + { + /* Attach to the system process */ + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); + AttachedToProcess = TRUE; + } + } + else + { + /* Get the current handle table */ + HandleTable = PsGetCurrentProcess()->ObjectTable; + } + + /* Increment the handle count */ + Status = ObpIncrementUnnamedHandleCount(Object, + &DesiredAccess, + AccessMode, + HandleAttributes, + PsGetCurrentProcess()); + if (!NT_SUCCESS(Status)) + { + /* + * We failed (meaning security failure, according to NT Internals) + * detach and return + */ + if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); + return Status; + } + + /* Save the object header (assert its validity too) */ + ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); + NewEntry.Object = ObjectHeader; + + /* Mask out the internal attributes */ + NewEntry.ObAttributes |= HandleAttributes & + (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | + EX_HANDLE_ENTRY_INHERITABLE | + EX_HANDLE_ENTRY_AUDITONCLOSE); + + /* Save the access mask */ + NewEntry.GrantedAccess = DesiredAccess; + + /* + * Create the actual handle. We'll need to do this *after* calling + * ObpIncrementHandleCount to make sure that Object Security is valid + * (specified in Gl00my documentation on Ob) + */ + OBTRACE("OBTRACE - %s - Handle Properties: [%p-%lx-%lx]\n", + __FUNCTION__, + NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess); + Handle = ExCreateHandle(HandleTable, &NewEntry); + + /* Detach if needed */ + if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); + + /* Make sure we got a handle */ + if (Handle) + { + /* Handle extra references */ + while (AdditionalReferences--) + { + /* Increment the count */ + InterlockedIncrement(&ObjectHeader->PointerCount); + } + + /* Check if this was a kernel handle */ + if (HandleAttributes & OBJ_KERNEL_HANDLE) + { + /* Set the kernel handle bit */ + Handle = ObMarkHandleAsKernelHandle(Handle); + } + + /* Return handle and object */ + *ReturnedHandle = Handle; + if (ReturnedObject) *ReturnedObject = Object; + OBTRACE("OBTRACE - %s - Returning Handle: %lx HC LC %lx %lx\n", + __FUNCTION__, + Handle, + ObjectHeader->HandleCount, + ObjectHeader->PointerCount); + return STATUS_SUCCESS; + } + + /* Decrement the handle count and detach */ + ObpDecrementHandleCount(&ObjectHeader->Body, + PsGetCurrentProcess(), + NewEntry.GrantedAccess); + return STATUS_INSUFFICIENT_RESOURCES; }
/*++ @@ -752,35 +1016,21 @@ * @remarks None. * *--*/ -#if 0 // waiting on thomas -BOOLEAN +VOID NTAPI ObpCloseHandleCallback(IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context) { +#if 0 POBP_CLOSE_HANDLE_CONTEXT CloseContext = (POBP_CLOSE_HANDLE_CONTEXT)Context;
/* Simply decrement the handle count */ - ObpCloseHandleTableEntry(Context->HandleTable, + ObpCloseHandleTableEntry(CloseContext->HandleTable, HandleTableEntry, Handle, - Context->AccessMode, + CloseContext->AccessMode, TRUE); - - /* Return success */ - return TRUE; -#else -VOID -NTAPI -ObpCloseHandleCallback(IN PHANDLE_TABLE HandleTable, - IN PVOID Object, - IN ULONG GrantedAccess, - IN PVOID Context) -{ - ObpDecrementHandleCount(&EX_OBJ_TO_HDR(Object)->Body, - PsGetCurrentProcess(), - GrantedAccess); #endif }
@@ -1409,7 +1659,6 @@ AUX_DATA AuxData; BOOLEAN IsNamed = FALSE; OB_OPEN_REASON OpenReason = ObCreateHandle; - static int LostOptimizations = 0; PAGED_CODE();
/* Get the Header and Create Info */ @@ -1424,14 +1673,31 @@ /* Check if the object is unnamed and also doesn't have security */ if ((!ObjectType->TypeInfo.SecurityRequired) && !(IsNamed)) { - /* - * FIXME: TODO (Optimized path through ObpIncrement*UnNamed*HandleCount). - * Described in chapter 6 of Gl00my, but babelfish translation isn't fully - * clear, so waiting on Aleksey's translation. Currently just profiling. - * (about ~500 calls per boot - not critical atm). - */ - ++LostOptimizations; - DPRINT("Optimized case could've be taken: %d times!\n", LostOptimizations); + /* ReactOS HACK */ + if (Handle) + { + /* Assume failure */ + *Handle = NULL; + + /* Create the handle */ + Status = ObpCreateUnnamedHandle(Object, + DesiredAccess, + AdditionalReferences + 1, + ObjectCreateInfo->Attributes, + ExGetPreviousMode(), + ReferencedObject, + Handle); + } + + /* Free the create information */ + ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo); + Header->ObjectCreateInfo = NULL; + + /* Remove the extra keep-alive reference */ + //ObDereferenceObject(Object); FIXME: Will require massive changes + + /* Return */ + return Status; }
/* Check if we didn't get an access state */