mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 14:08:22 +00:00
[NTOS:EX] Fix handle table code for x64.
Based on patch by Ivan Labutin. See PR #115
This commit is contained in:
parent
2daf2391a6
commit
cbc4cfeed6
2 changed files with 46 additions and 38 deletions
|
@ -18,6 +18,7 @@
|
|||
LIST_ENTRY HandleTableListHead;
|
||||
EX_PUSH_LOCK HandleTableListLock;
|
||||
#define SizeOfHandle(x) (sizeof(HANDLE) * (x))
|
||||
#define INDEX_TO_HANDLE_VALUE(x) ((x) << HANDLE_TAG_BITS)
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
|
@ -67,12 +68,14 @@ ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
|
||||
/* Get the mid level pointer array */
|
||||
PointerArray = PointerArray[Handle.HighIndex];
|
||||
ASSERT(PointerArray != NULL);
|
||||
|
||||
/* Fall through */
|
||||
case 1:
|
||||
|
||||
/* Get the handle array */
|
||||
HandleArray = PointerArray[Handle.MidIndex];
|
||||
ASSERT(HandleArray != NULL);
|
||||
|
||||
/* Fall through */
|
||||
case 0:
|
||||
|
@ -255,8 +258,8 @@ ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
IN EXHANDLE Handle,
|
||||
IN PHANDLE_TABLE_ENTRY HandleTableEntry)
|
||||
{
|
||||
ULONG OldValue, NewValue, *Free;
|
||||
ULONG i;
|
||||
ULONG OldValue, *Free;
|
||||
ULONG LockIndex;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Sanity checks */
|
||||
|
@ -267,16 +270,16 @@ ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
InterlockedDecrement(&HandleTable->HandleCount);
|
||||
|
||||
/* Mark the handle as free */
|
||||
NewValue = (ULONG)Handle.Value & ~(SizeOfHandle(1) - 1);
|
||||
Handle.TagBits = 0;
|
||||
|
||||
/* Check if we're FIFO */
|
||||
if (!HandleTable->StrictFIFO)
|
||||
{
|
||||
/* Select a lock index */
|
||||
i = (NewValue >> 2) % 4;
|
||||
LockIndex = Handle.Index % 4;
|
||||
|
||||
/* Select which entry to use */
|
||||
Free = (HandleTable->HandleTableLock[i].Locked) ?
|
||||
Free = (HandleTable->HandleTableLock[LockIndex].Locked) ?
|
||||
&HandleTable->FirstFree : &HandleTable->LastFree;
|
||||
}
|
||||
else
|
||||
|
@ -290,8 +293,8 @@ ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
{
|
||||
/* Get the current value and write */
|
||||
OldValue = *Free;
|
||||
HandleTableEntry->NextFreeTableEntry = (ULONG)OldValue;
|
||||
if (InterlockedCompareExchange((PLONG) Free, NewValue, OldValue) == OldValue)
|
||||
HandleTableEntry->NextFreeTableEntry = OldValue;
|
||||
if (InterlockedCompareExchange((PLONG)Free, Handle.AsULONG, OldValue) == OldValue)
|
||||
{
|
||||
/* Break out, we're done. Make sure the handle value makes sense */
|
||||
ASSERT((OldValue & FREE_HANDLE_MASK) <
|
||||
|
@ -354,7 +357,7 @@ ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL,
|
|||
{
|
||||
/* Set up the free data */
|
||||
HandleEntry->Value = 0;
|
||||
HandleEntry->NextFreeTableEntry = (i + 1) * SizeOfHandle(1);
|
||||
HandleEntry->NextFreeTableEntry = INDEX_TO_HANDLE_VALUE(i + 1);
|
||||
|
||||
/* Move to the next entry */
|
||||
HandleEntry++;
|
||||
|
@ -363,11 +366,11 @@ ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL,
|
|||
/* Terminate the last entry */
|
||||
HandleEntry->Value = 0;
|
||||
HandleEntry->NextFreeTableEntry = 0;
|
||||
HandleTable->FirstFree = SizeOfHandle(1);
|
||||
HandleTable->FirstFree = INDEX_TO_HANDLE_VALUE(1);
|
||||
}
|
||||
|
||||
/* Set the next handle needing pool after our allocated page from above */
|
||||
HandleTable->NextHandleNeedingPool = LOW_LEVEL_ENTRIES * SizeOfHandle(1);
|
||||
HandleTable->NextHandleNeedingPool = INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES);
|
||||
|
||||
/* Setup the rest of the handle table data */
|
||||
HandleTable->QuotaProcess = Process;
|
||||
|
@ -409,12 +412,12 @@ ExpAllocateLowLevelTable(IN PHANDLE_TABLE HandleTable,
|
|||
{
|
||||
/* Go to the next entry and the base entry */
|
||||
HandleEntry++;
|
||||
Base = HandleTable->NextHandleNeedingPool + SizeOfHandle(2);
|
||||
Base = HandleTable->NextHandleNeedingPool + INDEX_TO_HANDLE_VALUE(2);
|
||||
|
||||
/* Loop each entry */
|
||||
for (i = Base;
|
||||
i < Base + SizeOfHandle(LOW_LEVEL_ENTRIES - 2);
|
||||
i += SizeOfHandle(1))
|
||||
i < Base + INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES - 2);
|
||||
i += INDEX_TO_HANDLE_VALUE(1))
|
||||
{
|
||||
/* Free this entry and move on to the next one */
|
||||
HandleEntry->NextFreeTableEntry = i;
|
||||
|
@ -494,7 +497,7 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
|
|||
|
||||
/* Get if the next index can fit in the table */
|
||||
i = HandleTable->NextHandleNeedingPool /
|
||||
SizeOfHandle(LOW_LEVEL_ENTRIES);
|
||||
INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES);
|
||||
if (i < MID_LEVEL_ENTRIES)
|
||||
{
|
||||
/* We need to allocate a new table */
|
||||
|
@ -539,7 +542,7 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
|
|||
ThirdLevel = (PVOID)TableBase;
|
||||
|
||||
/* Get the index and check if it can fit */
|
||||
i = HandleTable->NextHandleNeedingPool / SizeOfHandle(MAX_MID_INDEX);
|
||||
i = HandleTable->NextHandleNeedingPool / INDEX_TO_HANDLE_VALUE(MAX_MID_INDEX);
|
||||
if (i >= HIGH_LEVEL_ENTRIES) return FALSE;
|
||||
|
||||
/* Check if there's no mid-level table */
|
||||
|
@ -556,8 +559,8 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
|
|||
else
|
||||
{
|
||||
/* We have one, check at which index we should insert our entry */
|
||||
Index = (HandleTable->NextHandleNeedingPool / SizeOfHandle(1)) -
|
||||
i * MAX_MID_INDEX;
|
||||
Index = (HandleTable->NextHandleNeedingPool / INDEX_TO_HANDLE_VALUE(1)) -
|
||||
i * MAX_MID_INDEX;
|
||||
j = Index / LOW_LEVEL_ENTRIES;
|
||||
|
||||
/* Allocate a new low level */
|
||||
|
@ -577,13 +580,13 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
|
|||
|
||||
/* Update the index of the next handle */
|
||||
Index = InterlockedExchangeAdd((PLONG) &HandleTable->NextHandleNeedingPool,
|
||||
SizeOfHandle(LOW_LEVEL_ENTRIES));
|
||||
INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
|
||||
|
||||
/* Check if need to initialize the table */
|
||||
if (DoInit)
|
||||
{
|
||||
/* Create a new index number */
|
||||
Index += SizeOfHandle(1);
|
||||
Index += INDEX_TO_HANDLE_VALUE(1);
|
||||
|
||||
/* Start free index change loop */
|
||||
for (;;)
|
||||
|
@ -646,7 +649,7 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
{
|
||||
ULONG OldValue, NewValue, NewValue1;
|
||||
PHANDLE_TABLE_ENTRY Entry;
|
||||
EXHANDLE Handle;
|
||||
EXHANDLE Handle, OldHandle;
|
||||
BOOLEAN Result;
|
||||
ULONG i;
|
||||
|
||||
|
@ -709,7 +712,8 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
Entry = ExpLookupHandleTableEntry(HandleTable, Handle);
|
||||
|
||||
/* Get an available lock and acquire it */
|
||||
i = ((OldValue & FREE_HANDLE_MASK) >> 2) % 4;
|
||||
OldHandle.Value = OldValue;
|
||||
i = OldHandle.Index % 4;
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquirePushLockShared(&HandleTable->HandleTableLock[i]);
|
||||
|
||||
|
@ -1063,7 +1067,7 @@ ExDupHandleTable(IN PEPROCESS Process,
|
|||
NewTable->FirstFree = 0;
|
||||
|
||||
/* Setup the first handle value */
|
||||
Handle.Value = SizeOfHandle(1);
|
||||
Handle.Value = INDEX_TO_HANDLE_VALUE(1);
|
||||
|
||||
/* Enter a critical region and lookup the new entry */
|
||||
KeEnterCriticalRegion();
|
||||
|
@ -1125,13 +1129,13 @@ ExDupHandleTable(IN PEPROCESS Process,
|
|||
}
|
||||
|
||||
/* Increase the handle value and move to the next entry */
|
||||
Handle.Value += SizeOfHandle(1);
|
||||
Handle.Value += INDEX_TO_HANDLE_VALUE(1);
|
||||
NewEntry++;
|
||||
HandleTableEntry++;
|
||||
} while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES));
|
||||
} while (Handle.Value % INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
|
||||
|
||||
/* We're done, skip the last entry */
|
||||
Handle.Value += SizeOfHandle(1);
|
||||
Handle.Value += INDEX_TO_HANDLE_VALUE(1);
|
||||
}
|
||||
|
||||
/* Acquire the table lock and insert this new table into the list */
|
||||
|
@ -1198,7 +1202,7 @@ ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
|
|||
PAGED_CODE();
|
||||
|
||||
/* Set the initial value and loop the entries */
|
||||
Handle.Value = SizeOfHandle(1);
|
||||
Handle.Value = INDEX_TO_HANDLE_VALUE(1);
|
||||
while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
|
||||
{
|
||||
/* Loop each handle */
|
||||
|
@ -1214,12 +1218,12 @@ ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
|
|||
}
|
||||
|
||||
/* Go to the next handle and entry */
|
||||
Handle.Value += SizeOfHandle(1);
|
||||
Handle.Value += INDEX_TO_HANDLE_VALUE(1);
|
||||
HandleTableEntry++;
|
||||
} while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES));
|
||||
} while (Handle.Value % INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
|
||||
|
||||
/* Skip past the last entry */
|
||||
Handle.Value += SizeOfHandle(1);
|
||||
Handle.Value += INDEX_TO_HANDLE_VALUE(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1271,7 +1275,7 @@ ExEnumHandleTable(IN PHANDLE_TABLE HandleTable,
|
|||
}
|
||||
|
||||
/* Go to the next entry */
|
||||
Handle.Value += SizeOfHandle(1);
|
||||
Handle.Value += INDEX_TO_HANDLE_VALUE(1);
|
||||
}
|
||||
|
||||
/* Leave the critical region and return callback result */
|
||||
|
|
|
@ -68,25 +68,29 @@ VOID NTAPI ExpDebuggerWorker(IN PVOID Context);
|
|||
#define HANDLE_LOW_BITS (PAGE_SHIFT - 3)
|
||||
#define HANDLE_HIGH_BITS (PAGE_SHIFT - 2)
|
||||
#endif
|
||||
#define KERNEL_FLAG_BITS (sizeof(PVOID)*8 - 31)
|
||||
#define HANDLE_TAG_BITS (2)
|
||||
#define HANDLE_INDEX_BITS (HANDLE_LOW_BITS + 2*HANDLE_HIGH_BITS)
|
||||
#define KERNEL_FLAG_BITS (sizeof(PVOID)*8 - HANDLE_INDEX_BITS - HANDLE_TAG_BITS)
|
||||
|
||||
typedef union _EXHANDLE
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG_PTR TagBits:2;
|
||||
ULONG_PTR Index:29;
|
||||
ULONG_PTR TagBits: HANDLE_TAG_BITS;
|
||||
ULONG_PTR Index: HANDLE_INDEX_BITS;
|
||||
ULONG_PTR KernelFlag : KERNEL_FLAG_BITS;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONG_PTR TagBits2:2;
|
||||
ULONG_PTR LowIndex:HANDLE_LOW_BITS;
|
||||
ULONG_PTR MidIndex:HANDLE_HIGH_BITS;
|
||||
ULONG_PTR HighIndex:HANDLE_HIGH_BITS;
|
||||
ULONG_PTR KernelFlag:KERNEL_FLAG_BITS;
|
||||
ULONG_PTR TagBits2: HANDLE_TAG_BITS;
|
||||
ULONG_PTR LowIndex: HANDLE_LOW_BITS;
|
||||
ULONG_PTR MidIndex: HANDLE_HIGH_BITS;
|
||||
ULONG_PTR HighIndex: HANDLE_HIGH_BITS;
|
||||
ULONG_PTR KernelFlag2: KERNEL_FLAG_BITS;
|
||||
};
|
||||
HANDLE GenericHandleOverlay;
|
||||
ULONG_PTR Value;
|
||||
ULONG AsULONG;
|
||||
} EXHANDLE, *PEXHANDLE;
|
||||
|
||||
typedef struct _ETIMER
|
||||
|
|
Loading…
Reference in a new issue