HvpDoAllocateCell

INT64 __fastcall HvpDoAllocateCell(
        _HHIVE *Hive,
        UINT64 NewSize,
        HSTORAGE_TYPE Type,
        VOID **CellAddress,
        _HV_GET_CELL_CONTEXT *CellAddressContext){
  VOID **v5; 
  unsigned int v7; 
  __int64 v8; 
  _CMSI_RW_LOCK *p_WriterLock; 
  unsigned int FreeCell; 
  wchar_t *Name; 
  char v13; 
  unsigned int v14; 
  unsigned int v15; 
  INT64 v16; 
  unsigned int v17; 
  unsigned int v18; 
  unsigned int v19; 
  unsigned int v20; 
  unsigned int v22; 
  unsigned int v23; 
  int v24; 
  _CELL_DATA *v25; 
  _HCELL **pCell; 
  _HV_GET_CELL_CONTEXT pCellContext; 
  INT64 v28; 
  v28 = 0i64;
  pCellContext.Cell = -1;
  v5 = CellAddress;
  v7 = ((unsigned int)NewSize >> 3) - 1;
  v8 = (unsigned int)NewSize;
  *(_DWORD *)&pCellContext.BinContext = 0;
  if( v7 >= 0x10 )
  {
    v22 = v7 >> 4;
    if( v22 > 0xFF )
    {
      v7 = 23;
    }
    else
    {
      _BitScanReverse(&v23, v22);
      v7 = v23 + 16;
    }
  }
  p_WriterLock = &Hive->WriterLock;
  ExAcquirePushLockExclusiveEx((UINT64)&Hive->WriterLock, 0i64);
  FreeCell = HvpFindFreeCell(Hive, v7, (unsigned int)v8, Type, (_HCELL **)&v28, &pCellContext);
  if( FreeCell != -1 )
  {
    Name = (wchar_t *)v28;
    v13 = 0;
    goto LABEL_4;
  }
  v24 = HvpAddBin(Hive, (unsigned int)v8, Type);
  if( v24 != -1 )
  {
    FreeCell = v24 + 32;
    v25 = Hive->GetCellRoutine(Hive, (unsigned int)(v24 + 32), &pCellContext);
    if( v25 )
    {
      Name = v25[-1].u.KeyNode.Name;
      v28 = (INT64)&v25[-1].u.KeyString[38];
      if( v25 != (_CELL_DATA *)4 )
      {
        v13 = 1;
LABEL_4:
        v14 = *(_DWORD *)Name;
        if( (unsigned int)(v8 + 8) > *(_DWORD *)Name )
        {
          HvpDelistFreeCell(Hive, FreeCell, Type);
          *(_DWORD *)Name = -*(_DWORD *)Name;
          goto LABEL_14;
        }
        v15 = v14 - v8;
        *(_DWORD *)((char *)Name + v8) = v14 - v8;
        *(_DWORD *)Name = -(int)v8;
        if( !v13 )
        {
          v16 = (v14 >> 3) - 1;
          if( (unsigned int)v16 >= 0x10 )
          {
            v17 = (unsigned int)v16 >> 4;
            if( v17 > 0xFF )
            {
              v16 = 23i64;
            }
            else
            {
              _BitScanReverse(&v18, v17);
              v16 = v18 + 16;
            }
          }
          v19 = (v15 >> 3) - 1;
          if( v19 >= 0x10 )
          {
            v20 = v19 >> 4;
            if( v20 > 0xFF )
            {
              v19 = 23;
            }
            else
            {
              _BitScanReverse(&v20, v20);
              v19 = v20 + 16;
            }
          }
          if( (_DWORD)v16 == v19 )
            goto LABEL_13;
          LODWORD(pCell) = 0;
          HvpRemoveFreeCellHint((UINT64)Hive, FreeCell, v16, (unsigned int)Type, (INT64)pCell);
        }
        HvpEnlistFreeCell((ULONG_PTR)Hive);
LABEL_13:
        v5 = CellAddress;
LABEL_14:
        if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_WriterLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock((volatile INT64 *)p_WriterLock);
        KeAbPostRelease(p_WriterLock);
        if( v5 )
        {
          *v5 = (VOID *)(v28 + 4);
          *CellAddressContext = pCellContext;
        }
        else
        {
          Hive->ReleaseCellRoutine(Hive, &pCellContext);
        }
        return FreeCell;
      }
    }
  }
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)p_WriterLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)p_WriterLock);
  KeAbPostRelease(p_WriterLock);
  return 0xFFFFFFFFi64;
}

Referenced by:

HvAllocateCell
HvReallocateCell