ReactOS 0.4.15-dev-5669-g09dde2c
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

VOID NTAPI CmpLazyFlush (VOID)
 
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 550 of file hivecell.c.

◆ NDEBUG

#define NDEBUG

Definition at line 9 of file hivecell.c.

Function Documentation

◆ CmpLazyFlush()

VOID NTAPI CmpLazyFlush ( VOID  )

Definition at line 158 of file cmlazy.c.

159{
161 PAGED_CODE();
162
163 /* Check if we should set the lazy flush timer */
164 if ((!CmpNoWrite) && (!CmpHoldLazyFlush))
165 {
166 /* Do it */
168 -10 * 1000 * 1000);
170 }
171}
#define PAGED_CODE()
ULONG CmpLazyFlushIntervalInSeconds
Definition: cmlazy.c:25
KDPC CmpLazyFlushDpc
Definition: cmlazy.c:18
BOOLEAN CmpHoldLazyFlush
Definition: cmlazy.c:24
KTIMER CmpLazyFlushTimer
Definition: cmlazy.c:17
BOOLEAN CmpNoWrite
Definition: cmsysini.c:29
#define Int32x32To64(a, b)
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190

Referenced by _Function_class_(), HvMarkCellDirty(), and NtInitializeRegistry().

◆ HvAllocateCell()

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

Definition at line 357 of file hivecell.c.

362{
363 PHCELL FreeCell;
364 HCELL_INDEX FreeCellOffset;
365 PHCELL NewCell;
366 PHBIN Bin;
367
368 ASSERT(RegistryHive->ReadOnly == FALSE);
369
370 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, Size %x, %s, Vicinity %08lx\n",
371 __FUNCTION__, RegistryHive, Size, (Storage == 0) ? "Stable" : "Volatile", Vicinity);
372
373 /* Round to 16 bytes multiple. */
374 Size = ROUND_UP(Size + sizeof(HCELL), 16);
375
376 /* First search in free blocks. */
377 FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
378
379 /* If no free cell was found we need to extend the hive file. */
380 if (FreeCellOffset == HCELL_NIL)
381 {
382 Bin = HvpAddBin(RegistryHive, Size, Storage);
383 if (Bin == NULL)
384 return HCELL_NIL;
385 FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
386 FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
387 }
388
389 FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
390
391 /* Split the block in two parts */
392
393 /* The free block that is created has to be at least
394 sizeof(HCELL) + sizeof(HCELL_INDEX) big, so that free
395 cell list code can work. Moreover we round cell sizes
396 to 16 bytes, so creating a smaller block would result in
397 a cell that would never be allocated. */
398 if ((ULONG)FreeCell->Size > Size + 16)
399 {
400 NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
401 NewCell->Size = FreeCell->Size - Size;
402 FreeCell->Size = Size;
403 HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
404 if (Storage == Stable)
405 HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
406 }
407
408 if (Storage == Stable)
409 HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
410
411 FreeCell->Size = -FreeCell->Size;
412 RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
413
414 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - CellIndex %08lx\n",
415 __FUNCTION__, FreeCellOffset);
416
417 return FreeCellOffset;
418}
Definition: bin.h:44
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
PHBIN CMAPI HvpAddBin(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
Definition: hivebin.c:12
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define __FUNCTION__
Definition: types.h:112
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
static __inline PHCELL CMAPI HvpGetCellHeader(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:23
static NTSTATUS CMAPI HvpAddFree(PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
Definition: hivecell.c:202
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellIndex, BOOLEAN HoldingLock)
Definition: hivecell.c:109
static HCELL_INDEX CMAPI HvpFindFree(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
Definition: hivecell.c:276
#define HCELL_TYPE_SHIFT
Definition: hivedata.h:91
@ Stable
Definition: hivedata.h:102
struct _HCELL * PHCELL
#define HCELL_NIL
Definition: hivedata.h:85
struct _HBIN HBIN
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define ASSERT(a)
Definition: mode.c:44
static IStorage Storage
Definition: ole2.c:3548
LONG Size
Definition: hivedata.h:190
BOOLEAN ReadOnly
Definition: hivedata.h:310
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by HvReallocateCell().

◆ HvFreeCell()

VOID CMAPI HvFreeCell ( PHHIVE  RegistryHive,
HCELL_INDEX  CellIndex 
)

Definition at line 468 of file hivecell.c.

471{
472 PHCELL Free;
473 PHCELL Neighbor;
474 PHBIN Bin;
475 ULONG CellType;
476 ULONG CellBlock;
477
478 ASSERT(RegistryHive->ReadOnly == FALSE);
479
480 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
481 __FUNCTION__, RegistryHive, CellIndex);
482
483 Free = HvpGetCellHeader(RegistryHive, CellIndex);
484
485 ASSERT(Free->Size < 0);
486
487 Free->Size = -Free->Size;
488
489 CellType = HvGetCellType(CellIndex);
490 CellBlock = HvGetCellBlock(CellIndex);
491
492 /* FIXME: Merge free blocks */
493 Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
494
495 if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
496 Bin->FileOffset + Bin->Size)
497 {
498 Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
499 if (Neighbor->Size > 0)
500 {
501 HvpRemoveFree(RegistryHive, Neighbor,
502 ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
503 Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
504 Free->Size += Neighbor->Size;
505 }
506 }
507
508 Neighbor = (PHCELL)(Bin + 1);
509 while (Neighbor < Free)
510 {
511 if (Neighbor->Size > 0)
512 {
513 if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
514 {
515 HCELL_INDEX NeighborCellIndex =
516 ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
517 Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK);
518
519 if (HvpComputeFreeListIndex(Neighbor->Size) !=
520 HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
521 {
522 HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
523 Neighbor->Size += Free->Size;
524 HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
525 }
526 else
527 Neighbor->Size += Free->Size;
528
529 if (CellType == Stable)
530 HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
531
532 return;
533 }
534 Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
535 }
536 else
537 {
538 Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
539 }
540 }
541
542 /* Add block to the list of free blocks */
543 HvpAddFree(RegistryHive, Free, CellIndex);
544
545 if (CellType == Stable)
546 HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
547}
#define ULONG_PTR
Definition: config.h:101
static VOID CMAPI HvpRemoveFree(PHHIVE RegistryHive, PHCELL CellBlock, HCELL_INDEX CellIndex)
Definition: hivecell.c:227
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:174
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
#define HCELL_TYPE_MASK
Definition: hivedata.h:88
struct _HBIN * PHBIN
#define HvGetCellType(Cell)
Definition: hivedata.h:95
if(dx< 0)
Definition: linetemp.h:194
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
ULONG_PTR BinAddress
Definition: hivedata.h:259
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:815

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 94 of file hivecell.c.

96{
97 PHCELL CellHeader;
98 LONG Size;
99
101
102 CellHeader = (PHCELL)Address - 1;
103 Size = CellHeader->Size * -1;
104 Size -= sizeof(HCELL);
105 return Size;
106}
struct _HCELL HCELL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68

Referenced by HvReallocateCell().

◆ HvIsCellAllocated()

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

Definition at line 53 of file hivecell.c.

55{
56 ULONG Type, Block;
57
58 /* If it's a flat hive, the cell is always allocated */
59 if (RegistryHive->Flat)
60 return TRUE;
61
62 /* Otherwise, get the type and make sure it's valid */
63 Type = HvGetCellType(CellIndex);
64 Block = HvGetCellBlock(CellIndex);
65 if (Block >= RegistryHive->Storage[Type].Length)
66 return FALSE;
67
68 /* Try to get the cell block */
69 if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
70 return TRUE;
71
72 /* No valid block, fail */
73 return FALSE;
74}
Type
Definition: Type.h:7
#define TRUE
Definition: types.h:120

◆ HvIsCellDirty()

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

Definition at line 153 of file hivecell.c.

155{
156 BOOLEAN IsDirty = FALSE;
157
158 /* Sanity checks */
159 ASSERT(Hive->ReadOnly == FALSE);
160
161 /* Volatile cells are always "dirty" */
162 if (HvGetCellType(Cell) == Volatile)
163 return TRUE;
164
165 /* Check if the dirty bit is set */
166 if (RtlCheckBit(&Hive->DirtyVector, Cell / HBLOCK_SIZE))
167 IsDirty = TRUE;
168
169 /* Return result as boolean*/
170 return IsDirty;
171}
unsigned char BOOLEAN
@ Volatile
Definition: hivedata.h:103
#define HBLOCK_SIZE
Definition: hivedata.h:41
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3152

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 109 of file hivecell.c.

113{
114 ULONG CellBlock;
115 ULONG CellLastBlock;
116
117 ASSERT(RegistryHive->ReadOnly == FALSE);
118
119 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %u\n",
120 __FUNCTION__, RegistryHive, CellIndex, HoldingLock);
121
122 if (HvGetCellType(CellIndex) != Stable)
123 return TRUE;
124
125 CellBlock = HvGetCellBlock(CellIndex);
126 CellLastBlock = HvGetCellBlock(CellIndex + HBLOCK_SIZE - 1);
127
128 RtlSetBits(&RegistryHive->DirtyVector,
129 CellBlock, CellLastBlock - CellBlock);
130 RegistryHive->DirtyCount++;
131
132 /*
133 * FIXME: Querying a lazy flush operation is needed to
134 * ensure that the dirty data is being flushed to disk
135 * accordingly. However, this operation has to be done
136 * in a helper like HvMarkDirty that marks specific parts
137 * of the hive as dirty. Since we do not have such kind
138 * of helper we have to perform an eventual lazy flush
139 * when marking cells as dirty here for the moment being,
140 * so that not only we flush dirty data but also write
141 * logs.
142 */
143#if !defined(CMLIB_HOST) && !defined(_BLDR_)
144 if (!(RegistryHive->HiveFlags & HIVE_NOLAZYFLUSH))
145 {
146 CmpLazyFlush();
147 }
148#endif
149 return TRUE;
150}
VOID NTAPI CmpLazyFlush(VOID)
Definition: cmlazy.c:158
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
RTL_BITMAP DirtyVector
Definition: hivedata.h:304
ULONG HiveFlags
Definition: hivedata.h:321
ULONG DirtyCount
Definition: hivedata.h:305

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 202 of file hivecell.c.

206{
207 PHCELL_INDEX FreeBlockData;
209 ULONG Index;
210
211 ASSERT(RegistryHive != NULL);
212 ASSERT(FreeBlock != NULL);
213
214 Storage = HvGetCellType(FreeIndex);
216
217 FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
218 *FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
219 RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
220
221 /* FIXME: Eventually get rid of free bins. */
222
223 return STATUS_SUCCESS;
224}
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
HSTORAGE_TYPE
Definition: hivedata.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280
_In_ WDFCOLLECTION _In_ ULONG Index

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

◆ HvpComputeFreeListIndex()

static __inline ULONG CMAPI HvpComputeFreeListIndex ( ULONG  Size)
static

Definition at line 174 of file hivecell.c.

176{
177 ULONG Index;
178 static CCHAR FindFirstSet[128] = {
179 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
180 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
181 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
182 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
183 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
184 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
185 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
186 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
187
188 ASSERT(Size >= (1 << 3));
189 Index = (Size >> 3) - 1;
190 if (Index >= 16)
191 {
192 if (Index > 127)
193 Index = 23;
194 else
195 Index = FindFirstSet[Index] + 16;
196 }
197
198 return Index;
199}
char CCHAR
Definition: typedefs.h:51

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

◆ HvpCreateHiveFreeCellList()

NTSTATUS CMAPI HvpCreateHiveFreeCellList ( PHHIVE  Hive)

Definition at line 306 of file hivecell.c.

308{
310 PHCELL FreeBlock;
311 ULONG BlockIndex;
312 ULONG FreeOffset;
313 PHBIN Bin;
315 ULONG Index;
316
317 /* Initialize the free cell list */
318 for (Index = 0; Index < 24; Index++)
319 {
322 }
323
324 BlockOffset = 0;
325 BlockIndex = 0;
326 while (BlockIndex < Hive->Storage[Stable].Length)
327 {
328 Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
329
330 /* Search free blocks and add to list */
331 FreeOffset = sizeof(HBIN);
332 while (FreeOffset < Bin->Size)
333 {
334 FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
335 if (FreeBlock->Size > 0)
336 {
337 Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
338 if (!NT_SUCCESS(Status))
339 return Status;
340
341 FreeOffset += FreeBlock->Size;
342 }
343 else
344 {
345 FreeOffset -= FreeBlock->Size;
346 }
347 }
348
349 BlockIndex += Bin->Size / HBLOCK_SIZE;
350 BlockOffset += Bin->Size;
351 }
352
353 return STATUS_SUCCESS;
354}
LONG NTSTATUS
Definition: precomp.h:26
#define BlockOffset(V, L)
Definition: cdprocs.h:1650
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by HvpInitializeMemoryHive().

◆ HvpFindFree()

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

Definition at line 276 of file hivecell.c.

280{
281 PHCELL_INDEX FreeCellData;
282 HCELL_INDEX FreeCellOffset;
283 PHCELL_INDEX pFreeCellOffset;
284 ULONG Index;
285
287 {
288 pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
289 while (*pFreeCellOffset != HCELL_NIL)
290 {
291 FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
292 if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
293 {
294 FreeCellOffset = *pFreeCellOffset;
295 *pFreeCellOffset = *FreeCellData;
296 return FreeCellOffset;
297 }
298 pFreeCellOffset = FreeCellData;
299 }
300 }
301
302 return HCELL_NIL;
303}
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
static __inline LONG CMAPI HvpGetCellFullSize(PHHIVE RegistryHive, PVOID Cell)
Definition: hivecell.c:85

Referenced by HvAllocateCell().

◆ HvpGetCellData()

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

Definition at line 77 of file hivecell.c.

80{
81 return (PCELL_DATA)(HvpGetCellHeader(Hive, CellIndex) + 1);
82}

Referenced by HvInitialize().

◆ HvpGetCellFullSize()

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

Definition at line 85 of file hivecell.c.

88{
89 UNREFERENCED_PARAMETER(RegistryHive);
90 return ((PHCELL)Cell - 1)->Size;
91}

Referenced by HvpFindFree().

◆ HvpGetCellHeader()

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

Definition at line 23 of file hivecell.c.

26{
27 PVOID Block;
28
29 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
30 __FUNCTION__, RegistryHive, CellIndex);
31
32 ASSERT(CellIndex != HCELL_NIL);
33 if (!RegistryHive->Flat)
34 {
35 ULONG CellType = HvGetCellType(CellIndex);
36 ULONG CellBlock = HvGetCellBlock(CellIndex);
37 ULONG CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
38
39 ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
40 Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
41 ASSERT(Block != NULL);
42 return (PHCELL)((ULONG_PTR)Block + CellOffset);
43 }
44 else
45 {
46 ASSERT(HvGetCellType(CellIndex) == Stable);
47 return (PHCELL)((ULONG_PTR)RegistryHive->BaseBlock + HBLOCK_SIZE +
48 CellIndex);
49 }
50}
#define HCELL_OFFSET_MASK
Definition: hivedata.h:90
#define HCELL_OFFSET_SHIFT
Definition: hivedata.h:93
BOOLEAN Flat
Definition: hivedata.h:309
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
ULONG_PTR BlockAddress
Definition: hivedata.h:258
void * PVOID
Definition: typedefs.h:50

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

◆ HvpRemoveFree()

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

Definition at line 227 of file hivecell.c.

231{
232 PHCELL_INDEX FreeCellData;
233 PHCELL_INDEX pFreeCellOffset;
235 ULONG Index, FreeListIndex;
236
237 ASSERT(RegistryHive->ReadOnly == FALSE);
238
239 Storage = HvGetCellType(CellIndex);
241
242 pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
243 while (*pFreeCellOffset != HCELL_NIL)
244 {
245 FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
246 if (*pFreeCellOffset == CellIndex)
247 {
248 *pFreeCellOffset = *FreeCellData;
249 return;
250 }
251 pFreeCellOffset = FreeCellData;
252 }
253
254 /* Something bad happened, print a useful trace info and bugcheck */
255 CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
256 CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n", CellIndex);
257 CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %u\n", Index);
258 for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
259 {
260 CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%u]: ", FreeListIndex);
261 pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
262 while (*pFreeCellOffset != HCELL_NIL)
263 {
264 CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
265 FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
266 pFreeCellOffset = FreeCellData;
267 }
269 }
270 CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
271
272 ASSERT(FALSE);
273}

Referenced by HvFreeCell().

◆ HvReallocateCell()

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

Definition at line 421 of file hivecell.c.

425{
426 PVOID OldCell;
427 PVOID NewCell;
428 LONG OldCellSize;
429 HCELL_INDEX NewCellIndex;
431
432 ASSERT(CellIndex != HCELL_NIL);
433
434 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
435 __FUNCTION__, RegistryHive, CellIndex, Size);
436
437 Storage = HvGetCellType(CellIndex);
438
439 OldCell = HvGetCell(RegistryHive, CellIndex);
440 OldCellSize = HvGetCellSize(RegistryHive, OldCell);
441 ASSERT(OldCellSize > 0);
442
443 /*
444 * If new data size is larger than the current, destroy current
445 * data block and allocate a new one.
446 *
447 * FIXME: Merge with adjacent free cell if possible.
448 * FIXME: Implement shrinking.
449 */
450 if (Size > (ULONG)OldCellSize)
451 {
452 NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
453 if (NewCellIndex == HCELL_NIL)
454 return HCELL_NIL;
455
456 NewCell = HvGetCell(RegistryHive, NewCellIndex);
457 RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
458
459 HvFreeCell(RegistryHive, CellIndex);
460
461 return NewCellIndex;
462 }
463
464 return CellIndex;
465}
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, HCELL_INDEX Vicinity)
Definition: hivecell.c:357
LONG CMAPI HvGetCellSize(IN PHHIVE Hive, IN PVOID Address)
Definition: hivecell.c:94
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:468
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

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

◆ HvReleaseFreeCellRefArray()

VOID CMAPI HvReleaseFreeCellRefArray ( IN OUT PHV_TRACK_CELL_REF  CellRef)

Definition at line 634 of file hivecell.c.

636{
637 ULONG i;
638
639 PAGED_CODE();
640
641 ASSERT(CellRef);
642
643 /* Any references in the static array? */
644 if (CellRef->StaticCount > 0)
645 {
646 /* Sanity check */
647 ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
648
649 /* Loop over them and release them */
650 for (i = 0; i < CellRef->StaticCount; i++)
651 {
652 HvReleaseCell(CellRef->StaticArray[i].Hive,
653 CellRef->StaticArray[i].Cell);
654 }
655
656 /* We can reuse the static array */
657 CellRef->StaticCount = 0;
658 }
659
660 /* Any references in the dynamic array? */
661 if (CellRef->Count > 0)
662 {
663 /* Sanity checks */
664 ASSERT(CellRef->Count <= CellRef->Max);
665 ASSERT(CellRef->CellArray);
666
667 /* Loop over them and release them */
668 for (i = 0; i < CellRef->Count; i++)
669 {
670 HvReleaseCell(CellRef->CellArray[i].Hive,
671 CellRef->CellArray[i].Cell);
672 }
673
674 /* We can reuse the dynamic array */
675 CmpFree(CellRef->CellArray, 0); // TAG_CM
676 CellRef->CellArray = NULL;
677 CellRef->Count = CellRef->Max = 0;
678 }
679}
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:384
#define STATIC_CELL_PAIR_COUNT
Definition: cmlib.h:296
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

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 554 of file hivecell.c.

558{
559 PHV_HIVE_CELL_PAIR NewCellArray;
560
561 PAGED_CODE();
562
563 /* Sanity checks */
564 ASSERT(CellRef);
565 ASSERT(Hive);
566 ASSERT(Cell != HCELL_NIL);
567
568 /* NOTE: The hive cell is already referenced! */
569
570 /* Less than 4? Use the static array */
571 if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
572 {
573 /* Add the reference */
574 CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
575 CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
576 CellRef->StaticCount++;
577 return TRUE;
578 }
579
580 DPRINT("HvTrackCellRef: Static array full, use dynamic array.\n");
581
582 /* Sanity checks */
583 if (CellRef->Max == 0)
584 {
585 /* The dynamic array must not have been allocated already */
586 ASSERT(CellRef->CellArray == NULL);
587 ASSERT(CellRef->Count == 0);
588 }
589 else
590 {
591 /* The dynamic array must be allocated */
592 ASSERT(CellRef->CellArray);
593 }
594 ASSERT(CellRef->Count <= CellRef->Max);
595
596 if (CellRef->Count == CellRef->Max)
597 {
598 /* Allocate a new reference table */
599 NewCellArray = CmpAllocate((CellRef->Max + CELL_REF_INCREMENT) * sizeof(HV_HIVE_CELL_PAIR),
600 TRUE,
601 TAG_CM);
602 if (!NewCellArray)
603 {
604 DPRINT1("HvTrackCellRef: Cannot reallocate the reference table.\n");
605 /* We failed, dereference the hive cell */
606 HvReleaseCell(Hive, Cell);
607 return FALSE;
608 }
609
610 /* Free the old reference table and use the new one */
611 if (CellRef->CellArray)
612 {
613 /* Copy the handles from the old table to the new one */
614 RtlCopyMemory(NewCellArray,
615 CellRef->CellArray,
616 CellRef->Max * sizeof(HV_HIVE_CELL_PAIR));
617 CmpFree(CellRef->CellArray, 0); // TAG_CM
618 }
619 CellRef->CellArray = NewCellArray;
620 CellRef->Max += CELL_REF_INCREMENT;
621 }
622
623 // ASSERT(CellRef->Count < CellRef->Max);
624
625 /* Add the reference */
626 CellRef->CellArray[CellRef->Count].Hive = Hive;
627 CellRef->CellArray[CellRef->Count].Cell = Cell;
628 CellRef->Count++;
629 return TRUE;
630}
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define TAG_CM
Definition: cmlib.h:205
#define CELL_REF_INCREMENT
Definition: hivecell.c:550
#define DPRINT
Definition: sndvol32.h:71

Referenced by CmEnumerateKey(), and CmQueryKey().