|
|
/*++
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; }
|