- Create KD branch. All debugging support is removed in this branch (no symbols,...
[reactos.git] / reactos / lib / cmlib / hivebin.c
1 /*
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
7 */
8
9 #include "cmlib.h"
10
11 PHBIN CMAPI
12 HvpAddBin(
13 PHHIVE RegistryHive,
14 ULONG Size,
15 HV_STORAGE_TYPE Storage)
16 {
17 PHMAP_ENTRY BlockList;
18 PHBIN Bin;
19 SIZE_T BinSize;
20 ULONG i;
21 ULONG BitmapSize;
22 ULONG BlockCount;
23 ULONG OldBlockListSize;
24 PHCELL Block;
25
26 BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE);
27 BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE);
28
29 Bin = RegistryHive->Allocate(BinSize, TRUE);
30 if (Bin == NULL)
31 return NULL;
32 RtlZeroMemory(Bin, BinSize);
33
34 Bin->Signature = HV_BIN_SIGNATURE;
35 Bin->FileOffset = RegistryHive->Storage[Storage].Length *
36 HV_BLOCK_SIZE;
37 Bin->Size = (ULONG)BinSize;
38
39 /* Allocate new block list */
40 OldBlockListSize = RegistryHive->Storage[Storage].Length;
41 BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
42 (OldBlockListSize + BlockCount), TRUE);
43 if (BlockList == NULL)
44 {
45 RegistryHive->Free(Bin);
46 return NULL;
47 }
48
49 if (OldBlockListSize > 0)
50 {
51 RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
52 OldBlockListSize * sizeof(HMAP_ENTRY));
53 RegistryHive->Free(RegistryHive->Storage[Storage].BlockList);
54 }
55
56 RegistryHive->Storage[Storage].BlockList = BlockList;
57 RegistryHive->Storage[Storage].Length += BlockCount;
58
59 for (i = 0; i < BlockCount; i++)
60 {
61 RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block =
62 ((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE));
63 RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin;
64 }
65
66 /* Initialize a free block in this heap. */
67 Block = (PHCELL)(Bin + 1);
68 Block->Size = (LONG)(BinSize - sizeof(HBIN));
69
70 if (Storage == HvStable)
71 {
72 /* Calculate bitmap size in bytes (always a multiple of 32 bits). */
73 BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length,
74 sizeof(ULONG) * 8) / 8;
75
76 /* Grow bitmap if necessary. */
77 if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
78 {
79 PULONG BitmapBuffer;
80
81 BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE);
82 RtlZeroMemory(BitmapBuffer, BitmapSize);
83 RtlCopyMemory(BitmapBuffer,
84 RegistryHive->DirtyVector.Buffer,
85 RegistryHive->DirtyVector.SizeOfBitMap / 8);
86 RegistryHive->Free(RegistryHive->DirtyVector.Buffer);
87 RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
88 BitmapSize * 8);
89 }
90
91 /* Mark new bin dirty. */
92 RtlSetBits(&RegistryHive->DirtyVector,
93 Bin->FileOffset / HV_BLOCK_SIZE,
94 BlockCount);
95 }
96
97 return Bin;
98 }