HvFreeCell

VOID __stdcall HvFreeCell(ULONG_PTR Hive, ULONG_PTR Cell){
  _EX_PUSH_LOCK *v2; 
  void *v3; 
  _HHIVE *v4; 
  __int64 v5; 
  _HMAP_ENTRY *CellMap; 
  _HMAP_ENTRY *v7; 
  unsigned __int64 PermanentBinAddress; 
  unsigned int v9; 
  _HBIN *v10; 
  _HCELL *v11; 
  unsigned int v12; 
  _HCELL *v13; 
  int Size; 
  __int64 v15; 
  int v16; 
  int v17; 
  __int64 v18; 
  UINT64 v19; 
  unsigned int v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  _HMAP_ENTRY *v24; 
  int v25; 
  UINT8 Type; 
  int Cella[18]; 
  _HCELL *FreeNeighbor; 
  int v29; 

  FreeNeighbor = 0i64;
  v2 = (_EX_PUSH_LOCK *)(*(_QWORD *)&Hive + 80i64);
  v3 = (void *)Cell;
  v4 = *(_HHIVE **)&Hive;
  v5 = 0i64;
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(*(_QWORD *)&Hive + 80i64), 0i64);
  CellMap = HvpGetCellMap(v4, (unsigned int)v3);
  v7 = CellMap;
  if( !CellMap )
    KeBugCheckEx(0x51u, (PVOID)1, v4, v3, (PVOID)0x629);
  PermanentBinAddress = CellMap->PermanentBinAddress;
  v9 = (unsigned int)v3 >> 31;
  v10 = (_HBIN *)(PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64);
  if( (PermanentBinAddress & 4) != 0 )
  {
    v22 = *(_DWORD *)((PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64) + 4);
    v23 = v22 + *(_DWORD *)((PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64) + 8);
    while( v22 < v23 )
    {
      v24 = HvpGetCellMap(v4, v22);
      v24->PermanentBinAddress &= ~4ui64;
      v22 = v25 + 4096;
    }
  }
  v11 = (_HCELL *)((char *)v10 + v7->BlockOffset + ((unsigned __int16)v3 & 0xFFF));
  v11->Size = -v11->Size;
  do
  {
    if( HvpIsFreeNeighbor((ULONG_PTR)v4, v10, v11, &FreeNeighbor, (unsigned int)v3 >> 31) != 1 )
      break;
    v13 = FreeNeighbor;
    Size = v11->Size;
    v15 = (unsigned int)v5;
    v5 = (unsigned int)(v5 + 1);
    v16 = FreeNeighbor->Size;
    if( FreeNeighbor <= v11 )
    {
      FreeNeighbor->Size = v16 + Size;
      v17 = (_DWORD)v3 - v16;
      v11 = v13;
    }
    else
    {
      v11->Size = Size + v16;
      v17 = Size + (_DWORD)v3;
    }
    *(&v29 + v15) = v16;
    Cella[v15] = v17;
  }
  while( (unsigned int)v5 < 2 );
  v12 = (_DWORD)v11 + v10->FileOffset + (v9 << 31) - (_DWORD)v10;
  if( (_DWORD)v5 )
  {
    v18 = 0i64;
    do
    {
      v19 = (*(unsigned int *)((char *)&v29 + v18 * 4) >> 3) - 1;
      if( (unsigned int)v19 >= 0x10 )
      {
        v20 = (unsigned int)v19 >> 4;
        if( v20 > 0xFF )
        {
          v19 = 23i64;
        }
        else
        {
          _BitScanReverse(&v21, v20);
          v19 = v21 + 16;
        }
      }
      Type = v12;
      HvpRemoveFreeCellHint(v4, (unsigned int)Cella[v18++], v19, v9);
      --v5;
    }
    while( v5 );
  }
  HvpEnlistFreeCell(v4, v12, (unsigned int)v11->Size, v9, Type);
  if( (_InterlockedExchangeAdd64(&v2->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(v2);
  KeAbPostRelease(v2);
}

Referenced by:

CmDeleteValueKey
CmRenameKey
CmSetValueKey
CmpAddSubKeyEx
CmpAddToLeaf
CmpAddValueKeyNew
CmpCommitRenameKeyUoW
CmpCommitSetSecurityUoW
CmpCopyKeyPartial
CmpCopyValue
CmpCreateChild
CmpCreateHiveRootCell
CmpDereferenceSecurityNode
CmpDuplicateIndex
CmpFreeIndexByCell
CmpFreeKeyBody
CmpFreeKeyByCell
CmpFreeKeyValueList
CmpFreeKeyValues
CmpFreeSecurityDescriptor
CmpFreeValue
CmpFreeValueData
CmpFullPromoteSingleKeyFromKeyNodeStacks
CmpGetSecurityDescriptorNode
CmpLightWeightCleanupSetValueKeyUoW
CmpLightWeightCommitRenameKeyUoW
CmpLightWeightCommitSetSecDescUoW
CmpLightWeightCreateSetValueData
CmpRemoveSubKeyCellNoCellRef
CmpRemoveSubKeyFromList
CmpRemoveValueFromList
CmpSetSecurityDescriptorInfo
CmpSetValueDataExisting
CmpSetValueDataNew
CmpSetValueKeyExisting
CmpSplitLeaf
CmpSyncKeyValues
CmpTransMgrFreeVolatileData
HvReallocateCell