//前面省略小部分申请内存的代码
HandleTable->TableCode = (ULONG_PTR)HandleTableTable;
//下面是对这个刚申请的一级表进行初始化
HandleEntry = &HandleTableTable[0]; //第一个HANDLE_TABLE_ENTRY
HandleEntry->NextFreeTableEntry = EX_ADDITIONAL_INFO_SIGNATURE;//-2,作为标志;
HandleEntry->Value = 0; //对象值为0,对应于无效句柄NULL
//
// For duplicate calls we skip building the free list as we rebuild it manually as
// we traverse the old table we are duplicating
//
if (DoInit) { //这个参数在普通调用时为TRUE,仅在复制句柄表时则为False,因为复制时并不需要重新分配句柄
HandleEntry++; //从第二个HANDLE_TABLE_ENTRY开始
//
// Now setup the free list. We do this by chaining together the free
// entries such that each free entry give the next free index (i.e.,
// like a fat chain). The chain is terminated with a 0. Note that
// we'll skip handle zero because our callers will get that value
// confused with null.
//
for (i = 1; i < LOWLEVEL_COUNT - 1; i += 1) {
HandleEntry->Value = 0; //对象值初始化为0
//FreeHandle即自由的,未被使用的句柄
HandleEntry->NextFreeTableEntry = (i+1)*HANDLE_VALUE_INC; //构建FreeHandle列表,在初始化时,每一个HANDLE_TABLE_ENTRY都指向下一个句柄.这里的NextFreeTableEntry的值准确说是下一个FreeHandle,这样构成了一个单向链表一样的结构
HandleEntry++;
}
//对最后一项作特殊处理
HandleEntry->Value = 0;
HandleEntry->NextFreeTableEntry = 0; //最后一项的NextFreeTableEntry为0
HandleTable->FirstFree = HANDLE_VALUE_INC; //把刚初始化完的句柄表的FirstFree设为4,即第一个可用句柄
}
HandleTable->NextHandleNeedingPool = LOWLEVEL_COUNT * HANDLE_VALUE_INC; //一级表最大句柄
//
// Setup the necessary process information
//
HandleTable->QuotaProcess = Process; //设置所属的Process
HandleTable->UniqueProcessId = PsGetCurrentProcess()->UniqueProcessId; //调置所属Process的ProcessId
HandleTable->Flags = 0;