mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:05:48 +00:00
[FREELDR]
Completely rewrite the registry code. The old code was first loading the system hive and parsing it, duplicating each and every key and value into a custom freeldr specific registry format and used the latter to access the data. This was extremely slow when larger hive files (the one from a normal win 2003 installation is 2.5 MB vs 250kb in reactos) were imported. The new code uses the hive data directly. It's less code, faster and uses much less memory. In the same move, refactor some mkhive code and move it into cmlib to be shared with freeldr. svn path=/trunk/; revision=61595
This commit is contained in:
parent
f1c6047311
commit
43e433ed3f
9 changed files with 688 additions and 1067 deletions
|
@ -62,7 +62,6 @@ list(APPEND FREELDR_COMMON_SOURCE
|
|||
reactos/registry.c
|
||||
reactos/arcname.c
|
||||
reactos/archwsup.c
|
||||
reactos/binhive.c
|
||||
ui/directui.c
|
||||
ui/gui.c
|
||||
ui/minitui.c
|
||||
|
|
|
@ -1,343 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2001 Rex Jolliff
|
||||
* Copyright (C) 2001 Eric Kohl
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <cmlib.h>
|
||||
#include <debug.h>
|
||||
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
DBG_DEFAULT_CHANNEL(REGISTRY);
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static
|
||||
PVOID
|
||||
NTAPI
|
||||
CmpAllocate (SIZE_T Size, BOOLEAN Paged, ULONG Tag)
|
||||
{
|
||||
return FrLdrHeapAllocateEx(FrLdrDefaultHeap, Size, Tag);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
CmpFree (PVOID Ptr, IN ULONG Quota)
|
||||
{
|
||||
FrLdrHeapFreeEx(FrLdrDefaultHeap, Ptr, 0);
|
||||
}
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
RegImportValue (
|
||||
PHHIVE Hive,
|
||||
PCM_KEY_VALUE ValueCell,
|
||||
FRLDRHKEY Key)
|
||||
{
|
||||
PVOID DataCell;
|
||||
PWCHAR wName;
|
||||
LONG Error;
|
||||
ULONG DataLength;
|
||||
ULONG i;
|
||||
|
||||
if (ValueCell->Signature != CM_KEY_VALUE_SIGNATURE)
|
||||
{
|
||||
ERR("Invalid key cell!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ValueCell->Flags & VALUE_COMP_NAME)
|
||||
{
|
||||
wName = FrLdrTempAlloc((ValueCell->NameLength + 1) * sizeof(WCHAR), TAG_REG_NAME);
|
||||
for (i = 0; i < ValueCell->NameLength; i++)
|
||||
{
|
||||
wName[i] = ((PCHAR)ValueCell->Name)[i];
|
||||
}
|
||||
wName[ValueCell->NameLength] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wName = FrLdrTempAlloc(ValueCell->NameLength + sizeof(WCHAR), TAG_REG_NAME);
|
||||
memcpy(wName, ValueCell->Name, ValueCell->NameLength);
|
||||
wName[ValueCell->NameLength / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
DataLength = ValueCell->DataLength & REG_DATA_SIZE_MASK;
|
||||
|
||||
TRACE("ValueName: '%S'\n", wName);
|
||||
TRACE("DataLength: %u\n", DataLength);
|
||||
|
||||
if (DataLength <= sizeof(HCELL_INDEX) && (ValueCell->DataLength & REG_DATA_IN_OFFSET))
|
||||
{
|
||||
Error = RegSetValue(Key,
|
||||
wName,
|
||||
ValueCell->Type,
|
||||
(PCHAR)&ValueCell->Data,
|
||||
DataLength);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegSetValue() failed!\n");
|
||||
FrLdrTempFree(wName, TAG_REG_NAME);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DataCell = (PVOID)HvGetCell(Hive, ValueCell->Data);
|
||||
TRACE("DataCell: %x\n", DataCell);
|
||||
|
||||
Error = RegSetValue(Key,
|
||||
wName,
|
||||
ValueCell->Type,
|
||||
DataCell,
|
||||
DataLength);
|
||||
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegSetValue() failed!\n");
|
||||
FrLdrTempFree(wName, TAG_REG_NAME);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
FrLdrTempFree(wName, TAG_REG_NAME);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
RegImportSubKey(
|
||||
PHHIVE Hive,
|
||||
PCM_KEY_NODE KeyCell,
|
||||
FRLDRHKEY ParentKey);
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
RegImportIndexSubKey(
|
||||
PHHIVE Hive,
|
||||
PCM_KEY_INDEX IndexCell,
|
||||
FRLDRHKEY ParentKey)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
TRACE("IndexCell: %x\n", IndexCell);
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if ((IndexCell->Signature == CM_KEY_INDEX_ROOT) ||
|
||||
(IndexCell->Signature == CM_KEY_INDEX_LEAF))
|
||||
{
|
||||
for (i = 0; i < IndexCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_INDEX SubIndexCell = HvGetCell(Hive, IndexCell->List[i]);
|
||||
if (!RegImportIndexSubKey(Hive, SubIndexCell, ParentKey))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if ((IndexCell->Signature == CM_KEY_FAST_LEAF) ||
|
||||
(IndexCell->Signature == CM_KEY_HASH_LEAF))
|
||||
{
|
||||
PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
|
||||
for (i = 0; i < HashCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell = HvGetCell(Hive, HashCell->List[i].Cell);
|
||||
if (!RegImportSubKey(Hive, SubKeyCell, ParentKey))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
RegImportSubKey(
|
||||
PHHIVE Hive,
|
||||
PCM_KEY_NODE KeyCell,
|
||||
FRLDRHKEY ParentKey)
|
||||
{
|
||||
PCM_KEY_INDEX IndexCell;
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PCM_KEY_VALUE ValueCell = NULL;
|
||||
PWCHAR wName;
|
||||
FRLDRHKEY SubKey;
|
||||
LONG Error;
|
||||
ULONG i;
|
||||
|
||||
TRACE("KeyCell: %x\n", KeyCell);
|
||||
TRACE("KeyCell->Signature: %x\n", KeyCell->Signature);
|
||||
if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
|
||||
{
|
||||
ERR("Invalid key cell Signature!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||
{
|
||||
wName = FrLdrTempAlloc((KeyCell->NameLength + 1) * sizeof(WCHAR), TAG_REG_NAME);
|
||||
for (i = 0; i < KeyCell->NameLength; i++)
|
||||
{
|
||||
wName[i] = ((PCHAR)KeyCell->Name)[i];
|
||||
}
|
||||
wName[KeyCell->NameLength] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wName = FrLdrTempAlloc(KeyCell->NameLength + sizeof(WCHAR), TAG_REG_NAME);
|
||||
memcpy(wName, KeyCell->Name, KeyCell->NameLength);
|
||||
wName[KeyCell->NameLength / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
TRACE("KeyName: '%S'\n", wName);
|
||||
|
||||
/* Create new sub key */
|
||||
Error = RegCreateKey(ParentKey, wName, &SubKey);
|
||||
FrLdrTempFree(wName, TAG_REG_NAME);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegCreateKey() failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts);
|
||||
TRACE("Values: %u\n", KeyCell->ValueList.Count);
|
||||
|
||||
/* Enumerate and add values */
|
||||
if (KeyCell->ValueList.Count > 0)
|
||||
{
|
||||
ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyCell->ValueList.List);
|
||||
TRACE("ValueListCell: %x\n", ValueListCell);
|
||||
|
||||
for (i = 0; i < KeyCell->ValueList.Count; i++)
|
||||
{
|
||||
TRACE("ValueOffset[%d]: %x\n", i, ValueListCell->ValueOffset[i]);
|
||||
|
||||
ValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, ValueListCell->ValueOffset[i]);
|
||||
|
||||
TRACE("ValueCell[%d]: %x\n", i, ValueCell);
|
||||
|
||||
if (!RegImportValue(Hive, ValueCell, SubKey))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||
{
|
||||
IndexCell = HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
|
||||
|
||||
if (!RegImportIndexSubKey(Hive, IndexCell, SubKey))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
RegImportBinaryHive(
|
||||
PCHAR ChunkBase,
|
||||
ULONG ChunkSize)
|
||||
{
|
||||
PCM_KEY_NODE KeyCell;
|
||||
PCM_KEY_FAST_INDEX HashCell;
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
FRLDRHKEY SystemKey;
|
||||
ULONG i;
|
||||
LONG Error;
|
||||
PCMHIVE CmHive;
|
||||
PHHIVE Hive;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("RegImportBinaryHive(%x, %u) called\n", ChunkBase, ChunkSize);
|
||||
|
||||
CmHive = CmpAllocate(sizeof(CMHIVE), TRUE, 0);
|
||||
Status = HvInitialize(&CmHive->Hive,
|
||||
HINIT_FLAT,
|
||||
0,
|
||||
0,
|
||||
ChunkBase,
|
||||
CmpAllocate,
|
||||
CmpFree,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
1,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CmpFree(CmHive, 0);
|
||||
ERR("Invalid hive Signature!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Hive = &CmHive->Hive;
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, Hive->BaseBlock->RootCell);
|
||||
TRACE("KeyCell: %x\n", KeyCell);
|
||||
TRACE("KeyCell->Signature: %x\n", KeyCell->Signature);
|
||||
if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
|
||||
{
|
||||
ERR("Invalid key cell Signature!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts);
|
||||
TRACE("Values: %u\n", KeyCell->ValueList.Count);
|
||||
|
||||
/* Open 'System' key */
|
||||
Error = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM", &SystemKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Failed to open 'system' key!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||
{
|
||||
HashCell = (PCM_KEY_FAST_INDEX)HvGetCell(Hive, KeyCell->SubKeyLists[Stable]);
|
||||
TRACE("HashCell: %x\n", HashCell);
|
||||
TRACE("SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]);
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
||||
{
|
||||
TRACE("Cell[%d]: %x\n", i, HashCell->List[i].Cell);
|
||||
|
||||
SubKeyCell = (PCM_KEY_NODE)HvGetCell(Hive, HashCell->List[i].Cell);
|
||||
|
||||
TRACE("SubKeyCell[%d]: %x\n", i, SubKeyCell);
|
||||
|
||||
if (!RegImportSubKey(Hive, SubKeyCell, SystemKey))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@ add_definitions(
|
|||
|
||||
list(APPEND SOURCE
|
||||
cminit.c
|
||||
cmtools.c
|
||||
hivebin.c
|
||||
hivecell.c
|
||||
hiveinit.c
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#define REG_INIT_HASH_TABLE_SIZE 3
|
||||
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
||||
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
//
|
||||
// Key Types
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif//_WIN32
|
||||
|
||||
// Definitions copied from <ntstatus.h>
|
||||
// We only want to include host headers, so we define them manually
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
|
||||
|
@ -312,6 +317,49 @@ VOID CMAPI
|
|||
CmPrepareHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareHash(
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN PCHAR HashString,
|
||||
IN BOOLEAN CaseInsensitive);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmComparePackedNames(
|
||||
IN PCUNICODE_STRING Name,
|
||||
IN PVOID NameBuffer,
|
||||
IN USHORT NameBufferSize,
|
||||
IN BOOLEAN NamePacked,
|
||||
IN BOOLEAN CaseInsensitive);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareKeyName(
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN BOOLEAN CaseInsensitive);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareKeyValueName(
|
||||
IN PCM_KEY_VALUE ValueCell,
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN BOOLEAN CaseInsensitive);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCopyKeyName(
|
||||
IN PCM_KEY_NODE KeyNode,
|
||||
_Out_ PWCHAR KeyNameBuffer,
|
||||
_Inout_ ULONG BufferLength);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCopyKeyValueName(
|
||||
_In_ PCM_KEY_VALUE ValueCell,
|
||||
_Out_ PWCHAR ValueNameBuffer,
|
||||
_Inout_ ULONG BufferLength);
|
||||
|
||||
BOOLEAN
|
||||
CMAPI
|
||||
|
|
222
reactos/lib/cmlib/cmtools.c
Normal file
222
reactos/lib/cmlib/cmtools.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareHash(
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN PCHAR HashString,
|
||||
IN BOOLEAN CaseInsensitive)
|
||||
{
|
||||
CHAR Buffer[4];
|
||||
|
||||
Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0;
|
||||
Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0;
|
||||
Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0;
|
||||
Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0;
|
||||
|
||||
if (CaseInsensitive)
|
||||
{
|
||||
return (strncasecmp(Buffer, HashString, 4) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (strncmp(Buffer, HashString, 4) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmComparePackedNames(
|
||||
IN PCUNICODE_STRING CompareName,
|
||||
IN PVOID Name,
|
||||
IN USHORT NameLength,
|
||||
IN BOOLEAN NamePacked,
|
||||
IN BOOLEAN CaseInsensitive)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (NamePacked == TRUE)
|
||||
{
|
||||
PUCHAR PackedName = (PUCHAR)Name;
|
||||
|
||||
if (CompareName->Length != NameLength * sizeof(WCHAR))
|
||||
{
|
||||
//DPRINT1("Length doesn'T match %lu / %lu\n", CompareName->Length, NameLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CaseInsensitive)
|
||||
{
|
||||
for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
//DbgPrint("%c/%c,",
|
||||
// RtlUpcaseUnicodeChar(CompareName->Buffer[i]),
|
||||
// RtlUpcaseUnicodeChar(PackedName[i]));
|
||||
if (RtlUpcaseUnicodeChar(CompareName->Buffer[i]) !=
|
||||
RtlUpcaseUnicodeChar(PackedName[i]))
|
||||
{
|
||||
//DbgPrint("\nFailed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
//DbgPrint("\nSuccess!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (CompareName->Buffer[i] != PackedName[i])
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
PWCHAR UnicodeName = (PWCHAR)Name;
|
||||
|
||||
if (CompareName->Length != NameLength)
|
||||
return FALSE;
|
||||
|
||||
if (CaseInsensitive)
|
||||
{
|
||||
for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(CompareName->Buffer[i]) !=
|
||||
RtlUpcaseUnicodeChar(UnicodeName[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (CompareName->Buffer[i] != UnicodeName[i])
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareKeyName(
|
||||
IN PCM_KEY_NODE KeyNode,
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN BOOLEAN CaseInsensitive)
|
||||
{
|
||||
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||
return CmComparePackedNames(KeyName,
|
||||
KeyNode->Name,
|
||||
KeyNode->NameLength,
|
||||
(KeyNode->Flags & KEY_COMP_NAME) ? TRUE : FALSE,
|
||||
CaseInsensitive);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmCompareKeyValueName(
|
||||
IN PCM_KEY_VALUE ValueCell,
|
||||
IN PCUNICODE_STRING ValueName,
|
||||
IN BOOLEAN CaseInsensitive)
|
||||
{
|
||||
ASSERT(ValueCell->Signature == CM_KEY_VALUE_SIGNATURE);
|
||||
return CmComparePackedNames(ValueName,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameLength,
|
||||
(ValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE,
|
||||
CaseInsensitive);
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCopyPackedName(
|
||||
_Out_ PWCHAR Buffer,
|
||||
_In_ ULONG BufferLength,
|
||||
_In_ PVOID Name,
|
||||
_In_ USHORT NameLength,
|
||||
_In_ BOOLEAN NamePacked)
|
||||
{
|
||||
ULONG CharCount, i;
|
||||
ASSERT(Name != 0);
|
||||
ASSERT(NameLength != 0);
|
||||
|
||||
if (NamePacked == TRUE)
|
||||
{
|
||||
NameLength *= sizeof(WCHAR);
|
||||
CharCount = min(BufferLength, NameLength) / sizeof(WCHAR);
|
||||
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
PUCHAR PackedName = (PUCHAR)Name;
|
||||
|
||||
for (i = 0; i < CharCount; i++)
|
||||
{
|
||||
Buffer[i] = PackedName[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CharCount = min(BufferLength, NameLength) / sizeof(WCHAR);
|
||||
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
PWCHAR UnicodeName = (PWCHAR)Name;
|
||||
|
||||
for (i = 0; i < CharCount; i++)
|
||||
{
|
||||
Buffer[i] = UnicodeName[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BufferLength >= NameLength + sizeof(UNICODE_NULL))
|
||||
{
|
||||
Buffer[NameLength / sizeof(WCHAR)] = '\0';
|
||||
}
|
||||
|
||||
return NameLength + sizeof(WCHAR);
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCopyKeyName(
|
||||
IN PCM_KEY_NODE KeyNode,
|
||||
_Out_ PWCHAR KeyNameBuffer,
|
||||
_Inout_ ULONG BufferLength)
|
||||
{
|
||||
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||
return CmCopyPackedName(KeyNameBuffer,
|
||||
BufferLength,
|
||||
KeyNode->Name,
|
||||
KeyNode->NameLength,
|
||||
(KeyNode->Flags & KEY_COMP_NAME) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
CmCopyKeyValueName(
|
||||
_In_ PCM_KEY_VALUE ValueCell,
|
||||
_Out_ PWCHAR ValueNameBuffer,
|
||||
_Inout_ ULONG BufferLength)
|
||||
{
|
||||
ASSERT(ValueCell->Signature == CM_KEY_VALUE_SIGNATURE);
|
||||
return CmCopyPackedName(ValueNameBuffer,
|
||||
BufferLength,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameLength,
|
||||
(ValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE);
|
||||
}
|
|
@ -442,82 +442,6 @@ CmiCompareHashI(
|
|||
return (strncasecmp(Buffer, HashString, 4) == 0);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
CmiCompareKeyNames(
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PWCHAR UnicodeName;
|
||||
USHORT i;
|
||||
|
||||
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < KeyCell->NameLength; i++)
|
||||
{
|
||||
if (KeyName->Buffer[i] != ((PCHAR)KeyCell->Name)[i])
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameLength)
|
||||
return FALSE;
|
||||
|
||||
UnicodeName = (PWCHAR)KeyCell->Name;
|
||||
for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (KeyName->Buffer[i] != UnicodeName[i])
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
CmiCompareKeyNamesI(
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PWCHAR UnicodeName;
|
||||
USHORT i;
|
||||
|
||||
DPRINT("Flags: %hx\n", KeyCell->Flags);
|
||||
|
||||
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: use _strnicmp */
|
||||
for (i = 0; i < KeyCell->NameLength; i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
|
||||
RtlUpcaseUnicodeChar(((PCHAR)KeyCell->Name)[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameLength)
|
||||
return FALSE;
|
||||
|
||||
UnicodeName = (PWCHAR)KeyCell->Name;
|
||||
/* FIXME: use _strnicmp */
|
||||
for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
|
||||
RtlUpcaseUnicodeChar(UnicodeName[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
|
@ -529,6 +453,7 @@ CmiScanForSubKey(
|
|||
{
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
PCM_KEY_NODE CurSubKeyCell;
|
||||
BOOLEAN CaseInsensitive;
|
||||
ULONG Storage;
|
||||
ULONG i;
|
||||
|
||||
|
@ -537,6 +462,7 @@ CmiScanForSubKey(
|
|||
ASSERT(RegistryHive);
|
||||
|
||||
*pSubKeyCell = NULL;
|
||||
CaseInsensitive = (Attributes & OBJ_CASE_INSENSITIVE) != 0;
|
||||
|
||||
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
|
||||
{
|
||||
|
@ -553,40 +479,20 @@ CmiScanForSubKey(
|
|||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||
{
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if ((HashBlock->List[i].HashKey == 0
|
||||
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
HashBlock->List[i].Cell);
|
||||
if ((HashBlock->List[i].HashKey == 0) ||
|
||||
(CmCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey, CaseInsensitive)))
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
HashBlock->List[i].Cell);
|
||||
|
||||
if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell))
|
||||
{
|
||||
*pSubKeyCell = CurSubKeyCell;
|
||||
*pBlockOffset = HashBlock->List[i].Cell;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((HashBlock->List[i].HashKey == 0
|
||||
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
HashBlock->List[i].Cell);
|
||||
|
||||
if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell))
|
||||
{
|
||||
*pSubKeyCell = CurSubKeyCell;
|
||||
*pBlockOffset = HashBlock->List[i].Cell;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CmCompareKeyName(CurSubKeyCell, SubKeyName, CaseInsensitive))
|
||||
{
|
||||
*pSubKeyCell = CurSubKeyCell;
|
||||
*pBlockOffset = HashBlock->List[i].Cell;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -754,44 +660,6 @@ CmiAddValueKey(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
CmiComparePackedNames(
|
||||
IN PCUNICODE_STRING Name,
|
||||
IN PUCHAR NameBuffer,
|
||||
IN USHORT NameBufferSize,
|
||||
IN BOOLEAN NamePacked)
|
||||
{
|
||||
PWCHAR UNameBuffer;
|
||||
ULONG i;
|
||||
|
||||
if (NamePacked == TRUE)
|
||||
{
|
||||
if (Name->Length != NameBufferSize * sizeof(WCHAR))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Name->Length != NameBufferSize)
|
||||
return FALSE;
|
||||
|
||||
UNameBuffer = (PWCHAR)NameBuffer;
|
||||
|
||||
for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForValueKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
|
@ -823,11 +691,11 @@ CmiScanForValueKey(
|
|||
&RegistryHive->Hive,
|
||||
ValueListCell->ValueOffset[i]);
|
||||
|
||||
if (CmiComparePackedNames(
|
||||
ValueName,
|
||||
(PUCHAR)CurValueCell->Name,
|
||||
CurValueCell->NameLength,
|
||||
(BOOLEAN)((CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE)))
|
||||
if (CmComparePackedNames(ValueName,
|
||||
(PUCHAR)CurValueCell->Name,
|
||||
CurValueCell->NameLength,
|
||||
(CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE,
|
||||
TRUE))
|
||||
{
|
||||
*pValueCell = CurValueCell;
|
||||
*pValueCellOffset = ValueListCell->ValueOffset[i];
|
||||
|
|
|
@ -130,13 +130,6 @@ extern LIST_ENTRY CmiHiveListHead;
|
|||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif//_WIN32
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define _In_
|
||||
#define _Out_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue