mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:25:48 +00:00
Write log file header, block bitmap and dirty blocks.
svn path=/trunk/; revision=4166
This commit is contained in:
parent
32bef2128d
commit
acea065ea0
2 changed files with 166 additions and 11 deletions
|
@ -247,6 +247,7 @@ typedef struct _REGISTRY_HIVE
|
||||||
UNICODE_STRING LogFileName;
|
UNICODE_STRING LogFileName;
|
||||||
ULONG FileSize;
|
ULONG FileSize;
|
||||||
PHIVE_HEADER HiveHeader;
|
PHIVE_HEADER HiveHeader;
|
||||||
|
ULONG UpdateCounter;
|
||||||
ULONG BlockListSize;
|
ULONG BlockListSize;
|
||||||
PHBIN *BlockList;
|
PHBIN *BlockList;
|
||||||
ULONG FreeListSize;
|
ULONG FreeListSize;
|
||||||
|
|
|
@ -611,6 +611,9 @@ CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
|
|
||||||
/* FIXME: Check hive header */
|
/* FIXME: Check hive header */
|
||||||
|
|
||||||
|
/* Read update counter */
|
||||||
|
RegistryHive->UpdateCounter = RegistryHive->HiveHeader->UpdateCounter1;
|
||||||
|
|
||||||
Status = NtQueryInformationFile(FileHandle,
|
Status = NtQueryInformationFile(FileHandle,
|
||||||
&IoSB,
|
&IoSB,
|
||||||
&fsi,
|
&fsi,
|
||||||
|
@ -902,6 +905,156 @@ CmiCalcChecksum(PULONG Buffer)
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiStartLogUpdate(PREGISTRY_HIVE RegistryHive)
|
CmiStartLogUpdate(PREGISTRY_HIVE RegistryHive)
|
||||||
{
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
ULONG BufferSize;
|
||||||
|
ULONG BitmapSize;
|
||||||
|
PUCHAR Buffer;
|
||||||
|
PUCHAR Ptr;
|
||||||
|
ULONG BlockIndex;
|
||||||
|
ULONG BlockOffset;
|
||||||
|
PVOID BlockPtr;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT1("CmiStartLogUpdate() called\n");
|
||||||
|
|
||||||
|
BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8;
|
||||||
|
BufferSize = sizeof(HIVE_HEADER) +
|
||||||
|
sizeof(ULONG) +
|
||||||
|
BitmapSize;
|
||||||
|
BufferSize = ROUND_UP(BufferSize, 4096);
|
||||||
|
|
||||||
|
DPRINT1("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize);
|
||||||
|
|
||||||
|
Buffer = (PUCHAR)ExAllocatePool(NonPagedPool, BufferSize);
|
||||||
|
if (Buffer == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("ExAllocatePool() failed\n");
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open log file for writing */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&RegistryHive->LogFileName,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
Status = NtCreateFile(&FileHandle,
|
||||||
|
FILE_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NULL,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
0,
|
||||||
|
FILE_SUPERSEDE,
|
||||||
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update firt update counter and checksum */
|
||||||
|
RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1;
|
||||||
|
RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader);
|
||||||
|
|
||||||
|
/* Copy hive header */
|
||||||
|
memcpy(Buffer, RegistryHive->HiveHeader, sizeof(HIVE_HEADER));
|
||||||
|
|
||||||
|
Ptr = Buffer + sizeof(HIVE_HEADER);
|
||||||
|
memcpy(Ptr, "DIRT", 4);
|
||||||
|
Ptr += 4;
|
||||||
|
memcpy(Ptr, RegistryHive->DirtyBitMap.Buffer, BitmapSize);
|
||||||
|
|
||||||
|
/* Write hive block and block bitmap */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Buffer,
|
||||||
|
BufferSize,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
|
||||||
|
|
||||||
|
/* Write dirty blocks */
|
||||||
|
FileOffset.QuadPart = (ULONGLONG)BufferSize;
|
||||||
|
BlockIndex = 0;
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyBitMap,
|
||||||
|
1,
|
||||||
|
BlockIndex);
|
||||||
|
if (BlockIndex == (ULONG)-1)
|
||||||
|
{
|
||||||
|
DPRINT("No more set bits\n");
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Block %lu is dirty\n", BlockIndex);
|
||||||
|
|
||||||
|
BlockOffset = RegistryHive->BlockList[BlockIndex]->BlockOffset;
|
||||||
|
DPRINT1("Block offset %lx\n", BlockOffset);
|
||||||
|
|
||||||
|
BlockPtr = RegistryHive->BlockList[BlockIndex] + ((BlockIndex * 4096) - BlockOffset);
|
||||||
|
DPRINT1("BlockPtr %p\n", BlockPtr);
|
||||||
|
|
||||||
|
// FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL;
|
||||||
|
DPRINT1("File offset %I64x\n", FileOffset.QuadPart);
|
||||||
|
|
||||||
|
|
||||||
|
/* Write hive block */
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
BlockPtr,
|
||||||
|
REG_BLOCK_SIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockIndex++;
|
||||||
|
FileOffset.QuadPart += 4096ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush the log file */
|
||||||
|
Status = NtFlushBuffersFile(FileHandle,
|
||||||
|
&IoStatusBlock);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtFlushBuffersFile() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,11 +1104,8 @@ CmiStartHiveUpdate(PREGISTRY_HIVE RegistryHive)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update hive header */
|
/* Update firt update counter and checksum */
|
||||||
RegistryHive->HiveHeader->UpdateCounter1++;
|
RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1;
|
||||||
NtQuerySystemTime((PTIME)&RegistryHive->HiveHeader->DateModified);
|
|
||||||
|
|
||||||
/* Update header checksum */
|
|
||||||
RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader);
|
RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader);
|
||||||
|
|
||||||
/* Write hive block */
|
/* Write hive block */
|
||||||
|
@ -1069,13 +1219,10 @@ CmiFinishHiveUpdate(PREGISTRY_HIVE RegistryHive)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update hive header */
|
/* Update second update counter and checksum */
|
||||||
RegistryHive->HiveHeader->UpdateCounter2 = RegistryHive->HiveHeader->UpdateCounter1;
|
RegistryHive->HiveHeader->UpdateCounter2 = RegistryHive->UpdateCounter + 1;
|
||||||
|
|
||||||
/* Update header checksum */
|
|
||||||
RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader);
|
RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader);
|
||||||
|
|
||||||
|
|
||||||
/* Write hive block */
|
/* Write hive block */
|
||||||
FileOffset.QuadPart = 0ULL;
|
FileOffset.QuadPart = 0ULL;
|
||||||
Status = NtWriteFile(FileHandle,
|
Status = NtWriteFile(FileHandle,
|
||||||
|
@ -1127,6 +1274,10 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||||
DPRINT1("Log file: '%wZ'\n",
|
DPRINT1("Log file: '%wZ'\n",
|
||||||
&RegistryHive->LogFileName);
|
&RegistryHive->LogFileName);
|
||||||
|
|
||||||
|
|
||||||
|
/* Update hive header modification time */
|
||||||
|
NtQuerySystemTime((PTIME)&RegistryHive->HiveHeader->DateModified);
|
||||||
|
|
||||||
/* Start log update */
|
/* Start log update */
|
||||||
Status = CmiStartLogUpdate(RegistryHive);
|
Status = CmiStartLogUpdate(RegistryHive);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1159,6 +1310,9 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Increment update counter */
|
||||||
|
RegistryHive->UpdateCounter++;
|
||||||
|
|
||||||
/* Clear dirty bitmap and dirty flag */
|
/* Clear dirty bitmap and dirty flag */
|
||||||
RtlClearAllBits(&RegistryHive->DirtyBitMap);
|
RtlClearAllBits(&RegistryHive->DirtyBitMap);
|
||||||
RegistryHive->HiveDirty = FALSE;
|
RegistryHive->HiveDirty = FALSE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue