ExpWnfUpdateSubscription
INT64 __fastcall ExpWnfUpdateSubscription(
_WNF_NAME_INSTANCE *NameInstance,
_WNF_PROCESS_CONTEXT *ProcessContext,
UINT64 CallbackRoutine,
VOID *CallbackContext,
UINT64 EventMask,
_WNF_SUBSCRIPTION **ExistingSubscription,
INT64 *DataSubscriptionChanged,
INT64 *PendingDeliveryChanged,
UINT64 *SubscriptionId){
_WNF_PROCESS_CONTEXT *i;
_WNF_SUBSCRIPTION *p_DeliveryPendingListHead;
_WNF_LOCK *p_DeliveryPendingListLock;
_BYTE *v16;
_BYTE *v17;
int v18;
_WNF_SUBSCRIPTION_STATE SubscriptionState;
unsigned int v20;
_LIST_ENTRY *Flink;
char **Blink;
for( i = (_WNF_PROCESS_CONTEXT *)ProcessContext->ProcessSubscriptionListHead.Flink;
;
i = *(_WNF_PROCESS_CONTEXT **)&i->Header.NodeTypeCode )
{
if( i == (_WNF_PROCESS_CONTEXT *)&ProcessContext->ProcessSubscriptionListHead )
return 3221225524i64;
p_DeliveryPendingListHead = (_WNF_SUBSCRIPTION *)&i[-1].DeliveryPendingListHead;
if( (_WNF_NAME_INSTANCE *)i->WnfProcessesListEntry.Blink == NameInstance )
break;
}
p_DeliveryPendingListLock = &ProcessContext->DeliveryPendingListLock;
*(_DWORD *)DataSubscriptionChanged = 0;
*(_DWORD *)PendingDeliveryChanged = 0;
LODWORD(v16) = KeAbPreAcquire(&ProcessContext->DeliveryPendingListLock, 0i64, 0i64);
v17 = v16;
if( _interlockedbittestandset64((volatile signed __int32 *)p_DeliveryPendingListLock, 0i64) )
ExfAcquirePushLockExclusiveEx((UINT64 *)p_DeliveryPendingListLock, v16, p_DeliveryPendingListLock);
if( v17 )
v17[26] |= 1u;
v18 = p_DeliveryPendingListHead->SubscribedEventSet & 1;
if( (EventMask & 1) != 0 )
{
if( !v18 && _InterlockedIncrement(&NameInstance->DataSubscribersCount) == 1 )
*(_DWORD *)DataSubscriptionChanged = 1;
}
else if( v18 && _InterlockedExchangeAdd(&NameInstance->DataSubscribersCount, 0xFFFFFFFF) == 1 )
{
*(_DWORD *)DataSubscriptionChanged = -1;
}
SubscriptionState = p_DeliveryPendingListHead->SubscriptionState;
if( SubscriptionState != WNF_SUB_STATE_IN_DELIVERY
&& (p_DeliveryPendingListHead->SignaledEventSet & 1) != 0
&& (EventMask & 1) == 0 )
{
*(_DWORD *)PendingDeliveryChanged = -1;
}
v20 = EventMask & p_DeliveryPendingListHead->SignaledEventSet;
p_DeliveryPendingListHead->CallbackRoutine = CallbackRoutine;
p_DeliveryPendingListHead->CallbackContext = CallbackContext;
p_DeliveryPendingListHead->SubscribedEventSet = EventMask;
p_DeliveryPendingListHead->SignaledEventSet = v20;
if( SubscriptionState && !v20 && !p_DeliveryPendingListHead->InDeliveryEventSet )
{
Flink = p_DeliveryPendingListHead->PendingSubscriptionListEntry.Flink;
if( Flink->Blink != &p_DeliveryPendingListHead->PendingSubscriptionListEntry
|| (Blink = (char **)p_DeliveryPendingListHead->PendingSubscriptionListEntry.Blink,
*Blink != (char *)&p_DeliveryPendingListHead->PendingSubscriptionListEntry) )
{
__fastfail(3u);
}
*Blink = (char *)Flink;
Flink->Blink = (_LIST_ENTRY *)Blink;
p_DeliveryPendingListHead->SubscriptionState = WNF_SUB_STATE_QUIESCENT;
}
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_DeliveryPendingListLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)p_DeliveryPendingListLock);
KeAbPostRelease(p_DeliveryPendingListLock);
ExAcquireRundownProtection(&p_DeliveryPendingListHead->RunRef);
*ExistingSubscription = p_DeliveryPendingListHead;
if( SubscriptionId )
*SubscriptionId = p_DeliveryPendingListHead->SubscriptionId;
return 0i64;
}Referenced by:
ExpWnfSubscribeNameInstance