ReactOS  0.4.15-dev-4920-g5fa8403
hivecell.c File Reference
#include "cmlib.h"
#include <debug.h>
Include dependency graph for hivecell.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define CELL_REF_INCREMENT   10
 

Functions

static __inline PHCELL CMAPI HvpGetCellHeader (PHHIVE RegistryHive, HCELL_INDEX CellIndex)
 
BOOLEAN CMAPI HvIsCellAllocated (IN PHHIVE RegistryHive, IN HCELL_INDEX CellIndex)
 
PCELL_DATA CMAPI HvpGetCellData (_In_ PHHIVE Hive, _In_ HCELL_INDEX CellIndex)
 
static __inline LONG CMAPI HvpGetCellFullSize (PHHIVE RegistryHive, PVOID Cell)
 
LONG CMAPI HvGetCellSize (IN PHHIVE Hive, IN PVOID Address)
 
BOOLEAN CMAPI HvMarkCellDirty (PHHIVE RegistryHive, HCELL_INDEX CellIndex, BOOLEAN HoldingLock)
 
BOOLEAN CMAPI HvIsCellDirty (IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
static __inline ULONG CMAPI HvpComputeFreeListIndex (ULONG Size)
 
static NTSTATUS CMAPI HvpAddFree (PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
 
static VOID CMAPI HvpRemoveFree (PHHIVE RegistryHive, PHCELL CellBlock, HCELL_INDEX CellIndex)
 
static HCELL_INDEX CMAPI HvpFindFree (PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
 
NTSTATUS CMAPI HvpCreateHiveFreeCellList (PHHIVE Hive)
 
HCELL_INDEX CMAPI HvAllocateCell (PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, HCELL_INDEX Vicinity)
 
HCELL_INDEX CMAPI HvReallocateCell (PHHIVE RegistryHive, HCELL_INDEX CellIndex, ULONG Size)
 
VOID CMAPI HvFreeCell (PHHIVE RegistryHive, HCELL_INDEX CellIndex)
 
BOOLEAN CMAPI HvTrackCellRef (IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
VOID CMAPI HvReleaseFreeCellRefArray (IN OUT PHV_TRACK_CELL_REF CellRef)
 

Macro Definition Documentation

◆ CELL_REF_INCREMENT

#define CELL_REF_INCREMENT   10

Definition at line 522 of file hivecell.c.

◆ NDEBUG

#define NDEBUG

Definition at line 9 of file hivecell.c.

Function Documentation

◆ HvAllocateCell()

HCELL_INDEX CMAPI HvAllocateCell ( PHHIVE  RegistryHive,
ULONG  Size,
HSTORAGE_TYPE  Storage,
HCELL_INDEX  Vicinity 
)

Definition at line 329 of file hivecell.c.

334 {
335  PHCELL FreeCell;
336  HCELL_INDEX FreeCellOffset;
337  PHCELL NewCell;
338  PHBIN Bin;
339 
340  ASSERT(RegistryHive->ReadOnly == FALSE);
341 
342  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, Size %x, %s, Vicinity %08lx\n",
343  __FUNCTION__, RegistryHive, Size, (Storage == 0) ? "Stable" : "Volatile", Vicinity);
344 
345  /* Round to 16 bytes multiple. */
346  Size = ROUND_UP(Size + sizeof(HCELL), 16);
347 
348  /* First search in free blocks. */
349  FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
350 
351  /* If no free cell was found we need to extend the hive file. */
352  if (FreeCellOffset == HCELL_NIL)
353  {
354  Bin = HvpAddBin(RegistryHive, Size, Storage);
355  if (Bin == NULL)
356  return HCELL_NIL;
357  FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
358  FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
359  }
360 
361  FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
362 
363  /* Split the block in two parts */
364 
365  /* The free block that is created has to be at least
366  sizeof(HCELL) + sizeof(HCELL_INDEX) big, so that free
367  cell list code can work. Moreover we round cell sizes
368  to 16 bytes, so creating a smaller block would result in
369  a cell that would never be allocated. */
370  if ((ULONG)FreeCell->Size > Size + 16)
371  {
372  NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
373  NewCell->Size = FreeCell->Size - Size;
374  FreeCell->Size = Size;
375  HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
376  if (Storage == Stable)
377  HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
378  }
379 
380  if (Storage == Stable)
381  HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
382 
383  FreeCell->Size = -FreeCell->Size;
384  RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
385 
386  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - CellIndex %08lx\n",
387  __FUNCTION__, FreeCellOffset);
388 
389  return FreeCellOffset;
390 }
PHBIN CMAPI HvpAddBin(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
Definition: hivebin.c:12
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
static HCELL_INDEX CMAPI HvpFindFree(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
Definition: hivecell.c:248
static NTSTATUS CMAPI HvpAddFree(PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
Definition: hivecell.c:174
#define HCELL_NIL
Definition: hivedata.h:85
BOOLEAN ReadOnly
Definition: hivedata.h:310
#define CMLTRACE(x,...)
Definition: cmlib.h:165
struct _HBIN HBIN
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define HCELL_TYPE_SHIFT
Definition: hivedata.h:91
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellIndex, BOOLEAN HoldingLock)
Definition: hivecell.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
#define FALSE
Definition: types.h:117
Definition: bin.h:43
#define ASSERT(a)
Definition: mode.c:44
ULONG HCELL_INDEX
Definition: hivedata.h:80
LONG Size
Definition: hivedata.h:190
#define NULL
Definition: types.h:112
static __inline PHCELL CMAPI HvpGetCellHeader(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:13
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _HCELL * PHCELL
#define __FUNCTION__
Definition: types.h:112
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvReallocateCell().

◆ HvFreeCell()

VOID CMAPI HvFreeCell ( PHHIVE  RegistryHive,
HCELL_INDEX  CellIndex 
)

Definition at line 440 of file hivecell.c.

443 {
444  PHCELL Free;
445  PHCELL Neighbor;
446  PHBIN Bin;
447  ULONG CellType;
448  ULONG CellBlock;
449 
450  ASSERT(RegistryHive->ReadOnly == FALSE);
451 
452  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
453  __FUNCTION__, RegistryHive, CellIndex);
454 
455  Free = HvpGetCellHeader(RegistryHive, CellIndex);
456 
457  ASSERT(Free->Size < 0);
458 
459  Free->Size = -Free->Size;
460 
461  CellType = HvGetCellType(CellIndex);
462  CellBlock = HvGetCellBlock(CellIndex);
463 
464  /* FIXME: Merge free blocks */
465  Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
466 
467  if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
468  Bin->FileOffset + Bin->Size)
469  {
470  Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
471  if (Neighbor->Size > 0)
472  {
473  HvpRemoveFree(RegistryHive, Neighbor,
474  ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
475  Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
476  Free->Size += Neighbor->Size;
477  }
478  }
479 
480  Neighbor = (PHCELL)(Bin + 1);
481  while (Neighbor < Free)
482  {
483  if (Neighbor->Size > 0)
484  {
485  if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
486  {
487  HCELL_INDEX NeighborCellIndex =
488  ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
489  Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK);
490 
491  if (HvpComputeFreeListIndex(Neighbor->Size) !=
492  HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
493  {
494  HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
495  Neighbor->Size += Free->Size;
496  HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
497  }
498  else
499  Neighbor->Size += Free->Size;
500 
501  if (CellType == Stable)
502  HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
503 
504  return;
505  }
506  Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
507  }
508  else
509  {
510  Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
511  }
512  }
513 
514  /* Add block to the list of free blocks */
515  HvpAddFree(RegistryHive, Free, CellIndex);
516 
517  if (CellType == Stable)
518  HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
519 }
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
static NTSTATUS CMAPI HvpAddFree(PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
Definition: hivecell.c:174
BOOLEAN ReadOnly
Definition: hivedata.h:310
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define HvGetCellType(Cell)
Definition: hivedata.h:95
struct _HBIN * PHBIN
if(dx==0 &&dy==0)
Definition: linetemp.h:174
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:814
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellIndex, BOOLEAN HoldingLock)
Definition: hivecell.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
#define FALSE
Definition: types.h:117
#define HCELL_TYPE_MASK
Definition: hivedata.h:88
Definition: bin.h:43
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
#define ASSERT(a)
Definition: mode.c:44
ULONG HCELL_INDEX
Definition: hivedata.h:80
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
LONG Size
Definition: hivedata.h:190
static VOID CMAPI HvpRemoveFree(PHHIVE RegistryHive, PHCELL CellBlock, HCELL_INDEX CellIndex)
Definition: hivecell.c:199
ULONG_PTR BinAddress
Definition: hivedata.h:259
static __inline PHCELL CMAPI HvpGetCellHeader(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:13
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:146
struct _HCELL * PHCELL
#define __FUNCTION__
Definition: types.h:112

Referenced by CmCreateRootNode(), CmiAddValueKey(), CmiCreateSubKey(), CmpCopyKeyValueList(), CmpCopyValue(), CmpDeepCopyKeyInternal(), CmpDoCreateChild(), CmpFreeKeyBody(), CmpFreeKeyByCell(), CmpFreeSecurityDescriptor(), CmpFreeValue(), CmpFreeValueData(), CmpRemoveSubKey(), CmpRemoveValueFromList(), CmpSetValueKeyNew(), CmpSplitLeaf(), HvReallocateCell(), and RegSetValueExW().

◆ HvGetCellSize()

LONG CMAPI HvGetCellSize ( IN PHHIVE  Hive,
IN PVOID  Address 
)

Definition at line 84 of file hivecell.c.

86 {
87  PHCELL CellHeader;
88  LONG Size;
89 
91 
92  CellHeader = (PHCELL)Address - 1;
93  Size = CellHeader->Size * -1;
94  Size -= sizeof(HCELL);
95  return Size;
96 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
struct _HCELL HCELL
LONG Size
Definition: hivedata.h:190
struct _HCELL * PHCELL

Referenced by HvReallocateCell().

◆ HvIsCellAllocated()

BOOLEAN CMAPI HvIsCellAllocated ( IN PHHIVE  RegistryHive,
IN HCELL_INDEX  CellIndex 
)

Definition at line 43 of file hivecell.c.

45 {
46  ULONG Type, Block;
47 
48  /* If it's a flat hive, the cell is always allocated */
49  if (RegistryHive->Flat)
50  return TRUE;
51 
52  /* Otherwise, get the type and make sure it's valid */
53  Type = HvGetCellType(CellIndex);
54  Block = HvGetCellBlock(CellIndex);
55  if (Block >= RegistryHive->Storage[Type].Length)
56  return FALSE;
57 
58  /* Try to get the cell block */
59  if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
60  return TRUE;
61 
62  /* No valid block, fail */
63  return FALSE;
64 }
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
#define TRUE
Definition: types.h:120
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define FALSE
Definition: types.h:117
Type
Definition: Type.h:6
unsigned int ULONG
Definition: retypes.h:1

◆ HvIsCellDirty()

BOOLEAN CMAPI HvIsCellDirty ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 125 of file hivecell.c.

127 {
128  BOOLEAN IsDirty = FALSE;
129 
130  /* Sanity checks */
131  ASSERT(Hive->ReadOnly == FALSE);
132 
133  /* Volatile cells are always "dirty" */
134  if (HvGetCellType(Cell) == Volatile)
135  return TRUE;
136 
137  /* Check if the dirty bit is set */
138  if (RtlCheckBit(&Hive->DirtyVector, Cell / HBLOCK_SIZE))
139  IsDirty = TRUE;
140 
141  /* Return result as boolean*/
142  return IsDirty;
143 }
#define HBLOCK_SIZE
Definition: hivedata.h:41
#define TRUE
Definition: types.h:120
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3152
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmpAddValueToList(), CmpRemoveSubKey(), CmpRemoveValueFromList(), CmpSetValueKeyExisting(), CmpSetValueKeyNew(), RegDeleteKeyW(), and RegDeleteValueW().

◆ HvMarkCellDirty()

BOOLEAN CMAPI HvMarkCellDirty ( PHHIVE  RegistryHive,
HCELL_INDEX  CellIndex,
BOOLEAN  HoldingLock 
)

Definition at line 99 of file hivecell.c.

103 {
104  ULONG CellBlock;
105  ULONG CellLastBlock;
106 
107  ASSERT(RegistryHive->ReadOnly == FALSE);
108 
109  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %u\n",
110  __FUNCTION__, RegistryHive, CellIndex, HoldingLock);
111 
112  if (HvGetCellType(CellIndex) != Stable)
113  return TRUE;
114 
115  CellBlock = HvGetCellBlock(CellIndex);
116  CellLastBlock = HvGetCellBlock(CellIndex + HBLOCK_SIZE - 1);
117 
118  RtlSetBits(&RegistryHive->DirtyVector,
119  CellBlock, CellLastBlock - CellBlock);
120  RegistryHive->DirtyCount++;
121  return TRUE;
122 }
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
#define HBLOCK_SIZE
Definition: hivedata.h:41
RTL_BITMAP DirtyVector
Definition: hivedata.h:304
#define TRUE
Definition: types.h:120
BOOLEAN ReadOnly
Definition: hivedata.h:310
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define HvGetCellType(Cell)
Definition: hivedata.h:95
ULONG DirtyCount
Definition: hivedata.h:305
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
unsigned int ULONG
Definition: retypes.h:1
#define __FUNCTION__
Definition: types.h:112

Referenced by CmDeleteValueKey(), CmiAddSubKey(), CmiAddValueKey(), CmpAddSubKey(), CmpAddToLeaf(), CmpCreateLinkNode(), CmpDoCreate(), CmpMarkIndexDirty(), CmpMarkKeyDirty(), CmpMarkValueDataDirty(), CmpSelectLeaf(), CmpSetValueKeyExisting(), CmpSetValueKeyNew(), CmpSplitLeaf(), CmSetValueKey(), HvAllocateCell(), HvFreeCell(), RegDeleteValueW(), and RegSetValueExW().

◆ HvpAddFree()

static NTSTATUS CMAPI HvpAddFree ( PHHIVE  RegistryHive,
PHCELL  FreeBlock,
HCELL_INDEX  FreeIndex 
)
static

Definition at line 174 of file hivecell.c.

178 {
179  PHCELL_INDEX FreeBlockData;
181  ULONG Index;
182 
183  ASSERT(RegistryHive != NULL);
184  ASSERT(FreeBlock != NULL);
185 
186  Storage = HvGetCellType(FreeIndex);
187  Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
188 
189  FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
190  *FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
191  RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
192 
193  /* FIXME: Eventually get rid of free bins. */
194 
195  return STATUS_SUCCESS;
196 }
#define HvGetCellType(Cell)
Definition: hivedata.h:95
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
#define ASSERT(a)
Definition: mode.c:44
_In_ WDFCOLLECTION _In_ ULONG Index
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280
LONG Size
Definition: hivedata.h:190
HSTORAGE_TYPE
Definition: hivedata.h:100
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:146
#define STATUS_SUCCESS
Definition: shellext.h:65
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvAllocateCell(), HvFreeCell(), and HvpCreateHiveFreeCellList().

◆ HvpComputeFreeListIndex()

static __inline ULONG CMAPI HvpComputeFreeListIndex ( ULONG  Size)
static

Definition at line 146 of file hivecell.c.

148 {
149  ULONG Index;
150  static CCHAR FindFirstSet[128] = {
151  0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
152  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
153  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
154  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
155  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
156  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
157  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
158  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
159 
160  ASSERT(Size >= (1 << 3));
161  Index = (Size >> 3) - 1;
162  if (Index >= 16)
163  {
164  if (Index > 127)
165  Index = 23;
166  else
167  Index = FindFirstSet[Index] + 16;
168  }
169 
170  return Index;
171 }
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define ASSERT(a)
Definition: mode.c:44
char CCHAR
Definition: typedefs.h:51
_In_ WDFCOLLECTION _In_ ULONG Index
unsigned int ULONG
Definition: retypes.h:1

Referenced by HvFreeCell(), HvpAddFree(), HvpFindFree(), and HvpRemoveFree().

◆ HvpCreateHiveFreeCellList()

NTSTATUS CMAPI HvpCreateHiveFreeCellList ( PHHIVE  Hive)

Definition at line 278 of file hivecell.c.

280 {
282  PHCELL FreeBlock;
283  ULONG BlockIndex;
284  ULONG FreeOffset;
285  PHBIN Bin;
287  ULONG Index;
288 
289  /* Initialize the free cell list */
290  for (Index = 0; Index < 24; Index++)
291  {
294  }
295 
296  BlockOffset = 0;
297  BlockIndex = 0;
298  while (BlockIndex < Hive->Storage[Stable].Length)
299  {
300  Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
301 
302  /* Search free blocks and add to list */
303  FreeOffset = sizeof(HBIN);
304  while (FreeOffset < Bin->Size)
305  {
306  FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
307  if (FreeBlock->Size > 0)
308  {
309  Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
310  if (!NT_SUCCESS(Status))
311  return Status;
312 
313  FreeOffset += FreeBlock->Size;
314  }
315  else
316  {
317  FreeOffset -= FreeBlock->Size;
318  }
319  }
320 
321  BlockIndex += Bin->Size / HBLOCK_SIZE;
322  BlockOffset += Bin->Size;
323  }
324 
325  return STATUS_SUCCESS;
326 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define HBLOCK_SIZE
Definition: hivedata.h:41
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS CMAPI HvpAddFree(PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
Definition: hivecell.c:174
#define HCELL_NIL
Definition: hivedata.h:85
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct _HBIN * PHBIN
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define BlockOffset(V, L)
Definition: cdprocs.h:1650
Definition: bin.h:43
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ WDFCOLLECTION _In_ ULONG Index
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
LONG Size
Definition: hivedata.h:190
ULONG_PTR BinAddress
Definition: hivedata.h:259
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _HCELL * PHCELL
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvpInitializeMemoryHive().

◆ HvpFindFree()

static HCELL_INDEX CMAPI HvpFindFree ( PHHIVE  RegistryHive,
ULONG  Size,
HSTORAGE_TYPE  Storage 
)
static

Definition at line 248 of file hivecell.c.

252 {
253  PHCELL_INDEX FreeCellData;
254  HCELL_INDEX FreeCellOffset;
255  PHCELL_INDEX pFreeCellOffset;
256  ULONG Index;
257 
258  for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
259  {
260  pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
261  while (*pFreeCellOffset != HCELL_NIL)
262  {
263  FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
264  if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
265  {
266  FreeCellOffset = *pFreeCellOffset;
267  *pFreeCellOffset = *FreeCellData;
268  return FreeCellOffset;
269  }
270  pFreeCellOffset = FreeCellData;
271  }
272  }
273 
274  return HCELL_NIL;
275 }
#define HCELL_NIL
Definition: hivedata.h:85
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ WDFCOLLECTION _In_ ULONG Index
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280
static __inline LONG CMAPI HvpGetCellFullSize(PHHIVE RegistryHive, PVOID Cell)
Definition: hivecell.c:75
unsigned int ULONG
Definition: retypes.h:1
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:146
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvAllocateCell().

◆ HvpGetCellData()

PCELL_DATA CMAPI HvpGetCellData ( _In_ PHHIVE  Hive,
_In_ HCELL_INDEX  CellIndex 
)

Definition at line 67 of file hivecell.c.

70 {
71  return (PCELL_DATA)(HvpGetCellHeader(Hive, CellIndex) + 1);
72 }
static __inline PHCELL CMAPI HvpGetCellHeader(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:13

Referenced by HvInitialize().

◆ HvpGetCellFullSize()

static __inline LONG CMAPI HvpGetCellFullSize ( PHHIVE  RegistryHive,
PVOID  Cell 
)
static

Definition at line 75 of file hivecell.c.

78 {
79  UNREFERENCED_PARAMETER(RegistryHive);
80  return ((PHCELL)Cell - 1)->Size;
81 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

Referenced by HvpFindFree().

◆ HvpGetCellHeader()

static __inline PHCELL CMAPI HvpGetCellHeader ( PHHIVE  RegistryHive,
HCELL_INDEX  CellIndex 
)
static

Definition at line 13 of file hivecell.c.

16 {
17  PVOID Block;
18 
19  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
20  __FUNCTION__, RegistryHive, CellIndex);
21 
22  ASSERT(CellIndex != HCELL_NIL);
23  if (!RegistryHive->Flat)
24  {
25  ULONG CellType = HvGetCellType(CellIndex);
26  ULONG CellBlock = HvGetCellBlock(CellIndex);
27  ULONG CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
28 
29  ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
30  Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
31  ASSERT(Block != NULL);
32  return (PHCELL)((ULONG_PTR)Block + CellOffset);
33  }
34  else
35  {
36  ASSERT(HvGetCellType(CellIndex) == Stable);
37  return (PHCELL)((ULONG_PTR)RegistryHive->BaseBlock + HBLOCK_SIZE +
38  CellIndex);
39  }
40 }
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define HBLOCK_SIZE
Definition: hivedata.h:41
#define HCELL_OFFSET_SHIFT
Definition: hivedata.h:93
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
#define HCELL_NIL
Definition: hivedata.h:85
ULONG_PTR BlockAddress
Definition: hivedata.h:258
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
#define NULL
Definition: types.h:112
#define HCELL_OFFSET_MASK
Definition: hivedata.h:90
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
BOOLEAN Flat
Definition: hivedata.h:309
#define __FUNCTION__
Definition: types.h:112
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvAllocateCell(), HvFreeCell(), and HvpGetCellData().

◆ HvpRemoveFree()

static VOID CMAPI HvpRemoveFree ( PHHIVE  RegistryHive,
PHCELL  CellBlock,
HCELL_INDEX  CellIndex 
)
static

Definition at line 199 of file hivecell.c.

203 {
204  PHCELL_INDEX FreeCellData;
205  PHCELL_INDEX pFreeCellOffset;
207  ULONG Index, FreeListIndex;
208 
209  ASSERT(RegistryHive->ReadOnly == FALSE);
210 
211  Storage = HvGetCellType(CellIndex);
212  Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
213 
214  pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
215  while (*pFreeCellOffset != HCELL_NIL)
216  {
217  FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
218  if (*pFreeCellOffset == CellIndex)
219  {
220  *pFreeCellOffset = *FreeCellData;
221  return;
222  }
223  pFreeCellOffset = FreeCellData;
224  }
225 
226  /* Something bad happened, print a useful trace info and bugcheck */
227  CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
228  CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n", CellIndex);
229  CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %u\n", Index);
230  for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
231  {
232  CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%u]: ", FreeListIndex);
233  pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
234  while (*pFreeCellOffset != HCELL_NIL)
235  {
236  CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
237  FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
238  pFreeCellOffset = FreeCellData;
239  }
241  }
242  CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
243 
244  ASSERT(FALSE);
245 }
#define HCELL_NIL
Definition: hivedata.h:85
BOOLEAN ReadOnly
Definition: hivedata.h:310
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
#define FALSE
Definition: types.h:117
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
#define ASSERT(a)
Definition: mode.c:44
_In_ WDFCOLLECTION _In_ ULONG Index
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280
LONG Size
Definition: hivedata.h:190
HSTORAGE_TYPE
Definition: hivedata.h:100
unsigned int ULONG
Definition: retypes.h:1
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:146
static IStorage Storage
Definition: ole2.c:3548

Referenced by HvFreeCell().

◆ HvReallocateCell()

HCELL_INDEX CMAPI HvReallocateCell ( PHHIVE  RegistryHive,
HCELL_INDEX  CellIndex,
ULONG  Size 
)

Definition at line 393 of file hivecell.c.

397 {
398  PVOID OldCell;
399  PVOID NewCell;
400  LONG OldCellSize;
401  HCELL_INDEX NewCellIndex;
403 
404  ASSERT(CellIndex != HCELL_NIL);
405 
406  CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
407  __FUNCTION__, RegistryHive, CellIndex, Size);
408 
409  Storage = HvGetCellType(CellIndex);
410 
411  OldCell = HvGetCell(RegistryHive, CellIndex);
412  OldCellSize = HvGetCellSize(RegistryHive, OldCell);
413  ASSERT(OldCellSize > 0);
414 
415  /*
416  * If new data size is larger than the current, destroy current
417  * data block and allocate a new one.
418  *
419  * FIXME: Merge with adjacent free cell if possible.
420  * FIXME: Implement shrinking.
421  */
422  if (Size > (ULONG)OldCellSize)
423  {
424  NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
425  if (NewCellIndex == HCELL_NIL)
426  return HCELL_NIL;
427 
428  NewCell = HvGetCell(RegistryHive, NewCellIndex);
429  RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
430 
431  HvFreeCell(RegistryHive, CellIndex);
432 
433  return NewCellIndex;
434  }
435 
436  return CellIndex;
437 }
#define HCELL_NIL
Definition: hivedata.h:85
#define CMLTRACE(x,...)
Definition: cmlib.h:165
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
long LONG
Definition: pedump.c:60
#define ASSERT(a)
Definition: mode.c:44
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:440
ULONG_PTR SIZE_T
Definition: typedefs.h:80
LONG CMAPI HvGetCellSize(IN PHHIVE Hive, IN PVOID Address)
Definition: hivecell.c:84
HSTORAGE_TYPE
Definition: hivedata.h:100
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, HCELL_INDEX Vicinity)
Definition: hivecell.c:329
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define __FUNCTION__
Definition: types.h:112
static IStorage Storage
Definition: ole2.c:3548

Referenced by CmpAddToLeaf(), CmpAddValueToList(), CmpRemoveValueFromList(), CmpSetValueKeyExisting(), and CmpSplitLeaf().

◆ HvReleaseFreeCellRefArray()

VOID CMAPI HvReleaseFreeCellRefArray ( IN OUT PHV_TRACK_CELL_REF  CellRef)

Definition at line 606 of file hivecell.c.

608 {
609  ULONG i;
610 
611  PAGED_CODE();
612 
613  ASSERT(CellRef);
614 
615  /* Any references in the static array? */
616  if (CellRef->StaticCount > 0)
617  {
618  /* Sanity check */
619  ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
620 
621  /* Loop over them and release them */
622  for (i = 0; i < CellRef->StaticCount; i++)
623  {
624  HvReleaseCell(CellRef->StaticArray[i].Hive,
625  CellRef->StaticArray[i].Cell);
626  }
627 
628  /* We can reuse the static array */
629  CellRef->StaticCount = 0;
630  }
631 
632  /* Any references in the dynamic array? */
633  if (CellRef->Count > 0)
634  {
635  /* Sanity checks */
636  ASSERT(CellRef->Count <= CellRef->Max);
637  ASSERT(CellRef->CellArray);
638 
639  /* Loop over them and release them */
640  for (i = 0; i < CellRef->Count; i++)
641  {
642  HvReleaseCell(CellRef->CellArray[i].Hive,
643  CellRef->CellArray[i].Cell);
644  }
645 
646  /* We can reuse the dynamic array */
647  CmpFree(CellRef->CellArray, 0); // TAG_CM
648  CellRef->CellArray = NULL;
649  CellRef->Count = CellRef->Max = 0;
650  }
651 }
#define STATIC_CELL_PAIR_COUNT
Definition: cmlib.h:296
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:384
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define PAGED_CODE()

Referenced by CmEnumerateKey(), and CmQueryKey().

◆ HvTrackCellRef()

BOOLEAN CMAPI HvTrackCellRef ( IN OUT PHV_TRACK_CELL_REF  CellRef,
IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 526 of file hivecell.c.

530 {
531  PHV_HIVE_CELL_PAIR NewCellArray;
532 
533  PAGED_CODE();
534 
535  /* Sanity checks */
536  ASSERT(CellRef);
537  ASSERT(Hive);
538  ASSERT(Cell != HCELL_NIL);
539 
540  /* NOTE: The hive cell is already referenced! */
541 
542  /* Less than 4? Use the static array */
543  if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
544  {
545  /* Add the reference */
546  CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
547  CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
548  CellRef->StaticCount++;
549  return TRUE;
550  }
551 
552  DPRINT("HvTrackCellRef: Static array full, use dynamic array.\n");
553 
554  /* Sanity checks */
555  if (CellRef->Max == 0)
556  {
557  /* The dynamic array must not have been allocated already */
558  ASSERT(CellRef->CellArray == NULL);
559  ASSERT(CellRef->Count == 0);
560  }
561  else
562  {
563  /* The dynamic array must be allocated */
564  ASSERT(CellRef->CellArray);
565  }
566  ASSERT(CellRef->Count <= CellRef->Max);
567 
568  if (CellRef->Count == CellRef->Max)
569  {
570  /* Allocate a new reference table */
571  NewCellArray = CmpAllocate((CellRef->Max + CELL_REF_INCREMENT) * sizeof(HV_HIVE_CELL_PAIR),
572  TRUE,
573  TAG_CM);
574  if (!NewCellArray)
575  {
576  DPRINT1("HvTrackCellRef: Cannot reallocate the reference table.\n");
577  /* We failed, dereference the hive cell */
578  HvReleaseCell(Hive, Cell);
579  return FALSE;
580  }
581 
582  /* Free the old reference table and use the new one */
583  if (CellRef->CellArray)
584  {
585  /* Copy the handles from the old table to the new one */
586  RtlCopyMemory(NewCellArray,
587  CellRef->CellArray,
588  CellRef->Max * sizeof(HV_HIVE_CELL_PAIR));
589  CmpFree(CellRef->CellArray, 0); // TAG_CM
590  }
591  CellRef->CellArray = NewCellArray;
592  CellRef->Max += CELL_REF_INCREMENT;
593  }
594 
595  // ASSERT(CellRef->Count < CellRef->Max);
596 
597  /* Add the reference */
598  CellRef->CellArray[CellRef->Count].Hive = Hive;
599  CellRef->CellArray[CellRef->Count].Cell = Cell;
600  CellRef->Count++;
601  return TRUE;
602 }
#define TRUE
Definition: types.h:120
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define HCELL_NIL
Definition: hivedata.h:85
#define STATIC_CELL_PAIR_COUNT
Definition: cmlib.h:296
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define TAG_CM
Definition: cmlib.h:205
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:384
#define NULL
Definition: types.h:112
#define CELL_REF_INCREMENT
Definition: hivecell.c:522
#define DPRINT1
Definition: precomp.h:8
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DPRINT
Definition: sndvol32.h:71
#define PAGED_CODE()

Referenced by CmEnumerateKey(), and CmQueryKey().