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