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