ExpWnfResolveScopeInstance

NTSTATUS __stdcall ExpWnfResolveScopeInstance(
        _WNF_SCOPE_INSTANCE **ScopeInstance,
        _EPROCESS *Process,
        _ETHREAD *Thread,
        _WNF_DATA_SCOPE DataScope,
        VOID *ScopeInstanceId){
  __int64 v5; 
  _ESERVERSILO_GLOBALS *CurrentServerSiloGlobals; 
  volatile signed __int64 *p_WnfSiloState; 
  _WNF_PROCESS_CONTEXT *v10; 
  int v11; 
  NTSTATUS v12; 
  _WNF_SCOPE_INSTANCE **v13; 
  _WNF_SCOPE_INSTANCE *v14; 
  bool v15; 
  int CurrentScopeInstance; 
  PVOID *p_ScopeInstancea; 
  VOID **PoolWithTag; 
  _LIST_ENTRY *v20; 
  _EX_PUSH_LOCK *v21; 
  _BYTE *v22; 
  _WNF_SCOPE_INSTANCE *v23; 
  int v24; 
  _EJOB *v25; 
  _BYTE *v26; 
  _BYTE *v27; 
  _WNF_SCOPE_INSTANCE *v28; 
  _WNF_SCOPE_INSTANCE *v29; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *p_ResolverListEntry; 
  UINT64 NumberOfBytes; 
  _WNF_SCOPE_INSTANCE *Scope; 
  _WNF_SCOPE_MAP *ScopeMap; 
  _WNF_PROCESS_CONTEXT *ProcessContext; 
  PVOID ScopeInstancea; 
  PVOID P; 

  v5 = DataScope;
  ScopeInstancea = 0i64;
  ScopeMap = 0i64;
  P = 0i64;
  if( KeGetCurrentThread()->PreviousMode && (unsigned int)(DataScope - 4) > 1 )
  {
    CurrentServerSiloGlobals = PsGetCurrentServerSiloGlobals((_KSPIN_LOCK *)ScopeInstance);
  }
  else
  {
    LODWORD(v25) = HalSystemVectorDispatchEntry(
                     (UINT32)ScopeInstance,
                     (PKINTERRUPT_ROUTINE **)Process,
                     (PKINTERRUPT_ROUTINE *)Thread);
    CurrentServerSiloGlobals = PsGetServerSiloGlobals(v25);
  }
  p_WnfSiloState = (volatile signed __int64 *)&CurrentServerSiloGlobals->WnfSiloState;
  if( !CurrentServerSiloGlobals->WnfSiloState.ScopeMap )
  {
    CurrentScopeInstance = ExpWnfAllocateScopeMap(&ScopeMap);
    if( CurrentScopeInstance < 0 )
      return CurrentScopeInstance;
    if( _InterlockedCompareExchange64(p_WnfSiloState, (signed __int64)ScopeMap, 0i64) )
      ExFreePoolWithTag(ScopeMap, 0x20666E57u);
  }
  ProcessContext = (_WNF_PROCESS_CONTEXT *)Process->WnfContext;
  v10 = ProcessContext;
  if( !ProcessContext )
  {
    CurrentScopeInstance = ExpWnfCreateProcessContext(Process, &ProcessContext);
    if( CurrentScopeInstance < 0 )
      return CurrentScopeInstance;
    v10 = ProcessContext;
  }
  if( ScopeInstanceId || (v11 = 1, Thread) )
    v11 = 0;
  LODWORD(NumberOfBytes) = v11;
  v12 = 8;
  if( (_DWORD)v5 )
  {
    if( (_DWORD)v5 == 4 )
    {
      v13 = (_WNF_SCOPE_INSTANCE **)(*p_WnfSiloState + 16);
    }
    else
    {
      if( (_DWORD)v5 != 5 )
      {
        v13 = (_WNF_SCOPE_INSTANCE **)&v10->ImplicitScopeInstances[(unsigned int)(v5 - 1)];
        goto LABEL_12;
      }
      v13 = (_WNF_SCOPE_INSTANCE **)(*p_WnfSiloState + 24);
    }
  }
  else
  {
    v13 = (_WNF_SCOPE_INSTANCE **)(*p_WnfSiloState + 8);
  }
  LODWORD(NumberOfBytes) = 1;
LABEL_12:
  v14 = *v13;
  Scope = *v13;
  if( (_DWORD)NumberOfBytes && v14 )
    goto LABEL_14;
  if( ScopeInstanceId )
  {
    if( (_DWORD)v5 )
    {
      switch( (_DWORD)v5 )
      {
        case 1:
          v12 = 4;
          goto LABEL_48;
        case 2:
          v12 = RtlLengthSid((INT64)ScopeInstanceId);
          goto LABEL_48;
        case 3:
LABEL_48:
          HIDWORD(NumberOfBytes) = v12;
          LODWORD(NumberOfBytes) = 0;
          goto LABEL_30;
      }
    }
    v12 = 0;
    goto LABEL_48;
  }
  HIDWORD(NumberOfBytes) = 8;
  p_ScopeInstancea = &ScopeInstancea;
  CurrentScopeInstance = ExpWnfGetCurrentScopeInstance(
                           Process,
                           Thread,
                           (_WNF_DATA_SCOPE)v5,
                           &ScopeInstancea,
                           (UINT64 *)((char *)&NumberOfBytes + 4),
                           &NumberOfBytes);
  if( CurrentScopeInstance == -1073741789 )
  {
    PoolWithTag = ExAllocatePoolWithTag(1ui64, HIDWORD(NumberOfBytes), 543583831i64);
    P = PoolWithTag;
    if( !PoolWithTag )
      return -1073741670;
    p_ScopeInstancea = PoolWithTag;
    CurrentScopeInstance = ExpWnfGetCurrentScopeInstance(
                             Process,
                             Thread,
                             (_WNF_DATA_SCOPE)v5,
                             PoolWithTag,
                             (UINT64 *)((char *)&NumberOfBytes + 4),
                             &NumberOfBytes);
  }
  if( CurrentScopeInstance < 0 )
    goto LABEL_17;
  if( HIDWORD(NumberOfBytes) )
    ScopeInstanceId = p_ScopeInstancea;
LABEL_30:
  if( (_DWORD)NumberOfBytes && v14 )
  {
LABEL_14:
    v15 = ExAcquireRundownProtection(&v14->RunRef) == 0;
    goto LABEL_15;
  }
  v20 = (_LIST_ENTRY *)(*p_WnfSiloState + 8 * (2 * v5 + v5 + 5));
  v21 = (_EX_PUSH_LOCK *)(*p_WnfSiloState + 8 * (v5 + 2 * v5 + 4));
  v22 = KeAbPreAcquire(v21, 0i64, 0i64);
  if( _InterlockedCompareExchange64(&v21->_bf_0, 17i64, 0i64) )
    ExfAcquirePushLockSharedEx(v21, v22, v21);
  if( v22 )
    v22[26] |= 1u;
  v23 = ExpWnfFindScopeInstance(v20, ScopeInstanceId, HIDWORD(NumberOfBytes));
  v14 = v23;
  if( v23 )
  {
    v24 = ExAcquireRundownProtection(&v23->RunRef);
    if( _InterlockedCompareExchange64(&v21->_bf_0, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared(v21);
    KeAbPostRelease(v21);
  }
  else
  {
    if( _InterlockedCompareExchange64(&v21->_bf_0, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared(v21);
    KeAbPostRelease(v21);
    CurrentScopeInstance = ExpWnfAllocateScopeInstance(
                             &Scope,
                             (_WNF_DATA_SCOPE)v5,
                             ScopeInstanceId,
                             HIDWORD(NumberOfBytes));
    if( CurrentScopeInstance < 0 )
      goto LABEL_17;
    v26 = KeAbPreAcquire(v21, 0i64, 0i64);
    v27 = v26;
    if( _interlockedbittestandset64((volatile signed __int32 *)v21, 0i64) )
      ExfAcquirePushLockExclusiveEx(v21, v26, v21);
    if( v27 )
      v27[26] |= 1u;
    v28 = ExpWnfFindScopeInstance(v20, ScopeInstanceId, HIDWORD(NumberOfBytes));
    v14 = v28;
    if( !v28 )
    {
      v29 = Scope;
      ExAcquireRundownProtection(&Scope->RunRef);
      Flink = v20->Flink;
      p_ResolverListEntry = &v29->ResolverListEntry;
      if( v20->Flink->Blink != v20 )
        __fastfail(3u);
      p_ResolverListEntry->Flink = Flink;
      p_ResolverListEntry->Blink = v20;
      Flink->Blink = p_ResolverListEntry;
      v20->Flink = p_ResolverListEntry;
      if( (_InterlockedExchangeAdd64(&v21->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(v21);
      KeAbPostRelease(v21);
      if( (_DWORD)NumberOfBytes )
        _InterlockedCompareExchange64((volatile signed __int64 *)v13, (signed __int64)Scope, 0i64);
      v14 = Scope;
      goto LABEL_16;
    }
    v24 = ExAcquireRundownProtection(&v28->RunRef);
    if( (_InterlockedExchangeAdd64(&v21->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v21);
    KeAbPostRelease(v21);
    ExpWnfFreeScopeInstance(Scope, 0);
  }
  v15 = v24 == 0;
LABEL_15:
  if( !v15 )
  {
LABEL_16:
    CurrentScopeInstance = 0;
    *ScopeInstance = v14;
    goto LABEL_17;
  }
  CurrentScopeInstance = -1073741772;
LABEL_17:
  if( P )
    ExFreePoolWithTag(P, 0x20666E57u);
  return CurrentScopeInstance;
}

Referenced by:

ExpNtDeleteWnfStateData
ExpNtUpdateWnfStateData
ExpWnfCompleteThreadSubscriptions
ExpWnfSubscribeWnfStateChange
NtCreateWnfStateName
NtDeleteWnfStateName
NtQueryWnfStateData
NtQueryWnfStateNameInformation