AlpcpReceiveMessage

INT64 __fastcall AlpcpReceiveMessage(
        _ALPC_DISPATCH_CONTEXT *DispatchContext,
        _PORT_MESSAGE *ReceiveMessage,
        UINT64 *BufferLength,
        _ALPC_MESSAGE_ATTRIBUTES *MessageAttributes,
        _LARGE_INTEGER *Timeout,
        INT64 a6,
        INT64 a7,
        INT64 a8){
  UINT64 *v9; 
  _ETHREAD *CurrentThread; 
  unsigned int Flags; 
  UINT64 v13; 
  __int64 v14; 
  unsigned int v15; 
  __int64 v16; 
  int v17; 
  __int64 v18; 
  signed int AllocatedAttributes; 
  UINT64 v20; 
  int v21; 
  int v22; 
  int v23; 
  int v24; 
  unsigned int v25; 
  __int64 v26; 
  __int64 v27; 
  __int64 v28; 
  __int64 v29; 
  unsigned int v30; 
  unsigned int v31; 
  unsigned int v32; 
  unsigned int v33; 
  unsigned int v34; 
  __int64 v35; 
  __int16 v36; 
  unsigned __int16 v37; 
  char *v38; 
  __int16 v39; 
  __int16 v40; 
  _ALPC_PORT *v41; 
  int v42; 
  __int64 v43; 
  char v44; 
  signed __int64 v45; 
  ULONG_PTR BugCheckParameter4; 
  unsigned __int8 v48; 
  unsigned int v49; 
  signed int v50; 
  INT64 v51; 
  unsigned int a1; 
  ULONG_PTR BugCheckParameter2; 
  INT64 PortObject; 
  unsigned __int64 v55; 
  LONGLONG v56; 
  _ETHREAD *v57; 
  INT64 v58; 
  _DWORD a2[4]; 
  __int128 v60; 
  _ALPC_DISPATCH_CONTEXT *DispatchContexta; 
  UINT64 DispatchContextb; 
  DispatchContexta = DispatchContext;
  v9 = BufferLength;
  BugCheckParameter2 = 0i64;
  v55 = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v57 = CurrentThread;
  Flags = DispatchContext->Flags;
  a1 = Flags;
  PortObject = (INT64)DispatchContext->PortObject;
  v58 = PortObject;
  v48 = *((_BYTE *)CurrentThread + 562);
  v13 = v48;
  v56 = 0i64;
  v55 = -1i64;
  v51 = 0i64;
  if( v48 )
  {
    v14 = (__int64)Timeout;
    if( Timeout )
    {
      if( (unsigned __int64)Timeout >= 0x7FFFFFFF0000i64 )
        v14 = 0x7FFFFFFF0000i64;
      v56 = *(_QWORD *)v14;
      Timeout = (_LARGE_INTEGER *)&v56;
    }
    v15 = Flags & 0xC0000000;
    v16 = (__int64)ReceiveMessage;
    if( (Flags & 0xC0000000) == 0x80000000 )
    {
      if( ((unsigned __int8)ReceiveMessage & 3) != 0 )
        goto LABEL_65;
      if( (unsigned __int64)ReceiveMessage >= 0x7FFFFFFF0000i64 )
        v16 = 0x7FFFFFFF0000i64;
      *(_BYTE *)v16 = *(_BYTE *)v16;
      *(_BYTE *)(v16 + 23) = *(_BYTE *)(v16 + 23);
    }
    else
    {
      if( ((unsigned __int8)ReceiveMessage & 3) != 0 )
        goto LABEL_65;
      if( (unsigned __int64)ReceiveMessage >= 0x7FFFFFFF0000i64 )
        v16 = 0x7FFFFFFF0000i64;
      *(_BYTE *)v16 = *(_BYTE *)v16;
      *(_BYTE *)(v16 + 39) = *(_BYTE *)(v16 + 39);
    }
    v17 = Flags & 0x1000000;
    if( (Flags & 0x1000000) != 0 )
    {
      if( v15 == 0x80000000 )
      {
        HIDWORD(v51) = *((_DWORD *)ReceiveMessage + 4);
        LODWORD(v51) = *((_DWORD *)ReceiveMessage + 5);
      }
      else
      {
        HIDWORD(v51) = *((_DWORD *)ReceiveMessage + 6);
        LODWORD(v51) = *((_DWORD *)ReceiveMessage + 8);
      }
    }
    if( !MessageAttributes )
    {
      AllocatedAttributes = 0;
      v50 = 0;
      goto LABEL_36;
    }
    v18 = (__int64)MessageAttributes;
    if( (unsigned __int64)MessageAttributes >= 0x7FFFFFFF0000i64 )
      v18 = 0x7FFFFFFF0000i64;
    AllocatedAttributes = *(_DWORD *)v18;
    v20 = 8i64;
    if( v15 == 0x80000000 )
    {
      if( AllocatedAttributes < 0 )
        LODWORD(v20) = 20;
      v30 = v20 + 16;
      if( (AllocatedAttributes & 0x40000000) == 0 )
        v30 = v20;
      v31 = v30 + 20;
      if( (AllocatedAttributes & 0x20000000) == 0 )
        v31 = v30;
      v32 = v31 + 16;
      if( (AllocatedAttributes & 0x10000000) == 0 )
        v32 = v31;
      if( (AllocatedAttributes & 0x8000000) != 0 )
        v32 += 24;
      v26 = v32 + 8;
      if( (AllocatedAttributes & 0x2000000) == 0 )
        v26 = v32;
      v20 = 4i64;
    }
    else
    {
      v21 = 8;
      if( AllocatedAttributes < 0 )
        v21 = 32;
      v22 = v21 + 32;
      if( (AllocatedAttributes & 0x40000000) == 0 )
        v22 = v21;
      v23 = v22 + 32;
      if( (AllocatedAttributes & 0x20000000) == 0 )
        v23 = v22;
      v24 = v23 + 24;
      if( (AllocatedAttributes & 0x10000000) == 0 )
        v24 = v23;
      v25 = v24 + 24;
      if( (AllocatedAttributes & 0x8000000) == 0 )
        v25 = v24;
      if( (AllocatedAttributes & 0x4000000) != 0 )
        v25 += 8;
      v26 = v25 + 8;
      if( (AllocatedAttributes & 0x2000000) == 0 )
        v26 = v25;
    }
    v27 = (__int64)MessageAttributes;
    if( (unsigned __int64)(v26 - 1) > 0xFFE )
    {
      ProbeForWrite(MessageAttributes, (unsigned int)v26, v20);
      v9 = BufferLength;
LABEL_35:
      v50 = AllocatedAttributes;
LABEL_36:
      if( v9 )
      {
        v28 = (__int64)v9;
        if( (unsigned __int64)v9 >= 0x7FFFFFFF0000i64 )
          v28 = 0x7FFFFFFF0000i64;
        v55 = *(_QWORD *)v28;
        v29 = (__int64)v9;
        if( (unsigned __int64)v9 >= 0x7FFFFFFF0000i64 )
          v29 = 0x7FFFFFFF0000i64;
        *(_QWORD *)v29 = *(_QWORD *)v29;
        AllocatedAttributes = v50;
      }
      DispatchContext = DispatchContexta;
      v13 = v48;
      goto LABEL_66;
    }
    if( (((_DWORD)v20 - 1) & (unsigned int)MessageAttributes) == 0 )
    {
      if( (unsigned __int64)MessageAttributes >= 0x7FFFFFFF0000i64 )
        v27 = 0x7FFFFFFF0000i64;
      *(_BYTE *)v27 = *(_BYTE *)v27;
      *(_BYTE *)(v27 + (unsigned int)v26 - 1) = *(_BYTE *)(v27 + (unsigned int)v26 - 1);
      goto LABEL_35;
    }
LABEL_65:
    ExRaiseDatatypeMisalignment();
  }
  v17 = Flags & 0x1000000;
  if( (Flags & 0x1000000) != 0 )
  {
    HIDWORD(v51) = *((_DWORD *)ReceiveMessage + 6);
    LODWORD(v51) = *((_DWORD *)ReceiveMessage + 8);
  }
  if( MessageAttributes )
    AllocatedAttributes = MessageAttributes->AllocatedAttributes;
  else
    AllocatedAttributes = 0;
  if( v9 )
    v55 = *v9;
  if( (*((_DWORD *)CurrentThread + 29) & 0x400) != 0 )
    LOBYTE(v13) = 1;
LABEL_66:
  LODWORD(BugCheckParameter4) = AllocatedAttributes;
  if( v17 )
    v33 = AlpcpReceiveDirectMessagePort(
            (INT64 *)DispatchContext,
            HIDWORD(v51),
            (unsigned int)v51,
            &BugCheckParameter2,
            BugCheckParameter4);
  else
    v33 = AlpcpReceiveMessagePort(
            DispatchContext,
            v13,
            Timeout,
            (_KALPC_MESSAGE **)&BugCheckParameter2,
            BugCheckParameter4);
  v49 = v33;
  v34 = v33;
  if( !v33 )
  {
    v35 = BugCheckParameter2;
    v36 = 24;
    if( (a1 & 0xC0000000) != 0x80000000 )
      v36 = 40;
    v37 = *(_WORD *)(BugCheckParameter2 + 240) + v36;
    if( BufferLength && (DispatchContextb = v37, v37 > v55) )
    {
      *(_OWORD *)a2 = 0i64;
      v60 = 0i64;
      v34 = AlpcpReturnMessageOnInsufficientBuffer((_ALPC_PORT *)PortObject, (_KALPC_MESSAGE *)BugCheckParameter2);
      v49 = v34;
      if( v34 == -1073741789 )
      {
        *BufferLength = DispatchContextb;
        AlpcpExposeCapturedContextAttribute(a1, a2, (unsigned int)AllocatedAttributes, (INT64)MessageAttributes);
      }
    }
    else
    {
      *(_QWORD *)(BugCheckParameter2 + 200) = v57;
      if( (a1 & 0xC0000000) == 0x80000000 )
      {
        *(_WORD *)ReceiveMessage = *(_WORD *)(v35 + 240);
        *((_WORD *)ReceiveMessage + 1) = *(_WORD *)(v35 + 240) + 24;
        v39 = *(_WORD *)(v35 + 246);
        if( v39 )
          *((_WORD *)ReceiveMessage + 3) = v39 - 16;
        else
          *((_WORD *)ReceiveMessage + 3) = 0;
        v40 = *(_WORD *)(v35 + 244) | 0x1000;
        *((_WORD *)ReceiveMessage + 2) = v40;
        *((_DWORD *)ReceiveMessage + 2) = *(_DWORD *)(v35 + 248);
        *((_DWORD *)ReceiveMessage + 3) = *(_DWORD *)(v35 + 256);
        *((_DWORD *)ReceiveMessage + 4) = *(_DWORD *)(v35 + 264);
        *((_DWORD *)ReceiveMessage + 5) = *(_DWORD *)(v35 + 272);
        *((_DWORD *)ReceiveMessage + 5) = *(_DWORD *)(v35 + 272);
        if( (*(_DWORD *)(PortObject + 256) & 0x1000) != 0 )
          *((_WORD *)ReceiveMessage + 2) = v40 & 0xC00F;
        v38 = (char *)ReceiveMessage + 24;
      }
      else
      {
        *(_OWORD *)ReceiveMessage = *(_OWORD *)(v35 + 240);
        *((_OWORD *)ReceiveMessage + 1) = *(_OWORD *)(v35 + 256);
        *((_QWORD *)ReceiveMessage + 4) = *(_QWORD *)(v35 + 272);
        if( (*(_DWORD *)(PortObject + 256) & 0x1000) != 0 )
          *((_WORD *)ReceiveMessage + 2) &= 0xC00Fu;
        v38 = (char *)ReceiveMessage + 40;
      }
      if( *(_QWORD *)(v35 + 176) )
        AlpcpGetDataFromUserVaSafe(v35, v38);
      else
        AlpcpReadMessageData(v35, v38);
      if( MessageAttributes )
        AlpcpExposeAttributes(PortObject, a1, v35, (unsigned int)AllocatedAttributes, (INT64)MessageAttributes);
    }
    v41 = (_ALPC_PORT *)PortObject;
    if( v34 != -1073741789 && *(_QWORD *)(v35 + 64) == PortObject )
    {
      *(_QWORD *)(v35 + 64) = 0i64;
      *(_QWORD *)(v35 + 56) = 0i64;
    }
    if( ((v34 + 0x80000000) & 0x80000000) != 0 || v34 == -1073741789 )
    {
      if( AlpcpMessageLogEnabled )
        AlpcpEnterStateChangeEventMessageLog((_KALPC_MESSAGE *)v35);
      v42 = 0;
      v43 = v35 - 48;
      v44 = *(_BYTE *)(v35 - 48 + 16);
      if( (v44 & 1) != 0 )
      {
        v42 = 0x10000 - *(__int16 *)(v43 + 18);
        *(_BYTE *)(v43 + 16) = v44 & 0xFE;
        *(_WORD *)(v43 + 18) = 0;
      }
      if( v42 > 0 )
      {
        v45 = -v42 + _InterlockedExchangeAdd64((volatile signed __int64 *)(v43 + 24), -v42);
        if( v45 <= 0 )
        {
          if( v45 )
            KeBugCheckEx(0x18u, 0i64, BugCheckParameter2, 0x28ui64, v45);
          AlpcpDestroyBlob((PVOID)BugCheckParameter2);
          v35 = 0i64;
        }
        v34 = v49;
      }
      if( v35 )
      {
        if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v43 + 32), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock((volatile INT64 *)(v43 + 32));
        KeAbPostRelease((PVOID)(v43 + 32));
        return v49;
      }
    }
    else
    {
      *(_QWORD *)(v35 + 200) = 0i64;
      AlpcpCancelMessage(v41, (_KALPC_MESSAGE *)v35, 0x10000ui64);
    }
  }
  return v34;
}

Referenced by:

NtAlpcSendWaitReceivePort