ReactOS 0.4.15-dev-7842-g558ab78
hivewrt.c File Reference
#include "cmlib.h"
#include <debug.h>
Include dependency graph for hivewrt.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI IoSetThreadHardErrorMode (_In_ BOOLEAN HardErrorEnabled)
 
static VOID HvpValidateBaseHeader (_In_ PHHIVE RegistryHive)
 Validates the base block header of a primary hive for consistency.
 
static BOOLEAN CMAPI HvpWriteLog (_In_ PHHIVE RegistryHive)
 Writes dirty data in a transacted way to a hive log file during hive syncing operation. Log files are used by the kernel/bootloader to perform recovery operations against a damaged primary hive.
 
static BOOLEAN CMAPI HvpWriteHive (_In_ PHHIVE RegistryHive, _In_ BOOLEAN OnlyDirty, _In_ ULONG FileType)
 Writes data (dirty or non) to a primary hive during syncing operation. Hive writing is also performed during a flush occurrence on request by the system.
 
BOOLEAN CMAPI HvSyncHive (_In_ PHHIVE RegistryHive)
 Synchronizes a registry hive with latest updates from dirty data present in volatile memory, aka RAM. It writes both to hive log and corresponding primary hive. Syncing is done on request by the system during a flush occurrence.
 
BOOLEAN CMAPI HvHiveWillShrink (_In_ PHHIVE RegistryHive)
 Determines whether a registry hive needs to be shrinked or not based on its overall size of the hive space to avoid unnecessary bloat.
 
BOOLEAN CMAPI HvWriteHive (_In_ PHHIVE RegistryHive)
 Writes data to a registry hive. Unlike HvSyncHive, this function just writes the wholy registry data to a primary hive, ignoring if a certain data block is dirty or not.
 
BOOLEAN CMAPI HvWriteAlternateHive (_In_ PHHIVE RegistryHive)
 Writes data to an alternate registry hive. An alternate hive is usually backed up by a primary hive. This function is tipically used to force write data into the alternate hive if both hives no longer match.
 
BOOLEAN CMAPI HvSyncHiveFromRecover (_In_ PHHIVE RegistryHive)
 Synchronizes a hive with recovered data during a healing/resuscitation operation of the registry.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file hivewrt.c.

Function Documentation

◆ HvHiveWillShrink()

BOOLEAN CMAPI HvHiveWillShrink ( _In_ PHHIVE  RegistryHive)

Determines whether a registry hive needs to be shrinked or not based on its overall size of the hive space to avoid unnecessary bloat.

@unimplemented

Parameters
[in]RegistryHiveA pointer to a hive descriptor where hive shrinking is to be determined.
Returns
Returns TRUE if hive shrinking needs to be done, FALSE otherwise.

Definition at line 570 of file hivewrt.c.

572{
573 /* No shrinking yet */
575 return FALSE;
576}
#define FALSE
Definition: types.h:117
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30

◆ HvpValidateBaseHeader()

static VOID HvpValidateBaseHeader ( _In_ PHHIVE  RegistryHive)
static

Validates the base block header of a primary hive for consistency.

Parameters
[in]RegistryHiveA pointer to a hive descriptor to look for the header block.

Definition at line 39 of file hivewrt.c.

41{
42 PHBASE_BLOCK BaseBlock;
43
44 /*
45 * Cache the base block and validate it.
46 * Especially...
47 *
48 * 1. It must must have a valid signature.
49 * 2. It must have a valid format.
50 * 3. It must be of an adequate major version,
51 * not anything else.
52 */
53 BaseBlock = RegistryHive->BaseBlock;
55 ASSERT(BaseBlock->Format == HBASE_FORMAT_MEMORY);
56 ASSERT(BaseBlock->Major == HSYS_MAJOR);
57}
#define HV_HBLOCK_SIGNATURE
Definition: hivedata.h:63
#define HSYS_MAJOR
Definition: hivedata.h:69
#define HBASE_FORMAT_MEMORY
Definition: hivedata.h:78
#define ASSERT(a)
Definition: mode.c:44
ULONG Major
Definition: hivedata.h:154
ULONG Signature
Definition: hivedata.h:144
ULONG Format
Definition: hivedata.h:164

Referenced by HvpWriteHive(), and HvpWriteLog().

◆ HvpWriteHive()

static BOOLEAN CMAPI HvpWriteHive ( _In_ PHHIVE  RegistryHive,
_In_ BOOLEAN  OnlyDirty,
_In_ ULONG  FileType 
)
static

Writes data (dirty or non) to a primary hive during syncing operation. Hive writing is also performed during a flush occurrence on request by the system.

Parameters
[in]RegistryHiveA pointer to a hive descriptor where the data is to be written to that hive.
[in]OnlyDirtyIf set to TRUE, the function only looks for dirty data to be written to the primary hive, otherwise if it's set to FALSE then the function writes all the data.
[in]FileTypeThe file type of a registry hive. This can be HFILE_TYPE_PRIMARY or HFILE_TYPE_ALTERNATE.
Returns
Returns TRUE if writing to hive has succeeded, FALSE otherwise.
Remarks
The on-disk header metadata of a hive is already written with type of HFILE_TYPE_PRIMARY, regardless of what file type the caller submits, as an alternate hive is basically a mirror of the primary hive.

Definition at line 311 of file hivewrt.c.

315{
318 ULONG BlockIndex;
319 ULONG LastIndex;
320 PVOID Block;
321
322 ASSERT(!RegistryHive->ReadOnly);
323 ASSERT(RegistryHive->BaseBlock->Length ==
324 RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
325 ASSERT(RegistryHive->BaseBlock->RootCell != HCELL_NIL);
326
327 /* Validate the base header before we go further */
328 HvpValidateBaseHeader(RegistryHive);
329
330 /*
331 * The sequences can diverge during a forced system shutdown
332 * occurrence, such as during a power failure, a hardware
333 * failure or during a system crash, and when one of the
334 * sequences have been modified during writing into the log
335 * or hive. In such cases the hive needs a repair.
336 */
337 if (RegistryHive->BaseBlock->Sequence1 !=
338 RegistryHive->BaseBlock->Sequence2)
339 {
340 DPRINT1("The sequences DO NOT MATCH (Sequence1 == 0x%x, Sequence2 == 0x%x)\n",
341 RegistryHive->BaseBlock->Sequence1, RegistryHive->BaseBlock->Sequence2);
342 return FALSE;
343 }
344
345 /*
346 * Update the primary sequence number and write
347 * the base block to hive.
348 */
349 RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
350 RegistryHive->BaseBlock->Sequence1++;
351 RegistryHive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
352
353 /* Write hive block */
354 FileOffset = 0;
355 Success = RegistryHive->FileWrite(RegistryHive, FileType,
356 &FileOffset, RegistryHive->BaseBlock,
357 sizeof(HBASE_BLOCK));
358 if (!Success)
359 {
360 DPRINT1("Failed to write the base block header to primary hive (primary sequence)\n");
361 return FALSE;
362 }
363
364 /* Write the whole primary hive, block by block */
365 BlockIndex = 0;
366 while (BlockIndex < RegistryHive->Storage[Stable].Length)
367 {
368 /*
369 * If we have to synchronize the registry hive we
370 * want to look for dirty blocks to reflect the new
371 * updates done to the hive. Otherwise just write
372 * all the blocks as if we were doing a regular
373 * hive write.
374 */
375 if (OnlyDirty)
376 {
377 /* Check if the block is clean or we're past the last block */
378 LastIndex = BlockIndex;
379 BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
380 if (BlockIndex == ~HV_CLEAN_BLOCK || BlockIndex < LastIndex)
381 {
382 break;
383 }
384 }
385
386 /* Get the block and offset position */
387 Block = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
388 FileOffset = (BlockIndex + 1) * HBLOCK_SIZE;
389
390 /* Now write this block to primary hive file */
391 Success = RegistryHive->FileWrite(RegistryHive, FileType,
392 &FileOffset, Block, HBLOCK_SIZE);
393 if (!Success)
394 {
395 DPRINT1("Failed to write hive block to primary hive file (block 0x%p, block index 0x%x)\n",
396 Block, BlockIndex);
397 return FALSE;
398 }
399
400 /* Go to the next block */
401 BlockIndex++;
402 }
403
404 /*
405 * We wrote all the hive contents to the file, we
406 * must flush the changes to disk now.
407 */
408 Success = RegistryHive->FileFlush(RegistryHive, FileType, NULL, 0);
409 if (!Success)
410 {
411 DPRINT1("Failed to flush the primary hive\n");
412 return FALSE;
413 }
414
415 /*
416 * Increment the secondary sequence number and
417 * update the checksum. A successful hive write
418 * transaction is when both of sequences are the
419 * same, indicating the write operation didn't
420 * fail.
421 */
422 RegistryHive->BaseBlock->Sequence2++;
423 RegistryHive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
424
425 /* Write hive block */
426 FileOffset = 0;
427 Success = RegistryHive->FileWrite(RegistryHive, FileType,
428 &FileOffset, RegistryHive->BaseBlock,
429 sizeof(HBASE_BLOCK));
430 if (!Success)
431 {
432 DPRINT1("Failed to write the base block header to primary hive (secondary sequence)\n");
433 return FALSE;
434 }
435
436 /* Flush the hive immediately */
437 Success = RegistryHive->FileFlush(RegistryHive, FileType, NULL, 0);
438 if (!Success)
439 {
440 DPRINT1("Failed to flush the primary hive\n");
441 return FALSE;
442 }
443
444 return TRUE;
445}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
@ Success
Definition: eventcreate.c:712
@ Stable
Definition: hivedata.h:127
#define HBLOCK_SIZE
Definition: hivedata.h:42
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
#define HV_CLEAN_BLOCK
Definition: hivedata.h:51
#define HCELL_NIL
Definition: hivedata.h:110
static VOID HvpValidateBaseHeader(_In_ PHHIVE RegistryHive)
Validates the base block header of a primary hive for consistency.
Definition: hivewrt.c:39
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
static IStorage Storage
Definition: ole2.c:3548
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741

Referenced by HvSyncHive(), HvSyncHiveFromRecover(), HvWriteAlternateHive(), and HvWriteHive().

◆ HvpWriteLog()

static BOOLEAN CMAPI HvpWriteLog ( _In_ PHHIVE  RegistryHive)
static

Writes dirty data in a transacted way to a hive log file during hive syncing operation. Log files are used by the kernel/bootloader to perform recovery operations against a damaged primary hive.

@unimplemented

Parameters
[in]RegistryHiveA pointer to a hive descriptor where the log belongs to and of which we write data into the said log.
Returns
Returns TRUE if log transaction writing has succeeded, FALSE otherwise.
Remarks
The function is not completely implemented, that is, it lacks the implementation for growing the log file size. See the FIXME comment below for further details.

Definition at line 85 of file hivewrt.c.

87{
90 ULONG BlockIndex;
91 ULONG LastIndex;
92 PVOID Block;
93 UINT32 BitmapSize, BufferSize;
94 PUCHAR HeaderBuffer, Ptr;
95
96 /*
97 * The hive log we are going to write data into
98 * has to be writable and with a sane storage.
99 */
100 ASSERT(!RegistryHive->ReadOnly);
101 ASSERT(RegistryHive->BaseBlock->Length ==
102 RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
103
104 /* Validate the base header before we go further */
105 HvpValidateBaseHeader(RegistryHive);
106
107 /*
108 * The sequences can diverge during a forced system shutdown
109 * occurrence, such as during a power failure, a hardware
110 * failure or during a system crash, and when one of the
111 * sequences have been modified during writing into the log
112 * or hive. In such cases the hive needs a repair.
113 */
114 if (RegistryHive->BaseBlock->Sequence1 !=
115 RegistryHive->BaseBlock->Sequence2)
116 {
117 DPRINT1("The sequences DO NOT MATCH (Sequence1 == 0x%x, Sequence2 == 0x%x)\n",
118 RegistryHive->BaseBlock->Sequence1, RegistryHive->BaseBlock->Sequence2);
119 return FALSE;
120 }
121
122 /*
123 * FIXME: We must set a new file size for this log
124 * here but ReactOS lacks the necessary code implementation
125 * that manages the growing and shrinking of a hive's log
126 * size. So for now don't set any new size for the log.
127 */
128
129 /*
130 * Now calculate the bitmap and buffer sizes to hold up our
131 * contents in a buffer.
132 */
133 BitmapSize = ROUND_UP(sizeof(ULONG) + RegistryHive->DirtyVector.SizeOfBitMap, HSECTOR_SIZE);
134 BufferSize = HV_LOG_HEADER_SIZE + BitmapSize;
135
136 /* Now allocate the base header block buffer */
137 HeaderBuffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
138 if (!HeaderBuffer)
139 {
140 DPRINT1("Couldn't allocate buffer for base header block\n");
141 return FALSE;
142 }
143
144 /* Great, now zero out the buffer */
145 RtlZeroMemory(HeaderBuffer, BufferSize);
146
147 /*
148 * Update the base block of this hive and
149 * increment the primary sequence number
150 * as we are at the half of the work.
151 */
152 RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
153 RegistryHive->BaseBlock->Sequence1++;
154 RegistryHive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
155
156 /* Copy the base block header */
157 RtlCopyMemory(HeaderBuffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
158 Ptr = HeaderBuffer + HV_LOG_HEADER_SIZE;
159
160 /* Copy the dirty vector */
162 Ptr += sizeof(HV_LOG_DIRTY_SIGNATURE);
163
164 /*
165 * FIXME: In ReactOS a vector contains one bit per block
166 * whereas in Windows each bit within a vector is per
167 * sector. Furthermore, the dirty blocks within a respective
168 * hive has to be marked as such in an appropriate function
169 * for this purpose (probably HvMarkDirty or similar).
170 *
171 * For the moment being, mark the relevant dirty blocks
172 * here.
173 */
174 BlockIndex = 0;
175 while (BlockIndex < RegistryHive->Storage[Stable].Length)
176 {
177 /* Check if the block is clean or we're past the last block */
178 LastIndex = BlockIndex;
179 BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
180 if (BlockIndex == ~HV_CLEAN_BLOCK || BlockIndex < LastIndex)
181 {
182 break;
183 }
184
185 /*
186 * Mark this block as dirty and go to the next one.
187 *
188 * FIXME: We should rather use RtlSetBits but that crashes
189 * the system with a bugckeck. So for now mark blocks manually
190 * by hand.
191 */
192 Ptr[BlockIndex] = HV_LOG_DIRTY_BLOCK;
193 BlockIndex++;
194 }
195
196 /* Now write the hive header and block bitmap into the log */
197 FileOffset = 0;
198 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
199 &FileOffset, HeaderBuffer, BufferSize);
200 RegistryHive->Free(HeaderBuffer, 0);
201 if (!Success)
202 {
203 DPRINT1("Failed to write the hive header block to log (primary sequence)\n");
204 return FALSE;
205 }
206
207 /* Now write the actual dirty data to log */
209 BlockIndex = 0;
210 while (BlockIndex < RegistryHive->Storage[Stable].Length)
211 {
212 /* Check if the block is clean or we're past the last block */
213 LastIndex = BlockIndex;
214 BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
215 if (BlockIndex == ~HV_CLEAN_BLOCK || BlockIndex < LastIndex)
216 {
217 break;
218 }
219
220 /* Get the block */
221 Block = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
222
223 /* Write it to log */
224 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
225 &FileOffset, Block, HBLOCK_SIZE);
226 if (!Success)
227 {
228 DPRINT1("Failed to write dirty block to log (block 0x%p, block index 0x%x)\n", Block, BlockIndex);
229 return FALSE;
230 }
231
232 /* Grow up the file offset as we go to the next block */
233 BlockIndex++;
235 }
236
237 /*
238 * We wrote the header and body of log with dirty,
239 * data do a flush immediately.
240 */
241 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
242 if (!Success)
243 {
244 DPRINT1("Failed to flush the log\n");
245 return FALSE;
246 }
247
248 /*
249 * OK, we're now at 80% of the work done.
250 * Increment the secondary sequence and flush
251 * the log again. We can have a fully successful
252 * transacted write of a log if the sequences
253 * are synced up properly.
254 */
255 RegistryHive->BaseBlock->Sequence2++;
256 RegistryHive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
257
258 /* Write new stuff into log first */
259 FileOffset = 0;
260 Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
261 &FileOffset, RegistryHive->BaseBlock,
263 if (!Success)
264 {
265 DPRINT1("Failed to write the log file (secondary sequence)\n");
266 return FALSE;
267 }
268
269 /* Flush it finally */
270 Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
271 if (!Success)
272 {
273 DPRINT1("Failed to flush the log\n");
274 return FALSE;
275 }
276
277 return TRUE;
278}
unsigned int UINT32
#define TAG_CM
Definition: cmlib.h:212
#define BufferSize
Definition: mmc.h:75
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define HV_LOG_HEADER_SIZE
Definition: hivedata.h:46
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
#define HV_LOG_DIRTY_BLOCK
Definition: hivedata.h:56
#define HV_LOG_DIRTY_SIGNATURE
Definition: hivedata.h:57
#define HSECTOR_SIZE
Definition: hivedata.h:43
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by HvSyncHive().

◆ HvSyncHive()

BOOLEAN CMAPI HvSyncHive ( _In_ PHHIVE  RegistryHive)

Synchronizes a registry hive with latest updates from dirty data present in volatile memory, aka RAM. It writes both to hive log and corresponding primary hive. Syncing is done on request by the system during a flush occurrence.

Parameters
[in]RegistryHiveA pointer to a hive descriptor where syncing is to be performed.
Returns
Returns TRUE if syncing has succeeded, FALSE otherwise.

Definition at line 466 of file hivewrt.c.

468{
469#if !defined(CMLIB_HOST) && !defined(_BLDR_)
470 BOOLEAN HardErrors;
471#endif
472
473 ASSERT(!RegistryHive->ReadOnly);
474 ASSERT(RegistryHive->Signature == HV_HHIVE_SIGNATURE);
475
476 /* Avoid any write operations on volatile hives */
477 if (RegistryHive->HiveFlags & HIVE_VOLATILE)
478 {
479 DPRINT("Hive 0x%p is volatile\n", RegistryHive);
480 return TRUE;
481 }
482
483 /*
484 * Check if there's any dirty data in the vector.
485 * A space with clean blocks would be pointless for
486 * a log because we want to write dirty data in and
487 * sync up, not clean data. So just consider our
488 * job as done as there's literally nothing to do.
489 */
490 if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~HV_CLEAN_BLOCK)
491 {
492 DPRINT("The dirty vector has clean data, nothing to do\n");
493 return TRUE;
494 }
495
496#if !defined(CMLIB_HOST) && !defined(_BLDR_)
497 /* Disable hard errors before syncing the hive */
498 HardErrors = IoSetThreadHardErrorMode(FALSE);
499#endif
500
501#if !defined(_BLDR_)
502 /* Update hive header modification time */
503 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
504#endif
505
506 /* Update the hive log file if present */
507 if (RegistryHive->Log)
508 {
509 if (!HvpWriteLog(RegistryHive))
510 {
511 DPRINT1("Failed to write a log whilst syncing the hive\n");
512#if !defined(CMLIB_HOST) && !defined(_BLDR_)
513 IoSetThreadHardErrorMode(HardErrors);
514#endif
515 return FALSE;
516 }
517 }
518
519 /* Update the primary hive file */
520 if (!HvpWriteHive(RegistryHive, TRUE, HFILE_TYPE_PRIMARY))
521 {
522 DPRINT1("Failed to write the primary hive\n");
523#if !defined(CMLIB_HOST) && !defined(_BLDR_)
524 IoSetThreadHardErrorMode(HardErrors);
525#endif
526 return FALSE;
527 }
528
529 /* Update the alternate hive file if present */
530 if (RegistryHive->Alternate)
531 {
532 if (!HvpWriteHive(RegistryHive, TRUE, HFILE_TYPE_ALTERNATE))
533 {
534 DPRINT1("Failed to write the alternate hive\n");
535#if !defined(CMLIB_HOST) && !defined(_BLDR_)
536 IoSetThreadHardErrorMode(HardErrors);
537#endif
538 return FALSE;
539 }
540 }
541
542 /* Clear dirty bitmap. */
543 RtlClearAllBits(&RegistryHive->DirtyVector);
544 RegistryHive->DirtyCount = 0;
545
546#if !defined(CMLIB_HOST) && !defined(_BLDR_)
547 IoSetThreadHardErrorMode(HardErrors);
548#endif
549 return TRUE;
550}
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define HV_HHIVE_SIGNATURE
Definition: hivedata.h:62
#define HFILE_TYPE_ALTERNATE
Definition: hivedata.h:36
#define HIVE_VOLATILE
Definition: hivedata.h:23
static BOOLEAN CMAPI HvpWriteHive(_In_ PHHIVE RegistryHive, _In_ BOOLEAN OnlyDirty, _In_ ULONG FileType)
Writes data (dirty or non) to a primary hive during syncing operation. Hive writing is also performed...
Definition: hivewrt.c:311
BOOLEAN NTAPI IoSetThreadHardErrorMode(_In_ BOOLEAN HardErrorEnabled)
static BOOLEAN CMAPI HvpWriteLog(_In_ PHHIVE RegistryHive)
Writes dirty data in a transacted way to a hive log file during hive syncing operation....
Definition: hivewrt.c:85
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
#define DPRINT
Definition: sndvol32.h:71

◆ HvSyncHiveFromRecover()

BOOLEAN CMAPI HvSyncHiveFromRecover ( _In_ PHHIVE  RegistryHive)

Synchronizes a hive with recovered data during a healing/resuscitation operation of the registry.

Parameters
[in]RegistryHiveA pointer to a hive descriptor where data syncing is to be done.
Returns
Returns TRUE if hive syncing during recovery succeeded, FALSE otherwise.

Definition at line 672 of file hivewrt.c.

674{
675 ASSERT(!RegistryHive->ReadOnly);
676 ASSERT(RegistryHive->Signature == HV_HHIVE_SIGNATURE);
677
678 /* Call the private API call to do the deed for us */
679 return HvpWriteHive(RegistryHive, TRUE, HFILE_TYPE_PRIMARY);
680}

Referenced by HvInitialize().

◆ HvWriteAlternateHive()

BOOLEAN CMAPI HvWriteAlternateHive ( _In_ PHHIVE  RegistryHive)

Writes data to an alternate registry hive. An alternate hive is usually backed up by a primary hive. This function is tipically used to force write data into the alternate hive if both hives no longer match.

Parameters
[in]RegistryHiveA pointer to a hive descriptor where data is to be written into.
Returns
Returns TRUE if hive writing has succeeded, FALSE otherwise.

Definition at line 634 of file hivewrt.c.

636{
637 ASSERT(!RegistryHive->ReadOnly);
638 ASSERT(RegistryHive->Signature == HV_HHIVE_SIGNATURE);
639 ASSERT(RegistryHive->Alternate);
640
641#if !defined(_BLDR_)
642 /* Update hive header modification time */
643 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
644#endif
645
646 /* Update hive file */
647 if (!HvpWriteHive(RegistryHive, FALSE, HFILE_TYPE_ALTERNATE))
648 {
649 DPRINT1("Failed to write the alternate hive\n");
650 return FALSE;
651 }
652
653 return TRUE;
654}

Referenced by _Function_class_().

◆ HvWriteHive()

BOOLEAN CMAPI HvWriteHive ( _In_ PHHIVE  RegistryHive)

Writes data to a registry hive. Unlike HvSyncHive, this function just writes the wholy registry data to a primary hive, ignoring if a certain data block is dirty or not.

Parameters
[in]RegistryHiveA pointer to a hive descriptor where data is be written into.
Returns
Returns TRUE if hive writing has succeeded, FALSE otherwise.

Definition at line 596 of file hivewrt.c.

598{
599 ASSERT(!RegistryHive->ReadOnly);
600 ASSERT(RegistryHive->Signature == HV_HHIVE_SIGNATURE);
601
602#if !defined(_BLDR_)
603 /* Update hive header modification time */
604 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
605#endif
606
607 /* Update hive file */
608 if (!HvpWriteHive(RegistryHive, FALSE, HFILE_TYPE_PRIMARY))
609 {
610 DPRINT1("Failed to write the hive\n");
611 return FALSE;
612 }
613
614 return TRUE;
615}

◆ IoSetThreadHardErrorMode()

BOOLEAN NTAPI IoSetThreadHardErrorMode ( _In_ BOOLEAN  HardErrorEnabled)

Referenced by HvSyncHive().