KeReleaseSemaphore
NTSTATUS __stdcall KeReleaseSemaphore(_KSEMAPHORE *Semaphore, INT64 Increment, INT64 Adjustment, UINT8 Wait){
int v4;
unsigned int v5;
UINT8 OldIrql;
_KPRCB *CurrentPrcb;
NTSTATUS v9;
NTSTATUS v10;
_KSEMAPHORE *v11;
__int64 v12;
_KWAIT_BLOCK *v13;
_LIST_ENTRY *Blink;
unsigned __int8 WaitType;
bool v16;
UINT64 v17;
_QWORD *v19;
_ETHREAD *v20;
char v21;
int v22;
_KWAIT_BLOCK **QuantumTarget;
_BOOL4 v24;
_QWORD *v25;
_KPRCB *Prcb;
_ETHREAD *CurrentThread;
_ETHREAD *Object;
v4 = Adjustment;
v5 = Increment;
v24 = Wait != 0;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
KiAcquireKobjectLockSafe(Semaphore);
v9 = *(_DWORD *)&Semaphore->gap0[4];
v10 = v9 + v4;
if( v9 + v4 > Semaphore->Limit || v10 < v9 )
{
_InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
__writecr8(OldIrql);
RtlRaiseStatus(-1073741753);
}
*(_DWORD *)&Semaphore->gap0[4] = v10;
if( !v9 )
{
v11 = *(_KSEMAPHORE **)&Semaphore->gap0[8];
while( v11 != (_KSEMAPHORE *)&Semaphore->gap0[8] )
{
v12 = *(_QWORD *)v11->gap0;
v13 = (_KWAIT_BLOCK *)v11;
v11 = (_KSEMAPHORE *)v12;
Blink = v13->WaitListEntry.Blink;
if( *(_KWAIT_BLOCK **)(v12 + 8) != v13 || (_KWAIT_BLOCK *)Blink->Flink != v13 )
LABEL_6:
__fastfail(3u);
Blink->Flink = (_LIST_ENTRY *)v12;
*(_QWORD *)(v12 + 8) = Blink;
WaitType = v13->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(CurrentPrcb, v13, v13->WaitKey, 0i64) )
{
v16 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
if( v16 )
break;
}
}
else
{
if( WaitType == 2 )
{
v13->BlockState = 5;
Object = v13->Thread;
v25 = &Object->Tcb.gap0[8];
v13->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
Prcb = KeGetCurrentPrcb();
CurrentThread = Prcb->CurrentThread;
KiAcquireKobjectLockSafe(Object);
v19 = v25;
v20 = Object;
if( (_QWORD *)*v19 == v19
|| LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
{
LABEL_25:
v22 = *(_DWORD *)&v20->Tcb.gap0[4];
*(_DWORD *)&v20->Tcb.gap0[4] = v22 + 1;
QuantumTarget = (_KWAIT_BLOCK **)v20->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&v20->Tcb.SListFaultAddress )
goto LABEL_6;
v13->WaitListEntry.Flink = (_LIST_ENTRY *)&v20->Tcb.SListFaultAddress;
v13->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v13;
v20->Tcb.QuantumTarget = (unsigned __int64)v13;
if( !v22 && (_QWORD *)*v19 != v19 )
{
KiWakeOtherQueueWaiters(Prcb, (_KQUEUE *)v20);
v20 = Object;
}
}
else
{
KiWakeQueueWaiter(Prcb, (_KQUEUE *)Object, (INT64)v13);
v20 = Object;
if( !v21 )
{
v19 = &Object->Tcb.gap0[8];
goto LABEL_25;
}
}
_InterlockedAnd((volatile signed __int32 *)v20, 0xFFFFFF7F);
v16 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
if( v16 )
break;
continue;
}
KiTryUnwaitThread(CurrentPrcb, v13, 256i64, 0i64);
}
}
}
_InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
v17 = 3i64;
if( !v24 )
v17 = 0i64;
KiExitDispatcher(CurrentPrcb, v17, AdjustUnwait, v5, OldIrql);
return v9;
}Referenced by:
AlpcpDoPortCleanup
FsRtlDeregisterUncProvider
FsRtlpRegisterUncProvider
IopAllocateBootResources
IopInsertLegacyBusDeviceNode
IopLegacyResourceAllocation
IopQueryConflictList
IopUncacheInterfaceInformation
NtReleaseKeyedEvent
NtReleaseSemaphore
NtSignalAndWaitForSingleObject
NtWaitForKeyedEvent
PnpAllocateResources
PnpReallocateResources
PopIrpWorker
PopSystemIrpCompletion
PpProfileCancelHardwareProfileTransition
PpProfileCancelTransitioningDock
PpProfileCommitTransitioningDock