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