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 2001 - 2005 Eric Kohl
26 ASSERT(RegistryHive
->ReadOnly
== FALSE
);
28 DPRINT("HvpWriteLog called\n");
30 if (RegistryHive
->HiveHeader
->Sequence1
!=
31 RegistryHive
->HiveHeader
->Sequence2
)
36 BitmapSize
= RegistryHive
->DirtyVector
.SizeOfBitMap
;
37 BufferSize
= HV_LOG_HEADER_SIZE
+ sizeof(ULONG
) + BitmapSize
;
38 BufferSize
= ROUND_UP(BufferSize
, HV_BLOCK_SIZE
);
40 DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize
, BufferSize
);
42 Buffer
= RegistryHive
->Allocate(BufferSize
, TRUE
);
48 /* Update first update counter and checksum */
49 RegistryHive
->HiveHeader
->Type
= HV_TYPE_LOG
;
50 RegistryHive
->HiveHeader
->Sequence1
++;
51 RegistryHive
->HiveHeader
->Checksum
=
52 HvpHiveHeaderChecksum(RegistryHive
->HiveHeader
);
54 /* Copy hive header */
55 RtlCopyMemory(Buffer
, RegistryHive
->HiveHeader
, HV_LOG_HEADER_SIZE
);
56 Ptr
= Buffer
+ HV_LOG_HEADER_SIZE
;
57 RtlCopyMemory(Ptr
, "DIRT", 4);
59 RtlCopyMemory(Ptr
, RegistryHive
->DirtyVector
.Buffer
, BitmapSize
);
61 /* Write hive block and block bitmap */
62 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_LOG
,
63 0, Buffer
, BufferSize
);
69 RegistryHive
->Free(Buffer
);
71 /* Write dirty blocks */
72 FileOffset
= BufferSize
;
74 while (BlockIndex
< RegistryHive
->Storage
[HvStable
].Length
)
76 LastIndex
= BlockIndex
;
77 BlockIndex
= RtlFindSetBits(&RegistryHive
->DirtyVector
, 1, BlockIndex
);
78 if (BlockIndex
== ~0 || BlockIndex
< LastIndex
)
83 BlockPtr
= (PVOID
)RegistryHive
->Storage
[HvStable
].BlockList
[BlockIndex
].Block
;
85 /* Write hive block */
86 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_LOG
,
95 FileOffset
+= HV_BLOCK_SIZE
;
98 Success
= RegistryHive
->FileSetSize(RegistryHive
, HV_TYPE_LOG
, FileOffset
);
101 DPRINT("FileSetSize failed\n");
105 /* Flush the log file */
106 Success
= RegistryHive
->FileFlush(RegistryHive
, HV_TYPE_LOG
);
109 DPRINT("FileFlush failed\n");
112 /* Update first and second update counter and checksum. */
113 RegistryHive
->HiveHeader
->Sequence2
++;
114 RegistryHive
->HiveHeader
->Checksum
=
115 HvpHiveHeaderChecksum(RegistryHive
->HiveHeader
);
117 /* Write hive header again with updated sequence counter. */
118 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_LOG
,
119 0, RegistryHive
->HiveHeader
,
126 /* Flush the log file */
127 Success
= RegistryHive
->FileFlush(RegistryHive
, HV_TYPE_LOG
);
130 DPRINT("FileFlush failed\n");
141 ULONGLONG FileOffset
;
147 ASSERT(RegistryHive
->ReadOnly
== FALSE
);
149 DPRINT("HvpWriteHive called\n");
151 if (RegistryHive
->HiveHeader
->Sequence1
!=
152 RegistryHive
->HiveHeader
->Sequence2
)
157 /* Update first update counter and checksum */
158 RegistryHive
->HiveHeader
->Type
= HV_TYPE_PRIMARY
;
159 RegistryHive
->HiveHeader
->Sequence1
++;
160 RegistryHive
->HiveHeader
->Checksum
=
161 HvpHiveHeaderChecksum(RegistryHive
->HiveHeader
);
163 /* Write hive block */
164 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_PRIMARY
,
165 0, RegistryHive
->HiveHeader
,
166 sizeof(HBASE_BLOCK
));
173 while (BlockIndex
< RegistryHive
->Storage
[HvStable
].Length
)
177 LastIndex
= BlockIndex
;
178 BlockIndex
= RtlFindSetBits(&RegistryHive
->DirtyVector
, 1, BlockIndex
);
179 if (BlockIndex
== ~0 || BlockIndex
< LastIndex
)
185 BlockPtr
= (PVOID
)RegistryHive
->Storage
[HvStable
].BlockList
[BlockIndex
].Block
;
186 FileOffset
= (ULONGLONG
)(BlockIndex
+ 1) * (ULONGLONG
)HV_BLOCK_SIZE
;
188 /* Write hive block */
189 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_PRIMARY
,
190 FileOffset
, BlockPtr
,
200 Success
= RegistryHive
->FileFlush(RegistryHive
, HV_TYPE_PRIMARY
);
203 DPRINT("FileFlush failed\n");
206 /* Update second update counter and checksum */
207 RegistryHive
->HiveHeader
->Sequence2
++;
208 RegistryHive
->HiveHeader
->Checksum
=
209 HvpHiveHeaderChecksum(RegistryHive
->HiveHeader
);
211 /* Write hive block */
212 Success
= RegistryHive
->FileWrite(RegistryHive
, HV_TYPE_PRIMARY
,
213 0, RegistryHive
->HiveHeader
,
214 sizeof(HBASE_BLOCK
));
220 Success
= RegistryHive
->FileFlush(RegistryHive
, HV_TYPE_PRIMARY
);
223 DPRINT("FileFlush failed\n");
233 ASSERT(RegistryHive
->ReadOnly
== FALSE
);
235 if (RtlFindSetBits(&RegistryHive
->DirtyVector
, 1, 0) == ~0)
240 /* Update hive header modification time */
241 KeQuerySystemTime(&RegistryHive
->HiveHeader
->TimeStamp
);
243 /* Update log file */
244 if (!HvpWriteLog(RegistryHive
))
249 /* Update hive file */
250 if (!HvpWriteHive(RegistryHive
, TRUE
))
255 /* Clear dirty bitmap. */
256 RtlClearAllBits(&RegistryHive
->DirtyVector
);
265 ASSERT(RegistryHive
->ReadOnly
== FALSE
);
267 /* Update hive header modification time */
268 KeQuerySystemTime(&RegistryHive
->HiveHeader
->TimeStamp
);
270 /* Update hive file */
271 if (!HvpWriteHive(RegistryHive
, FALSE
))