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