AlpcpSendMessage
NTSTATUS __stdcall AlpcpSendMessage(
_ALPC_DISPATCH_CONTEXT *DispatchContext,
_PORT_MESSAGE *Message,
_ALPC_MESSAGE_ATTRIBUTES *MessageAttributes,
CHAR PreviousMode){
CHAR v4;
NTSTATUS v6;
_ALPC_PORT *PortObject;
unsigned int Flags;
int v9;
NTSTATUS v10;
__int64 v11;
unsigned __int16 v12;
int v13;
bool v14;
__int16 v15;
int v16;
bool v17;
bool v18;
unsigned __int16 v19;
__int16 v20;
PSLIST_ENTRY v21;
ULONG_PTR v22;
signed __int64 v23;
int v24;
signed __int32 v25;
NTSTATUS v26;
int v27;
__int64 v28;
_ALPC_PORT *v29;
_ALPC_PORT **v30;
bool v31;
bool v32;
unsigned __int64 v33;
_ALPC_PORT **v34;
INT64 *v35;
_ALPC_MESSAGE_ATTRIBUTES *v36;
NTSTATUS v37;
__int64 v38;
__int64 v39;
unsigned __int64 v40;
INT64 v41;
INT64 v42;
void *v43;
__int64 v44;
void *v45;
ULONG_PTR v46;
void *v47;
unsigned __int64 v48;
__int64 v49;
char *v50;
unsigned __int64 v51;
UINT64 v52;
INT64 v53;
ULONG_PTR BugCheckParameter4;
unsigned __int16 v55;
NTSTATUS v56;
OBJECT_NAME_INFORMATION *PortNameInformation[4];
INT64 v58;
ULONG_PTR BugCheckParameter2;
INT64 v60;
__int64 v61;
__m128i v62;
INT64 v63;
INT64 result[2];
__int128 v65;
__int128 v66;
__int128 v67;
__int64 v68;
v4 = PreviousMode;
memset(PortNameInformation, 0, sizeof(PortNameInformation));
v58 = 0i64;
v6 = 0;
BugCheckParameter2 = 0i64;
*(_OWORD *)result = 0i64;
v65 = 0i64;
v66 = 0i64;
v67 = 0i64;
v68 = 0i64;
PortObject = DispatchContext->PortObject;
v60 = (INT64)PortObject;
Flags = DispatchContext->Flags;
v9 = *((_DWORD *)PortObject + 104);
if( (v9 & 0x10) != 0 )
return -1073741759;
if( (v9 & 8) != 0 )
return -1073740025;
if( (v9 & 0x20) != 0 && (*((_DWORD *)PortObject + 64) & 0x1000) == 0 )
return -1073741769;
if( PreviousMode )
{
v11 = 0x7FFFFFFF0000i64;
if( (Flags & 0xC0000000) == 0x80000000 )
{
if( (unsigned __int64)Message < 0x7FFFFFFF0000i64 )
v11 = (__int64)Message;
v62 = *(__m128i *)v11;
v63 = *(_QWORD *)(v11 + 16);
v12 = _mm_cvtsi128_si32(v62);
LOWORD(PortNameInformation[0]) = v12;
WORD1(PortNameInformation[0]) = v12 + 40;
HIDWORD(PortNameInformation[0]) = _mm_cvtsi128_si32(_mm_srli_si128(v62, 4));
PortNameInformation[1] = (OBJECT_NAME_INFORMATION *)(unsigned int)_mm_cvtsi128_si32(_mm_srli_si128(v62, 8));
PortNameInformation[2] = (OBJECT_NAME_INFORMATION *)(unsigned int)_mm_cvtsi128_si32(_mm_srli_si128(v62, 12));
v13 = v63;
LODWORD(PortNameInformation[3]) = v63;
v58 = HIDWORD(v63);
}
else
{
if( (unsigned __int64)Message < 0x7FFFFFFF0000i64 )
v11 = (__int64)Message;
*(_OWORD *)PortNameInformation = *(_OWORD *)v11;
*(_OWORD *)&PortNameInformation[2] = *(_OWORD *)(v11 + 16);
v58 = *(_QWORD *)(v11 + 32);
v13 = (int)PortNameInformation[3];
v12 = (unsigned __int16)PortNameInformation[0];
}
v55 = v12;
v14 = (*((_DWORD *)PortObject + 64) & 0x1000) != 0 || (Flags & 2) != 0;
if( v12 < (unsigned __int16)(v12 + 40) )
{
if( v14 )
{
if( (unsigned __int64)v12 + 40 <= WORD1(PortNameInformation[0]) )
{
WORD1(PortNameInformation[0]) = v12 + 40;
LABEL_25:
v15 = WORD2(PortNameInformation[0]) & 0x7FFF;
WORD2(PortNameInformation[0]) &= ~0x8000u;
if( HIWORD(PortNameInformation[0]) )
{
v10 = AlpcpValidateDataInformation(Message, PortNameInformation, (UINT64 *)Message);
if( v10 < 0 )
return v10;
v4 = PreviousMode;
}
v16 = *((_DWORD *)PortObject + 64);
goto LABEL_36;
}
}
else if( v12 + 40i64 == WORD1(PortNameInformation[0]) )
{
goto LABEL_25;
}
}
return -1073741811;
}
*(_OWORD *)PortNameInformation = *(_OWORD *)Message;
*(_OWORD *)&PortNameInformation[2] = *((_OWORD *)Message + 1);
v58 = *((_QWORD *)Message + 4);
v17 = (*((_DWORD *)PortObject + 64) & 0x1000) != 0 || (Flags & 2) != 0;
v10 = AlpcpValidateMessage((UINT16 *)PortNameInformation, v17);
if( v10 < 0 )
return v10;
v13 = (int)PortNameInformation[3];
v15 = WORD2(PortNameInformation[0]);
v55 = (unsigned __int16)PortNameInformation[0];
LABEL_36:
v18 = (v16 & 0x1000) != 0 || (Flags & 2) != 0;
v19 = (unsigned __int8)v15;
v20 = v15 & 0xFF00;
if( v18 )
{
if( (Flags & 1) != 0 )
{
if( v13 )
{
v20 = 0;
v19 = 2;
LABEL_62:
LODWORD(PortNameInformation[3]) = v13;
if( !v4 )
LODWORD(v58) = 0;
goto LABEL_64;
}
return -1073741811;
}
if( (Flags & 0x10000) != 0 )
{
if( v19 )
{
if( (unsigned int)v19 - 3 > 3 && v19 != 13 || (Flags & 2) == 0 )
return -1073741811;
}
else
{
v19 = 3;
}
}
else if( v19 )
{
if( v19 == 1 )
{
if( !v13 )
return -1073741811;
goto LABEL_62;
}
if( (unsigned int)v19 - 7 > 2 || (Flags & 2) == 0 )
return -1073741811;
}
else
{
v19 = 1;
}
v13 = 0;
goto LABEL_62;
}
if( v19 != 7 || v4 )
{
if( v13 && v13 >= 0 )
{
v19 = ((Flags & 0x10000) != 0) + 1;
}
else if( (Flags & 0x10000) != 0 )
{
v19 = 3;
}
else
{
v19 = 1;
}
}
if( !v13 && (PortNameInformation[1] || PortNameInformation[2]) )
return -1073740030;
LABEL_64:
WORD2(PortNameInformation[0]) = v19 | v20 & 0xEFFF;
if( (unsigned __int64)WORD1(PortNameInformation[0]) > *((_QWORD *)PortObject + 34) )
return -1073741777;
if( (Flags & 0x20000) != 0 )
{
if( (*((_DWORD *)KeGetCurrentThread() + 325) & 0x20) != 0 )
return -1073741823;
v13 = (int)PortNameInformation[3];
v55 = (unsigned __int16)PortNameInformation[0];
}
if( !v13 )
{
++dword_140CEBA94;
v21 = RtlpInterlockedPopEntrySList((PSLIST_HEADER)AlpcpLookasides);
if( !v21 )
{
++dword_140CEBA98;
v21 = (PSLIST_ENTRY)((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD))qword_140CEBAB0)(
(unsigned int)dword_140CEBAA4,
(unsigned int)dword_140CEBAAC,
(unsigned int)dword_140CEBAA8);
if( !v21 )
return -1073741670;
}
LOWORD(v21[1].Next) = 512;
*(_DWORD *)((char *)&v21[1].Next + 2) = 0;
HIWORD(v21[1].Next) = 0;
*((_QWORD *)&v21[2].Next + 1) = 0i64;
v21[2].Next = 0i64;
*((_QWORD *)&v21->Next + 1) = v21;
v21->Next = v21;
LOBYTE(v21[1].Next) |= 2u;
*((_QWORD *)&v21[1].Next + 1) = 1i64;
v22 = (ULONG_PTR)&v21[3];
if( v21 == (PSLIST_ENTRY)-48i64 )
return -1073741670;
ExAcquirePushLockExclusiveEx((UINT64)&v21[2], 0i64);
*(_BYTE *)(v22 - 32) |= 1u;
v23 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v22 - 24), 0x10000ui64) + 0x10000;
if( v23 <= 0 )
KeBugCheckEx(0x18u, 0i64, v22, 0x26ui64, v23);
v24 = *(_DWORD *)(v22 + 264);
memset(v22, 0i64);
*(_WORD *)(v22 + 242) = 40;
--*(_WORD *)(v22 - 30);
*(_DWORD *)(v22 + 264) = v24 & 0x7FFFFFFF;
do
v25 = _InterlockedIncrement(&AlpcpNextCallbackId);
while( !v25 );
*(_DWORD *)(v22 + 272) = v25;
if( AlpcpMessageLogEnabled )
AlpcpEnterAllocationEventMessageLog(v22);
*(_WORD *)(v22 + 242) = 40;
v26 = 0;
v13 = (int)PortNameInformation[3];
v55 = (unsigned __int16)PortNameInformation[0];
goto LABEL_125;
}
Flags |= 0x10u;
v26 = AlpcpLookupMessage((INT64)PortObject, (unsigned int)v13, (unsigned int)v58, PreviousMode, &BugCheckParameter2);
v56 = v26;
v22 = BugCheckParameter2;
if( v26 < 0 )
goto LABEL_124;
v27 = *(_DWORD *)(BugCheckParameter2 + 40);
if( (v27 & 0x80u) != 0 )
goto LABEL_124;
v28 = *(_QWORD *)(BugCheckParameter2 + 24);
v61 = v28;
if( v28 )
{
v29 = *(_ALPC_PORT **)(BugCheckParameter2 + 16);
if( v29 != PortObject )
{
if( (v27 & 7) == 0 )
{
v30 = *(_ALPC_PORT ***)(v28 + 16);
ExAcquirePushLockSharedEx((UINT64)(v30 - 2), 0i64);
if( ((*(_DWORD *)(v61 + 416) >> 1) & 3) == 1 || ((*(_DWORD *)(v61 + 416) >> 1) & 3) != 2 )
v31 = v30[2] == PortObject;
else
v31 = *v30 == PortObject || v30[1] == PortObject;
if( _InterlockedCompareExchange64((volatile signed __int64 *)v30 - 2, 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)v30 - 2);
KeAbPostRelease(v30 - 2);
v32 = !v31;
v22 = BugCheckParameter2;
if( !v32 )
{
v13 = (int)PortNameInformation[3];
v55 = (unsigned __int16)PortNameInformation[0];
v26 = v56;
goto LABEL_109;
}
LABEL_122:
AlpcpUnlockMessage(v22);
return -1073741790;
}
if( (*((_BYTE *)PortObject + 416) & 6) != 6 )
goto LABEL_122;
v34 = (_ALPC_PORT **)*((_QWORD *)PortObject + 2);
if( !v34 || *v34 != v29 )
goto LABEL_122;
}
if( (v27 & 7) != 3 || (v27 & 0x2000) != 0 )
goto LABEL_122;
}
LABEL_109:
if( *(_QWORD *)(v22 + 32) && !*(_QWORD *)(v22 + 48) && (Flags & 0x30000) == 0 )
{
v33 = 792i64;
if( *(_QWORD *)(v22 + 224) )
v33 = *(_QWORD *)(v22 + 232) + 792i64;
v26 = AlpcpChargePagedPoolQuota(*((_QWORD *)KeGetCurrentThread() + 23), v33);
if( v26 < 0 )
{
AlpcpUnlockMessage(BugCheckParameter2);
return v26;
}
*(_QWORD *)(v22 + 48) = *((_QWORD *)KeGetCurrentThread() + 23);
ObfReferenceObjectWithTag(*((PVOID *)KeGetCurrentThread() + 23), 0x63706C41u);
v13 = (int)PortNameInformation[3];
v55 = (unsigned __int16)PortNameInformation[0];
v22 = BugCheckParameter2;
}
LABEL_124:
if( v26 < 0 )
return v26;
LABEL_125:
v35 = 0i64;
v36 = MessageAttributes;
if( MessageAttributes )
{
v35 = result;
v26 = AlpcpCaptureAttributes(v60, Flags, (INT64 *)MessageAttributes, v22, (INT64)result);
v36 = MessageAttributes;
}
if( v13 && ((*(_DWORD *)(v22 + 40) & 0x200) != 0 || (*(_DWORD *)(v22 + 40) & 0x80) != 0) )
{
v37 = (*(_DWORD *)(v22 + 40) & 0x80) != 0 ? 0xC0000703 : 0;
if( v36 )
AlpcpReleaseAttributes(v35);
AlpcpReleaseAttributes((_QWORD *)(v22 + 104));
AlpcpCancelMessage((_ALPC_PORT *)v60, (_KALPC_MESSAGE *)v22, 0x10000ui64);
return v37;
}
else if( v26 >= 0 )
{
if( v13 )
{
v38 = *(_QWORD *)(v22 + 208);
if( v38 )
{
v39 = *(_QWORD *)(v22 + 208) & 7i64;
v40 = v38 & 0xFFFFFFFFFFFFFFF8ui64;
v41 = 0i64;
if( (_DWORD)v39 != 7 )
v41 = (unsigned int)v39;
v42 = 2i64;
if( (_DWORD)v39 != 7 )
v42 = 0i64;
LODWORD(BugCheckParameter4) = -1;
PspChargeProcessWakeCounter(v40, v42, v41, *(unsigned int *)(v22 + 264), BugCheckParameter4, 1, 0i64);
*(_QWORD *)(v22 + 208) = 0i64;
}
v43 = *(void **)(v22 + 216);
if( v43 )
{
PsReleaseProcessWakeCounter(v43, *(unsigned int *)(v22 + 264));
*(_QWORD *)(v22 + 216) = 0i64;
}
}
v44 = 0i64;
if( v13 && v13 >= 0 )
{
v44 = *(_QWORD *)(v22 + 160);
*(_QWORD *)(v22 + 160) = 0i64;
v45 = *(void **)(v22 + 136);
if( v45 )
{
AlpcpDereferenceBlobEx(v45, 1i64);
*(_QWORD *)(v22 + 136) = 0i64;
}
v46 = *(_QWORD *)(v22 + 144);
if( v46 )
{
AlpcpReleaseViewAttribute(v46);
*(_QWORD *)(v22 + 144) = 0i64;
}
v47 = *(void **)(v22 + 152);
if( v47 )
{
AlpcpDereferenceBlobEx(v47, 1i64);
*(_QWORD *)(v22 + 152) = 0i64;
}
v48 = *(_QWORD *)(v22 + 160);
if( (v48 & 1) != 0 )
{
if( v48 >= 4 && (v48 & 2) != 0 )
HalPutDmaAdapter((PADAPTER_OBJECT)(v48 & 0xFFFFFFFFFFFFFFFCui64));
*(_QWORD *)(v22 + 160) = 0i64;
}
}
if( v35 )
{
*(_OWORD *)(v22 + 104) = *(_OWORD *)v35;
*(_OWORD *)(v22 + 120) = *((_OWORD *)v35 + 1);
*(_OWORD *)(v22 + 136) = *((_OWORD *)v35 + 2);
*(_OWORD *)(v22 + 152) = *((_OWORD *)v35 + 3);
*(_QWORD *)(v22 + 168) = v35[8];
}
if( v44 )
*(_QWORD *)(v22 + 160) = v44;
v49 = 24i64;
if( (Flags & 0xC0000000) != 0x80000000 )
v49 = 40i64;
v50 = (char *)Message + v49;
if( PreviousMode && (unsigned __int64)&v50[v55] > 0x7FFFFFFF0000i64 )
{
AlpcpUnlockMessage(v22);
return -1073741819;
}
else
{
*(_QWORD *)(v22 + 176) = v50;
v51 = AlpcpAvailableBufferSize(v22);
if( v52 > v51 )
v6 = AlpcpCaptureMessageData(v53, v52, 0i64);
if( v6 >= 0 )
{
DispatchContext->Message = (_KALPC_MESSAGE *)v22;
*(_DWORD *)&DispatchContext->TotalLength = *(_DWORD *)((char *)PortNameInformation + 2);
DispatchContext->DataInfoOffset = HIWORD(PortNameInformation[0]);
if( *(_QWORD *)(v22 + 24) )
{
if( *(_QWORD *)(v22 + 32) )
return AlpcpDispatchReplyToWaitingThread((INT64)DispatchContext);
else
return AlpcpDispatchReplyToPort((INT64)DispatchContext);
}
else
{
return AlpcpDispatchNewMessage((INT64)DispatchContext);
}
}
else
{
AlpcpUnlockMessage(v22);
return v6;
}
}
}
else
{
AlpcpUnlockMessage(v22);
return v26;
}
}Referenced by:
AlpcpProcessSynchronousRequest
AlpcpSendLegacySynchronousRequest
LpcRequestPort
NtAlpcSendWaitReceivePort
NtReplyPort
NtReplyWaitReceivePortEx
NtRequestPort
NtWaitForWorkViaWorkerFactory