AlpcpSignalAndWait
INT64 __fastcall AlpcpSignalAndWait(
_ALPC_DISPATCH_CONTEXT *DispatchContext,
_KSEMAPHORE *WaitSemaphore,
_KWAIT_REASON WaitReason,
VOID *WaitMode,
_LARGE_INTEGER *Timeout,
UINT8 DonatePriority){
_ALPC_PORT *TargetPort;
KPROCESSOR_MODE v8;
bool v9;
__int64 v10;
unsigned __int8 PostedToCompletionList;
unsigned int v12;
_QWORD *v13;
_IO_MINI_COMPLETION_PACKET_USER *MiniPacket;
unsigned int v15;
_ETHREAD *CurrentThread;
unsigned int v17;
struct _DMA_ADAPTER *v18;
_ETHREAD *TargetThread;
_KALPC_DIRECT_EVENT v21;
_KALPC_DIRECT_EVENT v22;
struct _KLOCK_QUEUE_HANDLE LockHandle;
TargetPort = DispatchContext->TargetPort;
v8 = (char)WaitMode;
v9 = (DispatchContext->Flags & 0x200000) != 0;
if( TargetPort )
{
if( DispatchContext->SignalCompletion )
{
v10 = *((_QWORD *)TargetPort + 6);
PostedToCompletionList = DispatchContext->PostedToCompletionList;
memset(&LockHandle, 0, sizeof(LockHandle));
KeAcquireInStackQueuedSpinLock((UINT64 *)v10, &LockHandle);
v12 = *(_DWORD *)(v10 + 12);
if( v12 >= *(_DWORD *)(v10 + 8) )
{
MiniPacket = 0i64;
if( PostedToCompletionList )
++*(_DWORD *)(v10 + 20);
else
++*(_DWORD *)(v10 + 16);
}
else
{
v13 = *(_QWORD **)(v10 + 32);
if( v13 )
{
*(_QWORD *)(v10 + 32) = *v13;
v12 = *(_DWORD *)(v10 + 12);
}
MiniPacket = (_IO_MINI_COMPLETION_PACKET_USER *)v13[1];
*(_DWORD *)(v10 + 12) = v12 + 1;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
if( _InterlockedCompareExchange64((volatile signed __int64 *)TargetPort + 44, 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)TargetPort + 44);
KeAbPostRelease((char *)TargetPort + 352);
if( MiniPacket )
IoSetIoCompletionEx2(
*((PVOID *)TargetPort + 4),
*((PVOID *)TargetPort + 5),
(PVOID)-(__int64)(PostedToCompletionList != 0),
0i64,
0i64,
0,
MiniPacket,
1u);
}
else
{
KeReleaseSemaphoreEx(*((KSEMAPHORE **)TargetPort + 31), 1i64, 1i64, (UINT64)WaitMode);
}
}
else
{
TargetThread = DispatchContext->TargetThread;
if( TargetThread )
{
KeReleaseSemaphoreEx((KSEMAPHORE *)((char *)TargetThread + 1160), 1i64, 1i64, (UINT64)WaitMode);
}
else
{
v21.Value = (unsigned __int64)DispatchContext->DirectEvent;
if( (v21.Value & 1) != 0 )
{
if( v21.Value >= 4 )
{
KeSetEvent((PRKEVENT)(v21.Value & 0xFFFFFFFFFFFFFFFCui64), 0);
v22.Value = (unsigned __int64)DispatchContext->DirectEvent;
if( (v22.Value & 2) != 0 )
HalPutDmaAdapter((PADAPTER_OBJECT)(v22.Value & 0xFFFFFFFFFFFFFFFCui64));
}
DispatchContext->DirectEvent.Value = 0i64;
}
}
}
KeLeaveCriticalRegion();
v15 = KeWaitForSingleObject(WaitSemaphore, WaitReason, v8, v9, Timeout);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v17 = v15;
--*((_WORD *)CurrentThread + 242);
if( AlpcpLogEnabled )
AlpcpLogUnwait(v15);
v18 = (struct _DMA_ADAPTER *)DispatchContext->TargetPort;
if( v18 )
HalPutDmaAdapter(v18);
return v17;
}Referenced by:
AlpcpCompleteDeferSignalRequestAndWait
AlpcpReceiveSynchronousReply