376 lines
8.4 KiB
C
376 lines
8.4 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
cmhvlist.c
|
||
|
||
Abstract:
|
||
|
||
Code to maintain registry node that lists where the roots of
|
||
hives are and what files they map to.
|
||
|
||
Author:
|
||
|
||
Bryan M. Willman (bryanwi) 14-May-1992
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "cmp.h"
|
||
|
||
#define HIVE_LIST L"\\registry\\machine\\system\\currentcontrolset\\control\\hivelist"
|
||
|
||
extern PCMHIVE CmpMasterHive;
|
||
|
||
BOOLEAN
|
||
CmpGetHiveName(
|
||
PCMHIVE CmHive,
|
||
PUNICODE_STRING HiveName
|
||
);
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE,CmpAddToHiveFileList)
|
||
#pragma alloc_text(PAGE,CmpRemoveFromHiveFileList)
|
||
#pragma alloc_text(PAGE,CmpGetHiveName)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
CmpAddToHiveFileList(
|
||
PCMHIVE CmHive
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Add Hive to list of hives and their files in
|
||
\registry\machine\system\currentcontrolset\control\hivelist
|
||
|
||
Arguments:
|
||
|
||
HivePath - path to root of hive (e.g. \registry\machine\system)
|
||
|
||
CmHive - pointer to CM_HIVE structure for hive.
|
||
|
||
Return Value:
|
||
|
||
ntstatus
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// PERFNOTE - allocate small instead of large buffers after
|
||
// NtQueryObject is fixec - bryanwi 15may92
|
||
//
|
||
#define NAME_BUFFER_SIZE 512
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
HANDLE KeyHandle;
|
||
NTSTATUS Status;
|
||
PUCHAR Buffer;
|
||
ULONG Length;
|
||
PWSTR FilePath;
|
||
WCHAR UnicodeNull=UNICODE_NULL;
|
||
UNICODE_STRING TempName;
|
||
UNICODE_STRING HivePath;
|
||
|
||
//
|
||
// create/open the hive list key
|
||
//
|
||
RtlInitUnicodeString(
|
||
&TempName,
|
||
HIVE_LIST
|
||
);
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&TempName,
|
||
OBJ_CASE_INSENSITIVE,
|
||
(HANDLE)NULL,
|
||
NULL
|
||
);
|
||
|
||
Status = ZwCreateKey(
|
||
&KeyHandle,
|
||
KEY_READ | KEY_WRITE,
|
||
&ObjectAttributes,
|
||
0,
|
||
NULL,
|
||
REG_OPTION_VOLATILE,
|
||
NULL
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Create/Open of Hive list failed status = %08lx\n", Status));
|
||
return Status;
|
||
}
|
||
|
||
//
|
||
// allocate work buffers
|
||
//
|
||
Buffer = ExAllocatePool(PagedPool, NAME_BUFFER_SIZE);
|
||
if (Buffer == NULL) {
|
||
NtClose(KeyHandle);
|
||
return STATUS_NO_MEMORY;
|
||
}
|
||
|
||
//
|
||
// compute name of hive
|
||
//
|
||
if (! CmpGetHiveName(CmHive, &HivePath)) {
|
||
NtClose(KeyHandle);
|
||
ExFreePool(Buffer);
|
||
return STATUS_NO_MEMORY;
|
||
}
|
||
|
||
|
||
//
|
||
// get name of file
|
||
//
|
||
if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE)) {
|
||
Status = ZwQueryObject(
|
||
CmHive->FileHandles[HFILE_TYPE_PRIMARY],
|
||
ObjectNameInformation,
|
||
(PVOID)Buffer,
|
||
NAME_BUFFER_SIZE,
|
||
&Length
|
||
);
|
||
Length -= sizeof(UNICODE_STRING);
|
||
if (!NT_SUCCESS(Status)) {
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Query of name2 failed status = %08lx\n", Status));
|
||
NtClose(KeyHandle);
|
||
ExFreePool(HivePath.Buffer);
|
||
ExFreePool(Buffer);
|
||
return Status;
|
||
}
|
||
FilePath = ((POBJECT_NAME_INFORMATION)Buffer)->Name.Buffer;
|
||
FilePath[Length/sizeof(WCHAR)] = UNICODE_NULL;
|
||
Length+=sizeof(WCHAR);
|
||
} else {
|
||
FilePath = &UnicodeNull;
|
||
Length = sizeof(UnicodeNull);
|
||
}
|
||
|
||
//
|
||
// set entry in list
|
||
//
|
||
Status = ZwSetValueKey(
|
||
KeyHandle,
|
||
&HivePath,
|
||
0,
|
||
REG_SZ,
|
||
FilePath,
|
||
Length
|
||
);
|
||
if (!NT_SUCCESS(Status)) {
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
|
||
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Set of entry in Hive list failed status = %08lx\n", Status));
|
||
}
|
||
|
||
NtClose(KeyHandle);
|
||
ExFreePool(HivePath.Buffer);
|
||
ExFreePool(Buffer);
|
||
return Status;
|
||
}
|
||
|
||
|
||
VOID
|
||
CmpRemoveFromHiveFileList(
|
||
PCMHIVE CmHive
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Remove hive name from hive file list key
|
||
|
||
Arguments:
|
||
|
||
CmHive - pointer to CM_HIVE structure for hive.
|
||
|
||
Return Value:
|
||
|
||
ntstatus
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
UNICODE_STRING EntryName;
|
||
UNICODE_STRING TempName;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
HANDLE KeyHandle;
|
||
|
||
//
|
||
// open the hive list key
|
||
//
|
||
RtlInitUnicodeString(
|
||
&TempName,
|
||
HIVE_LIST
|
||
);
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&TempName,
|
||
OBJ_CASE_INSENSITIVE,
|
||
(HANDLE)NULL,
|
||
NULL
|
||
);
|
||
|
||
Status = ZwOpenKey(
|
||
&KeyHandle,
|
||
KEY_READ | KEY_WRITE,
|
||
&ObjectAttributes
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
return;
|
||
}
|
||
|
||
if( CmpGetHiveName(CmHive, &EntryName) ) {
|
||
ZwDeleteValueKey(KeyHandle, &EntryName);
|
||
ExFreePool(EntryName.Buffer);
|
||
}
|
||
|
||
NtClose(KeyHandle);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
CmpGetHiveName(
|
||
PCMHIVE CmHive,
|
||
PUNICODE_STRING HiveName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Compute full path to a hive.
|
||
|
||
Arguments:
|
||
|
||
CmHive - pointer to CmHive structure
|
||
|
||
HiveName - supplies pointer to unicode string structure that
|
||
will be filled in with pointer to name.
|
||
|
||
CALL IS EXPECTED TO FREE BUFFER
|
||
|
||
Return Value:
|
||
|
||
TRUE = it worked, FALSE = it failed (memory)
|
||
|
||
--*/
|
||
{
|
||
HCELL_INDEX RootCell;
|
||
HCELL_INDEX LinkCell;
|
||
PCM_KEY_NODE LinkKey;
|
||
PCM_KEY_NODE LinkParent;
|
||
ULONG size;
|
||
ULONG rsize;
|
||
ULONG KeySize;
|
||
ULONG ParentSize;
|
||
PWCHAR p;
|
||
PCM_KEY_NODE EntryKey;
|
||
|
||
//
|
||
// First find the link cell.
|
||
//
|
||
RootCell = CmHive->Hive.BaseBlock->RootCell;
|
||
EntryKey = (PCM_KEY_NODE)HvGetCell((PHHIVE)CmHive, RootCell);
|
||
if( EntryKey == NULL ) {
|
||
//
|
||
// we couldn't map a view for the bin containing this cell
|
||
//
|
||
return FALSE;
|
||
}
|
||
LinkCell = EntryKey->Parent;
|
||
HvReleaseCell((PHHIVE)CmHive, RootCell);
|
||
|
||
// for master we don't need to count cell usage
|
||
ASSERT( ((PHHIVE)CmpMasterHive)->ReleaseCellRoutine == NULL );
|
||
//
|
||
// Compute the value entry name, which is of the form:
|
||
// \registry\<parent of link node name>\<link node name>
|
||
//
|
||
LinkKey = (PCM_KEY_NODE)HvGetCell((PHHIVE)CmpMasterHive, LinkCell);
|
||
if( LinkKey == NULL ) {
|
||
//
|
||
// we couldn't map a view for the bin containing this cell
|
||
//
|
||
return FALSE;
|
||
}
|
||
LinkParent = (PCM_KEY_NODE)HvGetCell(
|
||
(PHHIVE)CmpMasterHive,
|
||
LinkKey->Parent
|
||
);
|
||
if( LinkParent == NULL ) {
|
||
//
|
||
// we couldn't map a view for the bin containing this cell
|
||
//
|
||
return FALSE;
|
||
}
|
||
rsize = wcslen(L"\\REGISTRY\\");
|
||
|
||
KeySize = CmpHKeyNameLen(LinkKey);
|
||
ParentSize = CmpHKeyNameLen(LinkParent);
|
||
size = KeySize + ParentSize +
|
||
(rsize * sizeof(WCHAR)) + sizeof(WCHAR);
|
||
|
||
HiveName->Buffer = ExAllocatePool(PagedPool, size);
|
||
if (HiveName->Buffer == NULL) {
|
||
return FALSE;
|
||
}
|
||
|
||
HiveName->Length = (USHORT)size;
|
||
HiveName->MaximumLength = (USHORT)size;
|
||
p = HiveName->Buffer;
|
||
|
||
RtlCopyMemory(
|
||
(PVOID)p,
|
||
(PVOID)L"\\REGISTRY\\",
|
||
rsize * sizeof(WCHAR)
|
||
);
|
||
p += rsize;
|
||
|
||
if (LinkParent->Flags & KEY_COMP_NAME) {
|
||
CmpCopyCompressedName(p,
|
||
ParentSize,
|
||
LinkParent->Name,
|
||
LinkParent->NameLength);
|
||
} else {
|
||
RtlCopyMemory(
|
||
(PVOID)p,
|
||
(PVOID)&(LinkParent->Name[0]),
|
||
ParentSize
|
||
);
|
||
}
|
||
|
||
p += ParentSize / sizeof(WCHAR);
|
||
|
||
*p = OBJ_NAME_PATH_SEPARATOR;
|
||
p++;
|
||
|
||
if (LinkKey->Flags & KEY_COMP_NAME) {
|
||
CmpCopyCompressedName(p,
|
||
KeySize,
|
||
LinkKey->Name,
|
||
LinkKey->NameLength);
|
||
|
||
} else {
|
||
RtlCopyMemory(
|
||
(PVOID)p,
|
||
(PVOID)&(LinkKey->Name[0]),
|
||
KeySize
|
||
);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|