ExpWnfWriteStateData

NTSTATUS __stdcall ExpWnfWriteStateData(
        _WNF_NAME_INSTANCE *NameInstance,
        VOID *Data,
        UINT64 DataSize,
        UINT64 MatchingChangeStamp,
        UINT64 CheckStamp){
  int v5; 
  size_t v6; 
  VOID *v7; 
  _WNF_LOCK *p_StateDataLock; 
  _BYTE *v10; 
  _BYTE *v11; 
  _WNF_STATE_DATA *StateData; 
  _WNF_STATE_DATA *v13; 
  __int32 i; 
  void *PermanentDataStore; 
  _EPROCESS *CreatorProcess; 
  int v18; 
  _WNF_STATE_DATA *PoolWithTag; 
  _BYTE *v20; 
  _BYTE *v21; 
  unsigned int v22; 
  UINT64 DataSizea; 
  _WNF_STATE_DATA *v24; 
  int v25; 
  _WNF_STATE_DATA *P; 
  _UNICODE_STRING ValueName; 
  _WNF_NAME_INSTANCE *v29; 
  _KAPC_STATE ApcState; 
  __int64 v31; 

  v5 = MatchingChangeStamp;
  v6 = DataSize;
  v7 = Data;
  v29 = NameInstance;
  memset(&ApcState, 0, sizeof(ApcState));
  v25 = 0;
  *(_QWORD *)&ValueName.Length = 2228224i64;
  ValueName.Buffer = (wchar_t *)&v31;
  if( NameInstance->PermanentDataStore )
    ExpWnfComposeValueName(NameInstance->StateName, &ValueName);
  v24 = 0i64;
  P = 0i64;
  p_StateDataLock = &NameInstance->StateDataLock;
  v10 = KeAbPreAcquire(&NameInstance->StateDataLock, 0i64, 0i64);
  v11 = v10;
  if( _interlockedbittestandset64((volatile signed __int32 *)&NameInstance->StateDataLock, 0i64) )
    ExfAcquirePushLockExclusiveEx(&NameInstance->StateDataLock.PushLock, v10, &NameInstance->StateDataLock);
  if( v11 )
    v11[26] |= 1u;
  if( (_DWORD)CheckStamp )
  {
    v22 = NameInstance->StateData ? NameInstance->CurrentChangeStamp : 0;
    if( v22 != v5 )
    {
      if( (_InterlockedExchangeAdd64(&p_StateDataLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(&NameInstance->StateDataLock.PushLock);
      KeAbPostRelease(&NameInstance->StateDataLock);
      return -1073741823;
    }
  }
  StateData = 0i64;
  if( NameInstance->StateData != (_WNF_STATE_DATA *)1 )
    StateData = NameInstance->StateData;
  if( !StateData && (NameInstance->PermanentDataStore || v6)
    || (v13 = StateData) != 0i64 && StateData->AllocatedSize < v6 )
  {
    if( (_InterlockedExchangeAdd64(&p_StateDataLock->PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&NameInstance->StateDataLock.PushLock);
    KeAbPostRelease(&NameInstance->StateDataLock);
    if( ((LODWORD(NameInstance->StateName._bf_0) >> 4) & 3) != 3
      || PsInitialSystemProcess == NameInstance->CreatorProcess )
    {
      PoolWithTag = (_WNF_STATE_DATA *)ExAllocatePoolWithTag(1ui64, v6 + 16, 543583831i64);
      v24 = PoolWithTag;
    }
    else
    {
      CreatorProcess = NameInstance->CreatorProcess;
      if( !CreatorProcess )
        return -1073741772;
      if( CreatorProcess == KeGetCurrentThread()->ApcState.Process )
      {
        v18 = 0;
      }
      else
      {
        v18 = 1;
        KiStackAttachProcess(CreatorProcess, 0i64, &ApcState);
      }
      PoolWithTag = (_WNF_STATE_DATA *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, v6 + 16, 0x20666E57ui64);
      v24 = PoolWithTag;
      if( v18 )
        KiUnstackDetachProcess(&ApcState, 0i64);
      v7 = Data;
    }
    if( !PoolWithTag )
      return -1073741670;
    *(_QWORD *)&PoolWithTag->DataSize = 0i64;
    PoolWithTag->Header = (_WNF_NODE_HEADER)1050884;
    PoolWithTag->AllocatedSize = v6;
    v20 = KeAbPreAcquire(&NameInstance->StateDataLock, 0i64, 0i64);
    v21 = v20;
    if( _interlockedbittestandset64((volatile signed __int32 *)p_StateDataLock, 0i64) )
      ExfAcquirePushLockExclusiveEx(&NameInstance->StateDataLock.PushLock, v20, &NameInstance->StateDataLock);
    if( v21 )
      v21[26] |= 1u;
    v13 = 0i64;
    if( NameInstance->StateData != (_WNF_STATE_DATA *)1 )
      v13 = NameInstance->StateData;
    if( !v13 || v13->AllocatedSize < v6 )
      v13 = v24;
  }
  for( i = NameInstance->CurrentChangeStamp + 1; !i; i = 1 )
    ;
  if( v13 )
  {
    memmove(&v13[1], v7, v6);
    v13->DataSize = v6;
    v13->ChangeStamp = i;
    PermanentDataStore = NameInstance->PermanentDataStore;
    if( PermanentDataStore )
    {
      LODWORD(DataSizea) = v6 + 4;
      v25 = ZwSetValueKey(PermanentDataStore, &ValueName, 0i64, 3ui64, &v13->ChangeStamp, DataSizea);
      if( v25 < 0 )
      {
        P = NameInstance->StateData;
        NameInstance->StateData = 0i64;
        goto LABEL_24;
      }
    }
    if( v13 == v24 )
    {
      P = NameInstance->StateData;
      NameInstance->StateData = v13;
      v24 = 0i64;
    }
  }
  else
  {
    NameInstance->StateData = (_WNF_STATE_DATA *)1;
  }
  _InterlockedExchange((volatile __int32 *)&NameInstance->CurrentChangeStamp, i);
LABEL_24:
  if( (_InterlockedExchangeAdd64(&NameInstance->StateDataLock.PushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&NameInstance->StateDataLock.PushLock);
  KeAbPostRelease(&NameInstance->StateDataLock);
  if( (unsigned __int64)P >= 2 )
    ExFreePoolWithTag(P, 0x20666E57u);
  if( v24 )
    ExFreePoolWithTag(v24, 0x20666E57u);
  return v25;
}

Referenced by:

ExpNtUpdateWnfStateData