- 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, IN BOOLEAN NoBuffering,
OUT PULONG ClusterSize OPTIONAL); 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 #if 0
static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell) static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
{ {

View file

@ -24,153 +24,44 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS NTSTATUS
NTAPI CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
CmpInitializeHive(OUT PEREGISTRY_HIVE *RegistryHive, IN PUNICODE_STRING FileName,
IN ULONG OperationType, IN ULONG Flags)
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)
{ {
PEREGISTRY_HIVE CmHive; PEREGISTRY_HIVE Hive;
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;
NTSTATUS Status; NTSTATUS Status;
//ULONG Operation; BOOLEAN Allocate = TRUE;
PEREGISTRY_HIVE NewHive;
*Hive = NULL; DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
Status = CmpOpenHiveFiles(HiveName, if (Flags & ~REG_NO_LAZY_FLUSH) return STATUS_INVALID_PARAMETER;
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);
}
}
Status = CmpInitializeHive(&NewHive, Status = CmpInitHiveFromFile(FileName,
HINIT_FILE, (Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0,
HiveFlags, &Hive,
HFILE_TYPE_PRIMARY, &Allocate,
NULL, 0);
FileHandle,
NULL,
NULL,
HiveName,
0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to open hive\n"); DPRINT1("CmpInitHiveFromFile() failed (Status %lx)\n", Status);
ZwClose(FileHandle); ExFreePool(Hive);
return Status; return Status;
} }
CmPrepareHive(&NewHive->Hive); Status = CmiConnectHive(KeyObjectAttributes, Hive);
NewHive->Flags = HiveFlags; if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
// CmiRemoveRegistryHive (Hive);
}
RtlCreateUnicodeString(&NewHive->HiveFileName, HiveName->Buffer); DPRINT ("CmiLoadHive() done\n");
/* Close the hive file */
ZwClose(FileHandle);
*Hive = NewHive;
return Status; 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 NTSTATUS
CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive) CmiRemoveRegistaryHive(PEREGISTRY_HIVE RegistryHive)
{ {
/* Remove hive from hive list */ /* Remove hive from hive list */
RemoveEntryList (&RegistryHive->HiveList); RemoveEntryList (&RegistryHive->HiveList);

View file

@ -846,6 +846,21 @@ CmpLinkHiveToMaster(
IN PSECURITY_DESCRIPTOR SecurityDescriptor 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 // Registry Utility Functions
// //

View file

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

View file

@ -16,9 +16,128 @@
KGUARDED_MUTEX CmpSelfHealQueueLock; KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead; LIST_ENTRY CmpSelfHealQueueListHead;
PEPROCESS CmpSystemProcess; PEPROCESS CmpSystemProcess;
BOOLEAN HvShutdownComplete;
/* FUNCTIONS *****************************************************************/ /* 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 NTSTATUS
NTAPI NTAPI
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)