ReactOS  0.4.14-dev-552-g2fad488
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 
12 static BOOLEAN CMAPI
14  PHHIVE RegistryHive)
15 {
18  UINT32 BitmapSize;
19  PUCHAR Buffer;
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 
146 static 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 
275 BOOLEAN
276 CMAPI
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 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
PULONG Buffer
Definition: typedefs.h:89
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG Sequence2
Definition: hivedata.h:123
#define HBLOCK_SIZE
Definition: hivedata.h:41
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
BOOLEAN CMAPI HvWriteHive(PHHIVE RegistryHive)
Definition: hivewrt.c:285
RTL_BITMAP DirtyVector
Definition: hivedata.h:304
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define U(x)
Definition: wordpad.c:44
BOOLEAN ReadOnly
Definition: hivedata.h:310
ULONG_PTR BlockAddress
Definition: hivedata.h:258
PFREE_ROUTINE Free
Definition: hivedata.h:294
PALLOCATE_ROUTINE Allocate
Definition: hivedata.h:293
ULONG Length
Definition: hivedata.h:146
ULONG DirtyCount
Definition: hivedata.h:305
LARGE_INTEGER TimeStamp
Definition: hivedata.h:126
#define CMAPI
Definition: cfgmgr32.h:41
unsigned int UINT32
ULONG Sequence1
Definition: hivedata.h:122
ULONG CheckSum
Definition: hivedata.h:158
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
PFILE_SET_SIZE_ROUTINE FileSetSize
Definition: hivedata.h:295
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
#define BufferSize
Definition: classpnp.h:419
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TAG_CM
Definition: cmlib.h:203
#define HV_LOG_HEADER_SIZE
Definition: hivedata.h:45
PFILE_WRITE_ROUTINE FileWrite
Definition: hivedata.h:296
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
ULONG SizeOfBitMap
Definition: typedefs.h:88
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
static BOOLEAN CMAPI HvpWriteHive(PHHIVE RegistryHive, BOOLEAN OnlyDirty)
Definition: hivewrt.c:147
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
static BOOLEAN CMAPI HvpWriteLog(PHHIVE RegistryHive)
Definition: hivewrt.c:13
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
PFILE_FLUSH_ROUTINE FileFlush
Definition: hivedata.h:298
ULONG Length
Definition: hivedata.h:276
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
Definition: hivewrt.c:277
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static IStorage Storage
Definition: ole2.c:3548
ULONG Type
Definition: hivedata.h:136