NtInitiatePowerAction
NTSTATUS __stdcall NtInitiatePowerAction(
POWER_ACTION SystemAction,
_SYSTEM_POWER_STATE LightestSystemState,
UINT64 Flags,
UINT8 Asynchronous){
_ETHREAD *CurrentThread;
int Lock;
_KEVENT *v6;
int v8;
char v11;
_KEVENT *PoolWithTag;
char *p_WaitListHead;
__int64 v14;
char **Blink;
PLARGE_INTEGER Timeout;
union _LARGE_INTEGER v18;
_DWORD a3[4];
int a1;
int a1_4;
__int128 v22;
v22 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Lock = 0;
v6 = 0i64;
v18.QuadPart = -1500000000i64;
v8 = Flags;
v11 = *((_BYTE *)CurrentThread + 562);
if( v11 )
{
if( SystemAction == PowerActionWarmEject )
return -1073741811;
if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeShutdownPrivilege, *((_BYTE *)CurrentThread + 562)) )
return -1073741727;
}
if( LightestSystemState > PowerSystemMaximum
|| SystemAction > PowerActionWarmEject
|| (v8 & 0x10000000) != 0
|| SystemAction == PowerActionSleep && LightestSystemState >= PowerSystemHibernate
|| (v8 & 0xCFFFFC0) != 0 )
{
return -1073741811;
}
if( (unsigned int)(SystemAction - 4) > 2 && PsIsCurrentThreadInServerSilo() )
return -1073741637;
a3[2] = 0;
a3[0] = SystemAction;
a3[1] = v8;
a1_4 = 128;
v22 = 0i64;
if( !v11 && SystemAction == PowerActionShutdownOff && (v8 & 0x3000000) != 0 )
{
a1 = 15;
}
else
{
a1 = 4;
PopDiagTracePolicyInitiatePowerActionApiCall((unsigned int)SystemAction, (unsigned int)LightestSystemState);
}
if( !Asynchronous )
{
PoolWithTag = (_KEVENT *)ExAllocatePoolWithTag(NonPagedPoolNx, 0x38ui64, 0x57634150ui64);
v6 = PoolWithTag;
if( !PoolWithTag )
return -1073741670;
*(_OWORD *)&PoolWithTag->Header.Lock = 0i64;
*(_OWORD *)&PoolWithTag->Header.WaitListHead.Blink = 0i64;
PoolWithTag[1].Header.WaitListHead = 0i64;
*(_QWORD *)&PoolWithTag[2].Header.Lock = &a1;
KeInitializeEvent(PoolWithTag, NotificationEvent, 0);
a1_4 |= 0x20u;
*(_QWORD *)&v22 = v6;
}
if( (unsigned int)(SystemAction - 4) <= 2 && (*(_BYTE *)(&PopBsdPowerTransition + 1) & 8) == 0 )
{
PopAcquireRwLockExclusive(&PopBsdUpdateLock);
*((_BYTE *)&PopBsdPowerTransition + 8) |= 8u;
LOBYTE(PopBsdPowerTransitionExtension) = SleepReason;
PopBsdHandleRequest(8i64);
PopReleaseRwLock((UINT64)&PopBsdUpdateLock);
}
PopAcquirePolicyLock();
LODWORD(Timeout) = 1;
PopExecutePowerAction((INT64)&a1, 0i64, (INT64)a3, (unsigned int)LightestSystemState, (UINT64)Timeout);
PopReleasePolicyLock();
if( v6 )
{
p_WaitListHead = (char *)&v6[1].Header.WaitListHead;
if( !v6[1].Header.WaitListHead.Flink )
goto LABEL_23;
Lock = KeWaitForSingleObject(v6, Suspended, 0, 1u, &v18);
if( Lock == 258 && (byte_140C23261 & 3) != 0 )
Lock = KeWaitForSingleObject(v6, Suspended, 0, 1u, 0i64);
PopAcquirePolicyLock();
v14 = *(_QWORD *)p_WaitListHead;
if( *(char **)(*(_QWORD *)p_WaitListHead + 8i64) != p_WaitListHead
|| (Blink = (char **)v6[1].Header.WaitListHead.Blink, *Blink != p_WaitListHead) )
{
__fastfail(3u);
}
*Blink = (char *)v14;
*(_QWORD *)(v14 + 8) = Blink;
PopReleasePolicyLock();
if( Lock >= 0 )
{
LABEL_23:
Lock = v6[1].Header.Lock;
if( Lock >= 0 )
Lock = 0;
}
ExFreePoolWithTag(v6, 0);
}
return Lock;
}Referenced by:
IopWarmEjectDevice
PopCheckPowerSourceAfterRtcWakeTimerWorker