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