ExpWnfDeliverThreadNotifications
NTSTATUS __stdcall ExpWnfDeliverThreadNotifications(
_WNF_PROCESS_CONTEXT *ProcessContext,
_WNF_DELIVERY_DESCRIPTOR *NewDeliveryDescriptor,
UINT64 DescriptorSize){
_WNF_PROCESS_CONTEXT *v3;
NTSTATUS v4;
_EX_PUSH_LOCK *p_PushLock;
_BYTE *v6;
_EX_PUSH_LOCK *v7;
_BYTE *v8;
_BYTE *v9;
__int64 p_DeliveryPendingListHead;
__int64 Flink;
unsigned __int64 v12;
int *v13;
unsigned int v14;
_WNF_DELIVERY_DESCRIPTOR *v15;
_GUID *v16;
__int64 **v18;
__int64 v19;
__int64 *v20;
int v21;
_WNF_LOCK *p_DeliveryPendingListLock;
_WNF_LOCK *p_ProcessSubscriptionListLock;
NTSTATUS v24;
UINT64 DataSize;
_LIST_ENTRY *v26;
unsigned __int64 v27;
int *v28;
_DWORD *v29;
VOID *Lock;
_EX_PUSH_LOCK *PushLock;
__int64 *v32;
int v35;
UINT64 ChangeStamp;
v3 = ProcessContext;
LODWORD(DataSize) = 0;
v4 = -2147483622;
v35 = -2147483622;
v24 = 0;
LODWORD(ChangeStamp) = 0;
HIDWORD(DataSize) = DescriptorSize - 48;
LABEL_2:
p_PushLock = &v3->ProcessSubscriptionListLock.PushLock;
PushLock = &v3->ProcessSubscriptionListLock.PushLock;
v6 = KeAbPreAcquire(&v3->ProcessSubscriptionListLock, 0i64, 0i64);
if( _InterlockedCompareExchange64(&v3->ProcessSubscriptionListLock.PushLock._bf_0, 17i64, 0i64) )
ExfAcquirePushLockSharedEx(&v3->ProcessSubscriptionListLock.PushLock, v6, &v3->ProcessSubscriptionListLock);
if( v6 )
v6[26] |= 1u;
v7 = &v3->DeliveryPendingListLock.PushLock;
Lock = &v3->DeliveryPendingListLock;
v8 = KeAbPreAcquire(&v3->DeliveryPendingListLock, 0i64, 0i64);
v9 = v8;
if( _interlockedbittestandset64((volatile signed __int32 *)&v3->DeliveryPendingListLock, 0i64) )
ExfAcquirePushLockExclusiveEx(&v3->DeliveryPendingListLock.PushLock, v8, &v3->DeliveryPendingListLock);
if( v9 )
v9[26] |= 1u;
p_DeliveryPendingListHead = (__int64)&v3->DeliveryPendingListHead;
v26 = &v3->DeliveryPendingListHead;
Flink = (__int64)v3->DeliveryPendingListHead.Flink;
while( 1 )
{
v32 = (__int64 *)Flink;
if( Flink == p_DeliveryPendingListHead )
break;
v29 = (_DWORD *)(Flink + 16);
if( *(_DWORD *)(Flink + 16) != 1 )
goto LABEL_36;
v12 = *(_QWORD *)(Flink - 56);
v27 = v12;
if( v12 )
{
v12 &= -(__int64)(ExAcquireRundownProtection((_EX_RUNDOWN_REF *)(v12 + 8)) != 0);
v27 = v12;
}
v13 = (int *)(Flink + 20);
v28 = (int *)(Flink + 20);
v14 = *(_DWORD *)(Flink + 20) & *(_DWORD *)(Flink - 4) & 0xFFFFFFFE;
if( v12 )
v14 = *(_DWORD *)(Flink + 20) & *(_DWORD *)(Flink - 4);
if( !v14 )
goto LABEL_40;
v15 = NewDeliveryDescriptor;
*(_OWORD *)&NewDeliveryDescriptor->SubscriptionId = 0i64;
*(_OWORD *)&NewDeliveryDescriptor->ChangeStamp = 0i64;
*(_OWORD *)&NewDeliveryDescriptor->TypeId.TypeId[0].Data2 = 0i64;
NewDeliveryDescriptor->StateName = (_WNF_STATE_NAME)(*(_QWORD *)(Flink - 48) ^ 0x41C64E6DA3BC0074i64);
NewDeliveryDescriptor->SubscriptionId = *(_QWORD *)(Flink - 88);
if( (v14 & 1) != 0 )
{
v16 = *(_GUID **)(v12 + 64);
if( v16 )
NewDeliveryDescriptor->TypeId.TypeId[0] = *v16;
v24 = ExpWnfReadStateData(
(_WNF_NAME_INSTANCE *)v12,
&ChangeStamp,
&NewDeliveryDescriptor->TypeId.TypeId[1].Data2,
HIDWORD(DataSize),
&DataSize);
if( v24 < 0 )
goto LABEL_24;
v15 = NewDeliveryDescriptor;
NewDeliveryDescriptor->ChangeStamp = ChangeStamp;
NewDeliveryDescriptor->StateDataSize = DataSize;
}
v15->TypeId.TypeId[1].Data1 = 48;
v15->EventMask = v14;
LABEL_24:
if( v12 )
{
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(v12 + 8));
v12 = 0i64;
}
if( v24 < 0 )
{
v4 = v35;
if( v35 == -2147483622 )
{
v4 = v24;
v35 = v24;
}
goto LABEL_36;
}
if( !(_DWORD)ChangeStamp )
v14 &= ~1u;
if( v14 )
{
*(_DWORD *)(Flink + 24) = v14;
*v28 = 0;
*v29 = 2;
v4 = 0;
break;
}
v13 = v28;
LABEL_40:
v18 = *(__int64 ***)(Flink + 8);
Flink = (__int64)v18;
v19 = (__int64)v32;
v20 = (__int64 *)*v32;
if( *(__int64 **)(*v32 + 8) != v32 || *v18 != v32 )
__fastfail(3u);
*v18 = v20;
v20[1] = (__int64)v18;
*v29 = 0;
v21 = *v13;
*v13 = 0;
*(_DWORD *)(v19 + 24) = 0;
if( v12 )
{
if( (v21 & 1) != 0 && _InterlockedExchangeAdd((volatile signed __int32 *)(v12 + 164), 0xFFFFFFFF) == 1 )
{
p_DeliveryPendingListLock = &ProcessContext->DeliveryPendingListLock;
if( (_InterlockedExchangeAdd64(&ProcessContext->DeliveryPendingListLock.PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&p_DeliveryPendingListLock->PushLock);
KeAbPostRelease(p_DeliveryPendingListLock);
p_ProcessSubscriptionListLock = &ProcessContext->ProcessSubscriptionListLock;
if( _InterlockedCompareExchange64(&ProcessContext->ProcessSubscriptionListLock.PushLock._bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(&p_ProcessSubscriptionListLock->PushLock);
KeAbPostRelease(p_ProcessSubscriptionListLock);
ExpWnfNotifyNameSubscribers((_WNF_NAME_INSTANCE *)v12, 8ui64, 1ui64, 1ui64);
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(v12 + 8));
v4 = v35;
v3 = ProcessContext;
goto LABEL_2;
}
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(v12 + 8));
}
v4 = v35;
LABEL_36:
Flink = *(_QWORD *)Flink;
p_DeliveryPendingListHead = (__int64)v26;
}
if( (_InterlockedExchangeAdd64(&v7->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v7);
KeAbPostRelease(v7);
if( _InterlockedCompareExchange64(&p_PushLock->_bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(p_PushLock);
KeAbPostRelease(p_PushLock);
return v4;
}Referenced by:
NtGetCompleteWnfStateSubscription