/* 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);
+ PEREGISTRY_HIVE Hive;
+ NTSTATUS Status;
+ BOOLEAN Allocate = TRUE;
- return(Status);
-}
+ DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
-static NTSTATUS
-CmiInitNonVolatileRegistryHive (IN ULONG HiveFlags,
- IN PUNICODE_STRING HiveName,
- OUT PEREGISTRY_HIVE *Hive)
-{
- ULONG CreateDisposition, LogDisposition;
- HANDLE FileHandle, LogHandle;
- NTSTATUS Status;
- //ULONG Operation;
- PEREGISTRY_HIVE NewHive;
-
- *Hive = NULL;
-
- 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;
-
- RtlCreateUnicodeString(&NewHive->HiveFileName, HiveName->Buffer);
-
- /* Close the hive file */
- ZwClose(FileHandle);
-
- *Hive = NewHive;
- 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))
+ Status = CmiConnectHive(KeyObjectAttributes, Hive);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
-// CmiRemoveRegistryHive (Hive);
+ DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
+ // CmiRemoveRegistryHive (Hive);
}
- DPRINT ("CmiLoadHive() done\n");
-
- return Status;
+ DPRINT ("CmiLoadHive() done\n");
+ return Status;
}
NTSTATUS
-CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive)
+CmiRemoveRegistaryHive(PEREGISTRY_HIVE RegistryHive)
{
/* Remove hive from hive list */
RemoveEntryList (&RegistryHive->HiveList);
KGUARDED_MUTEX CmpSelfHealQueueLock;\r
LIST_ENTRY CmpSelfHealQueueListHead;\r
PEPROCESS CmpSystemProcess;\r
+BOOLEAN HvShutdownComplete;\r
\r
/* FUNCTIONS *****************************************************************/\r
\r
+NTSTATUS\r
+NTAPI\r
+CmpInitHiveFromFile(IN PUNICODE_STRING HiveName,\r
+ IN ULONG HiveFlags,\r
+ OUT PCMHIVE *Hive,\r
+ IN OUT PBOOLEAN New,\r
+ IN ULONG CheckFlags)\r
+{\r
+ ULONG HiveDisposition, LogDisposition;\r
+ HANDLE FileHandle = NULL, LogHandle = NULL;\r
+ NTSTATUS Status;\r
+ ULONG Operation, FileType;\r
+ PEREGISTRY_HIVE NewHive;\r
+ PAGED_CODE();\r
+\r
+ /* Assume failure */\r
+ *Hive = NULL;\r
+\r
+ /* Open or create the hive files */\r
+ Status = CmpOpenHiveFiles(HiveName,\r
+ L".LOG",\r
+ &FileHandle,\r
+ &LogHandle,\r
+ &HiveDisposition,\r
+ &LogDisposition,\r
+ *New,\r
+ FALSE,\r
+ TRUE,\r
+ NULL);\r
+ if (!NT_SUCCESS(Status)) return Status;\r
+\r
+ /* Check if we have a log handle */\r
+ FileType = (LogHandle) ? HFILE_TYPE_LOG : HFILE_TYPE_PRIMARY;\r
+\r
+ /* Check if we created or opened the hive */\r
+ if (HiveDisposition == FILE_CREATED)\r
+ {\r
+ /* Do a create operation */\r
+ Operation = HINIT_CREATE;\r
+ *New = TRUE;\r
+ }\r
+ else\r
+ {\r
+ /* Open it as a file */\r
+ Operation = HINIT_FILE;\r
+ *New = FALSE;\r
+ }\r
+\r
+ /* Check if we're sharing hives */\r
+ if (CmpShareSystemHives)\r
+ {\r
+ /* Then force using the primary hive */\r
+ FileType = HFILE_TYPE_PRIMARY;\r
+ if (LogHandle)\r
+ {\r
+ /* Get rid of the log handle */\r
+ ZwClose(LogHandle);\r
+ LogHandle = NULL;\r
+ }\r
+ }\r
+\r
+ /* Check if we're too late */\r
+ if (HvShutdownComplete)\r
+ {\r
+ /* Fail */\r
+ ZwClose(FileHandle);\r
+ if (LogHandle) ZwClose(LogHandle);\r
+ return STATUS_TOO_LATE;\r
+ }\r
+\r
+ /* Initialize the hive */\r
+ Status = CmpInitializeHive((PCMHIVE*)&NewHive,\r
+ Operation,\r
+ HiveFlags,\r
+ FileType,\r
+ NULL,\r
+ FileHandle,\r
+ LogHandle,\r
+ NULL,\r
+ HiveName,\r
+ 0);\r
+ if (!NT_SUCCESS(Status))\r
+ {\r
+ /* Fail */\r
+ ZwClose(FileHandle);\r
+ if (LogHandle) ZwClose(LogHandle);\r
+ return Status;\r
+ }\r
+\r
+ /* Success, return hive */\r
+ *Hive = (PCMHIVE)NewHive;\r
+\r
+ /* ROS: Init root key cell and prepare the hive */\r
+ if (Operation == HINIT_CREATE) CmCreateRootNode(&NewHive->Hive, L"");\r
+ CmPrepareHive(&NewHive->Hive);\r
+\r
+ /* Duplicate the hive name */\r
+ NewHive->HiveFileName.Buffer = ExAllocatePoolWithTag(PagedPool,\r
+ HiveName->Length,\r
+ TAG_CM);\r
+ if (NewHive->HiveFileName.Buffer)\r
+ {\r
+ /* Copy the string */\r
+ RtlCopyMemory(NewHive->HiveFileName.Buffer,\r
+ HiveName->Buffer,\r
+ HiveName->Length);\r
+ NewHive->HiveFileName.Length = HiveName->Length;\r
+ NewHive->HiveFileName.MaximumLength = HiveName->MaximumLength;\r
+ }\r
+\r
+ /* ROS: Close the hive files */\r
+ ZwClose(FileHandle);\r
+ if (LogHandle) ZwClose(LogHandle);\r
+\r
+ /* Return success */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
NTSTATUS\r
NTAPI\r
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r