ExpWnfSubscribeNameInstance

__int64 __fastcall ExpWnfSubscribeNameInstance(
        __int64 a1,
        unsigned __int64 a2,
        __int64 a3,
        __int64 a4,
        int a5,
        int a6,
        char a7,
        signed __int64 *a8,
        struct _EX_RUNDOWN_REF **a9,
        struct _EX_RUNDOWN_REF **a10,
        _DWORD *a11){
  _WNF_PROCESS_CONTEXT *v11; 
  unsigned int v12; 
  _BYTE *v15; 
  _BYTE *v16; 
  int updated; 
  char *PoolWithTag; 
  char *v19; 
  signed __int64 v20; 
  _WNF_LOCK *p_ProcessSubscriptionListLock; 
  _BYTE *v22; 
  _BYTE *v23; 
  volatile signed __int64 *v24; 
  _BYTE *v25; 
  signed __int8 v26; 
  _LIST_ENTRY *v27; 
  _LIST_ENTRY *p_ProcessSubscriptionListHead; 
  _LIST_ENTRY *Blink; 
  _QWORD *v30; 
  _QWORD *v31; 
  signed __int32 v32; 
  int v33; 
  UINT64 v34; 
  UINT64 EventMask; 
  INT64 DataSubscriptionChanged; 
  _WNF_SUBSCRIPTION *ExistingSubscription; 
  _WNF_PROCESS_CONTEXT *ProcessContext; 
  _BYTE *v40; 
  v11 = *(_WNF_PROCESS_CONTEXT **)(a2 + 2152);
  v12 = 0;
  ExistingSubscription = 0i64;
  ProcessContext = v11;
  *a11 = 0;
  DataSubscriptionChanged = 0i64;
  if( a7 == 1 )
  {
    LODWORD(v15) = KeAbPreAcquire(&v11->ProcessSubscriptionListLock, 0i64, 0i64);
    v16 = v15;
    if( _InterlockedCompareExchange64((volatile signed __int64 *)&v11->ProcessSubscriptionListLock, 17i64, 0i64) )
      ExfAcquirePushLockSharedEx((UINT64 *)&v11->ProcessSubscriptionListLock, v15, &v11->ProcessSubscriptionListLock);
    if( v16 )
      v16[26] |= 1u;
    LODWORD(EventMask) = a6;
    updated = ExpWnfUpdateSubscription(
                (_WNF_NAME_INSTANCE *)a1,
                v11,
                a3,
                (VOID *)a4,
                EventMask,
                &ExistingSubscription,
                &DataSubscriptionChanged,
                (INT64 *)((char *)&DataSubscriptionChanged + 4),
                (UINT64 *)a8);
    if( _InterlockedCompareExchange64((volatile signed __int64 *)&v11->ProcessSubscriptionListLock, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared((INT64 *)&v11->ProcessSubscriptionListLock);
    KeAbPostRelease(&v11->ProcessSubscriptionListLock);
    if( updated >= 0 )
      goto LABEL_47;
  }
  if( PsInitialSystemProcess == (PEPROCESS)a2 )
    PoolWithTag = (char *)ExAllocatePoolWithTag(PagedPool, 0x88ui64, 0x20666E57ui64);
  else
    PoolWithTag = (char *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x88ui64, 0x20666E57ui64);
  v19 = PoolWithTag;
  if( !PoolWithTag )
    return 3221225626i64;
  memset((INT64)PoolWithTag, 0i64);
  *(_DWORD *)v19 = 8915205;
  *((_QWORD *)v19 + 10) = a3;
  *((_QWORD *)v19 + 11) = a4;
  *((_DWORD *)v19 + 24) = a5;
  *((_DWORD *)v19 + 25) = a6;
  *((_QWORD *)v19 + 1) = 0i64;
  *((_QWORD *)v19 + 7) = *(_QWORD *)(a1 + 40);
  if( a7 )
  {
    do
      v20 = _InterlockedIncrement64(&ExpWnfSubcriptionIdCounter);
    while( !v20 );
    if( a8 )
      *a8 = v20;
  }
  else
  {
    v20 = (signed __int64)v19;
    if( a9 )
      *a9 = (struct _EX_RUNDOWN_REF *)v19;
  }
  p_ProcessSubscriptionListLock = &ProcessContext->ProcessSubscriptionListLock;
  LODWORD(v22) = KeAbPreAcquire(&ProcessContext->ProcessSubscriptionListLock, 0i64, 0i64);
  v23 = v22;
  if( _interlockedbittestandset64((volatile signed __int32 *)p_ProcessSubscriptionListLock, 0i64) )
    ExfAcquirePushLockExclusiveEx((UINT64 *)p_ProcessSubscriptionListLock, v22, p_ProcessSubscriptionListLock);
  if( v23 )
    v23[26] |= 1u;
  v24 = (volatile signed __int64 *)(a1 + 112);
  LODWORD(v25) = KeAbPreAcquire((PVOID)(a1 + 112), 0i64, 0i64);
  v26 = _interlockedbittestandset64((volatile signed __int32 *)(a1 + 112), 0i64);
  v40 = v25;
  if( v26 )
  {
    ExfAcquirePushLockExclusiveEx((UINT64 *)(a1 + 112), v25, (VOID *)(a1 + 112));
    v25 = v40;
  }
  if( v25 )
    v25[26] |= 1u;
  if( *(_QWORD *)(a1 + 48) )
  {
    if( a7 != 1
      || (LODWORD(EventMask) = a6,
          (int)ExpWnfUpdateSubscription(
                 (_WNF_NAME_INSTANCE *)a1,
                 ProcessContext,
                 a3,
                 (VOID *)a4,
                 EventMask,
                 &ExistingSubscription,
                 &DataSubscriptionChanged,
                 (INT64 *)((char *)&DataSubscriptionChanged + 4),
                 (UINT64 *)a8) < 0) )
    {
      *((_QWORD *)v19 + 5) = a2;
      *((_QWORD *)v19 + 6) = a1;
      *((_QWORD *)v19 + 2) = v20;
      ExAcquireRundownProtection((PEX_RUNDOWN_REF)v19 + 1);
      if( a9 )
        ExAcquireRundownProtection((PEX_RUNDOWN_REF)v19 + 1);
      v27 = (_LIST_ENTRY *)(v19 + 24);
      p_ProcessSubscriptionListHead = &ProcessContext->ProcessSubscriptionListHead;
      Blink = ProcessContext->ProcessSubscriptionListHead.Blink;
      if( Blink->Flink != &ProcessContext->ProcessSubscriptionListHead
        || (v27->Flink = p_ProcessSubscriptionListHead,
            *((_QWORD *)v19 + 4) = Blink,
            Blink->Flink = v27,
            p_ProcessSubscriptionListHead->Blink = v27,
            v30 = *(_QWORD **)(a1 + 128),
            v31 = v19 + 64,
            *v30 != a1 + 120) )
      {
        __fastfail(3u);
      }
      *v31 = a1 + 120;
      *((_QWORD *)v19 + 9) = v30;
      *v30 = v31;
      *(_QWORD *)(a1 + 128) = v31;
      if( (v19[100] & 1) != 0 )
      {
        v32 = _InterlockedExchangeAdd((volatile signed __int32 *)(a1 + 160), 1u);
        v33 = DataSubscriptionChanged;
        if( !v32 )
          v33 = 1;
        LODWORD(DataSubscriptionChanged) = v33;
      }
      if( (_InterlockedExchangeAdd64(v24, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((volatile INT64 *)(a1 + 112));
      KeAbPostRelease((PVOID)(a1 + 112));
      if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_ProcessSubscriptionListLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((volatile INT64 *)p_ProcessSubscriptionListLock);
      KeAbPostRelease(p_ProcessSubscriptionListLock);
      *a10 = (struct _EX_RUNDOWN_REF *)v19;
      goto LABEL_40;
    }
    if( (_InterlockedExchangeAdd64(v24, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)(a1 + 112));
    KeAbPostRelease((PVOID)(a1 + 112));
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_ProcessSubscriptionListLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)p_ProcessSubscriptionListLock);
    KeAbPostRelease(p_ProcessSubscriptionListLock);
    ExFreePoolWithTag(v19, 0x20666E57u);
LABEL_47:
    *a10 = (struct _EX_RUNDOWN_REF *)ExistingSubscription;
LABEL_40:
    v34 = 0i64;
    if( DataSubscriptionChanged < 0 && _InterlockedExchangeAdd((volatile signed __int32 *)(a1 + 164), 0xFFFFFFFF) == 1 )
      v34 = 8i64;
    if( (int)DataSubscriptionChanged > 0 )
    {
      v34 = (unsigned int)v34 | 2;
    }
    else if( (int)DataSubscriptionChanged < 0 )
    {
      v34 = (unsigned int)v34 | 4;
    }
    if( (_DWORD)v34 )
    {
      LOBYTE(v12) = a7 != 0;
      ExpWnfNotifyNameSubscribers(a1, v34, 1i64, v12);
      *a11 = 1;
    }
    return 0i64;
  }
  if( (_InterlockedExchangeAdd64(v24, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)(a1 + 112));
  KeAbPostRelease((PVOID)(a1 + 112));
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_ProcessSubscriptionListLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)p_ProcessSubscriptionListLock);
  KeAbPostRelease(p_ProcessSubscriptionListLock);
  ExFreePoolWithTag(v19, 0x20666E57u);
  return 3221225524i64;
}

Referenced by:

ExpWnfSubscribeWnfStateChange