[NTOSKRNL]

Simplify code in ExpLookupHandleTableEntry
CORE-6843 #resolve

svn path=/trunk/; revision=62743
This commit is contained in:
Timo Kreuzer 2014-04-13 16:45:58 +00:00
parent 4d1dfdbc1b
commit 1823418a80
2 changed files with 64 additions and 76 deletions

View file

@ -34,90 +34,59 @@ ExpInitializeHandleTables(VOID)
PHANDLE_TABLE_ENTRY
NTAPI
ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable,
IN EXHANDLE LookupHandle)
IN EXHANDLE Handle)
{
ULONG TableLevel, NextHandle;
ULONG_PTR i, j, k, TableBase;
PHANDLE_TABLE_ENTRY Entry = NULL;
EXHANDLE Handle = LookupHandle;
PUCHAR Level1, Level2, Level3;
ULONG TableLevel;
ULONG_PTR TableBase;
PHANDLE_TABLE_ENTRY HandleArray, Entry;
PVOID *PointerArray;
/* Clear the tag bits and check what the next handle is */
/* Clear the tag bits */
Handle.TagBits = 0;
NextHandle = *(volatile ULONG*)&HandleTable->NextHandleNeedingPool;
if (Handle.Value >= NextHandle) return NULL;
/* Check if the handle is in the allocated range */
if (Handle.Value >= HandleTable->NextHandleNeedingPool)
{
return NULL;
}
/* Get the table code */
TableBase = *(volatile ULONG_PTR*)&HandleTable->TableCode;
TableBase = HandleTable->TableCode;
/* Extract the table level and actual table base */
TableLevel = (ULONG)(TableBase & 3);
TableBase = TableBase - TableLevel;
TableBase &= ~3;
PointerArray = (PVOID*)TableBase;
HandleArray = (PHANDLE_TABLE_ENTRY)TableBase;
/* Check what level we're running at */
switch (TableLevel)
{
/* Direct index */
case 0:
/* Use level 1 and just get the entry directly */
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);
/* Get the mid level pointer array */
PointerArray = PointerArray[Handle.HighIndex];
/* 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));
/* Fall through */
case 1:
/* Get the remaining index in the 2nd level table */
j = k % (MID_LEVEL_ENTRIES * sizeof(PHANDLE_TABLE_ENTRY));
/* Get the handle array */
HandleArray = PointerArray[Handle.MidIndex];
/* Get the remaining index, which is in the third table */
k -= j;
k /= MID_LEVEL_ENTRIES;
/* Fall through */
case 0:
/* 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:
/* Get the entry using the low index */
Entry = &HandleArray[Handle.LowIndex];
/* All done */
break;
default:
NT_ASSERT(FALSE);
Entry = NULL;
}
/* Return the handle entry */
@ -217,7 +186,7 @@ ExpFreeHandleTable(IN PHANDLE_TABLE HandleTable)
PAGED_CODE();
/* Check which level we're at */
if (!TableLevel)
if (TableLevel == 0)
{
/* Select the first level table base and just free it */
Level1 = (PVOID)TableBase;
@ -504,7 +473,7 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
PAGED_CODE();
/* Check how many levels we already have */
if (!TableLevel)
if (TableLevel == 0)
{
/* Allocate a mid level, since we only have a low level */
Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low);
@ -600,6 +569,11 @@ ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable,
ASSERT(Value == NULL);
}
}
else
{
/* Something is really broken */
ASSERT(FALSE);
}
/* Update the index of the next handle */
Index = InterlockedExchangeAdd((PLONG) &HandleTable->NextHandleNeedingPool,

View file

@ -33,18 +33,32 @@ extern LIST_ENTRY ExpPagedLookasideListHead;
extern KSPIN_LOCK ExpNonPagedLookasideListLock;
extern KSPIN_LOCK ExpPagedLookasideListLock;
typedef struct _EXHANDLE
#ifdef _WIN64
#define HANDLE_LOW_BITS (PAGE_SHIFT - 4)
#define HANDLE_HIGH_BITS (PAGE_SHIFT - 3)
#else
#define HANDLE_LOW_BITS (PAGE_SHIFT - 3)
#define HANDLE_HIGH_BITS (PAGE_SHIFT - 2)
#endif
#define KERNEL_FLAG_BITS (sizeof(PVOID)*8 - 31)
typedef union _EXHANDLE
{
union
{
struct
{
ULONG TagBits:2;
ULONG Index:30;
};
HANDLE GenericHandleOverlay;
ULONG_PTR Value;
};
struct
{
ULONG_PTR TagBits:2;
ULONG_PTR Index:29;
};
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;
};
HANDLE GenericHandleOverlay;
ULONG_PTR Value;
} EXHANDLE, *PEXHANDLE;
typedef struct _ETIMER