Author: ion
Date: Mon Sep 10 15:25:26 2012
New Revision: 57263
URL:
http://svn.reactos.org/svn/reactos?rev=57263&view=rev
Log:
[NTOSKRNL]: CORE-6491 #resolve #comment Implement hive list support by hbelusca, with some
minor cleanups by me. Loaded hives are now in the hivelist key.
Modified:
trunk/reactos/ntoskrnl/config/cmhvlist.c
trunk/reactos/ntoskrnl/config/cmsysini.c
trunk/reactos/ntoskrnl/include/internal/cm.h
Modified: trunk/reactos/ntoskrnl/config/cmhvlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmhvlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmhvlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmhvlist.c [iso-8859-1] Mon Sep 10 15:25:26 2012
@@ -1,24 +1,258 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/config/cmwraprs.c
- * PURPOSE: Configuration Manager - Wrappers for Hive Operations
- * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * FILE: ntoskrnl/config/cmhvlist.c
+ * PURPOSE: Configuration Manager - Hives file list management
+ * PROGRAMMERS: Hermes BELUSCA - MAITO
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
-/* FUNCTIONS *****************************************************************/
+/* GLOBALS ********************************************************************/
+
+UNICODE_STRING HiveListValueName =
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\hivelist");
+
+/* FUNCTIONS ******************************************************************/
+
+/* Note: the caller is expected to free the HiveName string buffer */
+BOOLEAN
+NTAPI
+CmpGetHiveName(IN PCMHIVE Hive,
+ OUT PUNICODE_STRING HiveName)
+{
+ HCELL_INDEX RootCell, LinkCell;
+ PCELL_DATA RootData, LinkData, ParentData;
+ ULONG ParentNameSize, LinkNameSize;
+ SIZE_T NameSize;
+ PWCHAR p;
+ UNICODE_STRING RegistryName = RTL_CONSTANT_STRING(L"\\REGISTRY\\");
+
+ /* Get the root cell of this hive */
+ RootCell = Hive->Hive.BaseBlock->RootCell;
+ RootData = HvGetCell(&Hive->Hive, RootCell);
+ if (!RootData) return FALSE;
+
+ /* Get the cell index at which this hive is linked to, and its parent */
+ LinkCell = RootData->u.KeyNode.Parent;
+ HvReleaseCell(&Hive->Hive, RootCell);
+
+ /* Sanity check */
+ ASSERT((&CmiVolatileHive->Hive)->ReleaseCellRoutine == NULL);
+
+ /* Get the cell data for link and parent */
+ LinkData = HvGetCell(&CmiVolatileHive->Hive, LinkCell);
+ if (!LinkData) return FALSE;
+ ParentData = HvGetCell(&CmiVolatileHive->Hive,
LinkData->u.KeyNode.Parent);
+ if (!ParentData) return FALSE;
+
+ /* Get the size of the parent name */
+ if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
+ {
+ ParentNameSize = CmpCompressedNameSize(ParentData->u.KeyNode.Name,
+ ParentData->u.KeyNode.NameLength);
+ }
+ else
+ {
+ ParentNameSize = ParentData->u.KeyNode.NameLength;
+ }
+
+ /* Get the size of the link name */
+ if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
+ {
+ LinkNameSize = CmpCompressedNameSize(LinkData->u.KeyNode.Name,
+ LinkData->u.KeyNode.NameLength);
+ }
+ else
+ {
+ LinkNameSize = LinkData->u.KeyNode.NameLength;
+ }
+
+ /* No need to account for terminal NULL character since we deal with counted UNICODE
strings */
+ NameSize = RegistryName.Length + ParentNameSize + sizeof(WCHAR) + LinkNameSize;
+
+ /* Allocate the memory */
+ HiveName->Buffer = ExAllocatePoolWithTag(PagedPool, NameSize, TAG_CM);
+ if (!HiveName->Buffer)
+ {
+ /* Fail */
+ DPRINT1("CmpGetHiveName: Unable to allocate memory\n");
+ return FALSE;
+ }
+
+ /* Build the string for it */
+ HiveName->Length = HiveName->MaximumLength = (USHORT)NameSize;
+ p = HiveName->Buffer;
+
+ /* Copy the parent name */
+ RtlCopyMemory(p, RegistryName.Buffer, RegistryName.Length);
+ p += RegistryName.Length / sizeof(WCHAR);
+ if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
+ {
+ CmpCopyCompressedName(p,
+ ParentNameSize,
+ ParentData->u.KeyNode.Name,
+ ParentData->u.KeyNode.NameLength);
+ }
+ else
+ {
+ RtlCopyMemory(p, ParentData->u.KeyNode.Name, ParentNameSize);
+ }
+
+ /* Add a path separator between parent and link */
+ p += ParentNameSize / sizeof(WCHAR);
+ *p = OBJ_NAME_PATH_SEPARATOR;
+ ++p;
+
+ /* Now copy the link name */
+ if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
+ {
+ CmpCopyCompressedName(p,
+ LinkNameSize,
+ LinkData->u.KeyNode.Name,
+ LinkData->u.KeyNode.NameLength);
+
+ }
+ else
+ {
+ RtlCopyMemory(p, LinkData->u.KeyNode.Name, LinkNameSize);
+ }
+
+ /* All done */
+ return TRUE;
+}
NTSTATUS
NTAPI
CmpAddToHiveFileList(IN PCMHIVE Hive)
{
- return STATUS_SUCCESS;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE KeyHandle;
+ UNICODE_STRING HivePath;
+ PWCHAR FilePath;
+ CHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + 512 * sizeof(WCHAR)];
+ ULONG Length = sizeof(Buffer);
+ POBJECT_NAME_INFORMATION LocalNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
+ HivePath.Buffer = NULL;
+
+ /* Create or open the hive list key */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &HiveListValueName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwCreateKey(&KeyHandle,
+ KEY_READ | KEY_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("CmpAddToHiveFileList: Creation or opening of the hive list failed,
status = %08lx\n", Status);
+ return Status;
+ }
+
+ /* Retrieve the name of the hive */
+ if (!CmpGetHiveName(Hive, &HivePath))
+ {
+ /* Fail */
+ DPRINT1("CmpAddToHiveFileList: Unable to retrieve the hive name\n");
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
+
+ /* Get the name of the corresponding file */
+ if (!(Hive->Hive.HiveFlags & HIVE_VOLATILE))
+ {
+ /* Try to get the value */
+ Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY],
+ ObjectNameInformation,
+ LocalNameInfo,
+ Length,
+ &Length);
+ if (NT_SUCCESS(Status))
+ {
+ /* Null-terminate and add the length of the terminator */
+ Length -= sizeof(OBJECT_NAME_INFORMATION);
+ FilePath = LocalNameInfo->Name.Buffer;
+ FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Length += sizeof(UNICODE_NULL);
+ }
+ else
+ {
+ /* Fail */
+ DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status =
%08lx\n", Status);
+ goto Quickie;
+ }
+ }
+ else
+ {
+ /* No name */
+ FilePath = L"";
+ Length = sizeof(UNICODE_NULL);
+ }
+
+ /* Set the entry in the hive list */
+ Status = ZwSetValueKey(KeyHandle,
+ &HivePath,
+ 0,
+ REG_SZ,
+ FilePath,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed,
status = %08lx\n", Status);
+ }
+
+Quickie:
+ /* Cleanup and return status */
+ if (HivePath.Buffer) ExFreePoolWithTag(HivePath.Buffer, TAG_CM);
+ ObCloseHandle(KeyHandle, KernelMode);
+ return Status;
}
-/* EOF */
+VOID
+NTAPI
+CmpRemoveFromHiveFileList(IN PCMHIVE Hive)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE KeyHandle;
+ UNICODE_STRING HivePath;
+
+ /* Open the hive list key */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &HiveListValueName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(&KeyHandle,
+ KEY_READ | KEY_WRITE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status
= %08lx\n", Status);
+ return;
+ }
+
+ /* Get the hive path name */
+ CmpGetHiveName(Hive, &HivePath);
+
+ /* Delete the hive path name from the list */
+ ZwDeleteValueKey(KeyHandle, &HivePath);
+
+ /* Cleanup allocation and handle */
+ ExFreePoolWithTag(HivePath.Buffer, TAG_CM);
+ ObCloseHandle(KeyHandle, KernelMode);
+}
+
+/* EOF */
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] Mon Sep 10 15:25:26 2012
@@ -1381,7 +1381,8 @@
/* Check if we created a new hive */
if (CmpMachineHiveList[i].CmHive2)
{
- /* TODO: Add to HiveList key */
+ /* Add to HiveList key */
+ CmpAddToHiveFileList(CmpMachineHiveList[i].CmHive2);
}
}
@@ -1569,7 +1570,8 @@
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
}
- /* FIXME: Add to HiveList key */
+ /* Add to HiveList key */
+ CmpAddToHiveFileList(HardwareHive);
/* Free the security descriptor */
ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
Modified: trunk/reactos/ntoskrnl/include/internal/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] Mon Sep 10 15:25:26 2012
@@ -624,9 +624,22 @@
//
// Hive List Routines
//
+BOOLEAN
+NTAPI
+CmpGetHiveName(
+ IN PCMHIVE Hive,
+ OUT PUNICODE_STRING HiveName
+);
+
NTSTATUS
NTAPI
CmpAddToHiveFileList(
+ IN PCMHIVE Hive
+);
+
+VOID
+NTAPI
+CmpRemoveFromHiveFileList(
IN PCMHIVE Hive
);