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