KeSaveExtendedAndSupervisorState
INT64 __stdcall KeSaveExtendedAndSupervisorState(UINT64 Mask, XSTATE_SAVE *XStateSave){
unsigned __int8 CurrentIrql;
_ETHREAD *CurrentThread;
bool v5;
unsigned __int8 v6;
__int64 v7;
unsigned __int64 v8;
INT64 result;
struct _KPRCB *CurrentPrcb;
unsigned int v11;
CurrentIrql = KeGetCurrentIrql();
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( CurrentIrql > 2u )
KeBugCheckEx(0x131u, 1ui64, CurrentIrql, 0i64, 0i64);
if( (KeFeatureBits & 0x800000) != 0 )
{
if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
{
if( (~(KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledSupervisorFeatures) & Mask) != 0 )
LABEL_32:
KeBugCheckEx(0x131u, 0i64, KeFeatureBits & 0x800000, (unsigned int)Mask, HIDWORD(Mask));
LABEL_25:
v6 = CurrentIrql + 1;
goto LABEL_9;
}
v5 = (~KUSER_SHARED_DATA.XState.EnabledFeatures & Mask) == 0;
}
else
{
v5 = (Mask & 0xFFFFFFFFFFFFFFFCui64) == 0;
}
if( !v5 )
goto LABEL_32;
if( CurrentIrql || (*((_BYTE *)CurrentThread + 192) & 1) != 0 )
goto LABEL_25;
v6 = 0;
LABEL_9:
v7 = *((_QWORD *)CurrentThread + 51);
v8 = (Mask | KUSER_SHARED_DATA.XState.EnabledFeatures) & 0xFFFFFFFFFFFFFFFCui64;
if( v7 && *(_BYTE *)(v7 + 16) > v6 )
KeBugCheckEx(0x131u, 2ui64, *(unsigned __int8 *)(v7 + 16), v6, 0i64);
if( v8 )
{
if( CurrentIrql < 2u || v7 && *(_BYTE *)(v7 + 16) == v6 )
{
result = KeAllocateXStateContext(&XStateSave->XStateContext, Mask);
if( (int)result < 0 )
return result;
}
else
{
CurrentPrcb = KeGetCurrentPrcb();
memset(*((_QWORD *)CurrentPrcb + 4282) + 512i64, 0i64);
v11 = KeXStateLength;
XStateSave->XStateContext.Buffer = 0i64;
XStateSave->XStateContext.Length = v11;
XStateSave->XStateContext.Area = (_XSAVE_AREA *)*((_QWORD *)CurrentPrcb + 4282);
}
}
else
{
XStateSave->XStateContext.Length = 0;
XStateSave->XStateContext.Buffer = 0i64;
XStateSave->XStateContext.Area = 0i64;
}
XStateSave->Thread = CurrentThread;
XStateSave->Level = v6;
XStateSave->XStateContext.Mask = v8;
if( !CurrentIrql )
--*((_WORD *)CurrentThread + 243);
XStateSave->Prev = (_XSTATE_SAVE *)*((_QWORD *)CurrentThread + 51);
if( v8 && (KeFeatureBits & 0x800000) != 0 )
{
if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
{
RtlXRestore(XStateSave->XStateContext.Area, 0i64);
XStateSave->XStateContext.Area->Header.CompactionMask = v8;
RtlXSaveS(&XStateSave->XStateContext.Area->LegacyState.ControlWord, v8);
}
else
{
RtlXSave(XStateSave->XStateContext.Area, v8);
}
}
*((_QWORD *)CurrentThread + 51) = XStateSave;
if( !CurrentIrql )
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
return 0i64;
}Referenced by:
KeSaveExtendedProcessorState
PnprQuiesceProcessorDpc
PopHandleNextState