CmpPerformUnloadKey
INT64 __fastcall CmpPerformUnloadKey(INT64 a1, CHAR a2, CHAR r8_0, VOID *a4){
UINT64 v7;
int v8;
__int64 v9;
int v10;
INT64 v11;
__int64 v12;
__int64 v14;
int v15;
INT64 v16;
int v17;
char v18;
PVOID **v19;
_CM_RM *v20;
INT64 v21;
INT64 v22;
void *v23;
char v24;
void *v25;
int v26[8];
char v27;
int v28;
INT64 v29[2];
LIST_ENTRY DeferredPostAsync;
INT64 a3[2];
VOID *v32;
INT64 v33[2];
__int128 v34;
KAPC_STATE ApcState;
v32 = a4;
v27 = 0;
DeferredPostAsync.Blink = &DeferredPostAsync;
DeferredPostAsync.Flink = &DeferredPostAsync;
*(_OWORD *)v33 = 0i64;
WORD1(v33[0]) = -1;
memset(&ApcState, 0, sizeof(ApcState));
*(_OWORD *)a3 = 0i64;
*(_OWORD *)v29 = 0i64;
v34 = 0i64;
CmpInitializeDelayDerefContext(a3);
LOCK_HIVE_LOAD();
CmpLockRegistryFreezeAware(1u);
v7 = *(_QWORD *)(a1 + 8);
v8 = 6;
v28 = 6;
v9 = *(_QWORD *)(v7 + 32);
if( (*(_DWORD *)(v7 + 8) & 0x80u) != 0 )
goto LABEL_56;
v10 = CmpPerformKeyBodyDeletionCheck(a1, 0i64);
if( v10 < 0 )
goto LABEL_48;
if( (*(_DWORD *)(v7 + 8) & 0x40000) != 0 )
{
v10 = -1073740763;
goto LABEL_48;
}
if( *(_BYTE *)(v9 + 2936) && ((a2 & 1) == 0 || (*(_DWORD *)(v9 + 4152) & 0x20) == 0) )
{
v10 = -1073741431;
goto LABEL_48;
}
if( (int)CmpStartKcbStackForTopLayerKcb((INT64)v33, v7) < 0 )
{
v10 = -1073741670;
goto LABEL_48;
}
CmpReportNotifyForKcbStack((INT64)v33, 0i64, 4i64, &DeferredPostAsync);
CmpFlushNotify((_CM_KEY_BODY *)a1, 1u, &DeferredPostAsync);
v12 = *(_QWORD *)(v7 + 32);
if( v12 == CmpMasterHive || (*(_DWORD *)(v7 + 184) & 0x40000) == 0 )
{
v10 = -1073741811;
goto LABEL_48;
}
if( (*(_DWORD *)(v12 + 4152) & 4) != 0 )
{
LABEL_56:
v10 = -1073741790;
goto LABEL_48;
}
if( (a2 & 1) == 0 )
{
if( CmpDoesKeyHaveOpenSubkeys(v7) || *(_QWORD *)v7 != 2i64 )
{
if( r8_0 )
{
v10 = CmpFreezeHive(v7, v32);
if( v10 >= 0 )
{
v10 = 259;
goto LABEL_14;
}
goto LABEL_48;
}
goto LABEL_47;
}
goto LABEL_27;
}
v14 = *(_QWORD *)(v7 + 192);
if( v14 && *(_QWORD *)(v14 + 32) != v14 + 32 )
{
CmpLogUnsupportedOperation(3i64);
LABEL_47:
v10 = -1073741535;
goto LABEL_48;
}
v15 = CmpTryAcquireKcbIXLocks(v7, 1, v11, (UINT64 *)v29);
v10 = v15;
if( v15 == -1073741267 )
{
LABEL_63:
CmpLogTransactionAbortedForRollbackPacket(v7, 10i64, (UINT64 *)v29, v16);
CmpUnlockRegistry();
UNLOCK_HIVE_LOAD();
v8 = 0;
v28 = 0;
v10 = CmpAbortRollbackPacket((INT64)v29);
if( v10 >= 0 )
v10 = -1073741267;
v18 = 0;
goto LABEL_49;
}
if( v15 < 0 )
{
LABEL_48:
v18 = v27;
goto LABEL_49;
}
v17 = CmpPrepareForSubtreeInvalidation(v7, (INT64)v29);
v10 = v17;
if( v17 == -1073741267 )
goto LABEL_63;
if( v17 < 0 )
goto LABEL_48;
CmpInvalidateSubtree(v7, 1i64, (INT64)a3, 0i64);
CmpFlushNotifiesOnKeyBodyList(v7, 1i64, (INT64)a3, 1);
LABEL_27:
*(_DWORD *)(v7 + 8) |= 0x40000u;
v18 = 1;
if( *(_BYTE *)(v9 + 2936) == 1 )
{
CmpUnfreezeHive((PVOID)v9);
++CmpActiveAppHiveUnloadCount;
}
CmpDrainDelayDerefContext((UINT64 **)a3);
CmpUnlockRegistry();
UNLOCK_HIVE_LOAD();
_InterlockedIncrement(&CmpActiveHiveRundownCount);
ExWaitForRundownProtectionRelease((EX_RUNDOWN_REF *)(v9 + 1632));
ExRundownCompleted((EX_RUNDOWN_REF *)(v9 + 1632));
LOCK_HIVE_LOAD();
CmpLockRegistryFreezeAware(1u);
v20 = *(_CM_RM **)(v9 + 4192);
if( !v20 )
goto LABEL_30;
v10 = CmSnapshotRMTxArray(v20, (UINT64 *)v29, v19);
if( v10 >= 0 )
{
CmpLogTransactionAbortedForRollbackPacket(v7, 9i64, (UINT64 *)v29, v22);
CmpUnlockRegistry();
UNLOCK_HIVE_LOAD();
v8 = 0;
v28 = 0;
v10 = CmpAbortRollbackPacket((INT64)v29);
if( v10 < 0 )
goto LABEL_49;
CmpCleanupRollbackPacket((INT64)v29);
*(_OWORD *)v29 = 0i64;
LOCK_HIVE_LOAD();
v23 = (void *)CmCloseRmHandle(*(_QWORD *)(v9 + 4192), 0);
v25 = (void *)CmCloseTmHandle(*(_QWORD *)(v9 + 4192), v24);
UNLOCK_HIVE_LOAD();
if( v23 )
ZwClose(v23);
if( v25 )
ZwClose(v25);
LOCK_HIVE_LOAD();
CmShutdownCmRM(*(_CM_RM **)(v9 + 4192), 1u);
CmpLockRegistryFreezeAware(1u);
v28 = 6;
LABEL_30:
CmpAttachToRegistryProcess(&ApcState);
CmpCompleteUnloadKey(v7, v21, &v28);
CmpDetachFromRegistryProcess(&ApcState);
v10 = 0;
goto LABEL_31;
}
v8 = v28;
LABEL_49:
if( (v8 & 4) == 0 )
{
LOCK_HIVE_LOAD();
v8 |= 4u;
v28 = v8;
}
if( (v8 & 2) == 0 )
{
CmpLockRegistryFreezeAware(1u);
v8 |= 2u;
v28 = v8;
}
if( v18 )
{
_InterlockedExchange64((volatile __int64 *)(v9 + 1632), 0i64);
*(_DWORD *)(v7 + 8) &= ~0x40000u;
LABEL_31:
if( _InterlockedExchangeAdd(&CmpActiveHiveRundownCount, 0xFFFFFFFF) == 1 )
{
_InterlockedOr(v26, 0);
if( CmpActiveHiveRundownEvent.0 )
ExfUnblockPushLock(&CmpActiveHiveRundownEvent, 0i64);
}
LOBYTE(v8) = v28;
}
LABEL_14:
if( (v8 & 2) != 0 )
CmpUnlockRegistry();
if( (v8 & 4) != 0 )
UNLOCK_HIVE_LOAD();
if( DeferredPostAsync.Flink != &DeferredPostAsync )
CmpSignalDeferredPosts(&DeferredPostAsync);
CmpCleanupKcbStack((INT64)v33);
CmpCleanupRollbackPacket((INT64)v29);
return(unsigned int)v10;
}Referenced by:
CmUnloadKey