mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 17:35:07 +00:00
- Remove unusued, complex hive checking code from regfile.c.
- Implement CmpInitializeHive based on Cm Rewrite but keep code compatible with the current EREGISTRY_HIVE structure in the current Cm. - Remove CmiCreateVolatileHive and CmiCreateTemp since they're unused. - Implement CmpCreateRootNode based on CmRewrite and CmCreateRootNode in cmlib, CmpCopyName and CmpNameSize from Cm Rewrite and use them. - Use CmpInitializeHive + CmpCreateRootNode for the master volatile hive. svn path=/trunk/; revision=26692
This commit is contained in:
parent
107f14ad9f
commit
59a8c8c5dc
|
@ -15,9 +15,7 @@
|
|||
#include <internal/debug.h>
|
||||
|
||||
#include "cm.h"
|
||||
|
||||
/* uncomment to enable hive checks (incomplete and probably buggy) */
|
||||
//#define HIVE_CHECK
|
||||
#include "..\config\cm.h"
|
||||
|
||||
/* LOCAL MACROS *************************************************************/
|
||||
|
||||
|
@ -165,276 +163,6 @@ CmiCreateNewRegFile(HANDLE FileHandle)
|
|||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HIVE_CHECK
|
||||
|
||||
static ULONG
|
||||
CmiCalcChecksum(PULONG Buffer)
|
||||
{
|
||||
ULONG Sum = 0;
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < 127; i++)
|
||||
Sum ^= Buffer[i];
|
||||
if (Sum == (ULONG)-1)
|
||||
Sum = (ULONG)-2;
|
||||
if (Sum == 0)
|
||||
Sum = 1;
|
||||
|
||||
return(Sum);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
CmiCheckAndFixHive(PEREGISTRY_HIVE RegistryHive)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
FILE_STANDARD_INFORMATION fsi;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE HiveHandle = INVALID_HANDLE_VALUE;
|
||||
HANDLE LogHandle = INVALID_HANDLE_VALUE;
|
||||
PHBASE_BLOCK HiveHeader = NULL;
|
||||
PHBASE_BLOCK LogHeader = NULL;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FileSize;
|
||||
ULONG BufferSize;
|
||||
ULONG BitmapSize;
|
||||
RTL_BITMAP BlockBitMap;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("CmiCheckAndFixHive() called\n");
|
||||
|
||||
/* Try to open the hive file */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->HiveFileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ZwCreateFile(&HiveHandle,
|
||||
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
FILE_OPEN,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateFile() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Try to open the log file */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->LogFileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ZwCreateFile(&LogHandle,
|
||||
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
FILE_OPEN,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
LogHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
else if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateFile() failed (Status %lx)\n", Status);
|
||||
ZwClose(HiveHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Allocate hive header */
|
||||
HiveHeader = ExAllocatePool(PagedPool,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (HiveHeader == NULL)
|
||||
{
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Read hive base block */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = ZwReadFile(HiveHandle,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&IoStatusBlock,
|
||||
HiveHeader,
|
||||
sizeof(HBASE_BLOCK),
|
||||
&FileOffset,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (LogHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) ||
|
||||
HiveHeader->Sequence1 != HiveHeader->Sequence2)
|
||||
{
|
||||
/* There is no way to fix the hive without log file - BSOD! */
|
||||
DPRINT("Hive header inconsistent and no log file available!\n");
|
||||
KEBUGCHECK(CONFIG_LIST_FAILED);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
goto ByeBye;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate hive header */
|
||||
LogHeader = ExAllocatePool(PagedPool,
|
||||
HV_LOG_HEADER_SIZE);
|
||||
if (LogHeader == NULL)
|
||||
{
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Read log file header */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = ZwReadFile(LogHandle,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&IoStatusBlock,
|
||||
LogHeader,
|
||||
HV_LOG_HEADER_SIZE,
|
||||
&FileOffset,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Check log file header integrity */
|
||||
if (LogHeader->Checksum != CmiCalcChecksum((PULONG)LogHeader) ||
|
||||
LogHeader->Sequence1 != LogHeader->Sequence2)
|
||||
{
|
||||
if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) ||
|
||||
HiveHeader->Sequence1 != HiveHeader->Sequence2)
|
||||
{
|
||||
DPRINT("Hive file and log file are inconsistent!\n");
|
||||
KEBUGCHECK(CONFIG_LIST_FAILED);
|
||||
}
|
||||
|
||||
/* Log file damaged but hive is okay */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (HiveHeader->Sequence1 == HiveHeader->Sequence2 &&
|
||||
HiveHeader->Sequence1 == LogHeader->Sequence1)
|
||||
{
|
||||
/* Hive and log file are up-to-date */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hive needs an update!
|
||||
*/
|
||||
|
||||
/* Get file size */
|
||||
Status = ZwQueryInformationFile(LogHandle,
|
||||
&IoStatusBlock,
|
||||
&fsi,
|
||||
sizeof(fsi),
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwQueryInformationFile() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
FileSize = fsi.EndOfFile.u.LowPart;
|
||||
|
||||
/* Calculate bitmap and block size */
|
||||
BitmapSize = ROUND_UP((FileSize / HV_BLOCK_SIZE) - 1, sizeof(ULONG) * 8) / 8;
|
||||
BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
|
||||
BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE);
|
||||
|
||||
/* Reallocate log header block */
|
||||
ExFreePool(LogHeader);
|
||||
LogHeader = ExAllocatePool(PagedPool,
|
||||
BufferSize);
|
||||
if (LogHeader == NULL)
|
||||
{
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Read log file header */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = ZwReadFile(LogHandle,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&IoStatusBlock,
|
||||
LogHeader,
|
||||
BufferSize,
|
||||
&FileOffset,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Initialize bitmap */
|
||||
RtlInitializeBitMap(&BlockBitMap,
|
||||
(PVOID)((ULONG_PTR)LogHeader + HV_BLOCK_SIZE + sizeof(ULONG)),
|
||||
BitmapSize * 8);
|
||||
|
||||
/* FIXME: Update dirty blocks */
|
||||
|
||||
|
||||
/* FIXME: Update hive header */
|
||||
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Clean up the mess */
|
||||
ByeBye:
|
||||
if (HiveHeader != NULL)
|
||||
ExFreePool(HiveHeader);
|
||||
|
||||
if (LogHeader != NULL)
|
||||
ExFreePool(LogHeader);
|
||||
|
||||
if (LogHandle != INVALID_HANDLE_VALUE)
|
||||
ZwClose(LogHandle);
|
||||
|
||||
ZwClose(HiveHandle);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
#endif
|
||||
|
||||
static NTSTATUS
|
||||
CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
||||
PWSTR Filename)
|
||||
|
@ -477,18 +205,6 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
wcscat(RegistryHive->LogFileName.Buffer,
|
||||
L".log");
|
||||
|
||||
#ifdef HIVE_CHECK
|
||||
/* Check and eventually fix a hive */
|
||||
Status = CmiCheckAndFixHive(RegistryHive);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
DPRINT1("CmiCheckAndFixHive() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
#endif
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->HiveFileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
|
@ -603,71 +319,143 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive)
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCheckRegistry(IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
PEREGISTRY_HIVE Hive;
|
||||
NTSTATUS Status;
|
||||
|
||||
*RegistryHive = NULL;
|
||||
|
||||
Hive = ExAllocatePool (NonPagedPool,
|
||||
sizeof(EREGISTRY_HIVE));
|
||||
if (Hive == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlZeroMemory (Hive,
|
||||
sizeof(EREGISTRY_HIVE));
|
||||
|
||||
DPRINT("Hive 0x%p\n", Hive);
|
||||
|
||||
Status = HvInitialize(&Hive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0,
|
||||
CmpAllocate, CmpFree,
|
||||
CmpFileRead, CmpFileWrite, CmpFileSetSize,
|
||||
CmpFileFlush, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool (Hive);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!CmCreateRootNode (&Hive->Hive, L""))
|
||||
{
|
||||
HvFree (&Hive->Hive);
|
||||
ExFreePool (Hive);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Hive->Flags = HIVE_NO_FILE;
|
||||
|
||||
/* Acquire hive list lock exclusively */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite (&CmiRegistryLock, TRUE);
|
||||
|
||||
/* Add the new hive to the hive list */
|
||||
InsertTailList (&CmiHiveListHead,
|
||||
&Hive->HiveList);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite (&CmiRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
VERIFY_REGISTRY_HIVE (Hive);
|
||||
|
||||
*RegistryHive = Hive;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
/* FIXME: HACK! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCreateVolatileHive(PEREGISTRY_HIVE *RegistryHive)
|
||||
NTAPI
|
||||
CmpInitializeHive(OUT PEREGISTRY_HIVE *RegistryHive,
|
||||
IN ULONG OperationType,
|
||||
IN ULONG HiveFlags,
|
||||
IN ULONG FileType,
|
||||
IN PVOID HiveData OPTIONAL,
|
||||
IN HANDLE Primary,
|
||||
IN HANDLE Log,
|
||||
IN HANDLE External,
|
||||
IN PUNICODE_STRING FileName OPTIONAL,
|
||||
IN ULONG CheckFlags)
|
||||
{
|
||||
DPRINT ("CmiCreateVolatileHive() called\n");
|
||||
return CmiCreateTempHive(RegistryHive);
|
||||
}
|
||||
PEREGISTRY_HIVE Hive;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_FS_SIZE_INFORMATION FileSizeInformation;
|
||||
NTSTATUS Status;
|
||||
ULONG Cluster;
|
||||
|
||||
/* Assume failure */
|
||||
*RegistryHive = NULL;
|
||||
|
||||
/*
|
||||
* The following are invalid:
|
||||
* An external hive that is also internal.
|
||||
* A log hive that's not a primary hive too.
|
||||
* A volatile hive that's linked to permanent storage.
|
||||
* An in-memory initialization without hive data.
|
||||
* A log hive that's not linked to a correct file type.
|
||||
*/
|
||||
if (((External) && ((Primary) || (Log))) ||
|
||||
((Log) && !(Primary)) ||
|
||||
((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
|
||||
((OperationType == HINIT_MEMORY) && (!HiveData)) ||
|
||||
((Log) && (FileType != HFILE_TYPE_LOG)))
|
||||
{
|
||||
/* Fail the request */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if this is a primary hive */
|
||||
if (Primary)
|
||||
{
|
||||
/* Get the cluster size */
|
||||
Status = ZwQueryVolumeInformationFile(Primary,
|
||||
&IoStatusBlock,
|
||||
&FileSizeInformation,
|
||||
sizeof(FILE_FS_SIZE_INFORMATION),
|
||||
FileFsSizeInformation);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Make sure it's not larger then the block size */
|
||||
if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_REGISTRY_IO_FAILED;
|
||||
}
|
||||
|
||||
/* Otherwise, calculate the cluster */
|
||||
Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
|
||||
Cluster = max(1, Cluster);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise use cluster 1 */
|
||||
Cluster = 1;
|
||||
}
|
||||
|
||||
/* Allocate and clear the hive */
|
||||
Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(EREGISTRY_HIVE), TAG_CM);
|
||||
if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
RtlZeroMemory(Hive, sizeof(EREGISTRY_HIVE));
|
||||
|
||||
/* Initialize it */
|
||||
Status = HvInitialize(&Hive->Hive,
|
||||
OperationType,
|
||||
HiveFlags,
|
||||
FileType,
|
||||
(ULONG_PTR)HiveData,
|
||||
Cluster,
|
||||
CmpAllocate,
|
||||
CmpFree,
|
||||
CmpFileRead,
|
||||
CmpFileWrite,
|
||||
CmpFileSetSize,
|
||||
CmpFileFlush,
|
||||
FileName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Clear allocations and fail */
|
||||
ExFreePool(Hive);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set flag */
|
||||
Hive->Flags = HIVE_NO_FILE;
|
||||
|
||||
/* Check if we should verify the registry */
|
||||
if ((OperationType == HINIT_FILE) ||
|
||||
(OperationType == HINIT_MEMORY) ||
|
||||
(OperationType == HINIT_MEMORY_INPLACE) ||
|
||||
(OperationType == HINIT_MAPFILE))
|
||||
{
|
||||
/* Verify integrity */
|
||||
if (CmCheckRegistry(Hive, TRUE))
|
||||
{
|
||||
/* Free all alocations */
|
||||
ExFreePool(Hive);
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire hive list lock exclusively */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
|
||||
|
||||
/* Add the new hive to the hive list */
|
||||
InsertTailList(&CmiHiveListHead, &Hive->HiveList);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
/* Return the hive and success */
|
||||
VERIFY_REGISTRY_HIVE(Hive);
|
||||
*RegistryHive = Hive;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <internal/debug.h>
|
||||
|
||||
#include "cm.h"
|
||||
#include "..\config\cm.h"
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
#pragma alloc_text(INIT, CmInitSystem1)
|
||||
|
@ -78,6 +79,30 @@ NTSTATUS
|
|||
NTAPI
|
||||
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive,
|
||||
ULONG OperationType,
|
||||
ULONG HiveFlags,
|
||||
ULONG FileType,
|
||||
PVOID HiveData OPTIONAL,
|
||||
HANDLE Primary,
|
||||
HANDLE Log,
|
||||
HANDLE External,
|
||||
PUNICODE_STRING FileName OPTIONAL,
|
||||
ULONG CheckFlags);
|
||||
|
||||
USHORT
|
||||
NTAPI
|
||||
CmpCopyName(IN PHHIVE Hive,
|
||||
IN PWCHAR Destination,
|
||||
IN PUNICODE_STRING Source);
|
||||
|
||||
USHORT
|
||||
NTAPI
|
||||
CmpNameSize(IN PHHIVE Hive,
|
||||
IN PUNICODE_STRING Name);
|
||||
|
||||
static VOID STDCALL
|
||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
|
@ -303,6 +328,61 @@ CmpCreateObjectTypes(VOID)
|
|||
return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmpCreateRootNode(IN PHHIVE Hive,
|
||||
IN PCWSTR Name,
|
||||
OUT PHCELL_INDEX Index)
|
||||
{
|
||||
UNICODE_STRING KeyName;
|
||||
PCM_KEY_NODE KeyCell;
|
||||
LARGE_INTEGER SystemTime;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Initialize the node name and allocate it */
|
||||
RtlInitUnicodeString(&KeyName, Name);
|
||||
*Index = HvAllocateCell(Hive,
|
||||
FIELD_OFFSET(CM_KEY_NODE, Name) +
|
||||
CmpNameSize(Hive, &KeyName),
|
||||
HvStable); // FIXME: , HCELL_NIL);
|
||||
if (*Index == HCELL_NIL) return FALSE;
|
||||
|
||||
/* Set the cell index and get the data */
|
||||
Hive->HiveHeader->RootCell = *Index;
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index);
|
||||
if (!KeyCell) return FALSE;
|
||||
|
||||
/* Setup the cell */
|
||||
KeyCell->Id = (USHORT)CM_KEY_NODE_SIGNATURE;;
|
||||
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||
KeQuerySystemTime(&SystemTime);
|
||||
KeyCell->LastWriteTime = SystemTime;
|
||||
KeyCell->Parent = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[HvStable] = 0;
|
||||
KeyCell->SubKeyCounts[HvVolatile] = 0;
|
||||
KeyCell->SubKeyLists[HvStable] = HCELL_NIL;
|
||||
KeyCell->SubKeyLists[HvVolatile] = HCELL_NIL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NIL;
|
||||
KeyCell->SecurityKeyOffset = HCELL_NIL;
|
||||
KeyCell->ClassNameOffset = HCELL_NIL;
|
||||
KeyCell->ClassSize = 0;
|
||||
|
||||
/* Copy the name (this will also set the length) */
|
||||
KeyCell->NameSize = CmpCopyName(Hive, (PWCHAR)KeyCell->Name, &KeyName);
|
||||
|
||||
/* Check if the name was compressed */
|
||||
if (KeyCell->NameSize < KeyName.Length)
|
||||
{
|
||||
/* Set the flag */
|
||||
KeyCell->Flags |= KEY_COMP_NAME;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
HvReleaseCell(Hive, *Index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmpCreateRegistryRoot(VOID)
|
||||
|
@ -311,7 +391,16 @@ CmpCreateRegistryRoot(VOID)
|
|||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PKEY_OBJECT RootKey;
|
||||
HANDLE RootKeyHandle;
|
||||
HCELL_INDEX RootIndex;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Setup the root node */
|
||||
if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex))
|
||||
{
|
||||
/* We failed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create '\Registry' key. */
|
||||
RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
|
||||
|
@ -333,8 +422,8 @@ CmpCreateRegistryRoot(VOID)
|
|||
|
||||
/* Setup the root key */
|
||||
RootKey->RegistryHive = CmiVolatileHive;
|
||||
RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell;
|
||||
RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootKey->KeyCellOffset);
|
||||
RootKey->KeyCellOffset = RootIndex;
|
||||
RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootIndex);
|
||||
RootKey->ParentKey = RootKey;
|
||||
RootKey->Flags = 0;
|
||||
RootKey->SubKeyCounts = 0;
|
||||
|
@ -421,8 +510,17 @@ CmInitSystem1(VOID)
|
|||
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
|
||||
}
|
||||
|
||||
/* Build volatile registry store */
|
||||
Status = CmiCreateVolatileHive(&CmiVolatileHive);
|
||||
/* Build the master hive */
|
||||
Status = CmpInitializeHive(&CmiVolatileHive,
|
||||
HINIT_CREATE,
|
||||
HIVE_VOLATILE,
|
||||
HFILE_TYPE_PRIMARY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bugcheck */
|
||||
|
@ -433,7 +531,7 @@ CmInitSystem1(VOID)
|
|||
if (!CmpCreateRegistryRoot())
|
||||
{
|
||||
/* Bugcheck */
|
||||
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 4, 0, 0);
|
||||
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
|
||||
}
|
||||
|
||||
/* Create '\Registry\Machine' key. */
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
//
|
||||
// Cell Masks
|
||||
//
|
||||
#define HCELL_NIL 0
|
||||
#define HCELL_NIL -1
|
||||
#define HCELL_CACHED 1
|
||||
|
||||
//
|
||||
|
@ -158,6 +158,8 @@
|
|||
#define CM_DELAYS_PER_PAGE \
|
||||
PAGE_SIZE / sizeof(CM_DELAYED_CLOSE_ENTRY)
|
||||
|
||||
#ifndef __INCLUDE_CM_H
|
||||
|
||||
//
|
||||
// Key Hash
|
||||
//
|
||||
|
@ -984,3 +986,5 @@ extern BOOLEAN ExpInTextModeSetup;
|
|||
// Inlined functions
|
||||
//
|
||||
#include "cm_x.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,62 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
USHORT
|
||||
NTAPI
|
||||
CmpCopyName(IN PHHIVE Hive,
|
||||
IN PWCHAR Destination,
|
||||
IN PUNICODE_STRING Source)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Check for old hives */
|
||||
if (Hive->Version == 1)
|
||||
{
|
||||
/* Just copy the source directly */
|
||||
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
|
||||
return Source->Length;
|
||||
}
|
||||
|
||||
/* For new versions, check for compressed name */
|
||||
for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
|
||||
{
|
||||
/* Check if the name is non compressed */
|
||||
if (Source->Buffer[i] > (UCHAR)-1)
|
||||
{
|
||||
/* Do the copy */
|
||||
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
|
||||
return Source->Length;
|
||||
}
|
||||
|
||||
/* Copy this character */
|
||||
Destination[i] = Source->Buffer[i];
|
||||
}
|
||||
|
||||
/* Compressed name, return length */
|
||||
return Source->Length / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
USHORT
|
||||
NTAPI
|
||||
CmpNameSize(IN PHHIVE Hive,
|
||||
IN PUNICODE_STRING Name)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* For old hives, just retun the length */
|
||||
if (Hive->Version == 1) return Name->Length;
|
||||
|
||||
/* For new versions, check for compressed name */
|
||||
for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)
|
||||
{
|
||||
/* Check if the name is non compressed */
|
||||
if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;
|
||||
}
|
||||
|
||||
/* Compressed name, return length */
|
||||
return Name->Length / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
LONG
|
||||
NTAPI
|
||||
CmpCompareCompressedName(IN PUNICODE_STRING SearchName,
|
||||
|
|
Loading…
Reference in a new issue