CcExtendVacbArray

VOID __stdcall CcExtendVacbArray(_SHARED_CACHE_MAP *SharedCacheMap, _LARGE_INTEGER NewSectionSize){
  unsigned int v2; 
  __int64 QuadPart; 
  __int64 v5; 
  unsigned int v6; 
  unsigned int v7; 
  ULONG LowPart; 
  unsigned int v9; 
  unsigned int v10; 
  UINT8 *PoolWithTag; 
  _SHARED_CACHE_MAP *Vacbs; 
  _LARGE_INTEGER v13; 
  _LIST_ENTRY *v14; 
  _LIST_ENTRY *v15; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY **p_Flink; 
  _LIST_ENTRY *p_BcbList; 
  _LIST_ENTRY *j; 
  _LIST_ENTRY *v20; 
  unsigned int v21; 
  int v22; 
  unsigned int v23; 
  _SHARED_CACHE_MAP *i; 
  _LIST_ENTRY *v25; 
  KIRQL v26; 
  _VACB **v27; 
  _VACB *v28; 
  _VACB *v29; 
  _QWORD *VacbLevel; 
  _DWORD *v31; 
  _VACB **v32; 
  VACB_LEVEL_ALLOCATION_LIST VacbLevels; 
  unsigned int v34; 
  v2 = 0;
  QuadPart = NewSectionSize.QuadPart;
  *(&VacbLevels.VacbLevelsAllocated + 1) = 0;
  if( NewSectionSize.HighPart < 0 )
    return;
  if( (SharedCacheMap->Flags & 0x200) != 0 && NewSectionSize.QuadPart > 0x200000 )
    v2 = 1;
  VacbLevels.VacbLevelWithBcbListHeads = 0i64;
  VacbLevels.VacbLevelsAllocated = 0;
  v5 = SharedCacheMap->SectionSize.QuadPart;
  VacbLevels.VacbLevelList.Blink = (_LIST_ENTRY *)&VacbLevels;
  VacbLevels.VacbLevelList.Flink = (_LIST_ENTRY *)&VacbLevels;
  if( NewSectionSize.QuadPart <= v5 )
    goto LABEL_29;
  if( v5 < 0x2000000 )
  {
    v5 = NewSectionSize.QuadPart;
    NewSectionSize.QuadPart = 0x100000i64;
    if( QuadPart >= 0x2000000 )
      v5 = 0x2000000i64;
    v6 = -1;
    if( HIDWORD(v5) )
    {
      v7 = -1;
    }
    else if( (unsigned int)v5 <= 0x100000 )
    {
      v7 = 32;
    }
    else
    {
      v7 = 8 * ((unsigned int)v5 >> 18);
    }
    v34 = v7;
    if( !SharedCacheMap->SectionSize.HighPart )
    {
      LowPart = SharedCacheMap->SectionSize.LowPart;
      if( LowPart > 0x100000 )
        v6 = 8 * (LowPart >> 18);
      else
        v6 = 32;
    }
    if( v7 > v6 )
    {
      if( v2 )
        v7 += (v7 + 15) & 0xFFFFFFF0;
      v9 = v7 + 8;
      if( QuadPart < 0x2000000 )
        v9 = v7;
      v10 = v9;
      PoolWithTag = (UINT8 *)ExAllocatePoolWithTag(NonPagedPoolNx, v9, 0x70566343ui64);
      if( !PoolWithTag )
        return;
      CcAcquireBcbLockAndVacbLock(v2, (FAST_MUTEX *)SharedCacheMap);
      Vacbs = (_SHARED_CACHE_MAP *)SharedCacheMap->Vacbs;
      if( Vacbs )
        memmove(PoolWithTag, (UINT8 *)SharedCacheMap->Vacbs, v6);
      else
        v6 = 0;
      memset((INT64)&PoolWithTag[v6], 0i64);
      if( QuadPart >= 0x2000000 )
        *(_QWORD *)&PoolWithTag[v10 - 8] = 0i64;
      if( v2 )
      {
        v13.QuadPart = 0i64;
        v14 = (_LIST_ENTRY *)&PoolWithTag[v34];
        if( SharedCacheMap->SectionSize.QuadPart > 0x200000 && Vacbs )
        {
          v15 = (_LIST_ENTRY *)((char *)Vacbs + v6);
          while( 1 )
          {
            Flink = v15->Flink;
            p_Flink = &v15->Blink->Flink;
            if( v15->Flink->Blink != v15 )
              goto LABEL_77;
            if( *p_Flink != v15 )
              goto LABEL_77;
            *p_Flink = Flink;
            Flink->Blink = (_LIST_ENTRY *)p_Flink;
            if( *p_Flink != Flink )
              goto LABEL_77;
            v14->Flink = Flink;
            v13.QuadPart += 0x80000i64;
            *(_QWORD *)&PoolWithTag[v34 - (unsigned __int64)v6 - (_QWORD)Vacbs + 8 + (_QWORD)v15++] = p_Flink;
            *p_Flink = v14;
            Flink->Blink = v14++;
            if( v13.QuadPart >= SharedCacheMap->SectionSize.QuadPart )
              goto LABEL_41;
          }
        }
        for( i = (_SHARED_CACHE_MAP *)SharedCacheMap->BcbList.Blink;
              i != (_SHARED_CACHE_MAP *)&SharedCacheMap->BcbList;
              i = (_SHARED_CACHE_MAP *)i->FileSize.QuadPart )
        {
          if( v13.QuadPart <= *(_QWORD *)&i[-1].NumActiveVacb )
          {
            v25 = *(_LIST_ENTRY **)&i->NodeTypeCode;
            while( (_SHARED_CACHE_MAP *)v25->Blink == i )
            {
              v14->Flink = v25;
              v13.QuadPart += 0x80000i64;
              v14->Blink = (_LIST_ENTRY *)i;
              v25->Blink = v14;
              v25 = v14;
              *(_QWORD *)&i->NodeTypeCode = v14++;
              if( v13.QuadPart > *(_QWORD *)&i[-1].NumActiveVacb )
                goto LABEL_55;
            }
LABEL_77:
            __fastfail(3u);
          }
LABEL_55:
          ;
        }
LABEL_41:
        if( v13.QuadPart < v5 )
        {
          p_BcbList = &SharedCacheMap->BcbList;
          for( j = SharedCacheMap->BcbList.Flink; ; j = v20 )
          {
            v20 = v14;
            if( j->Blink != p_BcbList )
              break;
            v14->Flink = j;
            v13.QuadPart += 0x80000i64;
            v14->Blink = p_BcbList;
            j->Blink = v14;
            p_BcbList->Flink = v14++;
            if( v13.QuadPart >= v5 )
              goto LABEL_24;
          }
          goto LABEL_77;
        }
      }
LABEL_24:
      SharedCacheMap->Vacbs = (_VACB **)PoolWithTag;
      SharedCacheMap->SectionSize.QuadPart = v5;
      CcReleaseBcbLockAndVacbLock(v2, (struct FAST_MUTEX *)SharedCacheMap);
      if( Vacbs != (_SHARED_CACHE_MAP *)SharedCacheMap->InitialVacbs && Vacbs )
        ExFreePoolWithTag(Vacbs, 0);
    }
    SharedCacheMap->SectionSize.QuadPart = v5;
  }
  if( QuadPart <= v5 )
  {
LABEL_29:
    CcFreeUnusedVacbLevels(&VacbLevels, (_LARGE_INTEGER)NewSectionSize.QuadPart);
    return;
  }
  v21 = 1;
  v22 = 25;
  if( v5 > 0x2000000 )
  {
    NewSectionSize = SharedCacheMap->SectionSize;
    do
    {
      v22 += 7;
      ++v21;
    }
    while( NewSectionSize.QuadPart > 1i64 << v22 );
  }
  v23 = v21;
  if( !((QuadPart - 1) >> v22) )
    goto LABEL_51;
  do
  {
    v22 += 7;
    ++v23;
  }
  while( (QuadPart - 1) >> v22 );
  if( v23 <= v21 )
  {
LABEL_51:
    SharedCacheMap->SectionSize.QuadPart = QuadPart;
    goto LABEL_29;
  }
  v26 = KeAcquireQueuedSpinLock(4ui64);
  if( v23 >= CcMaxVacbLevelsSeen )
    CcMaxVacbLevelsSeen = v23 + 1;
  KeReleaseQueuedSpinLock(4ui64, v26);
  if( (unsigned __int8)CcAllocateVacbLevels(v23 - v21, 0i64, &VacbLevels) )
  {
    CcAcquireBcbLockAndVacbLock(v2, (FAST_MUTEX *)SharedCacheMap);
    if( v21 == 1 )
      CcCalculateVacbLevelLockCount((INT64)SharedCacheMap, (INT64)SharedCacheMap->Vacbs);
    v27 = SharedCacheMap->Vacbs;
    if( *(_QWORD *)VacbLevelReference((INT64)SharedCacheMap, (INT64)v27, v21 - 1) )
    {
      do
      {
        ++v21;
        VacbLevel = CcAllocateVacbLevel((__int64)&VacbLevels, 0);
        *VacbLevel = SharedCacheMap->Vacbs;
        v31 = (_DWORD *)VacbLevelReference((INT64)SharedCacheMap, (INT64)VacbLevel, v21);
        ++*v31;
        SharedCacheMap->Vacbs = v32;
      }
      while( v21 < v23 );
    }
    else if( v21 == 1 && (SharedCacheMap->Flags & 0x200) != 0 )
    {
      SharedCacheMap->Vacbs = (_VACB **)CcAllocateVacbLevel((__int64)&VacbLevels, 0);
      v28 = v27[128];
      v29 = v27[255];
      *((_QWORD *)v28 + 1) = v29;
      *(_QWORD *)v29 = v28;
      ExFreeToNPagedLookasideList((NPAGED_LOOKASIDE_LIST *)CcVacbLevelWithBcbListHeadsLookasideList, v27);
    }
    SharedCacheMap->SectionSize.QuadPart = QuadPart;
    CcReleaseBcbLockAndVacbLock(v2, (struct FAST_MUTEX *)SharedCacheMap);
    goto LABEL_51;
  }
}

Referenced by:

CcSetFileSizesEx