mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[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.
svn path=/trunk/; revision=57263
This commit is contained in:
parent
6b74931d7c
commit
f09f448d95
3 changed files with 258 additions and 9 deletions
|
@ -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@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 */
|
||||
|
|
|
@ -1381,7 +1381,8 @@ CmpInitializeHiveList(IN USHORT Flag)
|
|||
/* 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 @@ CmInitSystem1(VOID)
|
|||
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);
|
||||
|
|
|
@ -624,12 +624,25 @@ CmCheckRegistry(
|
|||
//
|
||||
// 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
|
||||
);
|
||||
|
||||
//
|
||||
// Quota Routines
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue