ExpWnfCreateNameInstance

NTSTATUS __stdcall ExpWnfCreateNameInstance(
        _WNF_SCOPE_INSTANCE *ScopeInstance,
        _WNF_STATE_NAME_STRUCT StateName,
        _WNF_STATE_NAME_REGISTRATION *StateInfo,
        _EPROCESS *Process,
        _WNF_NAME_INSTANCE **NameInstance){
  const _WNF_TYPE_ID *TypeId; 
  unsigned __int64 v7; 
  UINT64 v10; 
  _WNF_NAME_INSTANCE *PoolWithTag; 
  _WNF_NAME_INSTANCE *v12; 
  VOID **p_SecurityDescriptor; 
  NTSTATUS v14; 
  _WNF_LOCK *p_NameSetLock; 
  _BYTE *v16; 
  _BYTE *v17; 
  _WNF_NAME_INSTANCE *v18; 
  _WNF_NAME_INSTANCE *v19; 
  _RTL_BALANCED_NODE *Root; 
  BOOL v21; 
  _RTL_BALANCED_NODE *v22; 
  _EX_PUSH_LOCK *WnfContext; 
  _BYTE *v24; 
  _BYTE *v25; 
  _LIST_ENTRY *bf_0; 
  _LIST_ENTRY *p_TemporaryNameListEntry; 
  UINT64 v29; 
  _WNF_STATE_DATA *StateData; 

  TypeId = StateInfo->TypeId;
  v7 = ((unsigned __int64)StateName._bf_0 >> 4) & 3;
  if( PsInitialSystemProcess == Process || (_DWORD)v7 != 3 )
  {
    v10 = 184i64;
    if( !TypeId )
      v10 = 168i64;
    PoolWithTag = (_WNF_NAME_INSTANCE *)ExAllocatePoolWithTag(1ui64, v10, 543583831i64);
  }
  else
  {
    v29 = 184i64;
    if( !TypeId )
      v29 = 168i64;
    PoolWithTag = (_WNF_NAME_INSTANCE *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, v29, 0x20666E57ui64);
  }
  v12 = PoolWithTag;
  if( !PoolWithTag )
    return -1073741670;
  memset(PoolWithTag, 0i64, sizeof(_WNF_NAME_INSTANCE));
  v12->Header = (_WNF_NODE_HEADER)11012355;
  v12->ScopeInstance = ScopeInstance;
  v12->StateName = StateName;
  v12->StateNameInfo.MaxStateSize = StateInfo->MaxStateSize;
  if( StateInfo->TypeId )
  {
    v12->StateNameInfo.TypeId = (const _WNF_TYPE_ID *)&v12[1];
    *(_GUID *)&v12[1].Header.NodeTypeCode = StateInfo->TypeId->TypeId[0];
  }
  p_SecurityDescriptor = (VOID **)&v12->StateNameInfo.SecurityDescriptor;
  if( ObLogSecurityDescriptor(StateInfo->SecurityDescriptor, (VOID **)&v12->StateNameInfo.SecurityDescriptor, 1ui64) < 0 )
  {
    ExFreePoolWithTag(v12, 0x20666E57u);
    return -1073741670;
  }
  v12->StateSubscriptionListHead.Blink = &v12->StateSubscriptionListHead;
  v12->StateSubscriptionListHead.Flink = &v12->StateSubscriptionListHead;
  v12->StateSubscriptionListLock.PushLock._bf_0 = 0i64;
  v12->StateDataLock.PushLock._bf_0 = 0i64;
  if( (StateName._bf_0 & 0x400) != 0
    && ExpWnfGetPermanentDataStoreHandle(ScopeInstance, (_WNF_STATE_NAME_LIFETIME)v7, 1ui64, &v12->PermanentDataStore) < 0 )
  {
    v14 = -1073741670;
    goto LABEL_42;
  }
  v14 = ExpWnfPopulateStateData(v12);
  if( v14 )
  {
LABEL_42:
    ObDereferenceSecurityDescriptor(*p_SecurityDescriptor, 1ui64);
    ExFreePoolWithTag(v12, 0x20666E57u);
    return v14;
  }
  p_NameSetLock = &ScopeInstance->NameSetLock;
  v16 = KeAbPreAcquire(&ScopeInstance->NameSetLock, 0i64, 0i64);
  v17 = v16;
  if( _interlockedbittestandset64((volatile signed __int32 *)&ScopeInstance->NameSetLock, 0i64) )
    ExfAcquirePushLockExclusiveEx(&ScopeInstance->NameSetLock.PushLock, v16, &ScopeInstance->NameSetLock);
  if( v17 )
    v17[26] |= 1u;
  v18 = ExpWnfFindStateName(ScopeInstance, StateName);
  v19 = v18;
  if( v18 )
  {
    ExAcquireRundownProtection(&v18->RunRef);
    if( (_InterlockedExchangeAdd64(&p_NameSetLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&ScopeInstance->NameSetLock.PushLock);
    KeAbPostRelease(&ScopeInstance->NameSetLock);
    ObDereferenceSecurityDescriptor(*p_SecurityDescriptor, 1ui64);
    StateData = v12->StateData;
    if( StateData )
      ExFreePoolWithTag(StateData, 0x20666E57u);
    ExFreePoolWithTag(v12, 0x20666E57u);
    *NameInstance = v19;
    return 0;
  }
  ExAcquireRundownProtection(&v12->RunRef);
  Root = ScopeInstance->NameSet.Root;
  v21 = 0;
  if( !Root )
    goto LABEL_23;
  while( (_RTL_BALANCED_NODE *)v12->StateName._bf_0 < Root[1].Children[0] )
  {
    v22 = Root->Children[0];
    if( !Root->Children[0] )
      goto LABEL_23;
LABEL_19:
    Root = v22;
  }
  v22 = Root->Children[1];
  if( v22 )
    goto LABEL_19;
  v21 = 1;
LABEL_23:
  RtlAvlInsertNodeEx(&ScopeInstance->NameSet.Root, (UINT64)Root, v21, &v12->TreeLinks);
  if( (_DWORD)v7 == 3 )
  {
    v12->CreatorProcess = Process;
    WnfContext = (_EX_PUSH_LOCK *)Process->WnfContext;
    v24 = KeAbPreAcquire(&WnfContext[7], 0i64, 0i64);
    v25 = v24;
    if( _interlockedbittestandset64((volatile signed __int32 *)&WnfContext[7], 0i64) )
      ExfAcquirePushLockExclusiveEx(WnfContext + 7, v24, &WnfContext[7]);
    if( v25 )
      v25[26] |= 1u;
    bf_0 = (_LIST_ENTRY *)WnfContext[9]._bf_0;
    p_TemporaryNameListEntry = &v12->TemporaryNameListEntry;
    if( (_EX_PUSH_LOCK *)bf_0->Flink != &WnfContext[8] )
      __fastfail(3u);
    p_TemporaryNameListEntry->Flink = (_LIST_ENTRY *)&WnfContext[8];
    v12->TemporaryNameListEntry.Blink = bf_0;
    bf_0->Flink = p_TemporaryNameListEntry;
    WnfContext[9]._bf_0 = (__int64)p_TemporaryNameListEntry;
    if( (_InterlockedExchangeAdd64(&WnfContext[7]._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(WnfContext + 7);
    KeAbPostRelease(&WnfContext[7]);
  }
  if( (_InterlockedExchangeAdd64(&p_NameSetLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&ScopeInstance->NameSetLock.PushLock);
  KeAbPostRelease(&ScopeInstance->NameSetLock);
  *NameInstance = v12;
  return 0;
}

Referenced by:

ExpNtUpdateWnfStateData
ExpWnfSubscribeWnfStateChange
NtCreateWnfStateName
NtQueryWnfStateData