ExpWnfCompleteThreadSubscriptions
NTSTATUS __stdcall ExpWnfCompleteThreadSubscriptions(
_WNF_PROCESS_CONTEXT *ProcessContext,
VOID *OldStateName,
UINT64 OldSubscriptionId,
UINT64 OldEventMask,
UINT64 OldStatus){
_WNF_NAME_INSTANCE *v7;
int v8;
UINT64 v9;
_BYTE *v10;
_BYTE *v11;
_BYTE *v12;
_LIST_ENTRY *Flink;
int v14;
int Flink_high;
_LIST_ENTRY *v16;
_LIST_ENTRY *Blink;
int v18;
_LIST_ENTRY *v19;
_EPROCESS *Process;
_WNF_STATE_NAME_STRUCT InternalStateName;
_WNF_NAME_INSTANCE *NameInstance;
_WNF_SCOPE_INSTANCE *ScopeInstance;
InternalStateName._bf_0 = 0i64;
v7 = 0i64;
v8 = OldEventMask;
if( ExpCaptureWnfStateName((const _WNF_STATE_NAME *)OldStateName, &InternalStateName, 0) < 0 )
return -1073741811;
v10 = KeAbPreAcquire(&ProcessContext->ProcessSubscriptionListLock, 0i64, v9);
if( _InterlockedCompareExchange64(&ProcessContext->ProcessSubscriptionListLock.PushLock._bf_0, 17i64, 0i64) )
ExfAcquirePushLockSharedEx(
&ProcessContext->ProcessSubscriptionListLock.PushLock,
v10,
&ProcessContext->ProcessSubscriptionListLock);
if( v10 )
v10[26] |= 1u;
v11 = KeAbPreAcquire(&ProcessContext->DeliveryPendingListLock, 0i64, 0i64);
v12 = v11;
if( _interlockedbittestandset64((volatile signed __int32 *)&ProcessContext->DeliveryPendingListLock, 0i64) )
ExfAcquirePushLockExclusiveEx(
&ProcessContext->DeliveryPendingListLock.PushLock,
v11,
&ProcessContext->DeliveryPendingListLock);
if( v12 )
v12[26] |= 1u;
Flink = ProcessContext->DeliveryPendingListHead.Flink;
if( Flink == &ProcessContext->DeliveryPendingListHead )
{
LABEL_36:
v14 = 0;
}
else
{
while( Flink[-6].Blink != (_LIST_ENTRY *)OldSubscriptionId
|| (_LIST_ENTRY *)InternalStateName._bf_0 != Flink[-3].Flink )
{
Flink = Flink->Flink;
if( Flink == &ProcessContext->DeliveryPendingListHead )
goto LABEL_36;
}
v14 = 1;
if( v8 != LODWORD(Flink[1].Blink) || SLODWORD(Flink[1].Flink) <= 1 )
goto LABEL_27;
Flink_high = HIDWORD(Flink[1].Flink);
if( Flink_high )
{
LODWORD(Flink[1].Flink) = 1;
if( (_DWORD)OldStatus == -1073741267 && (Flink_high & 1) == 0 )
HIDWORD(Flink[1].Flink) = Flink_high | 1;
}
else
{
if( (_DWORD)OldStatus )
{
LODWORD(Flink[1].Flink) = 3;
v18 = 3;
}
else
{
LODWORD(Flink[1].Flink) = 0;
v16 = Flink->Flink;
if( Flink->Flink->Blink != Flink || (Blink = Flink->Blink, Blink->Flink != Flink) )
__fastfail(3u);
Blink->Flink = v16;
v16->Blink = Blink;
v18 = (int)Flink[1].Flink;
}
if( v18 == 3 )
goto LABEL_27;
}
if( (BYTE4(Flink[1].Flink) & 1) == 0 && ((__int64)Flink[1].Blink & 1) != 0 )
{
v19 = Flink[-4].Blink;
if( v19 )
{
if( _InterlockedExchangeAdd((volatile signed __int32 *)&v19[10].Flink + 1, 0xFFFFFFFF) == 1
&& ExAcquireRundownProtection((_EX_RUNDOWN_REF *)&Flink[-4].Blink->Blink) )
{
v7 = (_WNF_NAME_INSTANCE *)Flink[-4].Blink;
}
}
}
LODWORD(Flink[1].Blink) = 0;
}
LABEL_27:
if( (_InterlockedExchangeAdd64(&ProcessContext->DeliveryPendingListLock.PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&ProcessContext->DeliveryPendingListLock.PushLock);
KeAbPostRelease(&ProcessContext->DeliveryPendingListLock);
if( _InterlockedCompareExchange64(&ProcessContext->ProcessSubscriptionListLock.PushLock._bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(&ProcessContext->ProcessSubscriptionListLock.PushLock);
KeAbPostRelease(&ProcessContext->ProcessSubscriptionListLock);
if( !v14 && (v8 & 1) != 0 )
{
Process = ProcessContext->Process;
NameInstance = 0i64;
ScopeInstance = 0i64;
ExpWnfResolveScopeInstance(
&ScopeInstance,
Process,
0i64,
(_WNF_DATA_SCOPE)(((unsigned __int64)InternalStateName._bf_0 >> 6) & 0xF),
0i64);
if( ExpWnfLookupNameInstance(ScopeInstance, InternalStateName, &NameInstance) >= 0 )
{
if( _InterlockedExchangeAdd(&NameInstance->CurrentDeliveryCount, 0xFFFFFFFF) == 1 )
v7 = NameInstance;
else
ExReleaseRundownProtection(&NameInstance->RunRef);
}
ExReleaseRundownProtection(&ScopeInstance->RunRef);
}
if( v7 )
{
ExpWnfNotifyNameSubscribers(v7, 8ui64, 1ui64, 1ui64);
ExReleaseRundownProtection(&v7->RunRef);
}
return 0;
}Referenced by:
NtGetCompleteWnfStateSubscription