MmExtendSection
NTSTATUS __stdcall MmExtendSection(VOID *SectionToExtend, UINT64 *NewSectionSize, UINT64 IgnoreFileSizeChecking){
int v3;
_CONTROL_AREA *v6;
_CONTROL_AREA *v7;
_SEGMENT *Segment;
UINT64 v9;
UINT64 v10;
int v11;
_SUBSECTION *LastSubsection;
unsigned __int64 v13;
unsigned __int64 v14;
NTSTATUS updated;
UINT64 v16;
_FILE_OBJECT *v18;
_FILE_OBJECT *v19;
_LARGE_INTEGER *v20;
NTSTATUS v21;
_ETHREAD *CurrentThread;
_LARGE_INTEGER *ExtendInfo;
int v24;
UINT64 v25;
NTSTATUS v26;
__int128 v27[2];
__int64 v28;
_LARGE_INTEGER FileSize;
UINT64 GrantedAccess;
FileSize.QuadPart = 0i64;
v3 = IgnoreFileSizeChecking;
memset(v27, 0, sizeof(v27));
v28 = 0i64;
v6 = MiSectionControlArea((_SECTION *)SectionToExtend);
v7 = v6;
if( (v6->u.LongFlags & 0x420) != 0 || !v6->FilePointer.Value )
return -1073741689;
if( *NewSectionSize <= 0x3FFFFFFFFFF000i64 )
{
Segment = v6->Segment;
v9 = *NewSectionSize + 4095;
DWORD2(v27[0]) = 16;
v10 = v9 >> 12;
MiLockControlAreaSectionExtend(v6);
if( (v7->u.LongFlags & 0x8000) == 0 )
{
v25 = *((_QWORD *)SectionToExtend + 6);
if( *NewSectionSize <= v25 )
{
*NewSectionSize = v25;
MiUnlockControlAreaSectionExtend(v7, (_MI_CONTROL_AREA_WAIT_BLOCK *)v27);
return 0;
}
}
if( v3 )
goto LABEL_6;
MiUnlockControlAreaSectionExtend(v7, (_MI_CONTROL_AREA_WAIT_BLOCK *)v27);
v18 = MiReferenceControlAreaFile(v7);
DWORD2(v27[0]) = 32;
v19 = v18;
MiLockControlAreaSectionExtend(v7);
v11 = FsRtlGetFileSize(v19, &FileSize);
if( v11 >= 0 )
{
if( *NewSectionSize <= FileSize.QuadPart )
{
LABEL_18:
if( Segment->ExtendInfo )
{
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(&stru_140C4C6D0, 0i64);
ExtendInfo = (_LARGE_INTEGER *)Segment->ExtendInfo;
if( ExtendInfo )
*ExtendInfo = FileSize;
if( (_InterlockedExchangeAdd64(&stru_140C4C6D0._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&stru_140C4C6D0);
KeAbPostRelease(&stru_140C4C6D0);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
MiUnlockControlAreaSectionExtend(v7, (_MI_CONTROL_AREA_WAIT_BLOCK *)v27);
MiDereferenceControlAreaFile(v7, v19);
DWORD2(v27[0]) = 16;
MiLockControlAreaSectionExtend(v7);
LABEL_6:
v11 = 0;
GrantedAccess = 0i64;
LastSubsection = MiFindLastSubsection(v7, 0i64);
v13 = Segment->TotalNumberOfPtes | ((unsigned __int64)(Segment->SegmentFlags.Short0 & 0x3FF) << 32);
if( v10 <= v13 )
{
*((_QWORD *)SectionToExtend + 6) = *NewSectionSize;
if( _InterlockedCompareExchange64((volatile signed __int64 *)&Segment->SizeOfSegment, -1i64, -1i64) < *NewSectionSize )
{
_InterlockedExchange64((volatile __int64 *)&Segment->SizeOfSegment, *NewSectionSize);
MiUpdateLastSubsectionSize(LastSubsection, NewSectionSize, 0i64);
}
}
else
{
v14 = v10 - v13;
if( v14 <= (LastSubsection->_bf_34 & 0x3FFFFFFFu) )
{
LOBYTE(v24) = MiControlAreaUsingExtents((INT64)v7);
if( v24 && LastSubsection->SubsectionBase )
{
MiSubsectionNeedsExtents(LastSubsection);
GrantedAccess = (UINT64)LastSubsection;
}
updated = MiUpdateLastSubsectionSize(LastSubsection, NewSectionSize, (unsigned int)v14);
}
else
{
updated = MiExtendSection(
LastSubsection,
NewSectionSize,
LastSubsection->_bf_34 & 0x3FFFFFFF,
v14 - (LastSubsection->_bf_34 & 0x3FFFFFFF));
}
v11 = updated;
if( updated >= 0 )
{
v11 = 0;
_InterlockedExchange64((volatile __int64 *)&Segment->SizeOfSegment, *NewSectionSize);
*((_QWORD *)SectionToExtend + 6) = *NewSectionSize;
}
}
MiUnlockControlAreaSectionExtend(v7, (_MI_CONTROL_AREA_WAIT_BLOCK *)v27);
if( GrantedAccess )
{
LOBYTE(v26) = MiUpdateActiveSubsection(GrantedAccess, v16);
return v26;
}
return v11;
}
if( (*((_DWORD *)SectionToExtend + 15) & 0x44) != 0 )
{
FileSize.QuadPart = *NewSectionSize;
v21 = FsRtlSetFileSize(v19, &FileSize, v20);
if( v21 >= 0 )
goto LABEL_18;
v11 = v21;
}
else
{
v11 = -1073741689;
}
}
MiUnlockControlAreaSectionExtend(v7, (_MI_CONTROL_AREA_WAIT_BLOCK *)v27);
MiDereferenceControlAreaFile(v7, v19);
return v11;
}
return -1073741760;
}Referenced by:
CcSetFileSizesEx
MiCreateSection
NtExtendSection