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