VrpUnloadDifferencingHive
NTSTATUS __stdcall VrpUnloadDifferencingHive(UNICODE_STRING *TargetKeyPath){
_ETHREAD *CurrentThread;
__int64 v3;
__int64 v4;
_ETHREAD *v5;
volatile signed __int64 *v6;
char v7;
char v8;
char v9;
int v10;
_ETHREAD *v11;
char v12;
signed __int64 v14;
unsigned __int64 i;
signed __int64 v16;
struct _OBJECT_ATTRIBUTES KeyObjectAttributes;
memset(&KeyObjectAttributes, 0, sizeof(KeyObjectAttributes));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockSharedEx((UINT64)&gLoadedDiffHivesLock, 0i64);
LODWORD(v3) = VrpFindDiffHiveEntryForMountPointWithLock(TargetKeyPath);
v4 = v3;
if( v3 && _InterlockedIncrement64((volatile signed __int64 *)(v3 + 16)) <= 1 )
__fastfail(0xEu);
ExReleasePushLockEx((UINT64)&gLoadedDiffHivesLock, 0i64);
KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
if( !v4 )
return -1073741772;
v5 = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)v5 + 242);
v6 = (volatile signed __int64 *)(v4 + 24);
ExAcquirePushLockExclusiveEx(v4 + 24, 0i64);
if( VrpDecrementDiffHiveEntryHardRefCount(v4) )
{
v7 = VrpBecomeDiffHiveEntryTransitionOwner(v4);
*(_DWORD *)(v4 + 56) &= ~1u;
v8 = v7;
v9 = _InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64);
if( (v9 & 2) != 0 && (v9 & 4) == 0 )
ExfTryToWakePushLock((volatile INT64 *)(v4 + 24));
KeAbPostRelease((PVOID)(v4 + 24));
KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
KeyObjectAttributes.RootDirectory = 0i64;
KeyObjectAttributes.Length = 48;
*(_OWORD *)&KeyObjectAttributes.SecurityDescriptor = 0i64;
KeyObjectAttributes.Attributes = 576;
KeyObjectAttributes.ObjectName = TargetKeyPath;
v10 = ZwUnloadKey(&KeyObjectAttributes);
if( v10 < 0 )
v10 = ZwUnloadKey2(&KeyObjectAttributes, 1ui64);
v11 = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)v11 + 242);
ExAcquirePushLockExclusiveEx(v4 + 24, 0i64);
if( v10 < 0 )
{
*(_DWORD *)(v4 + 56) |= 1u;
if( ++*(_QWORD *)(v4 + 32) <= 1ui64 )
{
_m_prefetchw((const void *)(v4 + 16));
v14 = *(_QWORD *)(v4 + 16);
for( i = v14 + 1; ; i = v14 + 1 )
{
if( i <= 1 )
{
if( i != 1 )
__fastfail(0xEu);
__fastfail(0xEu);
}
v16 = v14;
v14 = _InterlockedCompareExchange64((volatile signed __int64 *)(v4 + 16), i, v14);
if( v16 == v14 )
break;
}
}
}
if( v8 )
VrpRelinquishDiffHiveEntryTransitionOwner(v4);
}
else
{
v10 = 0;
}
v12 = _InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64);
if( (v12 & 2) != 0 && (v12 & 4) == 0 )
ExfTryToWakePushLock((volatile INT64 *)(v4 + 24));
KeAbPostRelease((PVOID)(v4 + 24));
KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
VrpDereferenceDiffHiveEntry((PVOID)v4);
return v10;
}Referenced by:
VrpCleanupNamespace
VrpHandleIoctlLoadDifferencingHive
VrpHandleIoctlUnloadDifferencingHiveForHost