一直在想windows下的句柄是怎么进行分配和管理的
而这个句柄分配的算法又是windows不与公布的
在网上找了下 发现这方面的资料很少啊 于是自己对着WRK和reactOS看了一下午
虽然明白了一点点 但是还是有好多地方很迷糊 希望大牛们指导一下
从ExCreateHandle开始
到ExpAllocateHandleEntry
再到ExpAllocateHandleTableEntrySlow
定位句柄分配算法大概就位于此处
代码:
if ( TableLevel == 0 ) { NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); if (NewMidLevel == NULL) { return FALSE; } NewMidLevel[1] = NewMidLevel[0]; NewMidLevel[0] = (PHANDLE_TABLE_ENTRY)CapturedTable; CapturedTable = ((ULONG_PTR)NewMidLevel) | 1; OldValue = InterlockedExchangePointer( (PVOID *)&HandleTable->TableCode, (PVOID)CapturedTable ); } else if (TableLevel == 1) { PHANDLE_TABLE_ENTRY *TableLevel2 = (PHANDLE_TABLE_ENTRY *)CapturedTable; i = HandleTable->NextHandleNeedingPool / (LOWLEVEL_COUNT * HANDLE_VALUE_INC); if (i < MIDLEVEL_COUNT) { NewLowLevel = ExpAllocateLowLevelTable( HandleTable, DoInit ); if (NewLowLevel == NULL) { return FALSE; } OldValue = InterlockedExchangePointer( (PVOID *) (&TableLevel2[i]), NewLowLevel ); EXASSERT (OldValue == NULL); } else { NewHighLevel = ExpAllocateTablePagedPool( HandleTable->QuotaProcess, HIGHLEVEL_SIZE ); if (NewHighLevel == NULL) { return FALSE; } NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); if (NewMidLevel == NULL) { ExpFreeTablePagedPool( HandleTable->QuotaProcess, NewHighLevel, HIGHLEVEL_SIZE ); return FALSE; } NewHighLevel[0] = (PHANDLE_TABLE_ENTRY*)CapturedTable; NewHighLevel[1] = NewMidLevel; CapturedTable = ((ULONG_PTR)NewHighLevel) | 2; OldValue = InterlockedExchangePointer( (PVOID *)&HandleTable->TableCode, (PVOID)CapturedTable ); } } else if (TableLevel == 2) { ULONG RemainingIndex; PHANDLE_TABLE_ENTRY **TableLevel3 = (PHANDLE_TABLE_ENTRY **)CapturedTable; i = HandleTable->NextHandleNeedingPool / (MIDLEVEL_THRESHOLD * HANDLE_VALUE_INC); if (i >= HIGHLEVEL_COUNT) { return FALSE; } if (TableLevel3[i] == NULL) { NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); if (NewMidLevel == NULL) { return FALSE; } OldValue = InterlockedExchangePointer( (PVOID *) &(TableLevel3[i]), NewMidLevel ); EXASSERT (OldValue == NULL); } else { RemainingIndex = (HandleTable->NextHandleNeedingPool / HANDLE_VALUE_INC) - i * MIDLEVEL_THRESHOLD; j = RemainingIndex / LOWLEVEL_COUNT; NewLowLevel = ExpAllocateLowLevelTable( HandleTable, DoInit ); if (NewLowLevel == NULL) { return FALSE; } OldValue = InterlockedExchangePointer( (PVOID *)(&TableLevel3[i][j]) , NewLowLevel ); EXASSERT (OldValue == NULL); } }
代码:
if ( TableLevel == 0 ) { NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); } else if ( TableLevel == 1 ) { if (i < MIDLEVEL_COUNT) { NewLowLevel = ExpAllocateLowLevelTable( HandleTable, DoInit ); } else { NewHighLevel = ExpAllocateTablePagedPool( HandleTable->QuotaProcess, HIGHLEVEL_SIZE ); NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); } } else if (TableLevel == 2) { if (i >= HIGHLEVEL_COUNT) return FALSE; if (TableLevel3[i] == NULL) NewMidLevel = ExpAllocateMidLevelTable( HandleTable, DoInit, &NewLowLevel ); else NewLowLevel = ExpAllocateLowLevelTable( HandleTable, DoInit ); }
这里有一个问题 当level=0时 并没有做任何判断 就用ExpAllocateMidLevelTable分配了一个中级表 这是为什么呢? 不是应该判断一下0级表有没有满吗?就像下面的都判断了i的值,这里为什么没有判断?
ps: 不知道有没有句柄算法的更详细的一点资料?