Index: lib/cmlib/cmlib.h =================================================================== --- lib/cmlib/cmlib.h (révision 57118) +++ lib/cmlib/cmlib.h (copie de travail) @@ -242,8 +242,11 @@ PHHIVE RegistryHive, HCELL_INDEX CellOffset); -#define HvReleaseCell(h, c) \ - if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c) +#define HvReleaseCell(h, c) \ + do { \ + if ((h)->ReleaseCellRoutine) \ + (h)->ReleaseCellRoutine(h, c); \ + } while(0) LONG CMAPI HvGetCellSize( Index: ntoskrnl/config/cmhvlist.c =================================================================== --- ntoskrnl/config/cmhvlist.c (révision 57118) +++ ntoskrnl/config/cmhvlist.c (copie de travail) @@ -1,9 +1,10 @@ /* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/config/cmwraprs.c - * PURPOSE: Configuration Manager - Wrappers for Hive Operations + * FILE: ntoskrnl/config/cmhvlist.c + * PURPOSE: Configuration Manager - Hives file list management * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Hermès BÉLUSCA - MAÏTO */ /* INCLUDES ******************************************************************/ @@ -12,13 +13,289 @@ #define NDEBUG #include "debug.h" +/* 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 dest; + UNICODE_STRING RegistryName = RTL_CONSTANT_STRING(L"\\REGISTRY\\"); + + /* + * Get the needed cells. + */ + + /* 1- Get the root cell of this hive */ + RootCell = Hive->Hive.BaseBlock->RootCell; + RootData = HvGetCell(&Hive->Hive, RootCell); + if (RootData == NULL) + return FALSE; + + /* 2- Get the cell 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); + + LinkData = HvGetCell(&CmiVolatileHive->Hive, LinkCell); + if (LinkData == NULL) + return FALSE; + + ParentData = HvGetCell(&CmiVolatileHive->Hive, LinkData->u.KeyNode.Parent); + if (ParentData == NULL) + return FALSE; + + + /* + * Build the hive name, of the form: + * \REGISTRY\name_of_parent_of_link_node\name_of_link_node + */ + + /* 1- Get the size */ + if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME) + { + ParentNameSize = CmpCompressedNameSize(ParentData->u.KeyNode.Name, + ParentData->u.KeyNode.NameLength); + } + else + { + ParentNameSize = ParentData->u.KeyNode.NameLength; + } + + 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; + + /* 2- Allocate the memory */ + HiveName->Buffer = ExAllocatePoolWithTag(PagedPool, NameSize, TAG_CM); + if (HiveName->Buffer == NULL) + { + /* Fail */ + DPRINT1("CmpGetHiveName: Unable to allocate memory\n"); + return FALSE; + } + + HiveName->Length = HiveName->MaximumLength = (USHORT)NameSize; + dest = HiveName->Buffer; + + /* 3- Copy the name */ + RtlCopyMemory(dest, RegistryName.Buffer, RegistryName.Length); + dest += RegistryName.Length / sizeof(WCHAR); + + if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME) + { + CmpCopyCompressedName(dest, + ParentNameSize, + ParentData->u.KeyNode.Name, + ParentData->u.KeyNode.NameLength); + } + else + { + RtlCopyMemory(dest, ParentData->u.KeyNode.Name, ParentNameSize); + } + + dest += ParentNameSize / sizeof(WCHAR); + *dest = OBJ_NAME_PATH_SEPARATOR; + ++dest; + + if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME) + { + CmpCopyCompressedName(dest, + LinkNameSize, + LinkData->u.KeyNode.Name, + LinkData->u.KeyNode.NameLength); + + } + else + { + RtlCopyMemory(dest, LinkData->u.KeyNode.Name, LinkNameSize); + } + + return TRUE; +} + NTSTATUS NTAPI CmpAddToHiveFileList(IN PCMHIVE Hive) { - return STATUS_SUCCESS; +#define DEFAULT_BUFFER_SIZE (sizeof(OBJECT_NAME_INFORMATION) + 512 * sizeof(WCHAR)) + + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KeyHandle; + UNICODE_STRING HivePath; + PWSTR FilePath; + ULONG Length = DEFAULT_BUFFER_SIZE; + CHAR Buffer[DEFAULT_BUFFER_SIZE]; + POBJECT_NAME_INFORMATION NewBuffer = NULL, LocalNameInfo; + + LocalNameInfo = (POBJECT_NAME_INFORMATION)&Buffer; + + /* 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 Done1; + } + + /* Get the name of the corresponding file */ + if ((Hive->Hive.HiveFlags & HIVE_VOLATILE) == 0) + { + /* Try to get the value */ + Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY], + ObjectNameInformation, + LocalNameInfo, + Length, + &Length); + if (Status == STATUS_BUFFER_OVERFLOW || + Status == STATUS_BUFFER_TOO_SMALL || + Status == STATUS_INFO_LENGTH_MISMATCH) + { + /* Allocate a new memory buffer */ + NewBuffer = ExAllocatePoolWithTag(PagedPool, Length + sizeof(UNICODE_NULL), TAG_CM); + if (NewBuffer == NULL) + { + /* Fail */ + DPRINT1("CmpAddToHiveFileList: Unable to allocate memory\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Done2; + } + LocalNameInfo = NewBuffer; + + /* Try again */ + Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY], + ObjectNameInformation, + LocalNameInfo, + Length, + &Length); + } + + if (NT_SUCCESS(Status)) + { + Length -= sizeof(OBJECT_NAME_INFORMATION); + FilePath = LocalNameInfo->Name.Buffer; + FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL; /* NULL-terminate the string */ + Length += sizeof(UNICODE_NULL); + } + else + { + /* Fail */ + DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = %08lx\n", Status); + goto Done2; + } + } + else + { + 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); + } + +Done2: + if (NewBuffer) ExFreePoolWithTag(NewBuffer, TAG_CM); + ExFreePoolWithTag(HivePath.Buffer, TAG_CM); + +Done1: + ZwClose(KeyHandle); + + return Status; } -/* EOF */ \ Pas de retour chariot à la fin du fichier +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); + + ExFreePoolWithTag(HivePath.Buffer, TAG_CM); + ZwClose(KeyHandle); + + return; +} + +/* EOF */ Index: ntoskrnl/config/cmsysini.c =================================================================== --- ntoskrnl/config/cmsysini.c (révision 57118) +++ ntoskrnl/config/cmsysini.c (copie de travail) @@ -1373,14 +1373,15 @@ if (CmpMachineHiveList[i].Allocate) { /* Sync the new hive */ - //HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2)); + HvSyncHive(&CmpMachineHiveList[i].CmHive2->Hive); } } /* Check if we created a new hive */ if (CmpMachineHiveList[i].CmHive2) { - /* TODO: Add to HiveList key */ + /* Add to HiveList key */ + CmpAddToHiveFileList(CmpMachineHiveList[i].CmHive2); } } @@ -1568,7 +1569,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); Index: ntoskrnl/include/internal/cm.h =================================================================== --- ntoskrnl/include/internal/cm.h (révision 57118) +++ ntoskrnl/include/internal/cm.h (copie de travail) @@ -624,12 +624,25 @@ // // 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 //