ExpWnfWriteStateData

INT64 __fastcall ExpWnfWriteStateData(
        _WNF_NAME_INSTANCE *NameInstance,
        const VOID *Data,
        UINT64 DataSize,
        UINT64 MatchingChangeStamp,
        UINT64 CheckStamp){
  int v5; 
  UINT64 v6; 
  UINT8 *v7; 
  _WNF_LOCK *p_StateDataLock; 
  _BYTE *v10; 
  _BYTE *v11; 
  _WNF_STATE_DATA *StateData; 
  _WNF_STATE_DATA *v13; 
  __int32 i; 
  void *PermanentDataStore; 
  _KPROCESS *CreatorProcess; 
  int v18; 
  _WNF_STATE_DATA *PoolWithTag; 
  _BYTE *v20; 
  _BYTE *v21; 
  unsigned int v22; 
  UINT64 DataSizea; 
  _WNF_STATE_DATA *v24; 
  NTSTATUS v25; 
  _WNF_STATE_DATA *P; 
  struct _UNICODE_STRING ValueName; 
  _WNF_NAME_INSTANCE *v29; 
  _KAPC_STATE ApcState; 
  __int64 v31; 
  v5 = MatchingChangeStamp;
  v6 = (unsigned int)DataSize;
  v7 = (UINT8 *)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;
  LODWORD(v10) = KeAbPreAcquire(&NameInstance->StateDataLock, 0i64, 0i64);
  v11 = v10;
  if( _interlockedbittestandset64((volatile signed __int32 *)&NameInstance->StateDataLock, 0i64) )
    ExfAcquirePushLockExclusiveEx((UINT64 *)&NameInstance->StateDataLock, v10, &NameInstance->StateDataLock);
  if( v11 )
    v11[26] |= 1u;
  if( (_DWORD)CheckStamp )
  {
    v22 = NameInstance->StateData ? NameInstance->CurrentChangeStamp : 0;
    if( v22 != v5 )
    {
      if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_StateDataLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((volatile INT64 *)&NameInstance->StateDataLock);
      KeAbPostRelease(&NameInstance->StateDataLock);
      return 3221225473i64;
    }
  }
  StateData = 0i64;
  if( NameInstance->StateData != (_WNF_STATE_DATA *)1 )
    StateData = NameInstance->StateData;
  if( !StateData && (NameInstance->PermanentDataStore || (_DWORD)v6)
    || (v13 = StateData) != 0i64 && StateData->AllocatedSize < (unsigned int)v6 )
  {
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_StateDataLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)&NameInstance->StateDataLock);
    KeAbPostRelease(&NameInstance->StateDataLock);
    if( ((*(_DWORD *)&NameInstance->StateName >> 4) & 3) != 3
      || PsInitialSystemProcess == (PEPROCESS)NameInstance->CreatorProcess )
    {
      PoolWithTag = (_WNF_STATE_DATA *)ExAllocatePoolWithTag(PagedPool, (unsigned int)(v6 + 16), 0x20666E57ui64);
      v24 = PoolWithTag;
    }
    else
    {
      CreatorProcess = NameInstance->CreatorProcess;
      if( !CreatorProcess )
        return 3221225524i64;
      if( CreatorProcess == *((_EPROCESS **)KeGetCurrentThread() + 23) )
      {
        v18 = 0;
      }
      else
      {
        v18 = 1;
        KiStackAttachProcess((_KPROCESS *)CreatorProcess, 0i64, &ApcState);
      }
      PoolWithTag = (_WNF_STATE_DATA *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, (unsigned int)(v6 + 16), 0x20666E57ui64);
      v24 = PoolWithTag;
      if( v18 )
        KiUnstackDetachProcess(&ApcState, 0i64);
      v7 = (UINT8 *)Data;
    }
    if( !PoolWithTag )
      return 3221225626i64;
    *(_QWORD *)&PoolWithTag->DataSize = 0i64;
    PoolWithTag->Header = (_WNF_NODE_HEADER)1050884;
    PoolWithTag->AllocatedSize = v6;
    LODWORD(v20) = KeAbPreAcquire(&NameInstance->StateDataLock, 0i64, 0i64);
    v21 = v20;
    if( _interlockedbittestandset64((volatile signed __int32 *)p_StateDataLock, 0i64) )
      ExfAcquirePushLockExclusiveEx((UINT64 *)&NameInstance->StateDataLock, v20, &NameInstance->StateDataLock);
    if( v21 )
      v21[26] |= 1u;
    v13 = 0i64;
    if( NameInstance->StateData != (_WNF_STATE_DATA *)1 )
      v13 = NameInstance->StateData;
    if( !v13 || v13->AllocatedSize < (unsigned int)v6 )
      v13 = v24;
  }
  for( i = NameInstance->CurrentChangeStamp + 1; !i; i = 1 )
    ;
  if( v13 )
  {
    memmove((UINT8 *)&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((volatile signed __int64 *)&NameInstance->StateDataLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)&NameInstance->StateDataLock);
  KeAbPostRelease(&NameInstance->StateDataLock);
  if( (unsigned __int64)P >= 2 )
    ExFreePoolWithTag(P, 0x20666E57u);
  if( v24 )
    ExFreePoolWithTag(v24, 0x20666E57u);
  return(unsigned int)v25;
}

Referenced by:

ExpNtUpdateWnfStateData