Convert Registry to Unicode. Part 2.

svn path=/trunk/; revision=4788
This commit is contained in:
Eric Kohl 2003-05-28 16:09:51 +00:00
parent 80344c77a6
commit 91987ce5dc
5 changed files with 256 additions and 144 deletions

View file

@ -414,15 +414,16 @@ CmiCreateHiveBitmap(PREGISTRY_HIVE Hive);
VOID VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey, CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
IN PKEY_OBJECT NewKey); IN PKEY_OBJECT NewKey);
NTSTATUS NTSTATUS
CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey); CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
PKEY_OBJECT CmiScanKeyList(IN PKEY_OBJECT Parent, PKEY_OBJECT
IN PCHAR KeyNameBuf, CmiScanKeyList(IN PKEY_OBJECT Parent,
IN ULONG Attributes); IN PUNICODE_STRING KeyName,
IN ULONG Attributes);
NTSTATUS NTSTATUS
CmiCreateRegistryHive(PWSTR Filename, CmiCreateRegistryHive(PWSTR Filename,
@ -453,22 +454,21 @@ CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
OUT PKEY_CELL *SubKeyCell, OUT PKEY_CELL *SubKeyCell,
OUT BLOCK_OFFSET *BlockOffset, OUT BLOCK_OFFSET *BlockOffset,
IN PCHAR KeyName, IN PUNICODE_STRING KeyName,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes); IN ULONG Attributes);
NTSTATUS NTSTATUS
CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive, CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_OBJECT Parent, IN PKEY_OBJECT Parent,
OUT PKEY_OBJECT SubKey, OUT PKEY_OBJECT SubKey,
IN PWSTR NewSubKeyName, IN PUNICODE_STRING SubKeyName,
IN USHORT NewSubKeyNameSize, IN ULONG TitleIndex,
IN ULONG TitleIndex, IN PUNICODE_STRING Class,
IN PUNICODE_STRING Class, IN ULONG CreateOptions);
IN ULONG CreateOptions);
NTSTATUS NTSTATUS
CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive, CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
@ -586,6 +586,23 @@ CmiCopyPackedName(PWCHAR NameBuffer,
PCHAR PackedNameBuffer, PCHAR PackedNameBuffer,
ULONG PackedNameSize); ULONG PackedNameSize);
BOOLEAN
CmiCompareHash(PUNICODE_STRING KeyName,
PCHAR HashString);
BOOLEAN
CmiCompareHashI(PUNICODE_STRING KeyName,
PCHAR HashString);
BOOLEAN
CmiCompareKeyNames(PUNICODE_STRING KeyName,
PKEY_CELL KeyCell);
BOOLEAN
CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
PKEY_CELL KeyCell);
VOID VOID
CmiSyncHives(VOID); CmiSyncHives(VOID);

View file

@ -53,8 +53,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyHandle, KeyHandle,
ObjectAttributes->RootDirectory); ObjectAttributes->RootDirectory);
/* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
Status = ObFindObject(ObjectAttributes, Status = ObFindObject(ObjectAttributes,
&Object, &Object,
&RemainingPath, &RemainingPath,
@ -133,8 +131,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
Status = CmiAddSubKey(KeyObject->RegistryHive, Status = CmiAddSubKey(KeyObject->RegistryHive,
KeyObject->ParentKey, KeyObject->ParentKey,
KeyObject, KeyObject,
RemainingPath.Buffer, &RemainingPath,
RemainingPath.Length,
TitleIndex, TitleIndex,
Class, Class,
CreateOptions); CreateOptions);

View file

@ -7,13 +7,12 @@
*/ */
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ddk/ntifs.h>
#include <roscfg.h> #include <roscfg.h>
#include <internal/ob.h> #include <internal/ob.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <internal/pool.h>
#include <internal/registry.h> #include <internal/registry.h>
#include <ntos/minmax.h>
#include <reactos/bugcodes.h> #include <reactos/bugcodes.h>
#define NDEBUG #define NDEBUG
@ -1996,18 +1995,17 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
OUT PKEY_CELL *SubKeyCell, OUT PKEY_CELL *SubKeyCell,
OUT BLOCK_OFFSET *BlockOffset, OUT BLOCK_OFFSET *BlockOffset,
IN PCHAR KeyName, IN PUNICODE_STRING KeyName,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes) IN ULONG Attributes)
{ {
PHASH_TABLE_CELL HashBlock; PHASH_TABLE_CELL HashBlock;
PKEY_CELL CurSubKeyCell; PKEY_CELL CurSubKeyCell;
USHORT KeyLength;
ULONG i; ULONG i;
VERIFY_KEY_CELL(KeyCell); VERIFY_KEY_CELL(KeyCell);
//DPRINT("Scanning for sub key %s\n", KeyName); DPRINT("Scanning for sub key %wZ\n", KeyName);
assert(RegistryHive); assert(RegistryHive);
@ -2027,14 +2025,14 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
KeyLength = strlen(KeyName);
for (i = 0; (i < KeyCell->NumberOfSubKeys) && (i < HashBlock->HashTableSize); i++) for (i = 0; (i < KeyCell->NumberOfSubKeys) && (i < HashBlock->HashTableSize); i++)
{ {
if (Attributes & OBJ_CASE_INSENSITIVE) if (Attributes & OBJ_CASE_INSENSITIVE)
{ {
if ((HashBlock->Table[i].KeyOffset != 0) && if (HashBlock->Table[i].KeyOffset != 0 &&
(HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1) && HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1 &&
(_strnicmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4) == 0)) (HashBlock->Table[i].HashValue == 0 ||
CmiCompareHashI(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
{ {
CurSubKeyCell = CmiGetBlock(RegistryHive, CurSubKeyCell = CmiGetBlock(RegistryHive,
HashBlock->Table[i].KeyOffset, HashBlock->Table[i].KeyOffset,
@ -2045,20 +2043,20 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if ((CurSubKeyCell->NameSize == KeyLength) if (CmiCompareKeyNamesI(KeyName, CurSubKeyCell))
&& (_strnicmp(KeyName, CurSubKeyCell->Name, KeyLength) == 0)) {
{ *SubKeyCell = CurSubKeyCell;
*SubKeyCell = CurSubKeyCell; *BlockOffset = HashBlock->Table[i].KeyOffset;
*BlockOffset = HashBlock->Table[i].KeyOffset; break;
break; }
} }
}
} }
else else
{ {
if (HashBlock->Table[i].KeyOffset != 0 && if (HashBlock->Table[i].KeyOffset != 0 &&
HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 && HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 &&
!strncmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4)) (HashBlock->Table[i].HashValue == 0 ||
CmiCompareHash(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
{ {
CurSubKeyCell = CmiGetBlock(RegistryHive, CurSubKeyCell = CmiGetBlock(RegistryHive,
HashBlock->Table[i].KeyOffset, HashBlock->Table[i].KeyOffset,
@ -2069,14 +2067,13 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (CurSubKeyCell->NameSize == KeyLength if (CmiCompareKeyNames(KeyName, CurSubKeyCell))
&& !_strnicmp(KeyName, CurSubKeyCell->Name, KeyLength)) {
{ *SubKeyCell = CurSubKeyCell;
*SubKeyCell = CurSubKeyCell; *BlockOffset = HashBlock->Table[i].KeyOffset;
*BlockOffset = HashBlock->Table[i].KeyOffset; break;
break; }
} }
}
} }
} }
@ -2088,8 +2085,7 @@ NTSTATUS
CmiAddSubKey(PREGISTRY_HIVE RegistryHive, CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
PKEY_OBJECT Parent, PKEY_OBJECT Parent,
PKEY_OBJECT SubKey, PKEY_OBJECT SubKey,
PWSTR NewSubKeyName, PUNICODE_STRING SubKeyName,
USHORT NewSubKeyNameSize,
ULONG TitleIndex, ULONG TitleIndex,
PUNICODE_STRING Class, PUNICODE_STRING Class,
ULONG CreateOptions) ULONG CreateOptions)
@ -2097,25 +2093,28 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL NewHashBlock; PHASH_TABLE_CELL NewHashBlock;
PHASH_TABLE_CELL HashBlock; PHASH_TABLE_CELL HashBlock;
BLOCK_OFFSET NKBOffset; BLOCK_OFFSET NKBOffset;
PKEY_CELL NewKeyCell; PKEY_CELL NewKeyCell;
ULONG NewBlockSize; ULONG NewBlockSize;
PKEY_CELL KeyCell; PKEY_CELL KeyCell;
NTSTATUS Status; NTSTATUS Status;
USHORT NameSize; USHORT NameSize;
PWSTR NamePtr;
KeyCell = Parent->KeyCell; KeyCell = Parent->KeyCell;
VERIFY_KEY_CELL(KeyCell); VERIFY_KEY_CELL(KeyCell);
if (NewSubKeyName[0] == L'\\') if (SubKeyName->Buffer[0] == L'\\')
{ {
NewSubKeyName++; NamePtr = &SubKeyName->Buffer[1];
NameSize = NewSubKeyNameSize / 2 - 1; NameSize = SubKeyName->Length / 2 - 1;
} }
else else
{ {
NameSize = NewSubKeyNameSize / 2; NamePtr = SubKeyName->Buffer;
NameSize = SubKeyName->Length / 2;
} }
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
NewBlockSize = sizeof(KEY_CELL) + NameSize; NewBlockSize = sizeof(KEY_CELL) + NameSize;
@ -2130,7 +2129,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
else else
{ {
NewKeyCell->Id = REG_KEY_CELL_ID; NewKeyCell->Id = REG_KEY_CELL_ID;
NewKeyCell->Flags = REG_KEY_NAME_PACKED; NewKeyCell->Flags = 0;
ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime); ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime);
NewKeyCell->ParentKeyOffset = -1; NewKeyCell->ParentKeyOffset = -1;
NewKeyCell->NumberOfSubKeys = 0; NewKeyCell->NumberOfSubKeys = 0;
@ -2138,10 +2137,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
NewKeyCell->NumberOfValues = 0; NewKeyCell->NumberOfValues = 0;
NewKeyCell->ValuesOffset = -1; NewKeyCell->ValuesOffset = -1;
NewKeyCell->SecurityKeyOffset = -1; NewKeyCell->SecurityKeyOffset = -1;
NewKeyCell->NameSize = NameSize;
wcstombs(NewKeyCell->Name, NewSubKeyName, NameSize);
NewKeyCell->ClassNameOffset = -1; NewKeyCell->ClassNameOffset = -1;
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
NewKeyCell->NameSize = NameSize;
wcstombs(NewKeyCell->Name, NamePtr, NameSize);
VERIFY_KEY_CELL(NewKeyCell); VERIFY_KEY_CELL(NewKeyCell);
if (Class) if (Class)
@ -2185,7 +2186,9 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
} }
else else
{ {
HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); HashBlock = CmiGetBlock(RegistryHive,
KeyCell->HashTableOffset,
NULL);
if (HashBlock == NULL) if (HashBlock == NULL)
{ {
DPRINT("CmiGetBlock() failed\n"); DPRINT("CmiGetBlock() failed\n");
@ -2723,9 +2726,13 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
if (HashBlock->Table[i].KeyOffset == 0) if (HashBlock->Table[i].KeyOffset == 0)
{ {
HashBlock->Table[i].KeyOffset = NKBOffset; HashBlock->Table[i].KeyOffset = NKBOffset;
RtlCopyMemory(&HashBlock->Table[i].HashValue, HashBlock->Table[i].HashValue = 0;
NewKeyCell->Name, if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
4); {
RtlCopyMemory(&HashBlock->Table[i].HashValue,
NewKeyCell->Name,
min(NewKeyCell->NameSize, 4));
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -2746,8 +2753,7 @@ CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
if (HashBlock->Table[i].KeyOffset == NKBOffset) if (HashBlock->Table[i].KeyOffset == NKBOffset)
{ {
HashBlock->Table[i].KeyOffset = 0; HashBlock->Table[i].KeyOffset = 0;
RtlZeroMemory(&HashBlock->Table[i].HashValue, HashBlock->Table[i].HashValue = 0;
4);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -3481,4 +3487,110 @@ CmiCopyPackedName(PWCHAR NameBuffer,
NameBuffer[i] = (WCHAR)PackedNameBuffer[i]; NameBuffer[i] = (WCHAR)PackedNameBuffer[i];
} }
BOOLEAN
CmiCompareHash(PUNICODE_STRING KeyName,
PCHAR HashString)
{
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;
return (strncmp(Buffer, HashString, 4) == 0);
}
BOOLEAN
CmiCompareHashI(PUNICODE_STRING KeyName,
PCHAR HashString)
{
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;
return (_strnicmp(Buffer, HashString, 4) == 0);
}
BOOLEAN
CmiCompareKeyNames(PUNICODE_STRING KeyName,
PKEY_CELL KeyCell)
{
PWCHAR UnicodeName;
USHORT i;
DPRINT1("Flags: %hx\n", KeyCell->Flags);
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
{
if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR))
return FALSE;
for (i = 0; i < KeyCell->NameSize; i++)
{
if (KeyName->Buffer[i] != (WCHAR)KeyCell->Name[i])
return FALSE;
}
}
else
{
if (KeyName->Length != KeyCell->NameSize)
return FALSE;
UnicodeName = (PWCHAR)KeyCell->Name;
for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++)
{
if (KeyName->Buffer[i] != UnicodeName[i])
return FALSE;
}
}
return TRUE;
}
BOOLEAN
CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
PKEY_CELL KeyCell)
{
PWCHAR UnicodeName;
USHORT i;
DPRINT1("Flags: %hx\n", KeyCell->Flags);
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
{
if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR))
return FALSE;
for (i = 0; i < KeyCell->NameSize; i++)
{
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
RtlUpcaseUnicodeChar((WCHAR)KeyCell->Name[i]))
return FALSE;
}
}
else
{
if (KeyName->Length != KeyCell->NameSize)
return FALSE;
UnicodeName = (PWCHAR)KeyCell->Name;
for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++)
{
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
RtlUpcaseUnicodeChar(UnicodeName[i]))
return FALSE;
}
}
return TRUE;
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.96 2003/05/28 12:04:17 ekohl Exp $ /* $Id: registry.c,v 1.97 2003/05/28 16:09:51 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -250,10 +250,8 @@ VOID
CmInitializeRegistry(VOID) CmInitializeRegistry(VOID)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING RootKeyName; UNICODE_STRING KeyName;
PKEY_OBJECT RootKey; PKEY_OBJECT RootKey;
PKEY_OBJECT MachineKey;
PKEY_OBJECT UserKey;
HANDLE RootKeyHandle; HANDLE RootKeyHandle;
HANDLE KeyHandle; HANDLE KeyHandle;
NTSTATUS Status; NTSTATUS Status;
@ -289,8 +287,8 @@ CmInitializeRegistry(VOID)
assert(NT_SUCCESS(Status)); assert(NT_SUCCESS(Status));
/* Create '\Registry' key. */ /* Create '\Registry' key. */
RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME); RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
Status = ObCreateObject(&RootKeyHandle, Status = ObCreateObject(&RootKeyHandle,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes, &ObjectAttributes,
@ -317,54 +315,38 @@ CmInitializeRegistry(VOID)
KeInitializeSpinLock(&CmiKeyListLock); KeInitializeSpinLock(&CmiKeyListLock);
/* Create '\Registry\Machine' key. */ /* Create '\Registry\Machine' key. */
Status = ObCreateObject(&KeyHandle, RtlInitUnicodeString(&KeyName,
STANDARD_RIGHTS_REQUIRED, L"Machine");
NULL, InitializeObjectAttributes(&ObjectAttributes,
CmiKeyType, &KeyName,
(PVOID*)&MachineKey); 0,
RootKeyHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
NULL);
assert(NT_SUCCESS(Status)); assert(NT_SUCCESS(Status));
Status = CmiAddSubKey(CmiVolatileHive,
RootKey,
MachineKey,
L"Machine",
wcslen(L"Machine") * sizeof(WCHAR),
0,
NULL,
0);
assert(NT_SUCCESS(Status));
MachineKey->RegistryHive = CmiVolatileHive;
MachineKey->Flags = 0;
MachineKey->NumberOfSubKeys = 0;
MachineKey->SubKeys = NULL;
MachineKey->SizeOfSubKeys = MachineKey->KeyCell->NumberOfSubKeys;
Status = RtlCreateUnicodeString(&MachineKey->Name, L"Machine");
assert(NT_SUCCESS(Status));
CmiAddKeyToList(RootKey, MachineKey);
/* Create '\Registry\User' key. */ /* Create '\Registry\User' key. */
Status = ObCreateObject(&KeyHandle, RtlInitUnicodeString(&KeyName,
STANDARD_RIGHTS_REQUIRED, L"User");
NULL, InitializeObjectAttributes(&ObjectAttributes,
CmiKeyType, &KeyName,
(PVOID*)&UserKey); 0,
RootKeyHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
NULL);
assert(NT_SUCCESS(Status)); assert(NT_SUCCESS(Status));
Status = CmiAddSubKey(CmiVolatileHive,
RootKey,
UserKey,
L"User",
wcslen(L"User") * sizeof(WCHAR),
0,
NULL,
0);
assert(NT_SUCCESS(Status));
UserKey->RegistryHive = CmiVolatileHive;
UserKey->Flags = 0;
UserKey->NumberOfSubKeys = 0;
UserKey->SubKeys = NULL;
UserKey->SizeOfSubKeys = UserKey->KeyCell->NumberOfSubKeys;
Status = RtlCreateUnicodeString(&UserKey->Name, L"User");
assert(NT_SUCCESS(Status));
CmiAddKeyToList(RootKey, UserKey);
} }

View file

@ -11,7 +11,6 @@
#include <internal/ob.h> #include <internal/ob.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <internal/pool.h>
#include <internal/registry.h> #include <internal/registry.h>
#include <ntos/minmax.h> #include <ntos/minmax.h>
@ -39,13 +38,13 @@ CmiObjectParse(PVOID ParsedObject,
PKEY_OBJECT FoundObject; PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey; PKEY_OBJECT ParsedKey;
PKEY_CELL SubKeyCell; PKEY_CELL SubKeyCell;
CHAR cPath[MAX_PATH];
NTSTATUS Status; NTSTATUS Status;
PWSTR StartPtr; PWSTR StartPtr;
PWSTR EndPtr; PWSTR EndPtr;
ULONG Length; ULONG Length;
UNICODE_STRING LinkPath; UNICODE_STRING LinkPath;
UNICODE_STRING TargetPath; UNICODE_STRING TargetPath;
UNICODE_STRING KeyName;
ParsedKey = ParsedObject; ParsedKey = ParsedObject;
@ -72,27 +71,37 @@ CmiObjectParse(PVOID ParsedObject,
else else
Length = wcslen(StartPtr); Length = wcslen(StartPtr);
wcstombs(cPath, StartPtr, Length);
cPath[Length] = 0; KeyName.Length = Length * sizeof(WCHAR);
KeyName.MaximumLength = KeyName.Length + sizeof(WCHAR);
KeyName.Buffer = ExAllocatePool(NonPagedPool,
KeyName.MaximumLength);
RtlCopyMemory(KeyName.Buffer,
StartPtr,
KeyName.Length);
KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes); FoundObject = CmiScanKeyList(ParsedKey,
&KeyName,
Attributes);
if (FoundObject == NULL) if (FoundObject == NULL)
{ {
Status = CmiScanForSubKey(ParsedKey->RegistryHive, Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell, ParsedKey->KeyCell,
&SubKeyCell, &SubKeyCell,
&BlockOffset, &BlockOffset,
cPath, &KeyName,
0, 0,
Attributes); Attributes);
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL)) if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
{ {
RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) && if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL) /*(end == NULL)*/)) !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{ {
RtlInitUnicodeString(&LinkPath, NULL); RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive, Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
@ -129,6 +138,8 @@ CmiObjectParse(PVOID ParsedObject,
*Path = FullPath->Buffer; *Path = FullPath->Buffer;
*NextObject = NULL; *NextObject = NULL;
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE); return(STATUS_REPARSE);
} }
} }
@ -142,27 +153,23 @@ CmiObjectParse(PVOID ParsedObject,
(PVOID*)&FoundObject); (PVOID*)&FoundObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
RtlFreeUnicodeString(&KeyName);
return(Status); return(Status);
} }
FoundObject->Flags = 0; FoundObject->Flags = 0;
FoundObject->Name.Length = Length * sizeof(WCHAR);
FoundObject->Name.MaximumLength = FoundObject->Name.Length + sizeof(WCHAR);
FoundObject->Name.Buffer = ExAllocatePool(NonPagedPool, FoundObject->Name.MaximumLength);
RtlCopyMemory(FoundObject->Name.Buffer, StartPtr, FoundObject->Name.Length);
FoundObject->Name.Buffer[FoundObject->Name.Length / sizeof(WCHAR)] = 0;
FoundObject->KeyCell = SubKeyCell; FoundObject->KeyCell = SubKeyCell;
FoundObject->BlockOffset = BlockOffset; FoundObject->BlockOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive; FoundObject->RegistryHive = ParsedKey->RegistryHive;
RtlCreateUnicodeString(&FoundObject->Name,
KeyName.Buffer);
CmiAddKeyToList(ParsedKey, FoundObject); CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%x\n", FoundObject); DPRINT("Created object 0x%x\n", FoundObject);
} }
else else
{ {
if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) && if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)/*(end == NULL)*/)) !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{ {
DPRINT("Found link\n"); DPRINT("Found link\n");
@ -201,6 +208,8 @@ CmiObjectParse(PVOID ParsedObject,
*Path = FullPath->Buffer; *Path = FullPath->Buffer;
*NextObject = NULL; *NextObject = NULL;
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE); return(STATUS_REPARSE);
} }
} }
@ -219,6 +228,8 @@ CmiObjectParse(PVOID ParsedObject,
*NextObject = FoundObject; *NextObject = FoundObject;
RtlFreeUnicodeString(&KeyName);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -375,19 +386,15 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
PKEY_OBJECT PKEY_OBJECT
CmiScanKeyList(PKEY_OBJECT Parent, CmiScanKeyList(PKEY_OBJECT Parent,
PCHAR KeyName, PUNICODE_STRING KeyName,
ULONG Attributes) ULONG Attributes)
{ {
PKEY_OBJECT CurKey; PKEY_OBJECT CurKey;
KIRQL OldIrql; KIRQL OldIrql;
ULONG Index; ULONG Index;
UNICODE_STRING UName;
DPRINT("Scanning key list for: %s (Parent: %wZ)\n", DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
KeyName, &Parent->Name); KeyName, &Parent->Name);
RtlCreateUnicodeStringFromAsciiz(&UName,
KeyName);
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */ /* FIXME: if list maintained in alphabetic order, use dichotomic search */
@ -396,27 +403,24 @@ CmiScanKeyList(PKEY_OBJECT Parent,
CurKey = Parent->SubKeys[Index]; CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE) if (Attributes & OBJ_CASE_INSENSITIVE)
{ {
if ((UName.Length == CurKey->Name.Length) if ((KeyName->Length == CurKey->Name.Length)
&& (_wcsicmp(UName.Buffer, CurKey->Name.Buffer) == 0)) && (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{ {
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
RtlFreeUnicodeString(&UName);
return CurKey; return CurKey;
} }
} }
else else
{ {
if ((UName.Length == CurKey->Name.Length) if ((KeyName->Length == CurKey->Name.Length)
&& (wcscmp(UName.Buffer, CurKey->Name.Buffer) == 0)) && (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{ {
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
RtlFreeUnicodeString(&UName);
return CurKey; return CurKey;
} }
} }
} }
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
RtlFreeUnicodeString(&UName);
return NULL; return NULL;
} }