Author: ion Date: Mon Jan 22 11:15:17 2007 New Revision: 25586
URL: http://svn.reactos.org/svn/reactos?rev=25586&view=rev Log: - Implement new ExHandle* implementation using pushlocks and the Windows 2003 HANDLE_TABLE structure and semantics. Only the currently used base APIs were implemented; support for audit masks still disabled, debug/tracing calls disabled. - Remove manual overrides of NTDDI_VERSION all over the thread and set it once globally, since ExHandle* was the only non-updated package. The entire kernel now builds with Windows 2003 SP1 as a target. - Remove this entry from kernel fun.
Modified: trunk/reactos/ntoskrnl/KrnlFun.c trunk/reactos/ntoskrnl/cm/ntfunc.c trunk/reactos/ntoskrnl/ex/handle.c trunk/reactos/ntoskrnl/include/internal/ex.h trunk/reactos/ntoskrnl/include/internal/ob.h trunk/reactos/ntoskrnl/include/ntoskrnl.h trunk/reactos/ntoskrnl/ke/apc.c trunk/reactos/ntoskrnl/ke/dpc.c trunk/reactos/ntoskrnl/ke/gate.c trunk/reactos/ntoskrnl/ke/gmutex.c trunk/reactos/ntoskrnl/ke/i386/kiinit.c trunk/reactos/ntoskrnl/ob/obhandle.c trunk/reactos/ntoskrnl/ob/oblife.c trunk/reactos/ntoskrnl/ob/obname.c trunk/reactos/ntoskrnl/ob/obref.c trunk/reactos/ntoskrnl/ob/obsecure.c trunk/reactos/ntoskrnl/ob/obwait.c trunk/reactos/ntoskrnl/ps/kill.c trunk/reactos/ntoskrnl/rtl/libsupp.c
Modified: trunk/reactos/ntoskrnl/KrnlFun.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=2558... ============================================================================== --- trunk/reactos/ntoskrnl/KrnlFun.c (original) +++ trunk/reactos/ntoskrnl/KrnlFun.c Mon Jan 22 11:15:17 2007 @@ -7,9 +7,6 @@ // Do NOT complain about it. // Do NOT ask when it will be fixed. // Failure to respect this will *ACHIEVE NOTHING*. -// -// Ex: -// - Use pushlocks for handle implementation. // // Ke2: // - Dispatcher Rewrite (DPCs-Timers-Waits).
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/cm/ntfunc.c (original) +++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon Jan 22 11:15:17 2007 @@ -66,7 +66,7 @@ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
/* check that this is a valid kernel pointer */ - ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); + //ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
if (GrantedAccess & MAXIMUM_ALLOWED) { @@ -82,9 +82,9 @@
NewEntry.Object = ObjectHeader; if(HandleAttributes & OBJ_INHERIT) - NewEntry.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; + NewEntry.ObAttributes |= OBJ_INHERIT; else - NewEntry.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; + NewEntry.ObAttributes &= ~OBJ_INHERIT; NewEntry.GrantedAccess = GrantedAccess;
if ((HandleAttributes & OBJ_KERNEL_HANDLE) &&
Modified: trunk/reactos/ntoskrnl/ex/handle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/handle.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ex/handle.c (original) +++ trunk/reactos/ntoskrnl/ex/handle.c Mon Jan 22 11:15:17 2007 @@ -1,937 +1,1241 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ex/handle.c +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ex/init.c * PURPOSE: Generic Executive Handle Tables - * - * PROGRAMMERS: Thomas Weidenmueller w3seek@reactos.com - * - * TODO: - * - * - the last entry of a subhandle list should be reserved for auditing - * - * ExReferenceHandleDebugInfo - * ExSnapShotHandleTables - * ExpMoveFreeHandles (???) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Thomas Weidenmueller w3seek@reactos.com */
-/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/
#include <ntoskrnl.h> - #define NDEBUG -#include <internal/debug.h> - -static LIST_ENTRY ExpHandleTableHead; -static FAST_MUTEX ExpHandleTableListLock; -static LARGE_INTEGER ExpHandleShortWait; - -#define ExAcquireHandleTableListLock() \ - ExAcquireFastMutexUnsafe(&ExpHandleTableListLock) - -#define ExReleaseHandleTableListLock() \ - ExReleaseFastMutexUnsafe(&ExpHandleTableListLock) - -#define ExAcquireHandleLockExclusive(HandleTable) \ - ExAcquireResourceExclusiveLite(&(HandleTable)->HandleLock, TRUE) - -#define ExAcquireHandleLockShared(HandleTable) \ - ExAcquireResourceSharedLite(&(HandleTable)->HandleLock, TRUE) - -#define ExReleaseHandleLock(HandleTable) \ - ExReleaseResourceLite(&(HandleTable)->HandleLock) - -/* - 5 bits: reserved - 8 bits: top level index - 10 bits: middle level index - 9 bits: sub handle index -*/ -#define N_TLI_BITS 8 /* top level index */ -#define N_MLI_BITS 10 /* middle level index */ -#define N_EI_BITS 9 /* sub handle index */ -#define TLI_OFFSET (N_MLI_BITS + N_EI_BITS) -#define MLI_OFFSET N_EI_BITS -#define EI_OFFSET 0 - -#define N_TOPLEVEL_POINTERS (1 << N_TLI_BITS) -#define N_MIDDLELEVEL_POINTERS (1 << N_MLI_BITS) -#define N_SUBHANDLE_ENTRIES (1 << N_EI_BITS) -#define EX_MAX_HANDLES (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES) - -#define VALID_HANDLE_MASK (((N_TOPLEVEL_POINTERS - 1) << TLI_OFFSET) | \ - ((N_MIDDLELEVEL_POINTERS - 1) << MLI_OFFSET) | ((N_SUBHANDLE_ENTRIES - 1) << EI_OFFSET)) -#define TLI_FROM_HANDLE(index) (ULONG)(((index) >> TLI_OFFSET) & (N_TOPLEVEL_POINTERS - 1)) -#define MLI_FROM_HANDLE(index) (ULONG)(((index) >> MLI_OFFSET) & (N_MIDDLELEVEL_POINTERS - 1)) -#define ELI_FROM_HANDLE(index) (ULONG)(((index) >> EI_OFFSET) & (N_SUBHANDLE_ENTRIES - 1)) - -#define N_MAX_HANDLE (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES) - -#define BUILD_HANDLE(tli, mli, eli) ((((tli) & (N_TOPLEVEL_POINTERS - 1)) << TLI_OFFSET) | \ - (((mli) & (N_MIDDLELEVEL_POINTERS - 1)) << MLI_OFFSET) | (((eli) & (N_SUBHANDLE_ENTRIES - 1)) << EI_OFFSET)) - -#define IS_INVALID_EX_HANDLE(index) \ - (((index) & ~VALID_HANDLE_MASK) != 0) -#define IS_VALID_EX_HANDLE(index) \ - (((index) & ~VALID_HANDLE_MASK) == 0) - -#define HANDLE_TO_EX_HANDLE(handle) \ - (LONG)(((LONG)(handle) >> 2) - 1) -#define EX_HANDLE_TO_HANDLE(exhandle) \ - (HANDLE)(((exhandle) + 1) << 2) - -static BOOLEAN ExpInitialized = FALSE; - -/******************************************************************************/ +#include <debug.h> + +/* GLOBALS *******************************************************************/ + +LIST_ENTRY HandleTableListHead; +EX_PUSH_LOCK HandleTableListLock; +#define SizeOfHandle(x) sizeof(HANDLE) * x + +/* PRIVATE FUNCTIONS *********************************************************/
VOID +NTAPI ExpInitializeHandleTables(VOID) { - ExpHandleShortWait.QuadPart = -50000; - InitializeListHead(&ExpHandleTableHead); - ExInitializeFastMutex(&ExpHandleTableListLock); - - ExpInitialized = TRUE; + /* Initialize the list of handle tables and the lock */ + InitializeListHead(&HandleTableListHead); + ExInitializePushLock((PULONG_PTR)&HandleTableListLock); +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN EXHANDLE LookupHandle) +{ + ULONG i, j, k, TableLevel, NextHandle; + ULONG_PTR TableBase; + PHANDLE_TABLE_ENTRY Entry = NULL; + EXHANDLE Handle = LookupHandle; + PCHAR Level1, Level2, Level3; + + /* Clear the tag bits and check what the next handle is */ + Handle.TagBits = 0; + NextHandle = HandleTable->NextHandleNeedingPool; + if (Handle.Value >= NextHandle) return NULL; + + /* Get the table code */ + TableBase = (ULONG_PTR)HandleTable->TableCode; + + /* Extract the table level and actual table base */ + TableLevel = (ULONG)(TableBase & 3); + TableBase = TableBase - TableLevel; + + /* Check what level we're running at */ + switch (TableLevel) + { + /* Direct index */ + case 0: + + /* Use level 1 and just get the entry directlry */ + Level1 = (PUCHAR)TableBase; + Entry = (PVOID)&Level1[Handle.Value * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + break; + + /* Nested index into mid level */ + case 1: + + /* Get the second table and index into it */ + Level2 = (PUCHAR)TableBase; + i = Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES); + + /* Substract this index, and get the next one */ + Handle.Value -= i; + j = Handle.Value / + (SizeOfHandle(LOW_LEVEL_ENTRIES) / sizeof(PHANDLE_TABLE_ENTRY)); + + /* Now get the next table and get the entry from it */ + Level1 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level2[j]; + Entry = (PVOID)&Level1[i * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + break; + + /* Nested index into high level */ + case 2: + + /* Start with the 3rd level table */ + Level3 = (PUCHAR)TableBase; + i = Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES); + + /* Subtract this index and get the index for the next lower table */ + Handle.Value -= i; + k = Handle.Value / + (SizeOfHandle(LOW_LEVEL_ENTRIES) / sizeof(PHANDLE_TABLE_ENTRY)); + + /* Get the remaining index in the 2nd level table */ + j = k % (MID_LEVEL_ENTRIES * sizeof(PHANDLE_TABLE_ENTRY)); + + /* Get the remaining index, which is in the third table */ + k -= j; + k /= MID_LEVEL_ENTRIES; + + /* Extract the table level for the handle in each table */ + Level2 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level3[k]; + Level1 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level2[j]; + + /* Get the handle table entry */ + Entry = (PVOID)&Level1[i * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + + default: + + /* All done */ + break; + } + + /* Return the handle entry */ + return Entry; +} + +PVOID +NTAPI +ExpAllocateTablePagedPool(IN PEPROCESS Process OPTIONAL, + IN SIZE_T Size) +{ + PVOID Buffer; + + /* Do the allocation */ + Buffer = ExAllocatePoolWithTag(PagedPool, Size, TAG('O', 'b', 't', 'b')); + if (Buffer) + { + /* Clear the memory */ + RtlZeroMemory(Buffer, Size); + + /* Check if we have a process to charge quota */ + if (Process) + { + /* FIXME: Charge quota */ + } + } + + /* Return the allocated memory */ + return Buffer; +} + +PVOID +NTAPI +ExpAllocateTablePagedPoolNoZero(IN PEPROCESS Process OPTIONAL, + IN SIZE_T Size) +{ + PVOID Buffer; + + /* Do the allocation */ + Buffer = ExAllocatePoolWithTag(PagedPool, Size, TAG('O', 'b', 't', 'b')); + if (Buffer) + { + /* Check if we have a process to charge quota */ + if (Process) + { + /* FIXME: Charge quota */ + } + } + + /* Return the allocated memory */ + return Buffer; +} + +VOID +NTAPI +ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, + IN PVOID Buffer, + IN SIZE_T Size) +{ + /* Free the buffer */ + ExFreePool(Buffer); + if (Process) + { + /* FIXME: Release quota */ + } +} + +VOID +NTAPI +ExpFreeLowLevelTable(IN PEPROCESS Process, + IN PHANDLE_TABLE_ENTRY TableEntry) +{ + /* Check if we have an entry */ + if (TableEntry[0].Object) + { + /* Free the entry */ + ExpFreeTablePagedPool(Process, + TableEntry[0].Object, + LOW_LEVEL_ENTRIES * + sizeof(HANDLE_TABLE_ENTRY_INFO)); + } + + /* Free the table */ + ExpFreeTablePagedPool(Process, TableEntry, PAGE_SIZE); +} + +VOID +NTAPI +ExpFreeHandleTable(IN PHANDLE_TABLE HandleTable) +{ + PEPROCESS Process = HandleTable->QuotaProcess; + ULONG i, j; + ULONG TableLevel = (ULONG)(HandleTable->TableCode & 3); + ULONG_PTR TableBase = HandleTable->TableCode & ~3; + PHANDLE_TABLE_ENTRY Level1, *Level2, **Level3; + PAGED_CODE(); + + /* Check which level we're at */ + if (!TableLevel) + { + /* Select the first level table base and just free it */ + Level1 = (PVOID)TableBase; + ExpFreeLowLevelTable(Process, Level1); + } + else if (TableLevel == 1) + { + /* Select the second level table base */ + Level2 = (PVOID)TableBase; + + /* Loop each mid level entry */ + for (i = 0; i < MID_LEVEL_ENTRIES; i++) + { + /* Leave if we've reached the last entry */ + if (!Level2[i]) break; + + /* Free the second level table */ + ExpFreeLowLevelTable(Process, Level2[i]); + } + + /* Free the second level table */ + ExpFreeTablePagedPool(Process, Level2, PAGE_SIZE); + } + else + { + /* Select the third level table base */ + Level3 = (PVOID)TableBase; + + /* Loop each high level entry */ + for (i = 0; i < HIGH_LEVEL_ENTRIES; i++) + { + /* Leave if we've reached the last entry */ + if (!Level3[i]) break; + + /* Loop each mid level entry */ + for (j = 0; j < MID_LEVEL_ENTRIES; j++) + { + /* Leave if we've reached the last entry */ + if (!Level3[i][j]) break; + + /* Free the second level table */ + ExpFreeLowLevelTable(Process, Level3[i][j]); + } + + /* Free the third level table entry */ + ExpFreeTablePagedPool(Process, Level3[i], PAGE_SIZE); + } + + /* Free the third level table */ + ExpFreeTablePagedPool(Process, + Level3, + HIGH_LEVEL_ENTRIES * + sizeof(PHANDLE_TABLE_ENTRY)); + } + + /* Free the actual table and check if we need to release quota */ + ExFreePool(HandleTable); + if (Process) + { + /* FIXME: TODO */ + } +} + +VOID +NTAPI +ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN EXHANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + ULONG OldValue, NewValue, *Free; + ULONG i; + PAGED_CODE(); + + /* Sanity checks */ + ASSERT(HandleTableEntry->Object == NULL); + ASSERT(HandleTableEntry == ExpLookupHandleTableEntry(HandleTable, Handle)); + + /* Decrement the handle count */ + InterlockedDecrement(&HandleTable->HandleCount); + + /* Mark the handle as free */ + NewValue = (ULONG)Handle.Value & ~(SizeOfHandle(1) - 1); + + /* Check if we're FIFO */ + if (!HandleTable->StrictFIFO) + { + /* Select a lock index */ + i = (NewValue >> 2) % 4; + + /* Select which entry to use */ + Free = (HandleTable->HandleTableLock[i].Locked) ? + &HandleTable->FirstFree : &HandleTable->LastFree; + } + else + { + /* No need to worry about locking, take the last entry */ + Free = &HandleTable->LastFree; + } + + /* Start value change loop */ + for (;;) + { + /* Get the current value and write */ + OldValue = *Free; + HandleTableEntry->NextFreeTableEntry = (ULONG)OldValue; + if (InterlockedCompareExchange(Free, NewValue, OldValue) == OldValue) + { + /* Break out, we're done. Make sure the handle value makes sense */ + ASSERT((OldValue & FREE_HANDLE_MASK) < + HandleTable->NextHandleNeedingPool); + break; + } + } }
PHANDLE_TABLE -ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL) -{ - PHANDLE_TABLE HandleTable; - - PAGED_CODE(); - - if(!ExpInitialized) - { +NTAPI +ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL, + IN BOOLEAN NewTable) +{ + PHANDLE_TABLE HandleTable; + PHANDLE_TABLE_ENTRY HandleTableTable, HandleEntry; + ULONG i; + PAGED_CODE(); + + /* Allocate the table */ + HandleTable = ExAllocatePoolWithTag(PagedPool, + sizeof(HANDLE_TABLE), + TAG('O', 'b', 't', 'b')); + if (!HandleTable) return NULL; + + /* Check if we have a process */ + if (Process) + { + /* FIXME: Charge quota */ + } + + /* Clear the table */ + RtlZeroMemory(HandleTable, sizeof(HANDLE_TABLE)); + + /* Now allocate the first level structures */ + HandleTableTable = ExpAllocateTablePagedPoolNoZero(Process, PAGE_SIZE); + if (!HandleTableTable) + { + /* Failed, free the table */ + ExFreePool(HandleTable); + return NULL; + } + + /* Write the pointer to our first level structures */ + HandleTable->TableCode = (ULONG_PTR)HandleTableTable; + + /* Initialize the first entry */ + HandleEntry = &HandleTableTable[0]; + HandleEntry->NextFreeTableEntry = -2; + HandleEntry->Value = 0; + + /* Check if this is a new table */ + if (NewTable) + { + /* Go past the root entry */ + HandleEntry++; + + /* Loop every low level entry */ + for (i = 1; i < (LOW_LEVEL_ENTRIES - 1); i++) + { + /* Set up the free data */ + HandleEntry->Value = 0; + HandleEntry->NextFreeTableEntry = (i + 1) * SizeOfHandle(1); + + /* Move to the next entry */ + HandleEntry++; + } + + /* Terminate the last entry */ + HandleEntry->Value = 0; + HandleEntry->NextFreeTableEntry = 0; + HandleTable->FirstFree = SizeOfHandle(1); + } + + /* Set the next handle needing pool after our allocated page from above */ + HandleTable->NextHandleNeedingPool = LOW_LEVEL_ENTRIES * SizeOfHandle(1); + + /* Setup the rest of the handle table data */ + HandleTable->QuotaProcess = Process; + HandleTable->UniqueProcessId = PsGetCurrentProcess()->UniqueProcessId; + HandleTable->Flags = 0; + + /* Loop all the handle table locks */ + for (i = 0; i < 4; i++) HandleTable->HandleTableLock[i].Value = 0; + + /* Initialize the contention event lock and return the lock */ + HandleTable->HandleContentionEvent.Value = 0; + return HandleTable; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpAllocateLowLevelTable(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit) +{ + ULONG i, Base; + PHANDLE_TABLE_ENTRY Low, HandleEntry; + + /* Allocate the low level table */ + Low = ExpAllocateTablePagedPoolNoZero(HandleTable->QuotaProcess, + PAGE_SIZE); + if (!Low) return NULL; + + /* Setup the initial entry */ + HandleEntry = &Low[0]; + HandleEntry->NextFreeTableEntry = -2; + HandleEntry->Value = 0; + + /* Check if we're initializing */ + if (DoInit) + { + /* Go to the next entry and the base entry */ + HandleEntry++; + Base = HandleTable->NextHandleNeedingPool + SizeOfHandle(2); + + /* Loop each entry */ + for (i = Base; + i < Base + SizeOfHandle(LOW_LEVEL_ENTRIES - 2); + i += SizeOfHandle(1)) + { + /* Free this entry and move on to the next one */ + HandleEntry->NextFreeTableEntry = i; + HandleEntry->Value = 0; + HandleEntry++; + } + + /* Terminate the last entry */ + HandleEntry->NextFreeTableEntry = 0; + HandleEntry->Value = 0; + } + + /* Return the low level table */ + return Low; +} + +PHANDLE_TABLE_ENTRY* +NTAPI +ExpAllocateMidLevelTable(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit, + OUT PHANDLE_TABLE_ENTRY *LowTableEntry) +{ + PHANDLE_TABLE_ENTRY *Mid, Low; + + /* Allocate the mid level table */ + Mid = ExpAllocateTablePagedPool(HandleTable->QuotaProcess, PAGE_SIZE); + if (!Mid) return NULL; + + /* Allocate a new low level for it */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) + { + /* We failed, free the mid table */ + ExpFreeTablePagedPool(HandleTable->QuotaProcess, Mid, PAGE_SIZE); + return NULL; + } + + /* Link the tables and return the pointer */ + Mid[0] = Low; + *LowTableEntry = Low; + return Mid; +} + +BOOLEAN +NTAPI +ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit) +{ + ULONG i, j, Index; + PHANDLE_TABLE_ENTRY Low, *Mid, **High, *SecondLevel, **ThirdLevel; + ULONG NewFree, FirstFree; + PVOID Value; + ULONG_PTR TableBase = HandleTable->TableCode & ~3; + ULONG TableLevel = (ULONG)(TableBase & 3); + PAGED_CODE(); + + /* Check how many levels we already have */ + if (!TableLevel) + { + /* Allocate a mid level, since we only have a low level */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) return FALSE; + + /* Link up the tables */ + Mid[1] = Mid[0]; + Mid[0] = (PVOID)TableBase; + + /* Write the new level and attempt to change the table code */ + TableBase = ((ULONG_PTR)Mid) | 1; + Value = InterlockedExchangePointer(&HandleTable->TableCode, TableBase); + } + else if (TableLevel == 1) + { + /* Setup the 2nd level table */ + SecondLevel = (PVOID)TableBase; + + /* Get if the next index can fit in the table */ + i = HandleTable->NextHandleNeedingPool / + SizeOfHandle(LOW_LEVEL_ENTRIES); + if (i < MID_LEVEL_ENTRIES) + { + /* We need to allocate a new table */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) return FALSE; + + /* Update the table */ + Value = InterlockedExchangePointer(&SecondLevel[i], Low); + ASSERT(Value == NULL); + } + else + { + /* We need a new high level table */ + High = ExpAllocateTablePagedPool(HandleTable->QuotaProcess, + HIGH_LEVEL_ENTRIES); + if (!High) return FALSE; + + /* Allocate a new mid level table as well */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) + { + /* We failed, free the high level table as welll */ + ExpFreeTablePagedPool(HandleTable->QuotaProcess, + High, + HIGH_LEVEL_ENTRIES); + return FALSE; + } + + /* Link up the tables */ + High[0] = (PVOID)TableBase; + High[1] = Mid; + + /* Write the new table and change the table code */ + TableBase = ((ULONG_PTR)High) | 2; + Value = InterlockedExchangePointer(&HandleTable->TableCode, + (PVOID)TableBase); + } + } + else if (TableLevel == 2) + { + /* Setup the 3rd level table */ + ThirdLevel = (PVOID)TableBase; + + /* Get the index and check if it can fit */ + i = HandleTable->NextHandleNeedingPool / SizeOfHandle(MAX_MID_INDEX); + if (i >= HIGH_LEVEL_ENTRIES) return FALSE; + + /* Check if there's no mid-level table */ + if (!ThirdLevel[i]) + { + /* Allocate a new mid level table */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) return FALSE; + + /* Update the table pointer */ + Value = InterlockedExchangePointer(&ThirdLevel[i], Mid); + ASSERT(Value == NULL); + } + else + { + /* We have one, check at which index we should insert our entry */ + Index = (HandleTable->NextHandleNeedingPool / SizeOfHandle(1)) - + i * MAX_MID_INDEX; + j = Index / LOW_LEVEL_ENTRIES; + + /* Allocate a new low level */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) return FALSE; + + /* Update the table pointer */ + Value = InterlockedExchangePointer(&ThirdLevel[i][j], Low); + ASSERT(Value == NULL); + } + } + + /* Update the index of the next handle */ + Index = InterlockedExchangeAdd(&HandleTable->NextHandleNeedingPool, + SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* Check if need to initialize the table */ + if (DoInit) + { + /* Create a new index number */ + Index += SizeOfHandle(1); + + /* Start free index change loop */ + for (;;) + { + /* Setup the first free index */ + FirstFree = HandleTable->FirstFree; + Low[LOW_LEVEL_ENTRIES - 1].NextFreeTableEntry = FirstFree; + + /* Change the index */ + NewFree = InterlockedCompareExchange(&HandleTable->FirstFree, + Index, + FirstFree); + if (NewFree == FirstFree) break; + } + } + + /* All done */ + return TRUE; +} + +ULONG +NTAPI +ExpMoveFreeHandles(IN PHANDLE_TABLE HandleTable) +{ + ULONG LastFree, i; + + /* Clear the last free index */ + LastFree = InterlockedExchange(&HandleTable->LastFree, 0); + + /* Check if we had no index */ + if (!LastFree) return LastFree; + + /* Acquire the locks we need */ + for (i = 1; i < 4; i++) + { + /* Acquire this lock exclusively */ + ExWaitOnPushLock(&HandleTable->HandleTableLock[i]); + } + + /* Check if we're not strict FIFO */ + if (!HandleTable->StrictFIFO) + { + /* Update the first free index */ + if (!InterlockedCompareExchange(&HandleTable->FirstFree, LastFree, 0)) + { + /* We're done, exit */ + return LastFree; + } + } + + /* We are strict FIFO, we need to reverse the entries */ KEBUGCHECK(0); - } - - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - /* allocate enough memory for the handle table and the lowest level */ - HandleTable = ExAllocatePoolWithTag(NonPagedPool, - sizeof(HANDLE_TABLE) + (N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*)), - TAG('E', 'x', 'H', 't')); - if(HandleTable != NULL) - { - /* initialize the handle table */ - HandleTable->Flags = 0; - HandleTable->HandleCount = 0; - HandleTable->Table = (PHANDLE_TABLE_ENTRY**)(HandleTable + 1); - HandleTable->QuotaProcess = QuotaProcess; - HandleTable->FirstFree = -1; /* no entries freed so far */ - HandleTable->NextHandleNeedingPool = 0; /* no entries freed so far, so we have to allocate already for the first handle */ - HandleTable->UniqueProcessId = (QuotaProcess ? QuotaProcess->UniqueProcessId : NULL); - - ExInitializeResource(&HandleTable->HandleLock); - - KeInitializeEvent(&HandleTable->HandleContentionEvent, - NotificationEvent, - FALSE); - - RtlZeroMemory(HandleTable->Table, N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*)); - - /* during bootup KeGetCurrentThread() might be NULL, needs to be fixed... */ - if(KeGetCurrentThread() != NULL) - { - /* insert it into the global handle table list */ - KeEnterCriticalRegion(); - - ExAcquireHandleTableListLock(); - InsertTailList(&ExpHandleTableHead, - &HandleTable->HandleTableList); - ExReleaseHandleTableListLock(); - - KeLeaveCriticalRegion(); + return LastFree; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable, + OUT PEXHANDLE NewHandle) +{ + ULONG OldValue, NewValue, NewValue1; + PHANDLE_TABLE_ENTRY Entry; + EXHANDLE Handle; + BOOLEAN Result; + ULONG i; + + /* Start allocation loop */ + for (;;) + { + /* Get the current link */ + OldValue = HandleTable->FirstFree; + while (!OldValue) + { + /* No free entries remain, lock the handle table */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTable->HandleTableLock[0]); + + /* Check the value again */ + OldValue = HandleTable->FirstFree; + if (OldValue) + { + /* Another thread has already created a new level, bail out */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + break; + } + + /* Now move any free handles */ + OldValue = ExpMoveFreeHandles(HandleTable); + if (OldValue) + { + /* Another thread has already moved them, bail out */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + break; + } + + /* We're the first one through, so do the actual allocation */ + Result = ExpAllocateHandleTableEntrySlow(HandleTable, TRUE); + + /* Unlock the table and get the value now */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + OldValue = HandleTable->FirstFree; + + /* Check if allocation failed */ + if (!Result) + { + /* Check if nobody else went through here */ + if (!OldValue) + { + /* We're still the only thread around, so fail */ + NewHandle->GenericHandleOverlay = NULL; + return NULL; + } + } + } + + /* We made it, write the current value */ + Handle.Value = (OldValue & FREE_HANDLE_MASK); + + /* Lookup the entry for this handle */ + Entry = ExpLookupHandleTableEntry(HandleTable, Handle); + + /* Get an available lock and acquire it */ + i = ((OldValue & FREE_HANDLE_MASK) >> 2) % 4; + KeEnterCriticalRegion(); + ExAcquirePushLockShared(&HandleTable->HandleTableLock[i]); + + /* Check if the value changed after acquiring the lock */ + if (OldValue != HandleTable->FirstFree) + { + /* It did, so try again */ + ExReleasePushLockShared(&HandleTable->HandleTableLock[i]); + KeLeaveCriticalRegion(); + continue; + } + + /* Now get the next value and do the compare */ + NewValue = Entry->NextFreeTableEntry; + NewValue1 = InterlockedCompareExchange(&HandleTable->FirstFree, + NewValue, + OldValue); + + /* The change was done, so release the lock */ + ExReleasePushLockShared(&HandleTable->HandleTableLock[i]); + KeLeaveCriticalRegion(); + + /* Check if the compare was successful */ + if (NewValue1 == OldValue) + { + /* Make sure that the new handle is in range, and break out */ + ASSERT((NewValue & FREE_HANDLE_MASK) < + HandleTable->NextHandleNeedingPool); + break; + } + else + { + /* The compare failed, make sure we expected it */ + ASSERT((NewValue1 & FREE_HANDLE_MASK) != + (OldValue & FREE_HANDLE_MASK)); + } + } + + /* Increase the number of handles */ + InterlockedIncrement(&HandleTable->HandleCount); + + /* Return the handle and the entry */ + *NewHandle = Handle; + return Entry; +} + +PHANDLE_TABLE +NTAPI +ExCreateHandleTable(IN PEPROCESS Process OPTIONAL) +{ + PHANDLE_TABLE HandleTable; + PAGED_CODE(); + + /* Allocate the handle table */ + HandleTable = ExpAllocateHandleTable(Process, TRUE); + if (!HandleTable) return NULL; + + /* Acquire the handle table lock */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTableListLock); + + /* Insert it into the list */ + InsertTailList(&HandleTableListHead, &HandleTable->HandleTableList); + + /* Release the lock */ + ExReleasePushLockExclusive(&HandleTableListLock); + KeLeaveCriticalRegion(); + + /* Return the handle table */ + return HandleTable; +} + +HANDLE +NTAPI +ExCreateHandle(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY NewEntry; + PAGED_CODE(); + + /* Start with a clean handle */ + Handle.GenericHandleOverlay = NULL; + + /* Allocate a new entry */ + NewEntry = ExpAllocateHandleTableEntry(HandleTable, &Handle); + if (NewEntry) + { + /* Enter a critical region */ + KeEnterCriticalRegion(); + + /* Write the entry */ + *NewEntry = *HandleTableEntry; + + /* Unlock it and leave the critical region */ + ExUnlockHandleTableEntry(HandleTable, NewEntry); + KeLeaveCriticalRegion(); + } + + /* Return the handle value */ + return Handle.GenericHandleOverlay; +} + +VOID +NTAPI +ExpBlockOnLockedHandleEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR OldValue; + DEFINE_WAIT_BLOCK(WaitBlock); + + /* Block on the pushlock */ + ExBlockPushLock(&HandleTable->HandleContentionEvent, WaitBlock); + + /* Get the current value and check if it's been unlocked */ + OldValue = HandleTableEntry->Value; + if (!(OldValue) || (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT)) + { + /* Unblock the pushlock and return */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, WaitBlock); } else { - InsertTailList(&ExpHandleTableHead, - &HandleTable->HandleTableList); - } - } - else - { - /* FIXME - return the quota to the process */ - } - - return HandleTable; + /* Wait for it to be unblocked */ + ExWaitForUnblockPushLock(&HandleTable->HandleContentionEvent, + WaitBlock); + } +} + +BOOLEAN +NTAPI +ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR NewValue, OldValue; + + /* Sanity check */ + ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) || + (KeGetCurrentIrql() == APC_LEVEL)); + + /* Start lock loop */ + for (;;) + { + /* Get the current value and check if it's locked */ + OldValue = (LONG_PTR)HandleTableEntry->Object; + if (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT) + { + /* It's not locked, remove the lock bit to lock it */ + NewValue = OldValue & ~EXHANDLE_TABLE_ENTRY_LOCK_BIT; + if (InterlockedCompareExchangePointer(&HandleTableEntry->Object, + NewValue, + OldValue) == (PVOID)OldValue) + { + /* We locked it, get out */ + return TRUE; + } + } + else + { + /* We couldn't lock it, bail out if it's been freed */ + if (!OldValue) return FALSE; + } + + /* It's locked, wait for it to be unlocked */ + ExpBlockOnLockedHandleEntry(HandleTable, HandleTableEntry); + } }
VOID -ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, - IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL) -{ - PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; - LONG ExHandle = 0; - - PAGED_CODE(); - - ASSERT(HandleTable); - - KeEnterCriticalRegion(); - - /* ensure there's no other operations going by acquiring an exclusive lock */ - ExAcquireHandleLockExclusive(HandleTable); - - ASSERT(!(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING)); - - HandleTable->Flags |= EX_HANDLE_TABLE_CLOSING; - - KePulseEvent(&HandleTable->HandleContentionEvent, - EVENT_INCREMENT, - FALSE); - - /* call the callback function to cleanup the objects associated with the - handle table */ - for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS; - tlp != lasttlp; - tlp++) - { - if((*tlp) != NULL) - { - for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS; - mlp != lastmlp; - mlp++) - { - if((*mlp) != NULL) - { - PHANDLE_TABLE_ENTRY curee, laste; - - for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES; - curee != laste; - curee++) - { - if(curee->Object != NULL && SweepHandleCallback != NULL) +NTAPI +ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR OldValue; + PAGED_CODE(); + + /* Sanity check */ + ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) || + (KeGetCurrentIrql() == APC_LEVEL)); + + /* Set the lock bit and make sure it wasn't earlier */ + OldValue = InterlockedOr(&HandleTableEntry->Value, + EXHANDLE_TABLE_ENTRY_LOCK_BIT); + ASSERT((OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + + /* Unblock any waiters */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL); +} + +VOID +NTAPI +ExRemoveHandleTable(IN PHANDLE_TABLE HandleTable) +{ + PAGED_CODE(); + + /* Acquire the table lock */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTableListLock); + + /* Remove the table and reset the list */ + RemoveEntryList(&HandleTable->HandleTableList); + InitializeListHead(&HandleTable->HandleTableList); + + /* Release the lock */ + ExReleasePushLockExclusive(&HandleTableListLock); + KeLeaveCriticalRegion(); +} + +VOID +NTAPI +ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, + IN PVOID DestroyHandleProcedure OPTIONAL) +{ + PAGED_CODE(); + + /* Remove the handle from the list */ + ExRemoveHandleTable(HandleTable); + + /* Check if we have a desotry callback */ + if (DestroyHandleProcedure) + { + /* FIXME: */ + KEBUGCHECK(0); + } + + /* Free the handle table */ + ExpFreeHandleTable(HandleTable); +} + +BOOLEAN +NTAPI +ExDestroyHandle(IN PHANDLE_TABLE HandleTable, + IN HANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL) +{ + EXHANDLE ExHandle; + PVOID Object; + PAGED_CODE(); + + /* Setup the actual handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Enter a critical region and check if we have to lookup the handle */ + KeEnterCriticalRegion(); + if (!HandleTableEntry) + { + /* Lookup the entry */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + + /* Make sure that we found an entry, and that it's valid */ + if (!(HandleTableEntry) || + !(HandleTableEntry->Object) || + (HandleTableEntry->NextFreeTableEntry == -2)) + { + /* Invalid handle, fail */ + KeLeaveCriticalRegion(); + return FALSE; + } + + /* Lock the entry */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Couldn't lock, fail */ + KeLeaveCriticalRegion(); + return FALSE; + } + } + else + { + /* Make sure the handle is locked */ + ASSERT((HandleTableEntry->Value & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + } + + /* Clear the handle */ + Object = InterlockedExchangePointer(&HandleTableEntry->Object, NULL); + + /* Sanity checks */ + ASSERT(Object != NULL); + ASSERT((((ULONG_PTR)Object) & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + + /* Unblock the pushlock */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL); + + /* Free the actual entry */ + ExpFreeHandleTableEntry(HandleTable, ExHandle, HandleTableEntry); + + /* If we got here, return success */ + KeLeaveCriticalRegion(); + return TRUE; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, + IN HANDLE Handle) +{ + EXHANDLE ExHandle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + PAGED_CODE(); + + /* Set the handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Fail if we got an invalid index */ + if (!(ExHandle.Index & (LOW_LEVEL_ENTRIES - 1))) return NULL; + + /* Do the lookup */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + if (!HandleTableEntry) return NULL; + + /* Lock it */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) return NULL; + + /* Return the entry */ + return HandleTableEntry; +} + +PHANDLE_TABLE +NTAPI +ExDupHandleTable(IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, + IN ULONG_PTR Mask) +{ + PHANDLE_TABLE NewTable; + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY HandleTableEntry, NewEntry; + BOOLEAN Failed = FALSE; + PAGED_CODE(); + + /* Allocate the duplicated copy */ + NewTable = ExpAllocateHandleTable(Process, FALSE); + if (!NewTable) return NULL; + + /* Loop each entry */ + while (NewTable->NextHandleNeedingPool < + HandleTable->NextHandleNeedingPool) + { + /* Insert it into the duplicated copy */ + if (!ExpAllocateHandleTableEntrySlow(NewTable, FALSE)) + { + /* Insert failed, free the new copy and return */ + ExpFreeHandleTable(NewTable); + return NULL; + } + } + + /* Setup the initial handle table data */ + NewTable->HandleCount = 0; + NewTable->ExtraInfoPages = 0; + NewTable->FirstFree = 0; + + /* Setup the first handle value */ + Handle.Value = SizeOfHandle(1); + + /* Enter a critical region and lookup the new entry */ + KeEnterCriticalRegion(); + while ((NewEntry = ExpLookupHandleTableEntry(NewTable, Handle))) + { + /* Lookup the old entry */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle); + + /* Loop each entry */ + do + { + /* Check if it doesn't match the audit mask */ + if (!(HandleTableEntry->Value & Mask)) { - curee->ObAttributes |= EX_HANDLE_ENTRY_LOCKED; - SweepHandleCallback(curee, EX_HANDLE_TO_HANDLE(ExHandle), Context); - } - - ExHandle++; - } - } - else - break; - } - } - else - break; - } - - ExReleaseHandleLock(HandleTable); - - KeLeaveCriticalRegion(); -} - -VOID -ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable) -{ - PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; - PEPROCESS QuotaProcess; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING); - - KeEnterCriticalRegion(); - - /* at this point the table should not be queried or altered anymore, - no locks should be necessary */ - - ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING); - - /* remove the handle table from the global handle table list */ - ExAcquireHandleTableListLock(); - RemoveEntryList(&HandleTable->HandleTableList); - ExReleaseHandleTableListLock(); - - QuotaProcess = HandleTable->QuotaProcess; - - /* free the tables */ - for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS; - tlp != lasttlp; - tlp++) - { - if((*tlp) != NULL) - { - for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS; - mlp != lastmlp; - mlp++) - { - if((*mlp) != NULL) - { - ExFreePool(*mlp); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - } - } - - ExFreePool(*tlp); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - } - } - - KeLeaveCriticalRegion(); - - /* free the handle table */ - ExDeleteResource(&HandleTable->HandleLock); - ExFreePool(HandleTable); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } -} - -PHANDLE_TABLE -ExDupHandleTable(IN PEPROCESS QuotaProcess OPTIONAL, - IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL, - IN PHANDLE_TABLE SourceHandleTable) -{ - PHANDLE_TABLE HandleTable; - - PAGED_CODE(); - - ASSERT(SourceHandleTable); - - HandleTable = ExCreateHandleTable(QuotaProcess); - if(HandleTable != NULL) - { - PHANDLE_TABLE_ENTRY **tlp, **srctlp, **etlp, *mlp, *srcmlp, *emlp, stbl, srcstbl, estbl; - LONG tli, mli, eli; - - tli = mli = eli = 0; - - /* make sure the other handle table isn't being changed during the duplication */ - ExAcquireHandleLockShared(SourceHandleTable); - - /* allocate enough tables */ - etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS; - for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table; - srctlp != etlp; - srctlp++, tlp++) - { - if(*srctlp != NULL) - { - /* allocate middle level entry tables */ - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - *tlp = ExAllocatePoolWithTag(PagedPool, - N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(*tlp != NULL) - { - RtlZeroMemory(*tlp, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY)); - - KeMemoryBarrier(); - - emlp = *srctlp + N_MIDDLELEVEL_POINTERS; - for(srcmlp = *srctlp, mlp = *tlp; - srcmlp != emlp; - srcmlp++, mlp++) - { - if(*srcmlp != NULL) - { - /* allocate subhandle tables */ - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - *mlp = ExAllocatePoolWithTag(PagedPool, - N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(*mlp != NULL) - { - RtlZeroMemory(*mlp, N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY)); - } - else - { - goto freehandletable; - } + /* Free it since we won't use it */ + Failed = TRUE; } else { - *mlp = NULL; - } - } - } - else - { -freehandletable: - DPRINT1("Failed to duplicate handle table 0x%p\n", SourceHandleTable); - - ExReleaseHandleLock(SourceHandleTable); - - ExDestroyHandleTable(HandleTable); - /* allocate an empty handle table */ - return ExCreateHandleTable(QuotaProcess); - } - } - } - - /* duplicate the handles */ - HandleTable->HandleCount = SourceHandleTable->HandleCount; - HandleTable->FirstFree = SourceHandleTable->FirstFree; - HandleTable->NextHandleNeedingPool = SourceHandleTable->NextHandleNeedingPool; - - /* make sure all tables are zeroed */ - KeMemoryBarrier(); - - etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS; - for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table; - srctlp != etlp; - srctlp++, tlp++, tli++) - { - if(*srctlp != NULL) - { - ASSERT(*tlp != NULL); - - emlp = *srctlp + N_MIDDLELEVEL_POINTERS; - for(srcmlp = *srctlp, mlp = *tlp; - srcmlp != emlp; - srcmlp++, mlp++, mli++) - { - if(*srcmlp != NULL) - { - ASSERT(*mlp != NULL); - - /* walk all handle entries and duplicate them if wanted */ - estbl = *srcmlp + N_SUBHANDLE_ENTRIES; - for(srcstbl = *srcmlp, stbl = *mlp; - srcstbl != estbl; - srcstbl++, stbl++, eli++) - { - /* try to duplicate the source handle */ - if(srcstbl->Object != NULL && - ExLockHandleTableEntry(SourceHandleTable, - srcstbl)) - { - /* ask the caller if this handle should be duplicated */ - if(DuplicateHandleCallback != NULL && - !DuplicateHandleCallback(HandleTable, - srcstbl, - Context)) + /* Lock the entry */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) { - /* free the entry and chain it into the free list */ - HandleTable->HandleCount--; - stbl->Object = NULL; - stbl->NextFreeTableEntry = HandleTable->FirstFree; - HandleTable->FirstFree = BUILD_HANDLE(tli, mli, eli); + /* Free it since we can't lock it, so we won't use it */ + Failed = TRUE; } else { - /* duplicate the handle and unlock it */ - stbl->GrantedAccess = srcstbl->GrantedAccess; - stbl->ObAttributes = srcstbl->ObAttributes & ~EX_HANDLE_ENTRY_LOCKED; + /* Copy the handle value */ + *NewEntry = *HandleTableEntry; + + /* Call the duplicate callback */ + if (DupHandleProcedure(Process, + HandleTable, + HandleTableEntry, + NewEntry)) + { + /* Lock the entry, increase the handle count */ + NewEntry->Value |= EXHANDLE_TABLE_ENTRY_LOCK_BIT; + NewTable->HandleCount++; + } + else + { + /* Duplication callback refused, fail */ + Failed = TRUE; + } } - ExUnlockHandleTableEntry(SourceHandleTable, - srcstbl); - } - else - { - /* this is a free handle table entry, copy over the entire - structure as-is */ - *stbl = *srcstbl; - } } - } - } - } - } - - /* release the source handle table */ - ExReleaseHandleLock(SourceHandleTable); - } - - return HandleTable; -} - -static PHANDLE_TABLE_ENTRY -ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable, - OUT PHANDLE Handle) -{ - PHANDLE_TABLE_ENTRY Entry = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Handle); - ASSERT(KeGetCurrentThread() != NULL); - - DPRINT("HT[0x%p]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount); - - if(HandleTable->HandleCount < EX_MAX_HANDLES) - { - ULONG tli, mli, eli; - - if(HandleTable->FirstFree != -1) - { - /* there's a free handle entry we can just grab and use */ - tli = TLI_FROM_HANDLE(HandleTable->FirstFree); - mli = MLI_FROM_HANDLE(HandleTable->FirstFree); - eli = ELI_FROM_HANDLE(HandleTable->FirstFree); - - /* the pointer should be valid in any way!!! */ - ASSERT(HandleTable->Table[tli]); - ASSERT(HandleTable->Table[tli][mli]); - - Entry = &HandleTable->Table[tli][mli][eli]; - - *Handle = EX_HANDLE_TO_HANDLE(HandleTable->FirstFree); - - /* save the index to the next free handle (if available) */ - HandleTable->FirstFree = Entry->NextFreeTableEntry; - Entry->NextFreeTableEntry = 0; - Entry->Object = NULL; - - HandleTable->HandleCount++; - } - else - { - /* we need to allocate a new subhandle table first */ - PHANDLE_TABLE_ENTRY cure, laste, ntbl, *nmtbl; - ULONG i; - BOOLEAN AllocatedMtbl; - - ASSERT(HandleTable->NextHandleNeedingPool <= N_MAX_HANDLE); - - /* the index of the next table to be allocated was saved in - NextHandleNeedingPool the last time a handle entry was allocated and - the subhandle entry list was full. the subhandle entry index of - NextHandleNeedingPool should be 0 here! */ - tli = TLI_FROM_HANDLE(HandleTable->NextHandleNeedingPool); - mli = MLI_FROM_HANDLE(HandleTable->NextHandleNeedingPool); - DPRINT("HandleTable->NextHandleNeedingPool: 0x%x\n", HandleTable->NextHandleNeedingPool); - DPRINT("tli: 0x%x mli: 0x%x eli: 0x%x\n", tli, mli, ELI_FROM_HANDLE(HandleTable->NextHandleNeedingPool)); - - ASSERT(ELI_FROM_HANDLE(HandleTable->NextHandleNeedingPool) == 0); - - DPRINT("HandleTable->Table[%d] == 0x%p\n", tli, HandleTable->Table[tli]); - - /* allocate a middle level entry list if required */ - nmtbl = HandleTable->Table[tli]; - if(nmtbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - nmtbl = ExAllocatePoolWithTag(PagedPool, - N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(nmtbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - - return NULL; - } - - /* clear the middle level entry list */ - RtlZeroMemory(nmtbl, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY)); - - /* make sure the table was zeroed before we set one item */ - KeMemoryBarrier(); - - /* note, don't set the the pointer in the top level list yet because we - might screw up lookups if allocating a subhandle entry table failed - and this newly allocated table might get freed again */ - AllocatedMtbl = TRUE; - } - else - { - AllocatedMtbl = FALSE; - - /* allocate a subhandle entry table in any case! */ - ASSERT(nmtbl[mli] == NULL); - } - - DPRINT("HandleTable->Table[%d][%d] == 0x%p\n", tli, mli, nmtbl[mli]); - - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - ntbl = ExAllocatePoolWithTag(PagedPool, - N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(ntbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Return process quota charged */ - } - - /* free the middle level entry list, if allocated, because it's empty and - unused */ - if(AllocatedMtbl) - { - ExFreePool(nmtbl); - - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Return process quota charged */ - } - } - - return NULL; - } - - /* let's just use the very first entry */ - Entry = ntbl; - Entry->ObAttributes = EX_HANDLE_ENTRY_LOCKED; - Entry->NextFreeTableEntry = 0; - - *Handle = EX_HANDLE_TO_HANDLE(HandleTable->NextHandleNeedingPool); - - HandleTable->HandleCount++; - - /* set the FirstFree member to the second entry and chain the - free entries */ - HandleTable->FirstFree = HandleTable->NextHandleNeedingPool + 1; - for(cure = Entry + 1, laste = Entry + N_SUBHANDLE_ENTRIES, i = HandleTable->FirstFree + 1; - cure != laste; - cure++, i++) - { - cure->Object = NULL; - cure->NextFreeTableEntry = i; - } - /* truncate the free entry list */ - (cure - 1)->NextFreeTableEntry = -1; - - /* save the pointers to the allocated list(s) */ - (void)InterlockedExchangePointer(&nmtbl[mli], ntbl); - if(AllocatedMtbl) - { - (void)InterlockedExchangePointer(&HandleTable->Table[tli], nmtbl); - } - - /* increment the NextHandleNeedingPool to the next index where we need to - allocate new memory */ - HandleTable->NextHandleNeedingPool += N_SUBHANDLE_ENTRIES; - } - } - else - { - DPRINT1("Can't allocate any more handles in handle table 0x%p!\n", HandleTable); - } - - return Entry; -} - -static VOID -ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN LONG Handle) -{ - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - ASSERT(IS_VALID_EX_HANDLE(Handle)); - - DPRINT("ExpFreeHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - /* automatically unlock the entry if currently locked. We however don't notify - anyone who waited on the handle because we're holding an exclusive lock after - all and these locks will fail then */ - (void)InterlockedExchangePointer(&Entry->Object, NULL); - Entry->NextFreeTableEntry = HandleTable->FirstFree; - HandleTable->FirstFree = Handle; - - HandleTable->HandleCount--; -} - -static PHANDLE_TABLE_ENTRY -ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN LONG Handle) -{ - PHANDLE_TABLE_ENTRY Entry = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - - if(IS_VALID_EX_HANDLE(Handle)) - { - ULONG tli, mli, eli; - PHANDLE_TABLE_ENTRY *mlp; - - tli = TLI_FROM_HANDLE(Handle); - mli = MLI_FROM_HANDLE(Handle); - eli = ELI_FROM_HANDLE(Handle); - - mlp = HandleTable->Table[tli]; - if(Handle < HandleTable->NextHandleNeedingPool && - mlp != NULL && mlp[mli] != NULL && mlp[mli][eli].Object != NULL) - { - Entry = &mlp[mli][eli]; - DPRINT("handle lookup 0x%x -> entry 0x%p [HT:0x%p] ptr: 0x%p\n", Handle, Entry, HandleTable, mlp[mli][eli].Object); - } - } - else - { - DPRINT("Looking up invalid handle 0x%x\n", Handle); - } - - return Entry; + + /* Check if we failed earlier and need to free */ + if (Failed) + { + /* Free this entry */ + NewEntry->Object = NULL; + NewEntry->NextFreeTableEntry = NewTable->FirstFree; + NewTable->FirstFree = Handle.Value; + } + + /* Increase the handle value and move to the next entry */ + Handle.Value += SizeOfHandle(1); + NewEntry++; + HandleTableEntry++; + } while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* We're done, skip the last entry */ + Handle.Value += SizeOfHandle(1); + } + + /* Acquire the table lock and insert this new table into the list */ + ExAcquirePushLockExclusive(&HandleTableListLock); + InsertTailList(&HandleTableListHead, &NewTable->HandleTableList); + ExReleasePushLockExclusive(&HandleTableListLock); + + /* Leave the critical region we entered previously and return the table */ + KeLeaveCriticalRegion(); + return NewTable; }
BOOLEAN -ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - ULONG_PTR Current, New; - - PAGED_CODE(); - - DPRINT("Entering handle table entry 0x%p lock...\n", Entry); - - ASSERT(HandleTable); - ASSERT(Entry); - - for(;;) - { - Current = (volatile ULONG_PTR)Entry->Object; - - if(!Current || (HandleTable->Flags & EX_HANDLE_TABLE_CLOSING)) - { - DPRINT("Attempted to lock empty handle table entry 0x%p or handle table shut down\n", Entry); - break; - } - - if(!(Current & EX_HANDLE_ENTRY_LOCKED)) - { - New = Current | EX_HANDLE_ENTRY_LOCKED; - if(InterlockedCompareExchangePointer(&Entry->Object, - (PVOID)New, - (PVOID)Current) == (PVOID)Current) - { - DPRINT("SUCCESS handle table 0x%p entry 0x%p lock\n", HandleTable, Entry); - /* we acquired the lock */ - return TRUE; - } - } - - /* wait about 5ms at maximum so we don't wait forever in unfortunate - co-incidences where releasing the lock in another thread happens right - before we're waiting on the contention event to get pulsed, which might - never happen again... */ - KeWaitForSingleObject(&HandleTable->HandleContentionEvent, - Executive, - KernelMode, - FALSE, - &ExpHandleShortWait); - } - - return FALSE; -} - -VOID -ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - ULONG_PTR Current, New; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - DPRINT("ExUnlockHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - Current = (volatile ULONG_PTR)Entry->Object; - - ASSERT(Current & EX_HANDLE_ENTRY_LOCKED); - - New = Current & ~EX_HANDLE_ENTRY_LOCKED; - - (void)InterlockedExchangePointer(&Entry->Object, - (PVOID)New); - - /* we unlocked the entry, pulse the contention event so threads who're waiting - on the release can continue */ - KePulseEvent(&HandleTable->HandleContentionEvent, - EVENT_INCREMENT, - FALSE); -} - -HANDLE -ExCreateHandle(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - PHANDLE_TABLE_ENTRY NewHandleTableEntry; - HANDLE Handle = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - /* The highest bit in Entry->Object has to be 1 so we make sure it's a - pointer to kmode memory. It will cleared though because it also indicates - the lock */ - ASSERT((ULONG_PTR)Entry->Object & EX_HANDLE_ENTRY_LOCKED); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - NewHandleTableEntry = ExpAllocateHandleTableEntry(HandleTable, - &Handle); - if(NewHandleTableEntry != NULL) - { - *NewHandleTableEntry = *Entry; - - ExUnlockHandleTableEntry(HandleTable, - NewHandleTableEntry); - } - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); - - return Handle; -} - -BOOLEAN -ExDestroyHandle(IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - LONG ExHandle; - BOOLEAN Ret = FALSE; - - PAGED_CODE(); - - ASSERT(HandleTable); - - ExHandle = HANDLE_TO_EX_HANDLE(Handle); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - ExHandle); - - if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - /* free and automatically unlock the handle. However we don't need to pulse - the contention event since other locks on this entry will fail */ - ExpFreeHandleTableEntry(HandleTable, - HandleTableEntry, - ExHandle); - Ret = TRUE; - } - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); - - return Ret; -} - -VOID -ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN HANDLE Handle) -{ - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - /* This routine requires the entry to be locked */ - ASSERT((ULONG_PTR)Entry->Object & EX_HANDLE_ENTRY_LOCKED); - - DPRINT("DestroyHandleByEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - /* free and automatically unlock the handle. However we don't need to pulse - the contention event since other locks on this entry will fail */ - ExpFreeHandleTableEntry(HandleTable, - Entry, - HANDLE_TO_EX_HANDLE(Handle)); - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); -} - -PHANDLE_TABLE_ENTRY -ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - - PAGED_CODE(); - - ASSERT(HandleTable); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - HANDLE_TO_EX_HANDLE(Handle)); - if (HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - DPRINT("ExMapHandleToPointer HT:0x%p Entry:0x%p locked\n", HandleTable, HandleTableEntry); - return HandleTableEntry; - } - - return NULL; -} - -BOOLEAN +NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, - IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback, - IN PVOID Context) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - BOOLEAN Ret = FALSE; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(ChangeHandleCallback); - - KeEnterCriticalRegion(); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - HANDLE_TO_EX_HANDLE(Handle)); - - if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - Ret = ChangeHandleCallback(HandleTable, - HandleTableEntry, - Context); - - ExUnlockHandleTableEntry(HandleTable, - HandleTableEntry); - } - - KeLeaveCriticalRegion(); - - return Ret; -} - -/* EOF */ + IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, + IN ULONG_PTR Context) +{ + EXHANDLE ExHandle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + BOOLEAN Result = FALSE; + PAGED_CODE(); + + /* Set the handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Find the entry for this handle */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + + /* Make sure that we found an entry, and that it's valid */ + if (!(HandleTableEntry) || + !(HandleTableEntry->Object) || + (HandleTableEntry->NextFreeTableEntry == -2)) + { + /* It isn't, fail */ + return FALSE; + } + + /* Enter a critical region */ + KeEnterCriticalRegion(); + + /* Try locking the handle entry */ + if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Call the change routine and unlock the entry */ + Result = ChangeRoutine(HandleTableEntry, Context); + ExUnlockHandleTableEntry(HandleTable, HandleTableEntry); + } + + /* Leave the critical region and return the callback result */ + KeLeaveCriticalRegion(); + return Result; +} + +VOID +NTAPI +ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, + IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, + IN PVOID Context) +{ + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + PAGED_CODE(); + + /* Set the initial value and loop the entries */ + Handle.Value = SizeOfHandle(1); + while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle))) + { + /* Loop each handle */ + do + { + /* Lock the entry */ + if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Notify the callback routine */ + EnumHandleProcedure(HandleTableEntry, + Handle.GenericHandleOverlay, + Context); + } + + /* Go to the next handle and entry */ + Handle.Value += SizeOfHandle(1); + HandleTableEntry++; + } while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* Skip past the last entry */ + Handle.Value += SizeOfHandle(1); + } +}
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/e... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h Mon Jan 22 11:15:17 2007 @@ -21,6 +21,20 @@ ULONG ExpUnicodeCaseTableDataOffset; PVOID ExpNlsSectionPointer;
+typedef struct _EXHANDLE +{ + union + { + struct + { + ULONG TagBits:2; + ULONG Index:30; + }; + HANDLE GenericHandleOverlay; + ULONG_PTR Value; + }; +} EXHANDLE, *PEXHANDLE; + typedef struct _ETIMER { KTIMER KeTimer; @@ -42,13 +56,6 @@
#define MAX_FAST_REFS 7
-#define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \ - ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE))) -#define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->Object) & \ - ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE))) - /* Note: we only use a spinlock on SMP. On UP, we cli/sti intead */ #ifndef CONFIG_SMP #define ExAcquireResourceLock(l, i) { \ @@ -67,6 +74,27 @@ #define ExWaitForRundownProtectionRelease _ExWaitForRundownProtectionRelease #define ExRundownCompleted _ExRundownCompleted #define ExGetPreviousMode KeGetPreviousMode + + +// +// Various bits tagged on the handle or handle table +// +#define EXHANDLE_TABLE_ENTRY_LOCK_BIT 1 +#define FREE_HANDLE_MASK -1 + +// +// Number of entries in each table level +// +#define LOW_LEVEL_ENTRIES (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)) +#define MID_LEVEL_ENTRIES (PAGE_SIZE / sizeof(PHANDLE_TABLE_ENTRY)) +#define HIGH_LEVEL_ENTRIES (65535 / (LOW_LEVEL_ENTRIES * MID_LEVEL_ENTRIES)) + +// +// Maximum index in each table level before we need another table +// +#define MAX_LOW_INDEX LOW_LEVEL_ENTRIES +#define MAX_MID_INDEX (MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES) +#define MAX_HIGH_INDEX (MID_LEVEL_ENTRIES * MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES)
// // Detect GCC 4.1.2+ @@ -308,104 +336,98 @@
/* HANDLE TABLE FUNCTIONS ***************************************************/
-#define EX_HANDLE_ENTRY_LOCKED (1 << ((sizeof(PVOID) * 8) - 1)) -#define EX_HANDLE_ENTRY_PROTECTFROMCLOSE (1 << 0) -#define EX_HANDLE_ENTRY_INHERITABLE (1 << 1) -#define EX_HANDLE_ENTRY_AUDITONCLOSE (1 << 2) - -#define EX_HANDLE_TABLE_CLOSING 0x1 - -#define EX_HANDLE_ENTRY_FLAGSMASK (EX_HANDLE_ENTRY_LOCKED | \ - EX_HANDLE_ENTRY_PROTECTFROMCLOSE | \ - EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE) - -typedef VOID (NTAPI PEX_SWEEP_HANDLE_CALLBACK)( +typedef VOID +(NTAPI *PEX_SWEEP_HANDLE_CALLBACK)( PHANDLE_TABLE_ENTRY HandleTableEntry, - HANDLE Handle, + HANDLE Handle, PVOID Context );
-typedef BOOLEAN (NTAPI PEX_DUPLICATE_HANDLE_CALLBACK)( - PHANDLE_TABLE HandleTable, - PHANDLE_TABLE_ENTRY HandleTableEntry, - PVOID Context -); - -typedef BOOLEAN (NTAPI PEX_CHANGE_HANDLE_CALLBACK)( - PHANDLE_TABLE HandleTable, - PHANDLE_TABLE_ENTRY HandleTableEntry, - PVOID Context -); - -VOID -ExpInitializeHandleTables(VOID); +typedef BOOLEAN +(NTAPI *PEX_DUPLICATE_HANDLE_CALLBACK)( + IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry, + IN PHANDLE_TABLE_ENTRY NewEntry +); + +typedef BOOLEAN +(NTAPI *PEX_CHANGE_HANDLE_CALLBACK)( + PHANDLE_TABLE_ENTRY HandleTableEntry, + ULONG_PTR Context +); + +VOID +NTAPI +ExpInitializeHandleTables( + VOID +);
PHANDLE_TABLE -ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL); - -VOID -ExDestroyHandleTable( - IN PHANDLE_TABLE HandleTable -); - -VOID -ExSweepHandleTable( - IN PHANDLE_TABLE HandleTable, - IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL -); - -PHANDLE_TABLE -ExDupHandleTable( - IN PEPROCESS QuotaProcess OPTIONAL, - IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL, - IN PHANDLE_TABLE SourceHandleTable -); - -BOOLEAN -ExLockHandleTableEntry( - IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry -); - -VOID +NTAPI +ExCreateHandleTable( + IN PEPROCESS Process OPTIONAL +); + +VOID +NTAPI ExUnlockHandleTableEntry( IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry + IN PHANDLE_TABLE_ENTRY HandleTableEntry );
HANDLE +NTAPI ExCreateHandle( IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry + IN PHANDLE_TABLE_ENTRY HandleTableEntry +); + +VOID +NTAPI +ExDestroyHandleTable( + IN PHANDLE_TABLE HandleTable, + IN PVOID DestroyHandleProcedure OPTIONAL );
BOOLEAN +NTAPI ExDestroyHandle( IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle -); - -VOID -ExDestroyHandleByEntry( - IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN HANDLE Handle + IN HANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL );
PHANDLE_TABLE_ENTRY +NTAPI ExMapHandleToPointer( IN PHANDLE_TABLE HandleTable, IN HANDLE Handle );
+PHANDLE_TABLE +NTAPI +ExDupHandleTable( + IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, + IN ULONG_PTR Mask +); + BOOLEAN +NTAPI ExChangeHandle( IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, - IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback, + IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, + IN ULONG_PTR Context +); + +VOID +NTAPI +ExSweepHandleTable( + IN PHANDLE_TABLE HandleTable, + IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context );
@@ -797,7 +819,7 @@ VOID FORCEINLINE ExWaitOnPushLock(PEX_PUSH_LOCK PushLock) -{ +{ /* Check if we're locked */ if (PushLock->Locked) {
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon Jan 22 11:15:17 2007 @@ -44,6 +44,16 @@ GENERIC_ALL)
// +// Handle Bit Flags +// +#define OBJ_PROTECT_CLOSE 0x01 +//#define OBJ_INHERIT 0x02 +#define OBJ_AUDIT_OBJECT_CLOSE 0x04 +#define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE |\ + OBJ_INHERIT | \ + OBJ_AUDIT_OBJECT_CLOSE) + +// // Identifies a Kernel Handle // #define KERNEL_HANDLE_FLAG \ @@ -65,6 +75,12 @@ // #define ObpGetHandleCountByHandleTable(HandleTable) \ ((PHANDLE_TABLE)HandleTable)->HandleCount + +// +// Converts from an EXHANDLE object to a POBJECT_HEADER +// +#define ObpGetHandleObject(x) \ + ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES))
// // Context Structures for Ex*Handle Callbacks @@ -214,9 +230,8 @@ BOOLEAN NTAPI ObpSetHandleAttributes( - IN PHANDLE_TABLE HandleTable, IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context + IN ULONG_PTR Context );
VOID
Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/ntoskrnl.h... ============================================================================== --- trunk/reactos/ntoskrnl/include/ntoskrnl.h (original) +++ trunk/reactos/ntoskrnl/include/ntoskrnl.h Mon Jan 22 11:15:17 2007 @@ -8,7 +8,9 @@
/* INCLUDES ******************************************************************/
-/* Tells the WDK that we don't want to import */ +/* Always target Windows 2003 Service Pack 1 */ +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WS03SP1 #define NTKERNELAPI
/* DDK/IFS/NDK Headers */
Modified: trunk/reactos/ntoskrnl/ke/apc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/apc.c?rev=25586... ============================================================================== --- trunk/reactos/ntoskrnl/ke/apc.c (original) +++ trunk/reactos/ntoskrnl/ke/apc.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@
/* INCLUDES *****************************************************************/
-#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> @@ -952,3 +951,4 @@
+
Modified: trunk/reactos/ntoskrnl/ke/dpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=25586... ============================================================================== --- trunk/reactos/ntoskrnl/ke/dpc.c (original) +++ trunk/reactos/ntoskrnl/ke/dpc.c Mon Jan 22 11:15:17 2007 @@ -9,8 +9,6 @@ */
/* INCLUDES ******************************************************************/ - -#define NTDDI_VERSION NTDDI_WS03
#include <ntoskrnl.h> #define NDEBUG
Modified: trunk/reactos/ntoskrnl/ke/gate.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/gate.c?rev=2558... ============================================================================== --- trunk/reactos/ntoskrnl/ke/gate.c (original) +++ trunk/reactos/ntoskrnl/ke/gate.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@
/* INCLUDES *****************************************************************/
-#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h>
Modified: trunk/reactos/ntoskrnl/ke/gmutex.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/gmutex.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ke/gmutex.c (original) +++ trunk/reactos/ntoskrnl/ke/gmutex.c Mon Jan 22 11:15:17 2007 @@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/
-#define NTDDI_VERSION NTDDI_WS03SP1 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h>
Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@
/* INCLUDES *****************************************************************/
-#define NTDDI_VERSION NTDDI_WS03SP1 #include <ntoskrnl.h> #define NDEBUG #include <debug.h> @@ -788,3 +787,4 @@ KiIdleLoop(); }
+
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jan 22 11:15:17 2007 @@ -131,16 +131,13 @@ if (HandleEntry) { /* Get the object header and validate the type*/ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry);
/* Get the granted access and validate it */ GrantedAccess = HandleEntry->GrantedAccess;
/* Mask out the internal attributes */ - Attributes = HandleEntry->ObAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Fill out the information */ HandleInformation->HandleAttributes = Attributes; @@ -588,7 +585,7 @@ PAGED_CODE();
/* Get the object data */ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); ObjectType = ObjectHeader->Type; Body = &ObjectHeader->Body; GrantedAccess = HandleEntry->GrantedAccess; @@ -621,7 +618,7 @@ }
/* The callback allowed us to close it, but does the handle itself? */ - if ((HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) && + if ((HandleEntry->ObAttributes & OBJ_PROTECT_CLOSE) && !(IgnoreHandleProtection)) { /* It doesn't, are we from user mode? */ @@ -650,7 +647,7 @@ }
/* Destroy and unlock the handle entry */ - ExDestroyHandleByEntry(HandleTable, HandleEntry, Handle); + ExDestroyHandle(HandleTable, Handle, HandleEntry);
/* Now decrement the handle count */ ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess); @@ -1258,10 +1255,7 @@ NewEntry.Object = ObjectHeader;
/* Mask out the internal attributes */ - NewEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Remove what's not in the valid access mask */ GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask | @@ -1460,14 +1454,11 @@ if (AccessState->GenerateOnClose) { /* Force the attribute on */ - HandleAttributes|= EX_HANDLE_ENTRY_AUDITONCLOSE; + HandleAttributes|= OBJ_AUDIT_OBJECT_CLOSE; }
/* Mask out the internal attributes */ - NewEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Get the original desired access */ DesiredAccess = AccessState->RemainingDesiredAccess | @@ -1697,9 +1688,6 @@ * * The ObpSetHandleAttributes routine <FILLMEIN> * -* @param HandleTable -* <FILLMEIN>. -* * @param HandleTableEntry * <FILLMEIN>. * @@ -1713,12 +1701,11 @@ *--*/ BOOLEAN NTAPI -ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable, - IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context) +ObpSetHandleAttributes(IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, + IN ULONG_PTR Context) { - POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo = Context; - POBJECT_HEADER ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); + POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo = (PVOID)Context; + POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry); PAGED_CODE();
/* Don't allow operations on kernel objects */ @@ -1740,24 +1727,24 @@ }
/* Set the flag */ - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; + HandleTableEntry->ObAttributes |= OBJ_INHERIT; } else { /* Otherwise this implies we're removing the flag */ - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; + HandleTableEntry->ObAttributes &= ~OBJ_INHERIT; }
/* Check if making the handle protected */ if (SetHandleInfo->Information.ProtectFromClose) { /* Set the flag */ - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + HandleTableEntry->ObAttributes |= OBJ_PROTECT_CLOSE; } else { /* Otherwise, remove it */ - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + HandleTableEntry->ObAttributes &= ~OBJ_PROTECT_CLOSE; }
/* Return success */ @@ -1823,9 +1810,10 @@ *--*/ BOOLEAN NTAPI -ObpDuplicateHandleCallback(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context) +ObpDuplicateHandleCallback(IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY OldEntry, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) { POBJECT_HEADER ObjectHeader; BOOLEAN Ret = FALSE; @@ -1834,11 +1822,17 @@ PAGED_CODE();
/* Make sure that the handle is inheritable */ - Ret = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0; + Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0; if (Ret) { /* Get the object header */ - ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); + ObjectHeader = ObpGetHandleObject(HandleTableEntry); + + /* Increment the pointer count */ + InterlockedIncrement(&ObjectHeader->PointerCount); + + /* Release the handle lock */ + ExUnlockHandleTableEntry(HandleTable, OldEntry);
/* Setup the access state */ AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess; @@ -1848,18 +1842,19 @@ &AccessState, KernelMode, HandleTableEntry->ObAttributes, - PsGetCurrentProcess(), + Process, ObInheritHandle); if (!NT_SUCCESS(Status)) { /* Return failure */ + ObDereferenceObject(&ObjectHeader->Body); Ret = FALSE; } - else - { - /* Otherwise increment the pointer count */ - InterlockedIncrement(&ObjectHeader->PointerCount); - } + } + else + { + /* Release the handle lock */ + ExUnlockHandleTableEntry(HandleTable, OldEntry); }
/* Return duplication result */ @@ -1906,9 +1901,9 @@
/* Duplicate the parent's */ HandleTable = ExDupHandleTable(Process, + HandleTable, ObpDuplicateHandleCallback, - NULL, - HandleTable); + OBJ_INHERIT); } else { @@ -1981,7 +1976,7 @@
/* Destroy the object table */ Process->ObjectTable = NULL; - ExDestroyHandleTable(HandleTable); + ExDestroyHandleTable(HandleTable, NULL); }
NTSTATUS @@ -2121,10 +2116,7 @@
/* Fill out the entry */ NewHandleEntry.Object = ObjectHeader; - NewHandleEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewHandleEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Check if we're using a generic mask */ if (DesiredAccess & GENERIC_ACCESS)
Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c Mon Jan 22 11:15:17 2007 @@ -1442,10 +1442,9 @@ ObjectInformation;
/* Set the flags */ - HandleFlags->Inherit = (HandleInfo.HandleAttributes & - EX_HANDLE_ENTRY_INHERITABLE) != 0; + HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT; HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes & - EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0; + OBJ_PROTECT_CLOSE) != 0;
/* Break out with success */ Status = STATUS_SUCCESS; @@ -1581,7 +1580,7 @@ if (!ExChangeHandle(ObjectTable, ObjectHandle, ObpSetHandleAttributes, - &Context)) + (ULONG_PTR)&Context)) { /* Some failure */ Status = STATUS_ACCESS_DENIED;
Modified: trunk/reactos/ntoskrnl/ob/obname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obname.c (original) +++ trunk/reactos/ntoskrnl/ob/obname.c Mon Jan 22 11:15:17 2007 @@ -11,7 +11,6 @@
/* INCLUDES ******************************************************************/
-#define NTDDI_VERSION NTDDI_WINXP #include <ntoskrnl.h> #define NDEBUG #include <debug.h>
Modified: trunk/reactos/ntoskrnl/ob/obref.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obref.c?rev=255... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obref.c (original) +++ trunk/reactos/ntoskrnl/ob/obref.c Mon Jan 22 11:15:17 2007 @@ -560,7 +560,7 @@ if (HandleEntry) { /* Get the object header and validate the type*/ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); if (!(ObjectType) || (ObjectType == ObjectHeader->Type)) { /* Get the granted access and validate it */ @@ -572,10 +572,7 @@ InterlockedIncrement(&ObjectHeader->PointerCount);
/* Mask out the internal attributes */ - Attributes = HandleEntry->ObAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Check if the caller wants handle information */ if (HandleInformation)
Modified: trunk/reactos/ntoskrnl/ob/obsecure.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obsecure.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obsecure.c (original) +++ trunk/reactos/ntoskrnl/ob/obsecure.c Mon Jan 22 11:15:17 2007 @@ -829,8 +829,7 @@ if(HandleEntry) { /* Check if the flag is set */ - *GenerateOnClose = (HandleEntry->ObAttributes & - EX_HANDLE_ENTRY_AUDITONCLOSE) != 0; + *GenerateOnClose = HandleEntry->ObAttributes & OBJ_AUDIT_OBJECT_CLOSE;
/* Unlock the entry */ ExUnlockHandleTableEntry(HandleTable, HandleEntry);
Modified: trunk/reactos/ntoskrnl/ob/obwait.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obwait.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obwait.c (original) +++ trunk/reactos/ntoskrnl/ob/obwait.c Mon Jan 22 11:15:17 2007 @@ -181,7 +181,7 @@ }
/* Get the Object Header */ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry);
/* Get default Object */ DefaultObject = ObjectHeader->Type->DefaultObject;
Modified: trunk/reactos/ntoskrnl/ps/kill.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/kill.c?rev=2558... ============================================================================== --- trunk/reactos/ntoskrnl/ps/kill.c (original) +++ trunk/reactos/ntoskrnl/ps/kill.c Mon Jan 22 11:15:17 2007 @@ -310,7 +310,7 @@ if (Process->UniqueProcessId) { /* Delete the PID */ - if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId))) + if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL))) { /* Something wrong happened, bugcheck */ KEBUGCHECK(CID_HANDLE_DELETION); @@ -360,7 +360,7 @@ if (Thread->Cid.UniqueThread) { /* Delete the CID Handle */ - if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread))) + if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread, NULL))) { /* Something wrong happened, bugcheck */ KEBUGCHECK(CID_HANDLE_DELETION);
Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/rtl/libsupp.c (original) +++ trunk/reactos/ntoskrnl/rtl/libsupp.c Mon Jan 22 11:15:17 2007 @@ -259,7 +259,7 @@ ExSweepHandleTable(AtomTable->ExHandleTable, NULL, NULL); - ExDestroyHandleTable(AtomTable->ExHandleTable); + ExDestroyHandleTable(AtomTable->ExHandleTable, NULL); AtomTable->ExHandleTable = NULL; } } @@ -308,7 +308,8 @@ RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) { ExDestroyHandle(AtomTable->ExHandleTable, - (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2)); + (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2), + NULL); }
BOOLEAN @@ -336,7 +337,8 @@ } else ExDestroyHandle(AtomTable->ExHandleTable, - Handle); + Handle, + NULL); }
return FALSE;