mirror of
https://github.com/reactos/reactos.git
synced 2025-05-21 18:16:07 +00:00

- Perform a case insensitive comparison to find existing subkeys in the tree. Dedicated to Hervé ;-) svn path=/trunk/; revision=64516
707 lines
15 KiB
C
707 lines
15 KiB
C
/*
|
|
* ReactOS kernel
|
|
* Copyright (C) 2006 ReactOS Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS hive maker
|
|
* FILE: tools/mkhive/registry.c
|
|
* PURPOSE: Registry code
|
|
* PROGRAMMER: Hervé Poussineau
|
|
*/
|
|
|
|
/*
|
|
* TODO:
|
|
* - Implement RegDeleteKeyW()
|
|
* - Implement RegEnumValue()
|
|
* - Implement RegQueryValueExW()
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#define NDEBUG
|
|
#include "mkhive.h"
|
|
|
|
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
|
#define REG_DATA_IN_OFFSET 0x80000000
|
|
|
|
static CMHIVE RootHive;
|
|
static MEMKEY RootKey;
|
|
CMHIVE DefaultHive; /* \Registry\User\.DEFAULT */
|
|
CMHIVE SamHive; /* \Registry\Machine\SAM */
|
|
CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
|
|
CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
|
|
CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */
|
|
|
|
static MEMKEY
|
|
CreateInMemoryStructure(
|
|
IN PCMHIVE RegistryHive,
|
|
IN HCELL_INDEX KeyCellOffset,
|
|
IN PCUNICODE_STRING KeyName)
|
|
{
|
|
MEMKEY Key;
|
|
|
|
Key = (MEMKEY) malloc (sizeof(KEY));
|
|
if (!Key)
|
|
return NULL;
|
|
|
|
InitializeListHead (&Key->SubKeyList);
|
|
InitializeListHead (&Key->ValueList);
|
|
InitializeListHead (&Key->KeyList);
|
|
|
|
Key->SubKeyCount = 0;
|
|
Key->ValueCount = 0;
|
|
|
|
Key->NameSize = KeyName->Length;
|
|
/* FIXME: It's not enough to allocate this way, because later
|
|
this memory gets overwritten with bigger names */
|
|
Key->Name = malloc (Key->NameSize);
|
|
if (!Key->Name)
|
|
return NULL;
|
|
memcpy(Key->Name, KeyName->Buffer, KeyName->Length);
|
|
|
|
Key->DataType = 0;
|
|
Key->DataSize = 0;
|
|
Key->Data = NULL;
|
|
|
|
Key->RegistryHive = RegistryHive;
|
|
Key->KeyCellOffset = KeyCellOffset;
|
|
Key->KeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, Key->KeyCellOffset);
|
|
if (!Key->KeyCell)
|
|
{
|
|
free(Key->Name);
|
|
free(Key);
|
|
return NULL;
|
|
}
|
|
Key->KeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
|
Key->KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
|
Key->LinkedKey = NULL;
|
|
return Key;
|
|
}
|
|
|
|
static LONG
|
|
RegpOpenOrCreateKey(
|
|
IN HKEY hParentKey,
|
|
IN PCWSTR KeyName,
|
|
IN BOOL AllowCreation,
|
|
OUT PHKEY Key)
|
|
{
|
|
PWSTR LocalKeyName;
|
|
PWSTR End;
|
|
UNICODE_STRING KeyString;
|
|
NTSTATUS Status;
|
|
MEMKEY ParentKey;
|
|
MEMKEY CurrentKey;
|
|
PLIST_ENTRY Ptr;
|
|
PCM_KEY_NODE SubKeyCell;
|
|
HCELL_INDEX BlockOffset;
|
|
|
|
DPRINT("RegpCreateOpenKey('%S')\n", KeyName);
|
|
|
|
if (*KeyName == L'\\')
|
|
{
|
|
KeyName++;
|
|
ParentKey = RootKey;
|
|
}
|
|
else if (hParentKey == NULL)
|
|
{
|
|
ParentKey = RootKey;
|
|
}
|
|
else
|
|
{
|
|
ParentKey = HKEY_TO_MEMKEY(RootKey);
|
|
}
|
|
|
|
LocalKeyName = (PWSTR)KeyName;
|
|
for (;;)
|
|
{
|
|
End = (PWSTR)strchrW(LocalKeyName, '\\');
|
|
if (End)
|
|
{
|
|
KeyString.Buffer = LocalKeyName;
|
|
KeyString.Length = KeyString.MaximumLength =
|
|
(USHORT)((ULONG_PTR)End - (ULONG_PTR)LocalKeyName);
|
|
}
|
|
else
|
|
{
|
|
RtlInitUnicodeString(&KeyString, LocalKeyName);
|
|
if (KeyString.Length == 0)
|
|
{
|
|
/* Trailing backslash char; we're done */
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Redirect from 'CurrentControlSet' to 'ControlSet001' */
|
|
if (!strncmpW(LocalKeyName, L"CurrentControlSet", 17) &&
|
|
ParentKey->NameSize == 12 &&
|
|
!memcmp(ParentKey->Name, L"SYSTEM", 12))
|
|
RtlInitUnicodeString(&KeyString, L"ControlSet001");
|
|
|
|
/* Check subkey in memory structure */
|
|
Ptr = ParentKey->SubKeyList.Flink;
|
|
while (Ptr != &ParentKey->SubKeyList)
|
|
{
|
|
CurrentKey = CONTAINING_RECORD(Ptr, KEY, KeyList);
|
|
if (CurrentKey->NameSize == KeyString.Length
|
|
&& strncmpiW(CurrentKey->Name, KeyString.Buffer, KeyString.Length / sizeof(WCHAR)) == 0)
|
|
{
|
|
goto nextsubkey;
|
|
}
|
|
|
|
Ptr = Ptr->Flink;
|
|
}
|
|
|
|
Status = CmiScanForSubKey(
|
|
ParentKey->RegistryHive,
|
|
ParentKey->KeyCell,
|
|
&KeyString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
&SubKeyCell,
|
|
&BlockOffset);
|
|
if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
{
|
|
Status = CmiAddSubKey(
|
|
ParentKey->RegistryHive,
|
|
ParentKey->KeyCell,
|
|
ParentKey->KeyCellOffset,
|
|
&KeyString,
|
|
0,
|
|
&SubKeyCell,
|
|
&BlockOffset);
|
|
}
|
|
if (!NT_SUCCESS(Status))
|
|
return ERROR_UNSUCCESSFUL;
|
|
|
|
/* Now, SubKeyCell/BlockOffset are valid */
|
|
CurrentKey = CreateInMemoryStructure(
|
|
ParentKey->RegistryHive,
|
|
BlockOffset,
|
|
&KeyString);
|
|
if (!CurrentKey)
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
/* Add CurrentKey in ParentKey */
|
|
InsertTailList(&ParentKey->SubKeyList, &CurrentKey->KeyList);
|
|
ParentKey->SubKeyCount++;
|
|
|
|
nextsubkey:
|
|
ParentKey = CurrentKey;
|
|
if (End)
|
|
LocalKeyName = End + 1;
|
|
else
|
|
break;
|
|
}
|
|
|
|
*Key = MEMKEY_TO_HKEY(ParentKey);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegCreateKeyW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpSubKey,
|
|
OUT PHKEY phkResult)
|
|
{
|
|
return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, phkResult);
|
|
}
|
|
|
|
static PWSTR
|
|
MultiByteToWideChar(
|
|
IN PCSTR MultiByteString)
|
|
{
|
|
ANSI_STRING Source;
|
|
UNICODE_STRING Destination;
|
|
NTSTATUS Status;
|
|
|
|
RtlInitAnsiString(&Source, MultiByteString);
|
|
Status = RtlAnsiStringToUnicodeString(&Destination, &Source, TRUE);
|
|
if (!NT_SUCCESS(Status))
|
|
return NULL;
|
|
return Destination.Buffer;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegCreateKeyA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpSubKey,
|
|
OUT PHKEY phkResult)
|
|
{
|
|
PWSTR lpSubKeyW;
|
|
LONG rc;
|
|
|
|
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
|
if (!lpSubKeyW)
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
rc = RegCreateKeyW(hKey, lpSubKeyW, phkResult);
|
|
free(lpSubKeyW);
|
|
return rc;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegDeleteKeyW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpSubKey)
|
|
{
|
|
DPRINT1("FIXME: implement RegDeleteKeyW!\n");
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegDeleteKeyA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpSubKey)
|
|
{
|
|
PWSTR lpSubKeyW = NULL;
|
|
LONG rc;
|
|
|
|
if (lpSubKey != NULL && strchr(lpSubKey, '\\') != NULL)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
if (lpSubKey)
|
|
{
|
|
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
|
if (!lpSubKeyW)
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
rc = RegDeleteKeyW(hKey, lpSubKeyW);
|
|
|
|
if (lpSubKey)
|
|
free(lpSubKeyW);
|
|
|
|
return rc;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegOpenKeyW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpSubKey,
|
|
OUT PHKEY phkResult)
|
|
{
|
|
return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, phkResult);
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegOpenKeyA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpSubKey,
|
|
OUT PHKEY phkResult)
|
|
{
|
|
PWSTR lpSubKeyW;
|
|
LONG rc;
|
|
|
|
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
|
if (!lpSubKeyW)
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
rc = RegOpenKeyW(hKey, lpSubKeyW, phkResult);
|
|
free(lpSubKeyW);
|
|
return rc;
|
|
}
|
|
|
|
static LONG
|
|
RegpOpenOrCreateValue(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR ValueName,
|
|
IN BOOL AllowCreation,
|
|
OUT PCM_KEY_VALUE *ValueCell,
|
|
OUT PHCELL_INDEX ValueCellOffset)
|
|
{
|
|
MEMKEY ParentKey;
|
|
UNICODE_STRING ValueString;
|
|
NTSTATUS Status;
|
|
|
|
ParentKey = HKEY_TO_MEMKEY(hKey);
|
|
RtlInitUnicodeString(&ValueString, ValueName);
|
|
|
|
Status = CmiScanForValueKey(
|
|
ParentKey->RegistryHive,
|
|
ParentKey->KeyCell,
|
|
&ValueString,
|
|
ValueCell,
|
|
ValueCellOffset);
|
|
if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
{
|
|
Status = CmiAddValueKey(
|
|
ParentKey->RegistryHive,
|
|
ParentKey->KeyCell,
|
|
ParentKey->KeyCellOffset,
|
|
&ValueString,
|
|
ValueCell,
|
|
ValueCellOffset);
|
|
}
|
|
if (!NT_SUCCESS(Status))
|
|
return ERROR_UNSUCCESSFUL;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegSetValueExW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpValueName OPTIONAL,
|
|
IN ULONG Reserved,
|
|
IN ULONG dwType,
|
|
IN const UCHAR* lpData,
|
|
IN USHORT cbData)
|
|
{
|
|
MEMKEY Key, DestKey;
|
|
PHKEY phKey;
|
|
PCM_KEY_VALUE ValueCell;
|
|
HCELL_INDEX ValueCellOffset;
|
|
PVOID DataCell;
|
|
LONG DataCellSize;
|
|
NTSTATUS Status;
|
|
|
|
if (dwType == REG_LINK)
|
|
{
|
|
/* Special handling of registry links */
|
|
if (cbData != sizeof(PVOID))
|
|
return STATUS_INVALID_PARAMETER;
|
|
phKey = (PHKEY)lpData;
|
|
Key = HKEY_TO_MEMKEY(hKey);
|
|
DestKey = HKEY_TO_MEMKEY(*phKey);
|
|
|
|
/* Create the link in memory */
|
|
Key->DataType = REG_LINK;
|
|
Key->LinkedKey = DestKey;
|
|
|
|
/* Create the link in registry hive (if applicable) */
|
|
if (Key->RegistryHive != DestKey->RegistryHive)
|
|
return STATUS_SUCCESS;
|
|
DPRINT1("Save link to registry\n");
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
if ((cbData & REG_DATA_SIZE_MASK) != cbData)
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
Key = HKEY_TO_MEMKEY(hKey);
|
|
|
|
Status = RegpOpenOrCreateValue(hKey, lpValueName, TRUE, &ValueCell, &ValueCellOffset);
|
|
if (!NT_SUCCESS(Status))
|
|
return ERROR_UNSUCCESSFUL;
|
|
|
|
/* Get size of the allocated cellule (if any) */
|
|
if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
|
|
(ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
|
|
{
|
|
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
|
if (!DataCell)
|
|
return ERROR_UNSUCCESSFUL;
|
|
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
|
}
|
|
else
|
|
{
|
|
DataCell = NULL;
|
|
DataCellSize = 0;
|
|
}
|
|
|
|
if (cbData <= sizeof(HCELL_INDEX))
|
|
{
|
|
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
|
|
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
|
if (DataCell)
|
|
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
|
|
|
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
|
|
ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
|
ValueCell->Type = dwType;
|
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
|
}
|
|
else
|
|
{
|
|
if (cbData > (SIZE_T)DataCellSize)
|
|
{
|
|
/* New data size is larger than the current, destroy current
|
|
* data block and allocate a new one. */
|
|
HCELL_INDEX NewOffset;
|
|
|
|
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
|
|
|
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
|
|
if (NewOffset == HCELL_NIL)
|
|
{
|
|
DPRINT("HvAllocateCell() failed with status 0x%08x\n", Status);
|
|
return ERROR_UNSUCCESSFUL;
|
|
}
|
|
|
|
if (DataCell)
|
|
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
|
|
|
ValueCell->Data = NewOffset;
|
|
DataCell = (PVOID)HvGetCell(&Key->RegistryHive->Hive, NewOffset);
|
|
}
|
|
|
|
/* Copy new contents to cellule */
|
|
RtlCopyMemory(DataCell, lpData, cbData);
|
|
ValueCell->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
|
ValueCell->Type = dwType;
|
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
|
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
|
}
|
|
|
|
if (cbData > Key->KeyCell->MaxValueDataLen)
|
|
Key->KeyCell->MaxValueDataLen = cbData;
|
|
|
|
HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset, FALSE);
|
|
|
|
DPRINT("Return status 0x%08x\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegSetValueExA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpValueName OPTIONAL,
|
|
IN ULONG Reserved,
|
|
IN ULONG dwType,
|
|
IN const UCHAR* lpData,
|
|
IN ULONG cbData)
|
|
{
|
|
LPWSTR lpValueNameW = NULL;
|
|
const UCHAR* lpDataW;
|
|
USHORT cbDataW;
|
|
LONG rc = ERROR_SUCCESS;
|
|
|
|
DPRINT("RegSetValueA(%s)\n", lpValueName);
|
|
if (lpValueName)
|
|
{
|
|
lpValueNameW = MultiByteToWideChar(lpValueName);
|
|
if (!lpValueNameW)
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
if ((dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ)
|
|
&& cbData != 0)
|
|
{
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING Data;
|
|
|
|
if (lpData[cbData - 1] != '\0')
|
|
cbData++;
|
|
RtlInitAnsiString(&AnsiString, NULL);
|
|
AnsiString.Buffer = (PSTR)lpData;
|
|
AnsiString.Length = (USHORT)cbData - 1;
|
|
AnsiString.MaximumLength = (USHORT)cbData;
|
|
RtlAnsiStringToUnicodeString (&Data, &AnsiString, TRUE);
|
|
lpDataW = (const UCHAR*)Data.Buffer;
|
|
cbDataW = Data.MaximumLength;
|
|
}
|
|
else
|
|
{
|
|
lpDataW = lpData;
|
|
cbDataW = (USHORT)cbData;
|
|
}
|
|
|
|
if (rc == ERROR_SUCCESS)
|
|
rc = RegSetValueExW(hKey, lpValueNameW, 0, dwType, lpDataW, cbDataW);
|
|
if (lpValueNameW)
|
|
free(lpValueNameW);
|
|
if (lpData != lpDataW)
|
|
free((PVOID)lpDataW);
|
|
return rc;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegQueryValueExW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpValueName,
|
|
IN PULONG lpReserved,
|
|
OUT PULONG lpType,
|
|
OUT PUCHAR lpData,
|
|
OUT PSIZE_T lpcbData)
|
|
{
|
|
//ParentKey = HKEY_TO_MEMKEY(RootKey);
|
|
PCM_KEY_VALUE ValueCell;
|
|
HCELL_INDEX ValueCellOffset;
|
|
LONG rc;
|
|
|
|
rc = RegpOpenOrCreateValue(
|
|
hKey,
|
|
lpValueName,
|
|
FALSE,
|
|
&ValueCell,
|
|
&ValueCellOffset);
|
|
if (rc != ERROR_SUCCESS)
|
|
return rc;
|
|
|
|
DPRINT1("RegQueryValueExW(%S) not implemented\n", lpValueName);
|
|
/* ValueCell and ValueCellOffset are valid */
|
|
|
|
return ERROR_UNSUCCESSFUL;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegQueryValueExA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpValueName,
|
|
IN PULONG lpReserved,
|
|
OUT PULONG lpType,
|
|
OUT PUCHAR lpData,
|
|
OUT PSIZE_T lpcbData)
|
|
{
|
|
LPWSTR lpValueNameW = NULL;
|
|
LONG rc;
|
|
|
|
if (lpValueName)
|
|
{
|
|
lpValueNameW = MultiByteToWideChar(lpValueName);
|
|
if (!lpValueNameW)
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
rc = RegQueryValueExW(hKey, lpValueNameW, lpReserved, lpType, lpData, lpcbData);
|
|
if (lpValueNameW)
|
|
free(lpValueNameW);
|
|
return rc;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegDeleteValueW(
|
|
IN HKEY hKey,
|
|
IN LPCWSTR lpValueName OPTIONAL)
|
|
{
|
|
DPRINT1("RegDeleteValueW() unimplemented\n");
|
|
return ERROR_UNSUCCESSFUL;
|
|
}
|
|
|
|
LONG WINAPI
|
|
RegDeleteValueA(
|
|
IN HKEY hKey,
|
|
IN LPCSTR lpValueName OPTIONAL)
|
|
{
|
|
LPWSTR lpValueNameW;
|
|
LONG rc;
|
|
|
|
if (lpValueName)
|
|
{
|
|
lpValueNameW = MultiByteToWideChar(lpValueName);
|
|
if (!lpValueNameW)
|
|
return ERROR_OUTOFMEMORY;
|
|
rc = RegDeleteValueW(hKey, lpValueNameW);
|
|
free(lpValueNameW);
|
|
}
|
|
else
|
|
rc = RegDeleteValueW(hKey, NULL);
|
|
return rc;
|
|
}
|
|
|
|
static BOOL
|
|
ConnectRegistry(
|
|
IN HKEY RootKey,
|
|
IN PCMHIVE HiveToConnect,
|
|
IN LPCWSTR Path)
|
|
{
|
|
NTSTATUS Status;
|
|
MEMKEY NewKey;
|
|
LONG rc;
|
|
|
|
Status = CmiInitializeTempHive(HiveToConnect);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Create key */
|
|
rc = RegCreateKeyW(
|
|
RootKey,
|
|
Path,
|
|
(PHKEY)&NewKey);
|
|
if (rc != ERROR_SUCCESS)
|
|
return FALSE;
|
|
|
|
NewKey->RegistryHive = HiveToConnect;
|
|
NewKey->KeyCellOffset = HiveToConnect->Hive.BaseBlock->RootCell;
|
|
NewKey->KeyCell = (PCM_KEY_NODE)HvGetCell (&HiveToConnect->Hive, NewKey->KeyCellOffset);
|
|
return TRUE;
|
|
}
|
|
|
|
LIST_ENTRY CmiHiveListHead;
|
|
|
|
VOID
|
|
RegInitializeRegistry(VOID)
|
|
{
|
|
UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\");
|
|
NTSTATUS Status;
|
|
HKEY ControlSetKey;
|
|
|
|
InitializeListHead(&CmiHiveListHead);
|
|
|
|
Status = CmiInitializeTempHive(&RootHive);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
|
return;
|
|
}
|
|
|
|
RootKey = CreateInMemoryStructure(
|
|
&RootHive,
|
|
RootHive.Hive.BaseBlock->RootCell,
|
|
&RootKeyName);
|
|
|
|
/* Create DEFAULT key */
|
|
ConnectRegistry(
|
|
NULL,
|
|
&DefaultHive,
|
|
L"Registry\\User\\.DEFAULT");
|
|
|
|
/* Create SAM key */
|
|
ConnectRegistry(
|
|
NULL,
|
|
&SamHive,
|
|
L"Registry\\Machine\\SAM");
|
|
|
|
/* Create SECURITY key */
|
|
ConnectRegistry(
|
|
NULL,
|
|
&SecurityHive,
|
|
L"Registry\\Machine\\SECURITY");
|
|
|
|
/* Create SOFTWARE key */
|
|
ConnectRegistry(
|
|
NULL,
|
|
&SoftwareHive,
|
|
L"Registry\\Machine\\SOFTWARE");
|
|
|
|
/* Create SYSTEM key */
|
|
ConnectRegistry(
|
|
NULL,
|
|
&SystemHive,
|
|
L"Registry\\Machine\\SYSTEM");
|
|
|
|
/* Create 'ControlSet001' key */
|
|
RegCreateKeyW(
|
|
NULL,
|
|
L"Registry\\Machine\\SYSTEM\\ControlSet001",
|
|
&ControlSetKey);
|
|
}
|
|
|
|
VOID
|
|
RegShutdownRegistry(VOID)
|
|
{
|
|
/* FIXME: clean up the complete hive */
|
|
|
|
free(RootKey->Name);
|
|
free(RootKey);
|
|
}
|
|
|
|
/* EOF */
|