reactos/reactos/lib/cmlib/cmtools.c
Timo Kreuzer 43e433ed3f [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
2014-01-12 21:37:29 +00:00

222 lines
5.6 KiB
C

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