Index: lib/cmlib/cmlib.h =================================================================== --- lib/cmlib/cmlib.h (révision 56819) +++ lib/cmlib/cmlib.h (copie de travail) @@ -243,7 +243,7 @@ HCELL_INDEX CellOffset); #define HvReleaseCell(h, c) \ - if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c) + if ((h)->ReleaseCellRoutine) (h)->ReleaseCellRoutine(h, c) LONG CMAPI HvGetCellSize( Index: ntoskrnl/config/cmhvlist.c =================================================================== --- ntoskrnl/config/cmhvlist.c (révision 56819) +++ 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,288 @@ #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 RegStrSize, NameSize; + PWCHAR dest; + + /* + * 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 */ + RegStrSize = 10; // == wcslen(L"\\REGISTRY\\"); + + 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 = RegStrSize * sizeof(WCHAR) + ParentNameSize + sizeof(WCHAR) + LinkNameSize; + + /* 2- Allocate the memory */ + HiveName->Buffer = ExAllocatePool(PagedPool, NameSize); + 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, L"\\REGISTRY\\", RegStrSize * sizeof(WCHAR)); + dest += RegStrSize; + + 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; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KeyHandle; + OBJECT_NAME_INFORMATION LocalNameInfo; + POBJECT_NAME_INFORMATION Buffer = NULL; + ULONG Length; + PWSTR FilePath; + UNICODE_STRING HivePath; + + /* Create or open the hive list key */ + InitializeObjectAttributes(&ObjectAttributes, + &HiveListValueName, + OBJ_CASE_INSENSITIVE, + 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 Done; + } + + /* Get the name of the corresponding file */ + if ((Hive->Hive.HiveFlags & HIVE_VOLATILE) == 0) + { + /* Get the needed size */ + Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY], + ObjectNameInformation, + &LocalNameInfo, + sizeof(OBJECT_NAME_INFORMATION), + &Length); + if ( Status == STATUS_BUFFER_OVERFLOW || + Status == STATUS_BUFFER_TOO_SMALL || + Status == STATUS_INFO_LENGTH_MISMATCH ) + { + /* Allocate the needed memory */ + Buffer = ExAllocatePool(PagedPool, Length + sizeof(WCHAR) /* For trailing NULL character */); + if (Buffer == NULL) + { + /* Fail */ + DPRINT1("CmpAddToHiveFileList: Unable to allocate memory\n"); + Status = STATUS_NO_MEMORY; + goto Done2; + } + + /* Get the value */ + Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY], + ObjectNameInformation, + Buffer, + Length, + &Length); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = %08lx\n", Status); + goto Done2; + } + + Length -= sizeof(UNICODE_STRING); + FilePath = Buffer->Name.Buffer; + FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL; /* NULL-terminate the string */ + Length += sizeof(WCHAR); + } + 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 (Buffer) ExFreePool(Buffer); + ExFreePool(HivePath.Buffer); + +Done: + 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, + 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); + + ExFreePool(HivePath.Buffer); + ZwClose(KeyHandle); + + return; +} + +/* EOF */ Index: ntoskrnl/config/cmsysini.c =================================================================== --- ntoskrnl/config/cmsysini.c (révision 56819) +++ 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 56819) +++ 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 //