ExpWnfSubscribeNameInstance

__int64 __fastcall ExpWnfSubscribeNameInstance(
        _WNF_NAME_INSTANCE *NameInstance,
        _EPROCESS *a2,
        UINT64 a3,
        VOID *a4,
        int a5,
        UINT64 a6,
        char a7,
        UINT64 *SubscriptionId,
        __int64 a9,
        __int64 a10,
        __int64 a11){
  _WNF_PROCESS_CONTEXT *WnfContext; 
  unsigned int v12; 
  _BYTE *v15; 
  NTSTATUS updated; 
  char *PoolWithTag; 
  char *v18; 
  UINT64 v19; 
  _WNF_LOCK *p_ProcessSubscriptionListLock; 
  _BYTE *v21; 
  _BYTE *v22; 
  _WNF_LOCK *p_StateSubscriptionListLock; 
  _BYTE *v24; 
  signed __int8 v25; 
  _LIST_ENTRY *v26; 
  _LIST_ENTRY *p_ProcessSubscriptionListHead; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *v29; 
  _LIST_ENTRY *v30; 
  signed __int32 v31; 
  int v32; 
  UINT64 v33; 
  UINT64 EventMask; 
  INT64 DataSubscriptionChanged; 
  _WNF_SUBSCRIPTION *ExistingSubscription; 
  _WNF_PROCESS_CONTEXT *ProcessContext; 
  _BYTE *v39; 

  WnfContext = (_WNF_PROCESS_CONTEXT *)a2->WnfContext;
  v12 = 0;
  ExistingSubscription = 0i64;
  ProcessContext = WnfContext;
  *(_DWORD *)a11 = 0;
  DataSubscriptionChanged = 0i64;
  if( a7 == 1 )
  {
    v15 = KeAbPreAcquire(&WnfContext->ProcessSubscriptionListLock, 0i64, 0i64);
    if( _InterlockedCompareExchange64(&WnfContext->ProcessSubscriptionListLock.PushLock._bf_0, 17i64, 0i64) )
      ExfAcquirePushLockSharedEx(
        &WnfContext->ProcessSubscriptionListLock.PushLock,
        v15,
        &WnfContext->ProcessSubscriptionListLock);
    if( v15 )
      v15[26] |= 1u;
    LODWORD(EventMask) = a6;
    updated = ExpWnfUpdateSubscription(
                NameInstance,
                WnfContext,
                a3,
                a4,
                EventMask,
                &ExistingSubscription,
                &DataSubscriptionChanged,
                (INT64 *)((char *)&DataSubscriptionChanged + 4),
                SubscriptionId);
    if( _InterlockedCompareExchange64(&WnfContext->ProcessSubscriptionListLock.PushLock._bf_0, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared(&WnfContext->ProcessSubscriptionListLock.PushLock);
    KeAbPostRelease(&WnfContext->ProcessSubscriptionListLock);
    if( updated >= 0 )
      goto LABEL_47;
  }
  if( PsInitialSystemProcess == a2 )
    PoolWithTag = (char *)ExAllocatePoolWithTag(1ui64, 0x88ui64, 543583831i64);
  else
    PoolWithTag = (char *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x88ui64, 0x20666E57ui64);
  v18 = PoolWithTag;
  if( !PoolWithTag )
    return 3221225626i64;
  memset(PoolWithTag, 0i64, 0x88u);
  *(_DWORD *)v18 = 8915205;
  *((_QWORD *)v18 + 10) = a3;
  *((_QWORD *)v18 + 11) = a4;
  *((_DWORD *)v18 + 24) = a5;
  *((_DWORD *)v18 + 25) = a6;
  *((_QWORD *)v18 + 1) = 0i64;
  *((_QWORD *)v18 + 7) = NameInstance->StateName._bf_0;
  if( a7 )
  {
    do
      v19 = _InterlockedIncrement64(&ExpWnfSubcriptionIdCounter);
    while( !v19 );
    if( SubscriptionId )
      *SubscriptionId = v19;
  }
  else
  {
    v19 = (UINT64)v18;
    if( a9 )
      *(_QWORD *)a9 = v18;
  }
  p_ProcessSubscriptionListLock = &ProcessContext->ProcessSubscriptionListLock;
  v21 = KeAbPreAcquire(&ProcessContext->ProcessSubscriptionListLock, 0i64, 0i64);
  v22 = v21;
  if( _interlockedbittestandset64((volatile signed __int32 *)p_ProcessSubscriptionListLock, 0i64) )
    ExfAcquirePushLockExclusiveEx(&p_ProcessSubscriptionListLock->PushLock, v21, p_ProcessSubscriptionListLock);
  if( v22 )
    v22[26] |= 1u;
  p_StateSubscriptionListLock = &NameInstance->StateSubscriptionListLock;
  v24 = KeAbPreAcquire(&NameInstance->StateSubscriptionListLock, 0i64, 0i64);
  v25 = _interlockedbittestandset64((volatile signed __int32 *)&NameInstance->StateSubscriptionListLock, 0i64);
  v39 = v24;
  if( v25 )
  {
    ExfAcquirePushLockExclusiveEx(
      &NameInstance->StateSubscriptionListLock.PushLock,
      v24,
      &NameInstance->StateSubscriptionListLock);
    v24 = v39;
  }
  if( v24 )
    v24[26] |= 1u;
  if( NameInstance->ScopeInstance )
  {
    if( a7 != 1
      || (LODWORD(EventMask) = a6,
          ExpWnfUpdateSubscription(
            NameInstance,
            ProcessContext,
            a3,
            a4,
            EventMask,
            &ExistingSubscription,
            &DataSubscriptionChanged,
            (INT64 *)((char *)&DataSubscriptionChanged + 4),
            SubscriptionId) < 0) )
    {
      *((_QWORD *)v18 + 5) = a2;
      *((_QWORD *)v18 + 6) = NameInstance;
      *((_QWORD *)v18 + 2) = v19;
      ExAcquireRundownProtection((_EX_RUNDOWN_REF *)v18 + 1);
      if( a9 )
        ExAcquireRundownProtection((_EX_RUNDOWN_REF *)v18 + 1);
      v26 = (_LIST_ENTRY *)(v18 + 24);
      p_ProcessSubscriptionListHead = &ProcessContext->ProcessSubscriptionListHead;
      Blink = ProcessContext->ProcessSubscriptionListHead.Blink;
      if( Blink->Flink != &ProcessContext->ProcessSubscriptionListHead
        || (v26->Flink = p_ProcessSubscriptionListHead,
            *((_QWORD *)v18 + 4) = Blink,
            Blink->Flink = v26,
            p_ProcessSubscriptionListHead->Blink = v26,
            v29 = NameInstance->StateSubscriptionListHead.Blink,
            v30 = (_LIST_ENTRY *)(v18 + 64),
            v29->Flink != &NameInstance->StateSubscriptionListHead) )
      {
        __fastfail(3u);
      }
      v30->Flink = &NameInstance->StateSubscriptionListHead;
      *((_QWORD *)v18 + 9) = v29;
      v29->Flink = v30;
      NameInstance->StateSubscriptionListHead.Blink = v30;
      if( (v18[100] & 1) != 0 )
      {
        v31 = _InterlockedExchangeAdd(&NameInstance->DataSubscribersCount, 1u);
        v32 = DataSubscriptionChanged;
        if( !v31 )
          v32 = 1;
        LODWORD(DataSubscriptionChanged) = v32;
      }
      if( (_InterlockedExchangeAdd64(&p_StateSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(&NameInstance->StateSubscriptionListLock.PushLock);
      KeAbPostRelease(&NameInstance->StateSubscriptionListLock);
      if( (_InterlockedExchangeAdd64(&p_ProcessSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(&p_ProcessSubscriptionListLock->PushLock);
      KeAbPostRelease(p_ProcessSubscriptionListLock);
      *(_QWORD *)a10 = v18;
      goto LABEL_40;
    }
    if( (_InterlockedExchangeAdd64(&p_StateSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&NameInstance->StateSubscriptionListLock.PushLock);
    KeAbPostRelease(&NameInstance->StateSubscriptionListLock);
    if( (_InterlockedExchangeAdd64(&p_ProcessSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&p_ProcessSubscriptionListLock->PushLock);
    KeAbPostRelease(p_ProcessSubscriptionListLock);
    ExFreePoolWithTag(v18, 0x20666E57u);
LABEL_47:
    *(_QWORD *)a10 = ExistingSubscription;
LABEL_40:
    v33 = 0i64;
    if( DataSubscriptionChanged < 0 && _InterlockedExchangeAdd(&NameInstance->CurrentDeliveryCount, 0xFFFFFFFF) == 1 )
      v33 = 8i64;
    if( (int)DataSubscriptionChanged > 0 )
    {
      v33 = (unsigned int)v33 | 2;
    }
    else if( (int)DataSubscriptionChanged < 0 )
    {
      v33 = (unsigned int)v33 | 4;
    }
    if( (_DWORD)v33 )
    {
      LOBYTE(v12) = a7 != 0;
      ExpWnfNotifyNameSubscribers(NameInstance, v33, 1ui64, v12);
      *(_DWORD *)a11 = 1;
    }
    return 0i64;
  }
  if( (_InterlockedExchangeAdd64(&p_StateSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&NameInstance->StateSubscriptionListLock.PushLock);
  KeAbPostRelease(&NameInstance->StateSubscriptionListLock);
  if( (_InterlockedExchangeAdd64(&p_ProcessSubscriptionListLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&p_ProcessSubscriptionListLock->PushLock);
  KeAbPostRelease(p_ProcessSubscriptionListLock);
  ExFreePoolWithTag(v18, 0x20666E57u);
  return 3221225524i64;
}

Referenced by:

ExpWnfSubscribeWnfStateChange