+++ /dev/null
-/*
- * PROJECT: Registry manipulation library
- * LICENSE: GPL - See COPYING in the top level directory
- * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
- * Copyright 2001 - 2005 Eric Kohl
- */
-
-#include "cmlib.h"
-#define NDEBUG
-#include <debug.h>
-
-static BOOLEAN CMAPI
-HvpWriteLog(
- PHHIVE RegistryHive)
-{
- ULONG FileOffset;
- UINT32 BufferSize;
- UINT32 BitmapSize;
- PUCHAR Buffer;
- PUCHAR Ptr;
- ULONG BlockIndex;
- ULONG LastIndex;
- PVOID BlockPtr;
- BOOLEAN Success;
- static ULONG PrintCount = 0;
-
- if (PrintCount++ == 0)
- {
- UNIMPLEMENTED;
- }
- return TRUE;
-
- ASSERT(RegistryHive->ReadOnly == FALSE);
- ASSERT(RegistryHive->BaseBlock->Length ==
- RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
-
- DPRINT("HvpWriteLog called\n");
-
- if (RegistryHive->BaseBlock->Sequence1 !=
- RegistryHive->BaseBlock->Sequence2)
- {
- return FALSE;
- }
-
- BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap;
- BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
- BufferSize = ROUND_UP(BufferSize, HBLOCK_SIZE);
-
- DPRINT("Bitmap size %u buffer size: %u\n", BitmapSize, BufferSize);
-
- Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
- if (Buffer == NULL)
- {
- return FALSE;
- }
-
- /* Update first update counter and CheckSum */
- RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
- RegistryHive->BaseBlock->Sequence1++;
- RegistryHive->BaseBlock->CheckSum =
- HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
-
- /* Copy hive header */
- RtlCopyMemory(Buffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
- Ptr = Buffer + HV_LOG_HEADER_SIZE;
- RtlCopyMemory(Ptr, "DIRT", 4);
- Ptr += 4;
- RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);
-
- /* Write hive block and block bitmap */
- FileOffset = 0;
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
- &FileOffset, Buffer, BufferSize);
- RegistryHive->Free(Buffer, 0);
-
- if (!Success)
- {
- return FALSE;
- }
-
- /* Write dirty blocks */
- FileOffset = BufferSize;
- BlockIndex = 0;
- while (BlockIndex < RegistryHive->Storage[Stable].Length)
- {
- LastIndex = BlockIndex;
- BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
- if (BlockIndex == ~0U || BlockIndex < LastIndex)
- {
- break;
- }
-
- BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
-
- /* Write hive block */
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
- &FileOffset, BlockPtr, HBLOCK_SIZE);
- if (!Success)
- {
- return FALSE;
- }
-
- BlockIndex++;
- FileOffset += HBLOCK_SIZE;
- }
-
- Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
- if (!Success)
- {
- DPRINT("FileSetSize failed\n");
- return FALSE;
- }
-
- /* Flush the log file */
- Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
- if (!Success)
- {
- DPRINT("FileFlush failed\n");
- }
-
- /* Update second update counter and CheckSum */
- RegistryHive->BaseBlock->Sequence2++;
- RegistryHive->BaseBlock->CheckSum =
- HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
-
- /* Write hive header again with updated sequence counter. */
- FileOffset = 0;
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
- &FileOffset, RegistryHive->BaseBlock,
- HV_LOG_HEADER_SIZE);
- if (!Success)
- {
- return FALSE;
- }
-
- /* Flush the log file */
- Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
- if (!Success)
- {
- DPRINT("FileFlush failed\n");
- }
-
- return TRUE;
-}
-
-static BOOLEAN CMAPI
-HvpWriteHive(
- PHHIVE RegistryHive,
- BOOLEAN OnlyDirty)
-{
- ULONG FileOffset;
- ULONG BlockIndex;
- ULONG LastIndex;
- PVOID BlockPtr;
- BOOLEAN Success;
-
- ASSERT(RegistryHive->ReadOnly == FALSE);
- ASSERT(RegistryHive->BaseBlock->Length ==
- RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
-
- DPRINT("HvpWriteHive called\n");
-
- if (RegistryHive->BaseBlock->Sequence1 !=
- RegistryHive->BaseBlock->Sequence2)
- {
- return FALSE;
- }
-
- /* Update first update counter and CheckSum */
- RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
- RegistryHive->BaseBlock->Sequence1++;
- RegistryHive->BaseBlock->CheckSum =
- HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
-
- /* Write hive block */
- FileOffset = 0;
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
- &FileOffset, RegistryHive->BaseBlock,
- sizeof(HBASE_BLOCK));
- if (!Success)
- {
- return FALSE;
- }
-
- BlockIndex = 0;
- while (BlockIndex < RegistryHive->Storage[Stable].Length)
- {
- if (OnlyDirty)
- {
- LastIndex = BlockIndex;
- BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
- if (BlockIndex == ~0U || BlockIndex < LastIndex)
- {
- break;
- }
- }
-
- BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
- FileOffset = (BlockIndex + 1) * HBLOCK_SIZE;
-
- /* Write hive block */
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
- &FileOffset, BlockPtr, HBLOCK_SIZE);
- if (!Success)
- {
- return FALSE;
- }
-
- BlockIndex++;
- }
-
- Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
- if (!Success)
- {
- DPRINT("FileFlush failed\n");
- }
-
- /* Update second update counter and CheckSum */
- RegistryHive->BaseBlock->Sequence2++;
- RegistryHive->BaseBlock->CheckSum =
- HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
-
- /* Write hive block */
- FileOffset = 0;
- Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
- &FileOffset, RegistryHive->BaseBlock,
- sizeof(HBASE_BLOCK));
- if (!Success)
- {
- return FALSE;
- }
-
- Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
- if (!Success)
- {
- DPRINT("FileFlush failed\n");
- }
-
- return TRUE;
-}
-
-BOOLEAN CMAPI
-HvSyncHive(
- PHHIVE RegistryHive)
-{
- ASSERT(RegistryHive->ReadOnly == FALSE);
-
- if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
- {
- return TRUE;
- }
-
- /* Update hive header modification time */
- KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
-
- /* Update log file */
- if (!HvpWriteLog(RegistryHive))
- {
- return FALSE;
- }
-
- /* Update hive file */
- if (!HvpWriteHive(RegistryHive, TRUE))
- {
- return FALSE;
- }
-
- /* Clear dirty bitmap. */
- RtlClearAllBits(&RegistryHive->DirtyVector);
- RegistryHive->DirtyCount = 0;
-
- return TRUE;
-}
-
-BOOLEAN
-CMAPI
-HvHiveWillShrink(IN PHHIVE RegistryHive)
-{
- /* No shrinking yet */
- UNIMPLEMENTED;
- return FALSE;
-}
-
-BOOLEAN CMAPI
-HvWriteHive(
- PHHIVE RegistryHive)
-{
- ASSERT(RegistryHive->ReadOnly == FALSE);
-
- /* Update hive header modification time */
- KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
-
- /* Update hive file */
- if (!HvpWriteHive(RegistryHive, FALSE))
- {
- return FALSE;
- }
-
- return TRUE;
-}