2 * PROJECT: Registry manipulation library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
5 * Copyright 2005 Hartmut Birr
6 * Copyright 2001 - 2005 Eric Kohl
15 HSTORAGE_TYPE Storage
)
17 PHMAP_ENTRY BlockList
;
23 ULONG OldBlockListSize
;
26 BinSize
= ROUND_UP(Size
+ sizeof(HBIN
), HBLOCK_SIZE
);
27 BlockCount
= (ULONG
)(BinSize
/ HBLOCK_SIZE
);
29 Bin
= RegistryHive
->Allocate(BinSize
, TRUE
, TAG_CM
);
32 RtlZeroMemory(Bin
, BinSize
);
34 Bin
->Signature
= HV_BIN_SIGNATURE
;
35 Bin
->FileOffset
= RegistryHive
->Storage
[Storage
].Length
*
37 Bin
->Size
= (ULONG
)BinSize
;
39 /* Allocate new block list */
40 OldBlockListSize
= RegistryHive
->Storage
[Storage
].Length
;
41 BlockList
= RegistryHive
->Allocate(sizeof(HMAP_ENTRY
) *
42 (OldBlockListSize
+ BlockCount
),
45 if (BlockList
== NULL
)
47 RegistryHive
->Free(Bin
, 0);
51 if (OldBlockListSize
> 0)
53 RtlCopyMemory(BlockList
, RegistryHive
->Storage
[Storage
].BlockList
,
54 OldBlockListSize
* sizeof(HMAP_ENTRY
));
55 RegistryHive
->Free(RegistryHive
->Storage
[Storage
].BlockList
, 0);
58 RegistryHive
->Storage
[Storage
].BlockList
= BlockList
;
59 RegistryHive
->Storage
[Storage
].Length
+= BlockCount
;
61 for (i
= 0; i
< BlockCount
; i
++)
63 RegistryHive
->Storage
[Storage
].BlockList
[OldBlockListSize
+ i
].BlockAddress
=
64 ((ULONG_PTR
)Bin
+ (i
* HBLOCK_SIZE
));
65 RegistryHive
->Storage
[Storage
].BlockList
[OldBlockListSize
+ i
].BinAddress
= (ULONG_PTR
)Bin
;
68 /* Initialize a free block in this heap. */
69 Block
= (PHCELL
)(Bin
+ 1);
70 Block
->Size
= (LONG
)(BinSize
- sizeof(HBIN
));
72 if (Storage
== Stable
)
74 /* Calculate bitmap size in bytes (always a multiple of 32 bits). */
75 BitmapSize
= ROUND_UP(RegistryHive
->Storage
[Stable
].Length
,
76 sizeof(ULONG
) * 8) / 8;
78 /* Grow bitmap if necessary. */
79 if (BitmapSize
> RegistryHive
->DirtyVector
.SizeOfBitMap
/ 8)
83 BitmapBuffer
= RegistryHive
->Allocate(BitmapSize
, TRUE
, TAG_CM
);
84 RtlZeroMemory(BitmapBuffer
, BitmapSize
);
85 if (RegistryHive
->DirtyVector
.SizeOfBitMap
> 0)
87 ASSERT(RegistryHive
->DirtyVector
.Buffer
);
88 RtlCopyMemory(BitmapBuffer
,
89 RegistryHive
->DirtyVector
.Buffer
,
90 RegistryHive
->DirtyVector
.SizeOfBitMap
/ 8);
91 RegistryHive
->Free(RegistryHive
->DirtyVector
.Buffer
, 0);
93 RtlInitializeBitMap(&RegistryHive
->DirtyVector
, BitmapBuffer
,
97 /* Mark new bin dirty. */
98 RtlSetBits(&RegistryHive
->DirtyVector
,
99 Bin
->FileOffset
/ HBLOCK_SIZE
,
102 /* Update size in the base block */
103 RegistryHive
->BaseBlock
->Length
+= BinSize
;