KeReleaseSemaphoreEx
NTSTATUS __stdcall KeReleaseSemaphoreEx(
_KSEMAPHORE *Semaphore,
INT64 BoostIncrement,
INT64 Adjustment,
VOID *Flags,
UINT64 Flagsa){
int v5;
unsigned int v6;
UINT8 OldIrql;
struct _KPRCB *CurrentPrcb;
NTSTATUS v10;
NTSTATUS v11;
unsigned int v12;
_KSEMAPHORE *v13;
__int64 v14;
_KWAIT_BLOCK *v15;
_LIST_ENTRY *Blink;
unsigned __int8 WaitType;
bool v18;
_QWORD *v20;
_ETHREAD *v21;
char v22;
int v23;
_KWAIT_BLOCK **QuantumTarget;
_KPRCB *Prcb;
_ETHREAD *CurrentThread;
_QWORD *v27;
unsigned int v28;
_ETHREAD *Object;
v28 = BoostIncrement;
v5 = Adjustment;
v6 = BoostIncrement;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
KiAcquireKobjectLockSafe(Semaphore);
v10 = *(_DWORD *)&Semaphore->gap0[4];
v11 = v10 + v5;
if( v10 + v5 > Semaphore->Limit || v11 < v10 )
{
_InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
__writecr8(OldIrql);
RtlRaiseStatus(-1073741753);
}
v12 = 0;
*(_DWORD *)&Semaphore->gap0[4] = v11;
if( !v10 )
{
v13 = *(_KSEMAPHORE **)&Semaphore->gap0[8];
while( v13 != (_KSEMAPHORE *)&Semaphore->gap0[8] )
{
v14 = *(_QWORD *)v13->gap0;
v15 = (_KWAIT_BLOCK *)v13;
v13 = (_KSEMAPHORE *)v14;
Blink = v15->WaitListEntry.Blink;
if( *(_KWAIT_BLOCK **)(v14 + 8) != v15 || (_KWAIT_BLOCK *)Blink->Flink != v15 )
LABEL_6:
__fastfail(3u);
Blink->Flink = (_LIST_ENTRY *)v14;
*(_QWORD *)(v14 + 8) = Blink;
WaitType = v15->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(CurrentPrcb, v15, v15->WaitKey, 0i64) )
{
v18 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
if( v18 )
break;
}
}
else
{
if( WaitType == 2 )
{
v15->BlockState = 5;
Object = v15->Thread;
v27 = &Object->Tcb.gap0[8];
v15->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
Prcb = KeGetCurrentPrcb();
CurrentThread = Prcb->CurrentThread;
KiAcquireKobjectLockSafe(Object);
v20 = v27;
v21 = Object;
if( (_QWORD *)*v20 == v20
|| LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
{
LABEL_28:
v23 = *(_DWORD *)&v21->Tcb.gap0[4];
*(_DWORD *)&v21->Tcb.gap0[4] = v23 + 1;
QuantumTarget = (_KWAIT_BLOCK **)v21->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&v21->Tcb.SListFaultAddress )
goto LABEL_6;
v15->WaitListEntry.Flink = (_LIST_ENTRY *)&v21->Tcb.SListFaultAddress;
v15->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v15;
v21->Tcb.QuantumTarget = (unsigned __int64)v15;
if( !v23 && (_QWORD *)*v20 != v20 )
{
KiWakeOtherQueueWaiters(Prcb, (_KQUEUE *)v21);
v21 = Object;
}
}
else
{
KiWakeQueueWaiter(Prcb, (_KQUEUE *)Object, (INT64)v15);
v21 = Object;
if( !v22 )
{
v20 = &Object->Tcb.gap0[8];
goto LABEL_28;
}
}
_InterlockedAnd((volatile signed __int32 *)v21, 0xFFFFFF7F);
v18 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
if( v18 )
break;
continue;
}
KiTryUnwaitThread(CurrentPrcb, v15, 256i64, 0i64);
}
}
v6 = v28;
}
_InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
if( (Flagsa & 1) != 0 )
{
v12 = 1;
if( (Flagsa & 4) == 0 )
v12 = 3;
}
else if( (Flagsa & 2) != 0 )
{
KiCompleteDirectSwitchThread(CurrentPrcb, &CurrentPrcb->CurrentThread->Tcb);
}
KiExitDispatcher(CurrentPrcb, v12, AdjustUnwait, v6, OldIrql);
return v10;
}Referenced by:
AlpcpCancelMessage
AlpcpCancelMessagesByRequestor
AlpcpCompleteDispatchMessage
AlpcpDispatchReplyToWaitingThread
AlpcpDoPortCleanup
AlpcpReplyLegacySynchronousRequest
AlpcpSignal
AlpcpSignalAndWait
AlpcpSignalPortAndUnlock
IoRaiseInformationalHardError
MiQueuePageFileExtension
NtWaitForWorkViaWorkerFactory
PnpDeviceCompletionQueueDispatchedEntryCompleted
PnpProcessRebalance
PopCompleteDirectedPowerTransitionCallback
PopCompleteNotifyTransitionCommon
PopDispatchQuerySetIrp
PopFxQueueWorkOrder
PopFxRequestWorker
VslpEnterIumSecureMode