ReactOS 0.4.15-dev-5865-g640e228
hivewrt.c
Go to the documentation of this file.
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 2001 - 2005 Eric Kohl
6 */
7
8#include "cmlib.h"
9#define NDEBUG
10#include <debug.h>
11
12static BOOLEAN CMAPI
14 PHHIVE RegistryHive)
15{
18 UINT32 BitmapSize;
20 PUCHAR Ptr;
21 ULONG BlockIndex;
22 ULONG LastIndex;
23 PVOID BlockPtr;
25 static ULONG PrintCount = 0;
26
27 if (PrintCount++ == 0)
28 {
30 }
31 return TRUE;
32
33 ASSERT(RegistryHive->ReadOnly == FALSE);
34 ASSERT(RegistryHive->BaseBlock->Length ==
35 RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
36
37 DPRINT("HvpWriteLog called\n");
38
39 if (RegistryHive->BaseBlock->Sequence1 !=
40 RegistryHive->BaseBlock->Sequence2)
41 {
42 return FALSE;
43 }
44
45 BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap;
46 BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
48
49 DPRINT("Bitmap size %u buffer size: %u\n", BitmapSize, BufferSize);
50
51 Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
52 if (Buffer == NULL)
53 {
54 return FALSE;
55 }
56
57 /* Update first update counter and CheckSum */
58 RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
59 RegistryHive->BaseBlock->Sequence1++;
60 RegistryHive->BaseBlock->CheckSum =
61 HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
62
63 /* Copy hive header */
66 RtlCopyMemory(Ptr, "DIRT", 4);
67 Ptr += 4;
68 RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);
69
70 /* Write hive block and block bitmap */
71 FileOffset = 0;
72 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
74 RegistryHive->Free(Buffer, 0);
75
76 if (!Success)
77 {
78 return FALSE;
79 }
80
81 /* Write dirty blocks */
83 BlockIndex = 0;
84 while (BlockIndex < RegistryHive->Storage[Stable].Length)
85 {
86 LastIndex = BlockIndex;
87 BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
88 if (BlockIndex == ~0U || BlockIndex < LastIndex)
89 {
90 break;
91 }
92
93 BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
94
95 /* Write hive block */
96 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
97 &FileOffset, BlockPtr, HBLOCK_SIZE);
98 if (!Success)
99 {
100 return FALSE;
101 }
102
103 BlockIndex++;
105 }
106
107 Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
108 if (!Success)
109 {
110 DPRINT("FileSetSize failed\n");
111 return FALSE;
112 }
113
114 /* Flush the log file */
115 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
116 if (!Success)
117 {
118 DPRINT("FileFlush failed\n");
119 }
120
121 /* Update second update counter and CheckSum */
122 RegistryHive->BaseBlock->Sequence2++;
123 RegistryHive->BaseBlock->CheckSum =
124 HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
125
126 /* Write hive header again with updated sequence counter. */
127 FileOffset = 0;
128 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
129 &FileOffset, RegistryHive->BaseBlock,
131 if (!Success)
132 {
133 return FALSE;
134 }
135
136 /* Flush the log file */
137 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
138 if (!Success)
139 {
140 DPRINT("FileFlush failed\n");
141 }
142
143 return TRUE;
144}
145
146static BOOLEAN CMAPI
148 PHHIVE RegistryHive,
149 BOOLEAN OnlyDirty)
150{
152 ULONG BlockIndex;
153 ULONG LastIndex;
154 PVOID BlockPtr;
156
157 ASSERT(RegistryHive->ReadOnly == FALSE);
158 ASSERT(RegistryHive->BaseBlock->Length ==
159 RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
160
161 DPRINT("HvpWriteHive called\n");
162
163 if (RegistryHive->BaseBlock->Sequence1 !=
164 RegistryHive->BaseBlock->Sequence2)
165 {
166 return FALSE;
167 }
168
169 /* Update first update counter and CheckSum */
170 RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
171 RegistryHive->BaseBlock->Sequence1++;
172 RegistryHive->BaseBlock->CheckSum =
173 HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
174
175 /* Write hive block */
176 FileOffset = 0;
177 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
178 &FileOffset, RegistryHive->BaseBlock,
179 sizeof(HBASE_BLOCK));
180 if (!Success)
181 {
182 return FALSE;
183 }
184
185 BlockIndex = 0;
186 while (BlockIndex < RegistryHive->Storage[Stable].Length)
187 {
188 if (OnlyDirty)
189 {
190 LastIndex = BlockIndex;
191 BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
192 if (BlockIndex == ~0U || BlockIndex < LastIndex)
193 {
194 break;
195 }
196 }
197
198 BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
199 FileOffset = (BlockIndex + 1) * HBLOCK_SIZE;
200
201 /* Write hive block */
202 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
203 &FileOffset, BlockPtr, HBLOCK_SIZE);
204 if (!Success)
205 {
206 return FALSE;
207 }
208
209 BlockIndex++;
210 }
211
212 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
213 if (!Success)
214 {
215 DPRINT("FileFlush failed\n");
216 }
217
218 /* Update second update counter and CheckSum */
219 RegistryHive->BaseBlock->Sequence2++;
220 RegistryHive->BaseBlock->CheckSum =
221 HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
222
223 /* Write hive block */
224 FileOffset = 0;
225 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
226 &FileOffset, RegistryHive->BaseBlock,
227 sizeof(HBASE_BLOCK));
228 if (!Success)
229 {
230 return FALSE;
231 }
232
233 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
234 if (!Success)
235 {
236 DPRINT("FileFlush failed\n");
237 }
238
239 return TRUE;
240}
241
244 PHHIVE RegistryHive)
245{
246 ASSERT(RegistryHive->ReadOnly == FALSE);
247
248 if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
249 {
250 return TRUE;
251 }
252
253 /* Update hive header modification time */
254 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
255
256 /* Update log file */
257 if (!HvpWriteLog(RegistryHive))
258 {
259 return FALSE;
260 }
261
262 /* Update hive file */
263 if (!HvpWriteHive(RegistryHive, TRUE))
264 {
265 return FALSE;
266 }
267
268 /* Clear dirty bitmap. */
269 RtlClearAllBits(&RegistryHive->DirtyVector);
270 RegistryHive->DirtyCount = 0;
271
272 return TRUE;
273}
274
276CMAPI
278{
279 /* No shrinking yet */
281 return FALSE;
282}
283
286 PHHIVE RegistryHive)
287{
288 ASSERT(RegistryHive->ReadOnly == FALSE);
289
290 /* Update hive header modification time */
291 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
292
293 /* Update hive file */
294 if (!HvpWriteHive(RegistryHive, FALSE))
295 {
296 return FALSE;
297 }
298
299 return TRUE;
300}
unsigned char BOOLEAN
unsigned int UINT32
#define U(x)
Definition: wordpad.c:45
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define CMAPI
Definition: cfgmgr32.h:41
Definition: bufpool.h:45
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17
#define TAG_CM
Definition: cmlib.h:205
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
@ Success
Definition: eventcreate.c:712
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
@ Stable
Definition: hivedata.h:102
#define HBLOCK_SIZE
Definition: hivedata.h:41
#define HV_LOG_HEADER_SIZE
Definition: hivedata.h:45
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
Definition: hivewrt.c:277
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
static BOOLEAN CMAPI HvpWriteLog(PHHIVE RegistryHive)
Definition: hivewrt.c:13
static BOOLEAN CMAPI HvpWriteHive(PHHIVE RegistryHive, BOOLEAN OnlyDirty)
Definition: hivewrt.c:147
BOOLEAN CMAPI HvWriteHive(PHHIVE RegistryHive)
Definition: hivewrt.c:285
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
#define ASSERT(a)
Definition: mode.c:44
static IStorage Storage
Definition: ole2.c:3548
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define DPRINT
Definition: sndvol32.h:71
ULONG Length
Definition: hivedata.h:276
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
ULONG Length
Definition: hivedata.h:146
ULONG Sequence1
Definition: hivedata.h:122
ULONG Type
Definition: hivedata.h:136
LARGE_INTEGER TimeStamp
Definition: hivedata.h:126
ULONG CheckSum
Definition: hivedata.h:158
ULONG Sequence2
Definition: hivedata.h:123
RTL_BITMAP DirtyVector
Definition: hivedata.h:304
PFILE_FLUSH_ROUTINE FileFlush
Definition: hivedata.h:298
PFILE_SET_SIZE_ROUTINE FileSetSize
Definition: hivedata.h:295
PFILE_WRITE_ROUTINE FileWrite
Definition: hivedata.h:296
PALLOCATE_ROUTINE Allocate
Definition: hivedata.h:293
PFREE_ROUTINE Free
Definition: hivedata.h:294
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
ULONG DirtyCount
Definition: hivedata.h:305
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
BOOLEAN ReadOnly
Definition: hivedata.h:310
ULONG_PTR BlockAddress
Definition: hivedata.h:258
ULONG SizeOfBitMap
Definition: typedefs.h:90
PULONG Buffer
Definition: typedefs.h:91
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254