AlpcpLookupMessage

INT64 __fastcall AlpcpLookupMessage(INT64 a1, INT64 a2, INT64 a3, INT64 a4, UINT64 *a5){
  int v5; 
  int v6; 
  _HANDLE_TABLE *v8; 
  ULONG_PTR v9; 
  char v10; 
  _HANDLE_TABLE_ENTRY *v11; 
  INT64 LowValue; 
  unsigned __int64 Value; 
  __int64 BugCheckParameter4; 
  bool v15; 
  __int64 v16; 
  signed __int64 v17; 
  __int64 v19; 
  __int64 v20; 
  _EX_PUSH_LOCK *v21; 
  volatile signed __int32 *v22; 
  signed __int32 v23; 
  signed __int32 v24[8]; 
  v5 = a2;
  v6 = a3;
  if( (int)a2 < 0 )
  {
    if( a1 )
    {
      v20 = *(_QWORD *)(a1 + 16);
      if( !v20 )
        return 3221226224i64;
      a2 = (unsigned int)a2;
      LODWORD(a2) = a2 & 0x7FFFFFFF;
      v21 = AlpcReferenceBlobByHandle((_ALPC_HANDLE_TABLE *)(v20 + 40), (VOID *)a2, &AlpcReserveType);
      v22 = (volatile signed __int32 *)v21;
      if( !v21 )
        return 3221226224i64;
      Value = v21[3].Value;
      AlpcpLockForCachedReferenceBlob((PVOID)Value);
      if( !_InterlockedCompareExchange(v22 + 10, 1, 0) )
      {
        *(_DWORD *)(Value + 264) &= ~0x80000000;
        do
          v23 = _InterlockedIncrement(&AlpcpNextCallbackId);
        while( !v23 );
        *(_DWORD *)(Value + 272) = v23;
        goto LABEL_25;
      }
      AlpcpUnlockMessage(Value);
      AlpcpDereferenceBlobEx((PVOID)v22, 1i64);
      return 3221227272i64;
    }
    return 3221227266i64;
  }
  if( (a2 & 0xFC000000) != 0 )
  {
    if( !AlpcpSecondaryMessageTables )
      return 3221227266i64;
    v8 = *(_HANDLE_TABLE **)(AlpcpSecondaryMessageTables + 8 * ((unsigned __int64)(unsigned int)a2 >> 26));
  }
  else
  {
    v8 = (_HANDLE_TABLE *)AlpcMessageTable;
  }
  if( !v8 )
    return 3221227266i64;
  v9 = a2 & 0x3FFFFFF;
  v10 = *((_BYTE *)KeGetCurrentThread() + 562);
  if( (a2 & 0x3FC) == 0 || (v11 = ExpLookupHandleTableEntry(v8, (_EXHANDLE)(unsigned int)v9)) == 0i64 )
  {
LABEL_31:
    ExHandleLogBadReference((ULONG_PTR)v8, v9, v10);
    return 3221227266i64;
  }
  do
  {
    while( 1 )
    {
      _m_prefetchw(v11);
      LowValue = v11->LowValue;
      if( (v11->LowValue & 1) != 0 )
        break;
      if( !LowValue )
        goto LABEL_31;
      ExpBlockOnLockedHandleEntry(v8, v11, LowValue);
    }
  }
  while( LowValue != _InterlockedCompareExchange64(&v11->VolatileLowValue, LowValue - 1, LowValue) );
  Value = (v11->LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
  if( *(_DWORD *)(Value + 0x108) != v5
    || v6 && *(_DWORD *)(((v11->LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64) + 0x110) != v6 )
  {
    goto LABEL_40;
  }
  _m_prefetchw((const void *)(Value - 24));
  BugCheckParameter4 = *(_QWORD *)(Value - 24);
  v15 = BugCheckParameter4 == 0;
  if( BugCheckParameter4 <= 0 )
  {
LABEL_50:
    if( !v15 )
      KeBugCheckEx(0x18u, 0i64, Value, 0x20ui64, BugCheckParameter4);
LABEL_40:
    _InterlockedExchangeAdd64(&v11->VolatileLowValue, 1ui64);
    _InterlockedOr(v24, 0);
    if( v8->HandleContentionEvent.Value )
      ExfUnblockPushLock(&v8->HandleContentionEvent, 0i64);
    return 3221227266i64;
  }
  while( 1 )
  {
    v16 = BugCheckParameter4;
    BugCheckParameter4 = _InterlockedCompareExchange64(
                           (volatile signed __int64 *)(Value - 24),
                           BugCheckParameter4 + 1,
                           BugCheckParameter4);
    if( BugCheckParameter4 == v16 )
      break;
    if( BugCheckParameter4 <= 0 )
    {
      v15 = BugCheckParameter4 == 0;
      goto LABEL_50;
    }
  }
  if( BugCheckParameter4 == -1 )
    goto LABEL_40;
  ExAcquirePushLockExclusiveEx(Value - 16, 0i64);
  *(_BYTE *)(Value - 32) |= 1u;
  v17 = _InterlockedExchangeAdd64((volatile signed __int64 *)(Value - 24), 0x10000ui64) + 0x10000;
  if( v17 <= 0 )
    KeBugCheckEx(0x18u, 0i64, Value, 0x26ui64, v17);
  --*(_WORD *)(Value - 30);
  _InterlockedExchangeAdd64(&v11->VolatileLowValue, 1ui64);
  _InterlockedOr(v24, 0);
  if( v8->HandleContentionEvent.Value )
    ExfUnblockPushLock(&v8->HandleContentionEvent, 0i64);
  if( *(_DWORD *)(Value + 264) != v5
    || v6 && *(_DWORD *)(Value + 272) != v6
    || !*(_QWORD *)(Value + 24) && !*(_QWORD *)(Value + 16) )
  {
    AlpcpUnlockMessage(Value);
    return 3221227266i64;
  }
  if( a1 )
  {
    if( *(_QWORD *)(Value + 184) == *(_QWORD *)(a1 + 16) || *(_QWORD *)(Value + 192) == a1 )
    {
LABEL_25:
      *a5 = Value;
      return 0i64;
    }
  }
  else
  {
    v19 = *(_QWORD *)(Value + 16);
    if( v19 && *(_QWORD *)(v19 + 24) == *((_QWORD *)KeGetCurrentThread() + 23) )
      goto LABEL_25;
  }
  AlpcpUnlockMessage(Value);
  return 3221225506i64;
}

Referenced by:

AlpcpAcceptConnectPort
AlpcpReceiveDirectMessagePort
AlpcpReplyLegacySynchronousRequest
AlpcpSendMessage
LpcpCopyRequestData
NtAlpcCancelMessage
NtAlpcImpersonateClientContainerOfPort
NtAlpcImpersonateClientOfPort
NtAlpcOpenSenderProcess
NtAlpcOpenSenderThread
NtAlpcQueryInformationMessage