- Rename CmiInitNonVolatileRegistryHive to CmiInitHiveFromFile.

- Remove CmiCreateNewRegFile and the way new hives were created, saved, then re-reloded. Instead initialize a new hive only once.
- Add support for calling either HINIT_FILE or HINIT_CREATE with a hive, and support log file hives now.
- Make hacks/oldcm differences smoother, and copy routine to cmsysini.c, since it's now compatible with the rewrite. This is probably the last function that was easily convertible/modifiable.

svn path=/trunk/; revision=26716
This commit is contained in:
Alex Ionescu 2007-05-12 08:27:28 +00:00
parent 66d03d55cd
commit 8202615b33
5 changed files with 165 additions and 131 deletions

View file

@ -445,6 +445,14 @@ CmpOpenHiveFiles(IN PUNICODE_STRING BaseName,
IN BOOLEAN NoBuffering,
OUT PULONG ClusterSize OPTIONAL);
NTSTATUS
NTAPI
CmpInitHiveFromFile(IN PUNICODE_STRING HiveName,
IN ULONG HiveFlags,
OUT PEREGISTRY_HIVE *Hive,
IN OUT PBOOLEAN New,
IN ULONG CheckFlags);
#if 0
static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
{

View file

@ -24,153 +24,44 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS
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);
static NTSTATUS
CmiCreateNewRegFile(HANDLE FileHandle)
CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN PUNICODE_STRING FileName,
IN ULONG Flags)
{
PEREGISTRY_HIVE CmHive;
PHHIVE Hive;
NTSTATUS Status;
CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE);
CmHive->HiveHandle = FileHandle;
Status = HvInitialize(&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0,
CmpAllocate, CmpFree,
CmpFileRead, CmpFileWrite, CmpFileSetSize,
CmpFileFlush, NULL);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
/* Init root key cell */
Hive = &CmHive->Hive;
if (!CmCreateRootNode(Hive, L""))
{
HvFree (Hive);
return FALSE;
}
Status = HvWriteHive(Hive) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
HvFree (Hive);
return(Status);
}
static NTSTATUS
CmiInitNonVolatileRegistryHive (IN ULONG HiveFlags,
IN PUNICODE_STRING HiveName,
OUT PEREGISTRY_HIVE *Hive)
{
ULONG CreateDisposition, LogDisposition;
HANDLE FileHandle, LogHandle;
PEREGISTRY_HIVE Hive;
NTSTATUS Status;
//ULONG Operation;
PEREGISTRY_HIVE NewHive;
BOOLEAN Allocate = TRUE;
*Hive = NULL;
DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
Status = CmpOpenHiveFiles(HiveName,
NULL, //L".LOG",
&FileHandle,
&LogHandle,
&CreateDisposition,
&LogDisposition,
TRUE,
FALSE,
TRUE,
NULL);
if (CreateDisposition == FILE_CREATED)
{
Status = CmiCreateNewRegFile(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("CmiCreateNewRegFile() failed (Status %lx)\n", Status);
ZwClose(FileHandle);
return(Status);
}
}
if (Flags & ~REG_NO_LAZY_FLUSH) return STATUS_INVALID_PARAMETER;
Status = CmpInitializeHive(&NewHive,
HINIT_FILE,
HiveFlags,
HFILE_TYPE_PRIMARY,
NULL,
FileHandle,
NULL,
NULL,
HiveName,
0);
Status = CmpInitHiveFromFile(FileName,
(Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0,
&Hive,
&Allocate,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open hive\n");
ZwClose(FileHandle);
DPRINT1("CmpInitHiveFromFile() failed (Status %lx)\n", Status);
ExFreePool(Hive);
return Status;
}
CmPrepareHive(&NewHive->Hive);
NewHive->Flags = HiveFlags;
Status = CmiConnectHive(KeyObjectAttributes, Hive);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
// CmiRemoveRegistryHive (Hive);
}
RtlCreateUnicodeString(&NewHive->HiveFileName, HiveName->Buffer);
/* Close the hive file */
ZwClose(FileHandle);
*Hive = NewHive;
DPRINT ("CmiLoadHive() done\n");
return Status;
}
NTSTATUS
CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN PUNICODE_STRING FileName,
IN ULONG Flags)
{
PEREGISTRY_HIVE Hive;
NTSTATUS Status;
DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
if (Flags & ~REG_NO_LAZY_FLUSH)
return STATUS_INVALID_PARAMETER;
Status = CmiInitNonVolatileRegistryHive ((Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0,
FileName,
&Hive);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("CmiInitNonVolatileRegistryHive() failed (Status %lx)\n", Status);
ExFreePool (Hive);
return Status;
}
Status = CmiConnectHive (KeyObjectAttributes,
Hive);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
// CmiRemoveRegistryHive (Hive);
}
DPRINT ("CmiLoadHive() done\n");
return Status;
}
NTSTATUS
CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive)
CmiRemoveRegistaryHive(PEREGISTRY_HIVE RegistryHive)
{
/* Remove hive from hive list */
RemoveEntryList (&RegistryHive->HiveList);

View file

@ -846,6 +846,21 @@ CmpLinkHiveToMaster(
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSTATUS
NTAPI
CmpOpenHiveFiles(
IN PUNICODE_STRING BaseName,
IN PWCHAR Extension OPTIONAL,
IN PHANDLE Primary,
IN PHANDLE Log,
IN PULONG PrimaryDisposition,
IN PULONG LogDisposition,
IN BOOLEAN CreateAllowed,
IN BOOLEAN MarkAsSystemHive,
IN BOOLEAN NoBuffering,
OUT PULONG ClusterSize OPTIONAL
);
//
// Registry Utility Functions
//

View file

@ -169,6 +169,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
/* Set flags */
Hive->Flags = HiveFlags;
Hive->HiveHandle = Primary;
Hive->LogHandle = Log;
/* Check how large the file is */
ZwQueryInformationFile(Primary,

View file

@ -16,9 +16,128 @@
KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead;
PEPROCESS CmpSystemProcess;
BOOLEAN HvShutdownComplete;
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
CmpInitHiveFromFile(IN PUNICODE_STRING HiveName,
IN ULONG HiveFlags,
OUT PCMHIVE *Hive,
IN OUT PBOOLEAN New,
IN ULONG CheckFlags)
{
ULONG HiveDisposition, LogDisposition;
HANDLE FileHandle = NULL, LogHandle = NULL;
NTSTATUS Status;
ULONG Operation, FileType;
PEREGISTRY_HIVE NewHive;
PAGED_CODE();
/* Assume failure */
*Hive = NULL;
/* Open or create the hive files */
Status = CmpOpenHiveFiles(HiveName,
L".LOG",
&FileHandle,
&LogHandle,
&HiveDisposition,
&LogDisposition,
*New,
FALSE,
TRUE,
NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Check if we have a log handle */
FileType = (LogHandle) ? HFILE_TYPE_LOG : HFILE_TYPE_PRIMARY;
/* Check if we created or opened the hive */
if (HiveDisposition == FILE_CREATED)
{
/* Do a create operation */
Operation = HINIT_CREATE;
*New = TRUE;
}
else
{
/* Open it as a file */
Operation = HINIT_FILE;
*New = FALSE;
}
/* Check if we're sharing hives */
if (CmpShareSystemHives)
{
/* Then force using the primary hive */
FileType = HFILE_TYPE_PRIMARY;
if (LogHandle)
{
/* Get rid of the log handle */
ZwClose(LogHandle);
LogHandle = NULL;
}
}
/* Check if we're too late */
if (HvShutdownComplete)
{
/* Fail */
ZwClose(FileHandle);
if (LogHandle) ZwClose(LogHandle);
return STATUS_TOO_LATE;
}
/* Initialize the hive */
Status = CmpInitializeHive((PCMHIVE*)&NewHive,
Operation,
HiveFlags,
FileType,
NULL,
FileHandle,
LogHandle,
NULL,
HiveName,
0);
if (!NT_SUCCESS(Status))
{
/* Fail */
ZwClose(FileHandle);
if (LogHandle) ZwClose(LogHandle);
return Status;
}
/* Success, return hive */
*Hive = (PCMHIVE)NewHive;
/* ROS: Init root key cell and prepare the hive */
if (Operation == HINIT_CREATE) CmCreateRootNode(&NewHive->Hive, L"");
CmPrepareHive(&NewHive->Hive);
/* Duplicate the hive name */
NewHive->HiveFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
HiveName->Length,
TAG_CM);
if (NewHive->HiveFileName.Buffer)
{
/* Copy the string */
RtlCopyMemory(NewHive->HiveFileName.Buffer,
HiveName->Buffer,
HiveName->Length);
NewHive->HiveFileName.Length = HiveName->Length;
NewHive->HiveFileName.MaximumLength = HiveName->MaximumLength;
}
/* ROS: Close the hive files */
ZwClose(FileHandle);
if (LogHandle) ZwClose(LogHandle);
/* Return success */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)