FsRtlAddToTunnelCacheEx

VOID __stdcall FsRtlAddToTunnelCacheEx(
        TUNNEL *Cache,
        ULONGLONG DirectoryKey,
        UNICODE_STRING *ShortName,
        UNICODE_STRING *LongName,
        UINT32 Flags,
        UINT32 DataLength,
        PVOID Data){
  _QWORD *v7; 
  char v8; 
  UINT32 v9; 
  UNICODE_STRING *v10; 
  UNICODE_STRING *v11; 
  TUNNEL *v12; 
  UINT32 v13; 
  int v14; 
  unsigned int v15; 
  char *PoolWithTag; 
  PRTL_SPLAY_LINKS *p_Cache; 
  __int64 v18; 
  PRTL_SPLAY_LINKS *v19; 
  int v20; 
  __int64 v21; 
  _LIST_ENTRY *v22; 
  _LIST_ENTRY *Blink; 
  unsigned __int16 Length; 
  unsigned __int16 v25; 
  unsigned __int16 v26; 
  UINT8 *v27; 
  _QWORD *v28; 
  _RTL_SPLAY_LINKS *RightChild; 
  _QWORD *v30; 
  _RTL_SPLAY_LINKS *Parent; 
  __int64 v32; 
  _QWORD *v33; 
  char *v34; 
  char v35; 
  char v36; 
  _LIST_ENTRY FreePoolList; 
  UINT32 Flagsa; 
  v7 = 0i64;
  v8 = Flags;
  v35 = 0;
  v9 = Flags & 2;
  v10 = LongName;
  v11 = ShortName;
  Flagsa = v9;
  v12 = Cache;
  v36 = v8 & 1;
  if( !TunnelMaxEntries )
    return;
  v13 = DataLength + ShortName->Length;
  v14 = LongName->Length + 112;
  FreePoolList.Blink = &FreePoolList;
  v15 = v14 + v13;
  FreePoolList.Flink = &FreePoolList;
  if( v15 > 0xB0
    || (LODWORD(v34) = ExAllocateFromNPagedLookasideList((NPAGED_LOOKASIDE_LIST *)TunnelLookasideList),
        (PoolWithTag = v34) == 0i64) )
  {
    PoolWithTag = (char *)ExAllocatePoolWithTag(PagedPool, v15, 0x506E7554ui64);
    if( !PoolWithTag )
      return;
    v35 = 1;
  }
  if( !v9 )
    v11 = v10;
  ExAcquireFastMutex(&v12->Mutex);
  p_Cache = &v12->Cache;
  v18 = (__int64)v12->Cache;
  v19 = &v12->Cache;
  if( v18 )
  {
    do
    {
      v7 = (_QWORD *)v18;
      v20 = FsRtlCompareNodeAndKey(v18, DirectoryKey, v11, v36);
      if( v20 > 0 )
      {
        v21 = 8i64;
      }
      else
      {
        if( v20 >= 0 )
          break;
        v21 = 16i64;
      }
      v19 = (PRTL_SPLAY_LINKS *)(v21 + v18);
      v18 = *(_QWORD *)(v21 + v18);
    }
    while( v18 );
    v12 = Cache;
    v10 = LongName;
    p_Cache = &Cache->Cache;
  }
  *(_QWORD *)PoolWithTag = PoolWithTag;
  *((_QWORD *)PoolWithTag + 1) = 0i64;
  *((_QWORD *)PoolWithTag + 2) = 0i64;
  if( v7 )
  {
    if( *v19 )
    {
      *((_QWORD *)PoolWithTag + 2) = (*v19)->RightChild;
      *((_QWORD *)PoolWithTag + 1) = (*v19)->LeftChild;
      v28 = *v19;
      RightChild = (*v19)->RightChild;
      if( RightChild )
      {
        RightChild->Parent = (_RTL_SPLAY_LINKS *)PoolWithTag;
        v28 = *v19;
      }
      v30 = (_QWORD *)v28[1];
      if( v30 )
      {
        *v30 = PoolWithTag;
        v28 = *v19;
      }
      if( (_QWORD *)*v28 == v28 )
      {
        *p_Cache = (PRTL_SPLAY_LINKS)PoolWithTag;
      }
      else
      {
        *(_QWORD *)PoolWithTag = *v28;
        Parent = (*v19)->Parent;
        if( Parent->LeftChild == *v19 )
          Parent->LeftChild = (_RTL_SPLAY_LINKS *)PoolWithTag;
        else
          Parent->RightChild = (_RTL_SPLAY_LINKS *)PoolWithTag;
      }
      v32 = v7[3];
      if( *(_QWORD **)(v32 + 8) != v7 + 3 || (v33 = (_QWORD *)v7[4], (_QWORD *)*v33 != v7 + 3) )
LABEL_39:
        __fastfail(3u);
      *v33 = v32;
      *(_QWORD *)(v32 + 8) = v33;
      FsRtlFreeTunnelNode(v7);
      --v12->NumEntries;
    }
    else
    {
      *(_QWORD *)PoolWithTag = v7;
      *v19 = (PRTL_SPLAY_LINKS)PoolWithTag;
    }
  }
  else
  {
    *p_Cache = (PRTL_SPLAY_LINKS)PoolWithTag;
  }
  v22 = (_LIST_ENTRY *)(PoolWithTag + 24);
  *((_QWORD *)PoolWithTag + 5) = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
  Blink = v12->TimerQueue.Blink;
  if( Blink->Flink != &v12->TimerQueue )
    goto LABEL_39;
  v22->Flink = &v12->TimerQueue;
  *((_QWORD *)PoolWithTag + 4) = Blink;
  Blink->Flink = v22;
  v12->TimerQueue.Blink = v22;
  ++v12->NumEntries;
  *((_QWORD *)PoolWithTag + 6) = DirectoryKey;
  *((_DWORD *)PoolWithTag + 14) = Flagsa != 0 ? 2 : 0;
  *((_QWORD *)PoolWithTag + 11) = PoolWithTag + 112;
  *((_QWORD *)PoolWithTag + 9) = &PoolWithTag[ShortName->Length + 112];
  Length = ShortName->Length;
  *((_WORD *)PoolWithTag + 41) = ShortName->Length;
  *((_WORD *)PoolWithTag + 40) = Length;
  v25 = v10->Length;
  *((_WORD *)PoolWithTag + 33) = v10->Length;
  *((_WORD *)PoolWithTag + 32) = v25;
  if( ShortName->Length )
    memmove((UINT8 *)PoolWithTag + 112, (UINT8 *)ShortName->Buffer, ShortName->Length);
  v26 = v10->Length;
  if( v10->Length )
  {
    memmove(*((UINT8 **)PoolWithTag + 9), (UINT8 *)v10->Buffer, v10->Length);
    v26 = v10->Length;
  }
  v27 = (UINT8 *)&PoolWithTag[ShortName->Length + 112 + v26];
  *((_QWORD *)PoolWithTag + 12) = v27;
  *((_DWORD *)PoolWithTag + 26) = DataLength;
  memmove(v27, (UINT8 *)Data, DataLength);
  if( v35 )
    *((_DWORD *)PoolWithTag + 14) |= 1u;
  FsRtlPruneTunnelCache(v12, &FreePoolList);
  KeReleaseGuardedMutex(&v12->Mutex);
  FsRtlEmptyFreePoolList(&FreePoolList);
}

Referenced by:

FsRtlAddToTunnelCache