Based on patch by Ivan Labutin. See PR #115
LIST_ENTRY HandleTableListHead;
EX_PUSH_LOCK HandleTableListLock;
#define SizeOfHandle(x) (sizeof(HANDLE) * (x))
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 *********************************************************/
/* PRIVATE FUNCTIONS *********************************************************/
/* Get the mid level pointer array */
PointerArray = PointerArray[Handle.HighIndex];
/* 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];
/* Fall through */
case 1:
/* Get the handle array */
HandleArray = PointerArray[Handle.MidIndex];
+ ASSERT(HandleArray != NULL);
/* Fall through */
case 0:
/* Fall through */
case 0:
IN EXHANDLE Handle,
IN PHANDLE_TABLE_ENTRY HandleTableEntry)
{
IN EXHANDLE Handle,
IN PHANDLE_TABLE_ENTRY HandleTableEntry)
{
- ULONG OldValue, NewValue, *Free;
- ULONG i;
+ ULONG OldValue, *Free;
+ ULONG LockIndex;
PAGED_CODE();
/* Sanity checks */
PAGED_CODE();
/* Sanity checks */
InterlockedDecrement(&HandleTable->HandleCount);
/* Mark the handle as free */
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 */
/* 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 */
/* Select which entry to use */
- Free = (HandleTable->HandleTableLock[i].Locked) ?
+ Free = (HandleTable->HandleTableLock[LockIndex].Locked) ?
&HandleTable->FirstFree : &HandleTable->LastFree;
}
else
&HandleTable->FirstFree : &HandleTable->LastFree;
}
else
{
/* Get the current value and write */
OldValue = *Free;
{
/* 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) <
{
/* Break out, we're done. Make sure the handle value makes sense */
ASSERT((OldValue & FREE_HANDLE_MASK) <
{
/* Set up the free data */
HandleEntry->Value = 0;
{
/* 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++;
/* Move to the next entry */
HandleEntry++;
/* Terminate the last entry */
HandleEntry->Value = 0;
HandleEntry->NextFreeTableEntry = 0;
/* 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 */
}
/* 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;
/* Setup the rest of the handle table data */
HandleTable->QuotaProcess = Process;
{
/* Go to the next entry and the base entry */
HandleEntry++;
{
/* 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;
/* 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;
{
/* Free this entry and move on to the next one */
HandleEntry->NextFreeTableEntry = i;
/* Get if the next index can fit in the table */
i = HandleTable->NextHandleNeedingPool /
/* 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 */
if (i < MID_LEVEL_ENTRIES)
{
/* We need to allocate a new table */
ThirdLevel = (PVOID)TableBase;
/* Get the index and check if it can fit */
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 */
if (i >= HIGH_LEVEL_ENTRIES) return FALSE;
/* Check if there's no mid-level table */
else
{
/* We have one, check at which index we should insert our entry */
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 */
j = Index / LOW_LEVEL_ENTRIES;
/* Allocate a new low level */
/* Update the index of the next handle */
Index = InterlockedExchangeAdd((PLONG) &HandleTable->NextHandleNeedingPool,
/* 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 */
/* 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 (;;)
/* Start free index change loop */
for (;;)
{
ULONG OldValue, NewValue, NewValue1;
PHANDLE_TABLE_ENTRY Entry;
{
ULONG OldValue, NewValue, NewValue1;
PHANDLE_TABLE_ENTRY Entry;
+ EXHANDLE Handle, OldHandle;
Entry = ExpLookupHandleTableEntry(HandleTable, Handle);
/* Get an available lock and acquire it */
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]);
KeEnterCriticalRegion();
ExAcquirePushLockShared(&HandleTable->HandleTableLock[i]);
NewTable->FirstFree = 0;
/* Setup the first handle value */
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();
/* Enter a critical region and lookup the new entry */
KeEnterCriticalRegion();
}
/* Increase the handle value and move to the next entry */
}
/* Increase the handle value and move to the next entry */
- Handle.Value += SizeOfHandle(1);
+ Handle.Value += INDEX_TO_HANDLE_VALUE(1);
NewEntry++;
HandleTableEntry++;
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 */
/* 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 */
}
/* Acquire the table lock and insert this new table into the list */
PAGED_CODE();
/* Set the initial value and loop the entries */
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 */
while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
{
/* Loop each handle */
}
/* Go to the next handle and entry */
}
/* Go to the next handle and entry */
- Handle.Value += SizeOfHandle(1);
+ Handle.Value += INDEX_TO_HANDLE_VALUE(1);
- } while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES));
+ } while (Handle.Value % INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
/* Skip past the last entry */
/* Skip past the last entry */
- Handle.Value += SizeOfHandle(1);
+ Handle.Value += INDEX_TO_HANDLE_VALUE(1);
}
/* Go to the next entry */
}
/* Go to the next entry */
- Handle.Value += SizeOfHandle(1);
+ Handle.Value += INDEX_TO_HANDLE_VALUE(1);
}
/* Leave the critical region and return callback result */
}
/* Leave the critical region and return callback result */
#define HANDLE_LOW_BITS (PAGE_SHIFT - 3)
#define HANDLE_HIGH_BITS (PAGE_SHIFT - 2)
#endif
#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
{
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;
- 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;
};
HANDLE GenericHandleOverlay;
ULONG_PTR Value;
} EXHANDLE, *PEXHANDLE;
typedef struct _ETIMER
} EXHANDLE, *PEXHANDLE;
typedef struct _ETIMER