CmpCompleteUnloadKey

UINT8 __fastcall CmpCompleteUnloadKey(UINT64 a1, INT64 a2, _DWORD *a3){
  ULONG_PTR v3; 
  __int64 v6; 
  int v7; 
  __int64 v8; 
  UINT64 v9; 
  UNICODE_STRING *v10; 
  UINT8 v11; 
  _ETHREAD *CurrentThread; 
  EVENT_DESCRIPTOR *v13; 
  int v14; 
  unsigned int v15; 
  EVENT_DESCRIPTOR *v16; 
  struct _PRIVILEGE_SET *v17; 
  unsigned int v18; 
  UINT64 v19; 
  UINT8 result; 
  unsigned int v21; 
  __int64 v22; 
  _QWORD *v23; 
  __int64 v24; 
  int v25; 
  unsigned int v26; 
  unsigned int v27; 
  __int64 v28; 
  unsigned int v29; 
  unsigned __int64 v30; 
  __int64 v31; 
  __int64 v32; 
  int v33[8]; 
  __int16 v34; 
  int v35; 
  INT64 a1a[2]; 
  EVENT_DESCRIPTOR EventDescriptor; 
  EVENT_DESCRIPTOR v38; 
  EVENT_DATA_DESCRIPTOR v39; 
  EVENT_DATA_DESCRIPTOR UserData[4]; 
  v3 = *(_QWORD *)(a1 + 32);
  *(_OWORD *)a1a = 0i64;
  CmpInitializeDelayDerefContext(a1a);
  v6 = 1i64;
  v7 = *(_DWORD *)(v3 + 4152) & 0x20;
  *(_DWORD *)(v3 + 4i64 * (_InterlockedExchangeAdd((volatile signed __int32 *)(v3 + 4276), 1u) & 0x7F) + 4280) = 6;
  _InterlockedCompareExchange64((volatile signed __int64 *)(v3 + 2944), 1i64, 0i64);
  v8 = *(_QWORD *)(v3 + 4192);
  if( v8 )
  {
    v24 = *(_QWORD *)(v3 + 64);
    v25 = *(_DWORD *)(v24 + 144);
    if( *(_QWORD *)(v8 + 16) == v8 + 16 )
      v26 = v25 & 0xFFFFFFFE;
    else
      v26 = v25 | 1;
    *(_DWORD *)(v24 + 144) = v26;
    HvMarkBaseBlockDirty((_HHIVE *)v3);
  }
  *(_DWORD *)(v3 + 160) |= 0x40u;
  v9 = EtwpRegTraceHandle;
  v34 = 0;
  EventDescriptor = (EVENT_DESCRIPTOR)REGISTRY_PERF_EVENT_HIVE_UNLOAD_START;
  if( EtwEventEnabled(EtwpRegTraceHandle, &EventDescriptor, (EVENT_DESCRIPTOR *)v6) )
  {
    v27 = 0;
    if( *(_QWORD *)(v3 + 1840) )
    {
      UserData[0].Ptr = *(_QWORD *)(v3 + 1840);
      v27 = 1;
      UserData[0].Size = *(unsigned __int16 *)(v3 + 1832);
      UserData[0].Reserved = 0;
    }
    v28 = v27;
    v29 = v27 + 1;
    UserData[v28].Ptr = (unsigned __int64)&v34;
    *(_QWORD *)&UserData[v28].Size = 2i64;
    v30 = *(_QWORD *)(v3 + 1856);
    if( v30 )
    {
      v31 = v29++;
      UserData[v31].Ptr = v30;
      UserData[v31].Size = *(unsigned __int16 *)(v3 + 1848);
      UserData[v31].Reserved = 0;
    }
    v32 = v29;
    UserData[v32].Ptr = (unsigned __int64)&v34;
    *(_QWORD *)&UserData[v32].Size = 2i64;
    EtwWrite(v9, &EventDescriptor, 0i64, v29 + 1, UserData);
  }
  CmpRemoveHiveFromNamespace((_CMHIVE *)v3, (_CM_KEY_CONTROL_BLOCK *)a1);
  *(_DWORD *)(v3 + 4i64 * (_InterlockedExchangeAdd((volatile signed __int32 *)(v3 + 4276), 1u) & 0x7F) + 4280) = 8;
  if( v7 )
  {
    *(_DWORD *)(v3 + 4808) = 1;
    CmpDecrementAppHiveUnloadCount();
  }
  CmpFlushNotifiesOnKeyBodyList(a1, 1i64, (INT64)a1a, 0);
  CmpMarkKeyUnbacked((_CM_KEY_CONTROL_BLOCK *)a1);
  CmpDiscardKcb(a1, (INT64)a1a);
  LOBYTE(v10) = 1;
  CmpCleanUpSubKeyInfo(*(UNICODE_STRING **)(*(_QWORD *)(a1 + 72) + 72i64), v10, v11);
  CmpDrainDelayDerefContext((UINT64 **)a1a);
  CmpUnlockRegistry();
  *a3 &= ~2u;
  if( (*a3 & 4) != 0 )
  {
    UNLOCK_HIVE_LOAD();
    *a3 &= ~4u;
  }
  ZwDeleteValueKey(CmpHiveFileListHandle, (UNICODE_STRING *)(v3 + 1848));
  CmpDestroySecurityCache(v3);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  CmpUnJoinClassOfTrust(v3);
  KeLeaveCriticalRegion();
  if( (*(_DWORD *)(v3 + 160) & 0x400) != 0 )
  {
    v22 = *(_QWORD *)(v3 + 1616);
    if( *(_QWORD *)(v22 + 8) != v3 + 1616 || (v23 = *(_QWORD **)(v3 + 1624), *v23 != v3 + 1616) )
      __fastfail(3u);
    *v23 = v22;
    *(_QWORD *)(v22 + 8) = v23;
  }
  CmpVERemoveHiveFromSIDMappingTable(v3);
  v14 = CmpFlushHive(v3, 44, v13);
  if( v14 == -1073741811 )
    v14 = 0;
  v15 = *(_DWORD *)(v3 + 272) + 4096;
  HvHiveCleanup(v3);
  if( v14 >= 0 && (*(_DWORD *)(v3 + 160) & 0x8000) == 0 && (__int64)(*(_QWORD *)(v3 + 1792) - v15) > 0x100000 )
    CmpDoFileSetSizeEx(v3, 0i64, v15, 0);
  CmpCmdHiveClose(v3);
  v17 = *(struct _PRIVILEGE_SET **)(v3 + 4832);
  if( v17 )
    CmpVolumeContextDecrementRefCount(v17);
  if( v7 )
  {
    *(_DWORD *)(v3 + 4808) = 0;
    _InterlockedOr(v33, 0);
    if( *(_QWORD *)(v3 + 4816) )
      ExfUnblockPushLock((_EX_PUSH_LOCK *)(v3 + 4816), 0i64);
  }
  v18 = 0;
  if( *(_DWORD *)(v3 + 2912) )
  {
    do
    {
      KeSetEvent(*(PRKEVENT *)(*(_QWORD *)(v3 + 2920) + 8i64 * v18), 0);
      HalPutDmaAdapter(*(PADAPTER_OBJECT *)(*(_QWORD *)(v3 + 2920) + 8i64 * v18));
      v21 = *(_DWORD *)(v3 + 2912);
      ++v18;
    }
    while( v18 < v21 );
    if( v21 )
      ExFreePoolWithTag(*(PVOID *)(v3 + 2920), 0);
  }
  v19 = EtwpRegTraceHandle;
  v35 = v14;
  v38 = (EVENT_DESCRIPTOR)REGISTRY_PERF_EVENT_HIVE_UNLOAD_STOP;
  result = EtwEventEnabled(EtwpRegTraceHandle, &v38, v16);
  if( result )
  {
    *(_QWORD *)&v39.Size = 4i64;
    v39.Ptr = (unsigned __int64)&v35;
    return EtwWrite(v19, &v38, 0i64, 1ui64, &v39);
  }
  return result;
}

Referenced by:

CmpLateUnloadHiveWorker
CmpPerformUnloadKey