ExDupHandleTable
NTSTATUS __stdcall ExDupHandleTable(
_EPROCESS *Process,
_HANDLE_TABLE *OldHandleTable,
UINT64 DupHandleCount,
VOID **DupHandleList,
_HANDLE_TABLE **NewHandleTable){
unsigned __int64 NextHandleNeedingPool;
_HANDLE_TABLE **v6;
unsigned int v7;
_HANDLE_TABLE *v8;
unsigned __int64 v9;
_HANDLE_TABLE_ENTRY *v10;
unsigned __int64 v11;
int v12;
_HANDLE_TABLE_ENTRY *v13;
_HANDLE_TABLE *v14;
_HANDLE_TABLE *v15;
_ETHREAD *CurrentThread;
NTSTATUS v17;
_EXHANDLE v18;
_HANDLE_TABLE_ENTRY **p_FirstFreeHandleEntry;
_HANDLE_TABLE_ENTRY *v20;
_HANDLE_TABLE_ENTRY *v21;
unsigned int v22;
_HANDLE_TABLE *v23;
_HANDLE_TABLE *v24;
_HANDLE_TABLE_ENTRY *v25;
unsigned int v26;
__int64 v27;
_LIST_ENTRY *v28;
_LIST_ENTRY *p_HandleTableList;
__int64 v31;
_HANDLE_TABLE_ENTRY *v32;
NTSTATUS v33;
UINT8 HandleTableEntrySlow;
unsigned int v35;
VOID **v36;
VOID *v37;
_HANDLE_TABLE *v38;
unsigned int v39;
_HANDLE_TABLE_ENTRY *v40;
unsigned __int64 v41;
_HANDLE_TABLE *v42;
char *v43;
_HANDLE_TABLE_ENTRY *v44;
_ETHREAD *v45;
_EPROCESS *Processa;
int v48;
Processa = Process;
NextHandleNeedingPool = OldHandleTable->NextHandleNeedingPool;
v6 = NewHandleTable;
v41 = NextHandleNeedingPool;
v7 = DupHandleCount;
v8 = OldHandleTable;
v9 = (unsigned int)NextHandleNeedingPool;
*NewHandleTable = 0i64;
if( (_DWORD)DupHandleCount )
{
if( (*(_BYTE *)DupHandleList & 3) == 0 )
{
v35 = 1;
if( (unsigned int)DupHandleCount <= 1 )
{
LABEL_55:
v37 = DupHandleList[v7 - 1];
if( (unsigned __int64)v37 < v9 )
{
v9 = (unsigned __int64)v37 + 4;
goto LABEL_13;
}
}
else
{
v36 = DupHandleList + 1;
while( ((unsigned __int8)*v36 & 3) == 0 && *v36 > DupHandleList[v35 - 1] )
{
++v35;
++v36;
if( v35 >= v7 )
goto LABEL_55;
}
}
}
return -1073741811;
}
if( !(_DWORD)NextHandleNeedingPool )
goto LABEL_14;
do
{
v10 = ExpLookupHandleTableEntry(v8, (_EXHANDLE)(v9 - 1024));
v12 = 255;
v13 = v10 + 255;
while( (v13->VolatileLowValue & 0x40000) == 0 )
{
if( (v13[-1].VolatileLowValue & 0x40000) != 0 )
{
--v12;
break;
}
if( (v13[-2].VolatileLowValue & 0x40000) != 0 )
{
v12 -= 2;
break;
}
if( (v13[-3].VolatileLowValue & 0x40000) != 0 )
{
v12 -= 3;
break;
}
if( (v13[-4].VolatileLowValue & 0x40000) != 0 )
{
v12 -= 4;
break;
}
v13 -= 5;
v12 -= 5;
if( !v12 )
break;
}
if( v12 )
break;
v9 = v11;
}
while( v11 );
LABEL_13:
Process = Processa;
v41 = v9;
LABEL_14:
if( !v9 )
{
v38 = ExCreateHandleTable(Process, 1ui64);
*NewHandleTable = v38;
if( v38 )
return 0;
return -1073741670;
}
v14 = ExpAllocateHandleTable(Process, 0);
*NewHandleTable = v14;
v15 = v14;
if( !v14 )
return -1073741670;
if( v14->NextHandleNeedingPool < v9 )
{
while( 1 )
{
HandleTableEntrySlow = ExpAllocateHandleTableEntrySlow(v15, 0i64);
v15 = *NewHandleTable;
if( !HandleTableEntrySlow )
break;
if( v15->NextHandleNeedingPool >= v9 )
goto LABEL_17;
}
ExpFreeHandleTable(v15);
*NewHandleTable = 0i64;
return -1073741670;
}
LABEL_17:
LOBYTE(v15->Flags) |= 8u;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.KernelApcDisable;
v45 = CurrentThread;
v42 = *NewHandleTable;
v17 = 0;
v39 = 0;
v18 = 0i64;
v48 = 0;
p_FirstFreeHandleEntry = &(*NewHandleTable)->FreeLists[0].FirstFreeHandleEntry;
do
{
v44 = ExpLookupHandleTableEntry(OldHandleTable, v18);
v20 = ExpLookupHandleTableEntry(*v6, v18);
v24 = *v6;
v25 = v21 + 1;
v40 = v20;
v26 = 1;
v43 = (char *)((char *)v20 - (char *)v21);
while( v17 >= 0 )
{
if( v7 && DupHandleList[v22] != (VOID *)(*(_QWORD *)&v18 + 4 * v26) )
goto LABEL_24;
if( (v25->VolatileLowValue & 0x40000) == 0 )
goto LABEL_22;
v31 = v26;
v32 = &v21[v31];
if( !ExLockHandleTableEntry(v23, &v21[v31]) )
{
v17 = v48;
LABEL_22:
if( v7 )
{
v17 = -1073741811;
v48 = -1073741811;
}
LABEL_24:
v27 = v26;
*p_FirstFreeHandleEntry = &v40[v27];
v42->FreeLists[0].LastFreeHandleEntry = &v40[v27];
p_FirstFreeHandleEntry = &v40[v27].NextFreeHandleEntry;
*(__int64 *)((char *)&v25->LowValue + (_QWORD)v43) = 0i64;
goto LABEL_25;
}
if( (v25->VolatileLowValue & 0x40000) == 0 )
{
ExUnlockHandleTableEntry(OldHandleTable, v32);
if( v7 )
{
v17 = -1073741811;
v48 = -1073741811;
}
else
{
v17 = v48;
}
goto LABEL_24;
}
v33 = ExpDuplicateSingleHandle(
Processa,
(PVOID)(*(_QWORD *)&v18 + 4 * v26),
OldHandleTable,
v32,
*NewHandleTable,
&v40[v31],
DupHandleList != 0i64);
v48 = v33;
v17 = v33;
if( v33 < 0 )
goto LABEL_24;
if( v33 == 263 )
{
v17 = 0;
v48 = 0;
goto LABEL_24;
}
v24 = *NewHandleTable;
++(*NewHandleTable)->FreeLists[0].HandleCount;
if( v7 && v39 < v7 - 1 )
++v39;
if( !v24->DebugInfo )
{
v6 = NewHandleTable;
goto LABEL_26;
}
ExpUpdateDebugInfo(v24, (_ETHREAD *)KeGetCurrentThread(), (VOID *)(*(_QWORD *)&v18 + 4 * v26), 1ui64);
LABEL_25:
v6 = NewHandleTable;
v24 = *NewHandleTable;
LABEL_26:
v21 = v44;
++v26;
v22 = v39;
++v25;
v23 = OldHandleTable;
if( v26 >= 0x100 )
goto LABEL_27;
}
memset(&v40[v26], 0i64, 4096 - 16 * v26);
LABEL_27:
*(_QWORD *)&v18 += 1024i64;
}
while( v18.Value < v41 );
*p_FirstFreeHandleEntry = 0i64;
if( v17 < 0 )
{
LOBYTE(v24->Flags) |= 4u;
v24->HandleTableList.Blink = &v24->HandleTableList;
v24->HandleTableList.Flink = &v24->HandleTableList;
}
else
{
v24->FreeLists[0].HighWaterMark = v24->FreeLists[0].HandleCount;
ExAcquirePushLockExclusiveEx(&HandleTableListLock, 0i64);
v28 = (_LIST_ENTRY *)qword_140D2DB48;
p_HandleTableList = &(*v6)->HandleTableList;
if( *(__int64 **)qword_140D2DB48 != &HandleTableListHead )
__fastfail(3u);
p_HandleTableList->Flink = (_LIST_ENTRY *)&HandleTableListHead;
p_HandleTableList->Blink = v28;
v28->Flink = p_HandleTableList;
qword_140D2DB48 = (__int64)p_HandleTableList;
if( (_InterlockedExchangeAdd64(&HandleTableListLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&HandleTableListLock);
KeAbPostRelease(&HandleTableListLock);
v17 = 0;
}
KeLeaveCriticalRegionThread(&v45->Tcb);
return v17;
}Referenced by:
ObInitProcess