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