CmpPromoteKey

__int64 __fastcall CmpPromoteKey(__int64 a1, char a2, char a3){
  INT16 v3; 
  INT16 v4; 
  int started; 
  bool v6; 
  unsigned int v7; 
  _PRIVILEGE_SET *TransientPoolWithTag; 
  _PRIVILEGE_SET *v9; 
  __int64 v10; 
  __int64 i; 
  INT64 *v12; 
  INT64 *v13; 
  INT64 v14; 
  int v15; 
  _EX_PUSH_LOCK *v16; 
  __int64 v17; 
  INT64 v18; 
  int v19; 
  char v20; 
  int v21; 
  _EX_PUSH_LOCK *v22; 
  INT64 *v23; 
  INT64 v25[2]; 
  PPRIVILEGE_SET v26[2]; 
  INT64 v27[2]; 
  PPRIVILEGE_SET v28[2]; 
  INT64 KcbAtLayerHeight; 
  _PRIVILEGE_SET *Privileges; 

  v3 = *(_WORD *)(a1 + 2);
  *(_OWORD *)v25 = 0i64;
  WORD1(v25[0]) = -1;
  *(_OWORD *)v27 = 0i64;
  WORD1(v27[0]) = -1;
  *(_OWORD *)v26 = 0i64;
  *(_OWORD *)v28 = 0i64;
  KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a1, v3);
  started = CmpStartKcbStack((INT64)v25, v4);
  if( started < 0 )
    goto LABEL_33;
  started = CmpStartKcbStack((INT64)v27, v3);
  if( started < 0 )
    goto LABEL_33;
  v6 = 1;
  v7 = ((*(_DWORD *)(KcbAtLayerHeight + 8) >> 21) & 0x3FF) + 1;
  TransientPoolWithTag = (_PRIVILEGE_SET *)CmpAllocateTransientPoolWithTag(1ui64, 8i64 * v7);
  Privileges = TransientPoolWithTag;
  v9 = TransientPoolWithTag;
  if( !TransientPoolWithTag )
  {
    started = -1073741670;
    goto LABEL_33;
  }
  memset(TransientPoolWithTag, 0i64, 8 * v7);
  LODWORD(v10) = v7;
  for( i = KcbAtLayerHeight; (*(_DWORD *)(i + 184) & 0x40000) == 0; i = *(_QWORD *)(i + 72) )
  {
    v10 = (*(_DWORD *)(i + 8) >> 21) & 0x3FF;
    *((_QWORD *)&v9->PrivilegeCount + v10) = i;
  }
  v12 = v25;
  v13 = v27;
  CmpPopulateKcbStack((__int64)v27, i);
  CmpLockKcbStackTopExclusiveRestShared((INT64)v27);
  v14 = KcbAtLayerHeight;
  if( i == KcbAtLayerHeight )
  {
    if( a2 )
    {
      ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(*(_QWORD *)(i + 32) + 72i64), 0i64);
      v15 = CmpFullPromoteHiveRootFromKcbStack((__int64)v27);
      v16 = *(_EX_PUSH_LOCK **)(i + 32);
      started = v15;
      if( _InterlockedCompareExchange64(&v16[9]._bf_0, 0i64, 17i64) != 17 )
        ExfReleasePushLockShared(v16 + 9);
      KeAbPostRelease(&v16[9]);
      if( started < 0 )
        goto LABEL_31;
    }
LABEL_29:
    started = 0;
    v6 = a3 == 0;
    goto LABEL_30;
  }
  if( (unsigned int)v10 >= v7 )
    goto LABEL_29;
  while( 1 )
  {
    v17 = *((_QWORD *)&Privileges->PrivilegeCount + (unsigned int)v10);
    CmpPopulateKcbStack((__int64)v12, v17);
    CmpLockKcbStackTopExclusiveRestShared(v18);
    if( CmpIsKeyStackDeleted((INT64)v12, 0i64) )
      break;
    v19 = *(_DWORD *)(v17 + 40);
    if( v17 == v14 )
    {
      if( v19 != -1 && !a2 )
        goto LABEL_25;
      ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(*(_QWORD *)(v17 + 32) + 72i64), 0i64);
      v20 = a2;
    }
    else
    {
      if( v19 != -1 )
        goto LABEL_25;
      ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(*(_QWORD *)(v17 + 32) + 72i64), 0i64);
      v20 = 0;
    }
    v21 = CmpPromoteSingleKeyFromKcbStacks((__int64)v13, (__int64)v12, v20);
    v22 = *(_EX_PUSH_LOCK **)(v17 + 32);
    started = v21;
    if( _InterlockedCompareExchange64(&v22[9]._bf_0, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared(v22 + 9);
    KeAbPostRelease(&v22[9]);
    if( started < 0 )
      goto LABEL_28;
    v14 = KcbAtLayerHeight;
LABEL_25:
    CmpUnlockKcbStack((INT64)v13);
    v23 = v12;
    LODWORD(v10) = v10 + 1;
    v12 = v13;
    v13 = v23;
    if( (unsigned int)v10 >= v7 )
      goto LABEL_29;
  }
  started = -1073741444;
LABEL_28:
  CmpUnlockKcbStack((INT64)v12);
LABEL_30:
  if( v6 )
LABEL_31:
    CmpUnlockKcbStack((INT64)v13);
  CmSiFreeMemory(Privileges);
LABEL_33:
  if( v26[1] )
    CmSiFreeMemory(v26[1]);
  if( v28[1] )
    CmSiFreeMemory(v28[1]);
  return(unsigned int)started;
}

Referenced by:

CmDeleteLayeredKey
CmDeleteValueKey
CmRenameKey
CmSetKeyFlags
CmSetLastWriteTimeKey
CmSetValueKey
CmpDoParseKey
CmpSetKeySecurity