PspQueryRateControlHistory
VOID __stdcall PspQueryRateControlHistory(
_EJOB *Job,
UINT64 SamplingInterval,
UINT8 ClearHistory,
UINT64 *OverQuotaRate,
_PSP_JOB_RATE_CONTROL_TYPE Type){
UINT8 v6;
int v7;
char **v9;
char **v10;
char *v11;
unsigned int v12;
UINT32 v13;
UINT64 v14;
int v15;
int v16;
unsigned int v17;
void *v18;
unsigned int v19;
unsigned int v20;
UINT64 *v21;
unsigned int v22;
VOID **PoolWithTag;
__int64 v24;
UINT64 IntervalLength;
UINT64 OverQuotaHistory;
__int128 Address;
_SYSTEM_NET_RATE_CONTROL_CONTEXT_HEADER Header[2];
__int128 v30;
IntervalLength = 0i64;
v6 = ClearHistory;
OverQuotaHistory = 0i64;
v7 = SamplingInterval;
*(_DWORD *)OverQuotaRate = 0;
*(_OWORD *)&Header[0].PolicyCookie = 0i64;
v30 = 0i64;
Address = 0i64;
if( Type == PspJobIoRateControl )
{
v11 = (char *)Job + 1360;
}
else
{
v9 = (char **)((char *)Job + 1312);
v10 = (char **)((char *)Job + 1008);
if( Type == PspJobMinRateControl )
v10 = v9;
v11 = *v10;
}
if( v11 )
{
if( Type )
{
if( Type == PspJobIoRateControl )
{
if( (int)PspJobIoRateQueryHistory(
(__int64)Job,
&OverQuotaHistory,
&IntervalLength,
(_DWORD *)&IntervalLength + 1) < 0 )
return;
}
else
{
KeQuerySchedulingGroupHistory(
(_KSCHEDULING_GROUP *)(v11 + 128),
&OverQuotaHistory,
&IntervalLength,
(UINT64 *)((char *)&IntervalLength + 4));
}
v12 = IntervalLength;
v13 = HIDWORD(IntervalLength);
v14 = OverQuotaHistory;
}
else
{
Header[1].PolicyCookie = 1;
Header[0] = *(_SYSTEM_NET_RATE_CONTROL_CONTEXT_HEADER *)(v11 + 56);
if( PspNetRateControlDispatch(Header) < 0 )
return;
v14 = v30;
v12 = DWORD2(v30);
v13 = HIDWORD(v30);
}
v15 = v7 - 2;
if( v15 )
{
if( v15 == 1 )
v16 = 600000;
else
v16 = 10000;
}
else
{
v16 = 60000;
}
v17 = (v12 + v16 - 1) / v12;
v18 = (void *)*((_QWORD *)v11 + 3);
v19 = v17;
v20 = (v17 + 7) >> 3;
if( v20 < 8 )
v20 = 8;
if( *((_QWORD *)v11 + 3) && *((_QWORD *)v11 + 4) < (unsigned __int64)v20 )
{
ExFreePoolWithTag(v18, 0x624A7350u);
*((_QWORD *)v11 + 3) = 0i64;
*((_QWORD *)v11 + 4) = 0i64;
v18 = 0i64;
}
if( v18 )
{
if( v13 >= 8 * v20 )
{
memset(v18, 0i64, v20);
}
else if( v13 )
{
RtlCopyBitMap((_RTL_BITMAP *)(v11 + 8), (_RTL_BITMAP *)(v11 + 8), v13);
RtlClearBits((PRTL_BITMAP)(v11 + 8), 0, v13);
}
}
else
{
PoolWithTag = ExAllocatePoolWithTag(1ui64, v20, 1649046352i64);
*((_QWORD *)v11 + 3) = PoolWithTag;
if( !PoolWithTag )
return;
memset(PoolWithTag, 0i64, v20);
v24 = *((_QWORD *)v11 + 3);
*((_DWORD *)v11 + 2) = 8 * v20;
*((_QWORD *)v11 + 2) = v24;
*((_QWORD *)v11 + 4) = v20;
v6 = ClearHistory;
}
v21 = (UINT64 *)*((_QWORD *)v11 + 3);
LODWORD(Address) = v19;
if( v13 > 0x40 )
LOBYTE(v13) = 64;
*v21 = v14 & ((1i64 << v13) - 1) | *v21 & ~((1i64 << v13) - 1);
*((_QWORD *)&Address + 1) = *((_QWORD *)v11 + 3);
v22 = 100 * RtlNumberOfSetBits((UINT64 *)&Address) / v19;
if( v22 >= 0x3C )
{
*(_DWORD *)OverQuotaRate = 3;
}
else if( v22 >= 0x28 )
{
*(_DWORD *)OverQuotaRate = 2;
}
else if( v22 >= 0x14 )
{
*(_DWORD *)OverQuotaRate = 1;
}
if( v6 )
memset(*((VOID **)v11 + 3), 0i64, *((_QWORD *)v11 + 4));
}
}Referenced by:
NtQueryInformationJobObject
PspEnforceLimitsJobPreCallback