PHANDLE_TABLE_ENTRYExpLookupHandleTableEntry ( IN PHANDLE_TABLE HandleTable, IN EXHANDLE tHandle )
/*++
Routine Description:
This routine looks up and returns the table entry for the specified handle value.
Arguments:
HandleTable - Supplies the handle table being queried
tHandle - Supplies the handle value being queried
Return Value:
Returns a pointer to the corresponding table entry for the input handle. Or NULL if the handle value is invalid (i.e., too large for the tables current allocation.
--*/
{ ULONG_PTR i,j,k; ULONG_PTR CapturedTable; ULONG TableLevel; PHANDLE_TABLE_ENTRY Entry = NULL; EXHANDLE Handle;
PUCHAR TableLevel1; PUCHAR TableLevel2; PUCHAR TableLevel3;
ULONG_PTR MaxHandle;
PAGED_CODE();
// // Extract the handle index // Handle = tHandle;
Handle.TagBits = 0;
MaxHandle = *(volatile ULONG *) &HandleTable->NextHandleNeedingPool;
// // See if this can be a valid handle given the table levels. // if (Handle.Value >= MaxHandle) { return NULL; }
// // Now fetch the table address and level bits. We must preserve the // ordering here. // CapturedTable = *(volatile ULONG_PTR *) &HandleTable->TableCode;
// // we need to capture the current table. This routine is lock free // so another thread may change the table at HandleTable->TableCode //
TableLevel = (ULONG)(CapturedTable & LEVEL_CODE_MASK); CapturedTable = CapturedTable - TableLevel;
// // The lookup code depends on number of levels we have //
switch (TableLevel) { case 0: // // We have a simple index into the array, for a single level // handle table //
TableLevel1 = (PUCHAR) CapturedTable;
// // The index for this level is already scaled by a factor of 4. Take advantage of this //
Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[Handle.Value * (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];
break; case 1: // // we have a 2 level handle table. We need to get the upper index // and lower index into the array //
TableLevel2 = (PUCHAR) CapturedTable;
i = Handle.Value % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);
Handle.Value -= i; j = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2[j]; Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[i * (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];
break; case 2: // // We have here a three level handle table. //
TableLevel3 = (PUCHAR) CapturedTable;
i = Handle.Value % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);
Handle.Value -= i;
k = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
j = k % (MIDLEVEL_COUNT * sizeof (PHANDLE_TABLE_ENTRY));
k -= j;
k /= MIDLEVEL_COUNT;
TableLevel2 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel3[k]; TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2[j]; Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[i * (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];
break;
default : _assume (0); }
return Entry;}