CmpPerformUnloadKey

__int64 __fastcall CmpPerformUnloadKey(__int64 a1, char a2, char a3, void *a4){
  UINT64 v7; 
  int v8; 
  _CMHIVE *v9; 
  int v10; 
  __int64 v11; 
  INT64 v12; 
  __int64 v13; 
  __int64 v15; 
  int v16; 
  __int64 v17; 
  int v18; 
  char v19; 
  PVOID **v20; 
  CM_RM *CmRm; 
  INT64 v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25; 
  UINT8 v26; 
  __int64 v27; 
  __int64 v28; 
  int v29[8]; 
  char v30; 
  int a3a; 
  UINT64 pCount[2]; 
  LIST_ENTRY DeferredPostAsync; 
  INT64 a1a[2]; 
  VOID *v35; 
  INT64 v36[2]; 
  __int128 v37; 
  _KAPC_STATE ApcState; 

  v35 = a4;
  v30 = 0;
  DeferredPostAsync.Blink = &DeferredPostAsync;
  DeferredPostAsync.Flink = &DeferredPostAsync;
  *(_OWORD *)v36 = 0i64;
  WORD1(v36[0]) = -1;
  memset(&ApcState, 0, sizeof(ApcState));
  *(_OWORD *)a1a = 0i64;
  *(_OWORD *)pCount = 0i64;
  v37 = 0i64;
  CmpInitializeDelayDerefContext(a1a);
  LOCK_HIVE_LOAD();
  CmpLockRegistryFreezeAware(1u);
  v7 = *(_QWORD *)(a1 + 8);
  v8 = 6;
  a3a = 6;
  v9 = *(_CMHIVE **)(v7 + 32);
  if( (*(_DWORD *)(v7 + 8) & 0x80u) != 0 )
    goto LABEL_56;
  v10 = CmpPerformKeyBodyDeletionCheck((CM_KEY_BODY *)a1, 0i64);
  if( v10 < 0 )
    goto LABEL_48;
  if( (*(_DWORD *)(v7 + 8) & 0x40000) != 0 )
  {
    v10 = -1073740763;
    goto LABEL_48;
  }
  if( v9->Frozen && ((a2 & 1) == 0 || (v9->Flags & 0x20) == 0) )
  {
    v10 = -1073741431;
    goto LABEL_48;
  }
  if( (int)CmpStartKcbStackForTopLayerKcb((INT64)v36, v7) < 0 )
  {
    v10 = -1073741670;
    goto LABEL_48;
  }
  CmpReportNotifyForKcbStack((INT64)v36, 0i64, 4i64, &DeferredPostAsync);
  LOBYTE(v11) = 1;
  CmpFlushNotify(a1, v11, (__int128 *)&DeferredPostAsync);
  v13 = *(_QWORD *)(v7 + 32);
  if( v13 == *(_QWORD *)&CmpMasterHive || (*(_DWORD *)(v7 + 184) & 0x40000) == 0 )
  {
    v10 = -1073741811;
    goto LABEL_48;
  }
  if( (*(_DWORD *)(v13 + 4152) & 4) != 0 )
  {
LABEL_56:
    v10 = -1073741790;
    goto LABEL_48;
  }
  if( (a2 & 1) == 0 )
  {
    if( CmpDoesKeyHaveOpenSubkeys(v7) || *(_QWORD *)v7 != 2i64 )
    {
      if( a3 )
      {
        v10 = CmpFreezeHive(v7, v35);
        if( v10 >= 0 )
        {
          v10 = 259;
          goto LABEL_14;
        }
        goto LABEL_48;
      }
      goto LABEL_47;
    }
    goto LABEL_27;
  }
  v15 = *(_QWORD *)(v7 + 192);
  if( v15 && *(_QWORD *)(v15 + 32) != v15 + 32 )
  {
    CmpLogUnsupportedOperation(3);
LABEL_47:
    v10 = -1073741535;
    goto LABEL_48;
  }
  v16 = CmpTryAcquireKcbIXLocks(v7, 1, v12, pCount);
  v10 = v16;
  if( v16 == -1073741267 )
  {
LABEL_63:
    CmpLogTransactionAbortedForRollbackPacket(v7, 10, (unsigned int *)pCount, v17);
    CmpUnlockRegistry();
    UNLOCK_HIVE_LOAD();
    v8 = 0;
    a3a = 0;
    v10 = CmpAbortRollbackPacket((INT64)pCount);
    if( v10 >= 0 )
      v10 = -1073741267;
    v19 = 0;
    goto LABEL_49;
  }
  if( v16 < 0 )
  {
LABEL_48:
    v19 = v30;
    goto LABEL_49;
  }
  v18 = CmpPrepareForSubtreeInvalidation(v7, (__int64)pCount);
  v10 = v18;
  if( v18 == -1073741267 )
    goto LABEL_63;
  if( v18 < 0 )
    goto LABEL_48;
  CmpInvalidateSubtree(v7, 1i64, (INT64)a1a, 0i64);
  CmpFlushNotifiesOnKeyBodyList(v7, 1i64, (__int64)a1a, 1);
LABEL_27:
  *(_DWORD *)(v7 + 8) |= 0x40000u;
  v19 = 1;
  if( v9->Frozen == 1 )
  {
    CmpUnfreezeHive(v9);
    ++*(&CmpDummyThreadEvent + 222);
  }
  CmpDrainDelayDerefContext((UINT64 **)a1a);
  CmpUnlockRegistry();
  UNLOCK_HIVE_LOAD();
  _InterlockedIncrement((_DWORD *)&WheapErrorSourceTable + 95);
  ExWaitForRundownProtectionRelease(&v9->HiveRundown);
  ExRundownCompleted((INT64 *)&v9->HiveRundown);
  LOCK_HIVE_LOAD();
  CmpLockRegistryFreezeAware(1u);
  CmRm = v9->CmRm;
  if( !CmRm )
    goto LABEL_30;
  v10 = CmSnapshotRMTxArray(CmRm, pCount, v20);
  if( v10 >= 0 )
  {
    CmpLogTransactionAbortedForRollbackPacket(v7, 9, (unsigned int *)pCount, v23);
    CmpUnlockRegistry();
    UNLOCK_HIVE_LOAD();
    v8 = 0;
    a3a = 0;
    v10 = CmpAbortRollbackPacket((INT64)pCount);
    if( v10 < 0 )
      goto LABEL_49;
    CmpCleanupRollbackPacket((INT64)pCount);
    *(_OWORD *)pCount = 0i64;
    LOCK_HIVE_LOAD();
    LODWORD(v24) = CmCloseRmHandle(v9->CmRm, 0);
    v25 = v24;
    LODWORD(v27) = CmCloseTmHandle(v9->CmRm, v26);
    v28 = v27;
    UNLOCK_HIVE_LOAD();
    if( v25 )
      ZwClose(v25);
    if( v28 )
      ZwClose(v28);
    LOCK_HIVE_LOAD();
    CmShutdownCmRM((__int64)v9->CmRm, 1);
    CmpLockRegistryFreezeAware(1u);
    a3a = 6;
LABEL_30:
    CmpAttachToRegistryProcess(&ApcState);
    CmpCompleteUnloadKey(v7, v22, &a3a);
    CmpDetachFromRegistryProcess(&ApcState);
    v10 = 0;
    goto LABEL_31;
  }
  v8 = a3a;
LABEL_49:
  if( (v8 & 4) == 0 )
  {
    LOCK_HIVE_LOAD();
    v8 |= 4u;
    a3a = v8;
  }
  if( (v8 & 2) == 0 )
  {
    CmpLockRegistryFreezeAware(1u);
    v8 |= 2u;
    a3a = v8;
  }
  if( v19 )
  {
    _InterlockedExchange64((volatile __int64 *)&v9->HiveRundown, 0i64);
    *(_DWORD *)(v7 + 8) &= ~0x40000u;
LABEL_31:
    if( _InterlockedExchangeAdd((_DWORD *)&WheapErrorSourceTable + 95, 0xFFFFFFFF) == 1 )
    {
      _InterlockedOr(v29, 0);
      if( *(&CmpDummyThreadEvent + 133) )
        ExfUnblockPushLock((INT64 *)&CmpDummyThreadEvent + 133, 0i64);
    }
    LOBYTE(v8) = a3a;
  }
LABEL_14:
  if( (v8 & 2) != 0 )
    CmpUnlockRegistry();
  if( (v8 & 4) != 0 )
    UNLOCK_HIVE_LOAD();
  if( DeferredPostAsync.Flink != &DeferredPostAsync )
    CmpSignalDeferredPosts(&DeferredPostAsync);
  CmpCleanupKcbStack((INT64)v36);
  CmpCleanupRollbackPacket((INT64)pCount);
  return(unsigned int)v10;
}

Referenced by:

CmUnloadKey