FsRtlAddToTunnelCacheEx
VOID **__fastcall FsRtlAddToTunnelCacheEx(
UINT64 a1,
UINT64 a2,
UINT16 *a3,
UINT16 *a4,
INT8 Flags,
UINT64 DataLength,
INT8 *Data){
TUNNEL_NODE *v7;
int v9;
UINT16 *v10;
_UNICODE_STRING *v11;
TUNNEL *v12;
VOID **result;
int v14;
int v15;
unsigned int v16;
char *v17;
PRTL_SPLAY_LINKS *p_Cache;
TUNNEL_NODE *Cache;
PRTL_SPLAY_LINKS *v20;
NTSTATUS v21;
__int64 v22;
_LIST_ENTRY *v23;
_LIST_ENTRY *Blink;
UINT16 v25;
UINT16 v26;
size_t v27;
char *v28;
_QWORD *v29;
_RTL_SPLAY_LINKS *RightChild;
_QWORD *v31;
_RTL_SPLAY_LINKS *Parent;
__int64 v33;
TUNNEL_NODE **v34;
char v35;
_LIST_ENTRY FreePoolList[6];
UINT32 Flagsa;
v7 = 0i64;
v35 = 0;
v9 = Flags & 2;
v10 = a4;
v11 = (_UNICODE_STRING *)a3;
Flagsa = v9;
v12 = (TUNNEL *)a1;
result = (VOID **)(Flags & 1);
if( !(_DWORD)TunnelMaxEntries )
return result;
v14 = DataLength + *a3;
v15 = *a4 + 112;
FreePoolList[0].Blink = FreePoolList;
v16 = v15 + v14;
FreePoolList[0].Flink = FreePoolList;
if( v16 > 0xB0 || (v17 = (char *)ExAllocateFromNPagedLookasideList(&TunnelLookasideList)) == 0i64 )
{
result = ExAllocatePoolWithTag(1ui64, v16, 1349416276i64);
v17 = (char *)result;
if( !result )
return result;
v35 = 1;
}
if( !v9 )
v11 = (_UNICODE_STRING *)v10;
ExAcquireFastMutex(&v12->Mutex);
p_Cache = &v12->Cache;
Cache = (TUNNEL_NODE *)v12->Cache;
v20 = &v12->Cache;
if( Cache )
{
do
{
v7 = Cache;
v21 = FsRtlCompareNodeAndKey(Cache, a2, v11);
if( v21 > 0 )
{
v22 = 2i64;
}
else
{
if( v21 >= 0 )
break;
v22 = 4i64;
}
v20 = (PRTL_SPLAY_LINKS *)&Cache[v22];
Cache = *(TUNNEL_NODE **)&Cache[v22];
}
while( Cache );
v12 = (TUNNEL *)a1;
v10 = a4;
p_Cache = (PRTL_SPLAY_LINKS *)(a1 + 56);
}
*(_QWORD *)v17 = v17;
*((_QWORD *)v17 + 1) = 0i64;
*((_QWORD *)v17 + 2) = 0i64;
if( v7 )
{
if( *v20 )
{
*((_QWORD *)v17 + 2) = (*v20)->RightChild;
*((_QWORD *)v17 + 1) = (*v20)->LeftChild;
v29 = *v20;
RightChild = (*v20)->RightChild;
if( RightChild )
{
RightChild->Parent = (_RTL_SPLAY_LINKS *)v17;
v29 = *v20;
}
v31 = (_QWORD *)v29[1];
if( v31 )
{
*v31 = v17;
v29 = *v20;
}
if( (_QWORD *)*v29 == v29 )
{
*p_Cache = (PRTL_SPLAY_LINKS)v17;
}
else
{
*(_QWORD *)v17 = *v29;
Parent = (*v20)->Parent;
if( Parent->LeftChild == *v20 )
Parent->LeftChild = (_RTL_SPLAY_LINKS *)v17;
else
Parent->RightChild = (_RTL_SPLAY_LINKS *)v17;
}
v33 = *((_QWORD *)v7 + 3);
if( *(TUNNEL_NODE **)(v33 + 8) != v7 + 6 || (v34 = (TUNNEL_NODE **)*((_QWORD *)v7 + 4), *v34 != v7 + 6) )
LABEL_39:
__fastfail(3u);
*v34 = (TUNNEL_NODE *)v33;
*(_QWORD *)(v33 + 8) = v34;
FsRtlFreeTunnelNode(v7);
--v12->NumEntries;
}
else
{
*(_QWORD *)v17 = v7;
*v20 = (PRTL_SPLAY_LINKS)v17;
}
}
else
{
*p_Cache = (PRTL_SPLAY_LINKS)v17;
}
v23 = (_LIST_ENTRY *)(v17 + 24);
*((_QWORD *)v17 + 5) = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
Blink = v12->TimerQueue.Blink;
if( Blink->Flink != &v12->TimerQueue )
goto LABEL_39;
v23->Flink = &v12->TimerQueue;
*((_QWORD *)v17 + 4) = Blink;
Blink->Flink = v23;
v12->TimerQueue.Blink = v23;
++v12->NumEntries;
*((_QWORD *)v17 + 6) = a2;
*((_DWORD *)v17 + 14) = Flagsa != 0 ? 2 : 0;
*((_QWORD *)v17 + 11) = v17 + 112;
*((_QWORD *)v17 + 9) = &v17[*a3 + 112];
v25 = *a3;
*((_WORD *)v17 + 41) = *a3;
*((_WORD *)v17 + 40) = v25;
v26 = *v10;
*((_WORD *)v17 + 33) = *v10;
*((_WORD *)v17 + 32) = v26;
if( *a3 )
memmove(v17 + 112, *((const VOID **)a3 + 1), *a3);
v27 = *v10;
if( (_WORD)v27 )
{
memmove(*((VOID **)v17 + 9), *((const VOID **)v10 + 1), v27);
LOWORD(v27) = *v10;
}
v28 = &v17[*a3 + 112 + (unsigned __int16)v27];
*((_QWORD *)v17 + 12) = v28;
*((_DWORD *)v17 + 26) = DataLength;
memmove(v28, Data, DataLength);
if( v35 )
*((_DWORD *)v17 + 14) |= 1u;
FsRtlPruneTunnelCache(v12, FreePoolList);
KeReleaseGuardedMutex(&v12->Mutex);
FsRtlEmptyFreePoolList(FreePoolList);
return result;
}Referenced by:
FsRtlAddToTunnelCache