KeSaveExtendedAndSupervisorState
NTSTATUS __stdcall KeSaveExtendedAndSupervisorState(UINT64 Mask, _XSTATE_SAVE *XStateSave){
unsigned __int8 CurrentIrql;
_ETHREAD *CurrentThread;
bool v5;
unsigned __int8 v6;
_BYTE *SparePtr;
UINT64 v8;
NTSTATUS result;
struct _KPRCB *CurrentPrcb;
unsigned int v11;
CurrentIrql = KeGetCurrentIrql();
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( CurrentIrql > 2u )
KeBugCheckEx(0x131u, (PVOID)1, (PVOID)CurrentIrql, 0i64, 0i64);
if( ((unsigned int)KeFeatureBits & 0x800000) != 0 )
{
if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState._bf_0 & 2) != 0 )
{
if( (~(KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledSupervisorFeatures) & Mask) != 0 )
LABEL_32:
KeBugCheckEx(
0x131u,
0i64,
(PVOID)((unsigned int)KeFeatureBits & 0x800000),
(PVOID)(unsigned int)Mask,
(PVOID)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 || (CurrentThread->Tcb.ApcState.InProgressFlags & 1) != 0 )
goto LABEL_25;
v6 = 0;
LABEL_9:
SparePtr = CurrentThread->Tcb.WaitBlock[1].SparePtr;
v8 = (Mask | KUSER_SHARED_DATA.XState.EnabledFeatures) & 0xFFFFFFFFFFFFFFFCui64;
if( SparePtr && SparePtr[16] > v6 )
KeBugCheckEx(0x131u, (PVOID)2, (PVOID)(unsigned __int8)SparePtr[16], (PVOID)v6, 0i64);
if( v8 )
{
if( CurrentIrql < 2u || SparePtr && SparePtr[16] == v6 )
{
result = KeAllocateXStateContext(&XStateSave->XStateContext, Mask);
if( result < 0 )
return result;
}
else
{
CurrentPrcb = KeGetCurrentPrcb();
memset(&CurrentPrcb->ExtendedState->Header, 0i64, sizeof(CurrentPrcb->ExtendedState->Header));
v11 = KeXStateLength;
XStateSave->XStateContext.Buffer = 0i64;
XStateSave->XStateContext.Length = v11;
XStateSave->XStateContext.Area = CurrentPrcb->ExtendedState;
}
}
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 )
--CurrentThread->Tcb.SpecialApcDisable;
XStateSave->Prev = CurrentThread->Tcb.XStateSave;
if( v8 && ((unsigned __int64)KeFeatureBits & 0x800000) != 0 )
{
if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState._bf_0 & 2) != 0 )
{
RtlXRestore(XStateSave->XStateContext.Area, 0i64);
XStateSave->XStateContext.Area->Header.CompactionMask = v8;
RtlXSaveS((INT64)XStateSave->XStateContext.Area, v8);
}
else
{
RtlXSave(XStateSave->XStateContext.Area, v8);
}
}
CurrentThread->Tcb.WaitBlock[1].SparePtr = XStateSave;
if( !CurrentIrql )
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
return 0;
}Referenced by:
KeSaveExtendedProcessorState
PnprQuiesceProcessorDpc
PopHandleNextState