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@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/c... ============================================================================== --- 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 );