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) do { ... } while (0) perhaps? Function-style macros with weird side effects make for ugly errors. LONG CMAPI HvGetCellSize( Index: ntoskrnl/config/cmhvlist.c =================================================================== --- ntoskrnl/config/cmhvlist.c (révision 56819) +++ ntoskrnl/config/cmhvlist.c (copie de travail) @@ -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\\"); How about making a const UNICODE_STRING for this somewhere? Then this could be the self-descriptive RegistryRoot.Length / sizeof(WCHAR) + + 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); Please use a pool tag. + 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)); Here's the literal again. + 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); This needs OBJ_KERNEL_HANDLE + + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); This key is volatile? Just checking... + + 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 ) No spaces after ( and before ) would be more consistent. + { + /* Allocate the needed memory */ + Buffer = ExAllocatePool(PagedPool, Length + sizeof(WCHAR) /* For trailing NULL character */); Pool tag please. sizeof(UNICODE_NULL) makes this explicit without a comment + if (Buffer == NULL) + { + /* Fail */ + DPRINT1("CmpAddToHiveFileList: Unable to allocate memory\n"); + Status = STATUS_NO_MEMORY; This is STATUS_INSUFFICIENT_RESOURCES. The other one is about quotas or something ;) + 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); Tags please. + +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); OBJ_KERNEL_HANDLE