Fixed querying and enumerating the subkeys of HKEY_LOCAL_MACHINE.

This fixes bug #78.

svn path=/trunk/; revision=7936
This commit is contained in:
Eric Kohl 2004-01-31 14:33:01 +00:00
parent faa1a76919
commit c88b53bb8e
4 changed files with 140 additions and 99 deletions

View file

@ -14,10 +14,10 @@
#define REG_DEVICEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP" #define REG_DEVICEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP"
#define REG_RESOURCEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP" #define REG_RESOURCEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"
#define REG_CLASSES_KEY_NAME L"\\Registry\\Machine\\Software\\Classes" #define REG_CLASSES_KEY_NAME L"\\Registry\\Machine\\Software\\Classes"
#define REG_SYSTEM_KEY_NAME L"\\Registry\\Machine\\System" #define REG_SYSTEM_KEY_NAME L"\\Registry\\Machine\\SYSTEM"
#define REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software" #define REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\SOFTWARE"
#define REG_SAM_KEY_NAME L"\\Registry\\Machine\\Sam" #define REG_SAM_KEY_NAME L"\\Registry\\Machine\\SAM"
#define REG_SEC_KEY_NAME L"\\Registry\\Machine\\Security" #define REG_SEC_KEY_NAME L"\\Registry\\Machine\\SECURITY"
#define REG_USER_KEY_NAME L"\\Registry\\User" #define REG_USER_KEY_NAME L"\\Registry\\User"
#define REG_DEFAULT_USER_KEY_NAME L"\\Registry\\User\\.Default" #define REG_DEFAULT_USER_KEY_NAME L"\\Registry\\User\\.Default"
#define REG_CURRENT_USER_KEY_NAME L"\\Registry\\User\\CurrentUser" #define REG_CURRENT_USER_KEY_NAME L"\\Registry\\User\\CurrentUser"
@ -451,6 +451,9 @@ CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
NTSTATUS NTSTATUS
CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive); CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
ULONG
CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject);
ULONG ULONG
CmiGetMaxNameLength(IN PKEY_OBJECT KeyObject); CmiGetMaxNameLength(IN PKEY_OBJECT KeyObject);

View file

@ -1,4 +1,4 @@
/* $Id: import.c,v 1.27 2004/01/05 14:28:19 weiden Exp $ /* $Id: import.c,v 1.28 2004/01/31 14:33:01 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -186,7 +186,7 @@ CmImportSystemHive(PCHAR ChunkBase,
/* Attach it to the machine key */ /* Attach it to the machine key */
RtlInitUnicodeString (&KeyName, RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\System"); REG_SYSTEM_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
@ -234,7 +234,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
{ {
/* Create '\Registry\Machine\HARDWARE' key. */ /* Create '\Registry\Machine\HARDWARE' key. */
RtlInitUnicodeString (&KeyName, RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\HARDWARE"); REG_HARDWARE_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
@ -255,7 +255,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
/* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
RtlInitUnicodeString(&KeyName, RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"); REG_DESCRIPTION_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
@ -276,7 +276,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
/* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
RtlInitUnicodeString (&KeyName, RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP"); REG_DEVICEMAP_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
@ -297,7 +297,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
/* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
RtlInitUnicodeString(&KeyName, RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"); REG_RESOURCEMAP_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
@ -338,7 +338,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
/* Attach it to the machine key */ /* Attach it to the machine key */
RtlInitUnicodeString (&KeyName, RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\HARDWARE"); REG_HARDWARE_KEY_NAME);
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,

View file

@ -272,7 +272,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength) OUT PULONG ResultLength)
{ {
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
PKEY_OBJECT SubKeyObject;
PREGISTRY_HIVE RegistryHive; PREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell, SubKeyCell; PKEY_CELL KeyCell, SubKeyCell;
PHASH_TABLE_CELL HashTableBlock; PHASH_TABLE_CELL HashTableBlock;
@ -314,6 +315,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
KeyCell = KeyObject->KeyCell; KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive; RegistryHive = KeyObject->RegistryHive;
SubKeyObject = NULL;
/* Check for hightest possible sub key index */ /* Check for hightest possible sub key index */
if (Index >= KeyCell->NumberOfSubKeys + KeyObject->NumberOfSubKeys) if (Index >= KeyCell->NumberOfSubKeys + KeyObject->NumberOfSubKeys)
{ {
@ -354,6 +357,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
} }
SubKeyObject = CurKey;
SubKeyCell = CurKey->KeyCell; SubKeyCell = CurKey->KeyCell;
} }
else else
@ -415,17 +419,28 @@ NtEnumerateKey(IN HANDLE KeyHandle,
BasicInformation->TitleIndex = Index; BasicInformation->TitleIndex = Index;
BasicInformation->NameLength = NameSize; BasicInformation->NameLength = NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED) if (SubKeyObject != NULL)
{ {
CmiCopyPackedName(BasicInformation->Name, BasicInformation->NameLength = SubKeyObject->Name.Length;
SubKeyCell->Name, RtlCopyMemory(BasicInformation->Name,
SubKeyCell->NameSize); SubKeyObject->Name.Buffer,
SubKeyObject->Name.Length);
} }
else else
{ {
RtlCopyMemory(BasicInformation->Name, BasicInformation->NameLength = NameSize;
SubKeyCell->Name, if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
SubKeyCell->NameSize); {
CmiCopyPackedName(BasicInformation->Name,
SubKeyCell->Name,
SubKeyCell->NameSize);
}
else
{
RtlCopyMemory(BasicInformation->Name,
SubKeyCell->Name,
SubKeyCell->NameSize);
}
} }
} }
break; break;
@ -456,19 +471,29 @@ NtEnumerateKey(IN HANDLE KeyHandle,
NodeInformation->TitleIndex = Index; NodeInformation->TitleIndex = Index;
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) + NameSize; NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) + NameSize;
NodeInformation->ClassLength = SubKeyCell->ClassSize; NodeInformation->ClassLength = SubKeyCell->ClassSize;
NodeInformation->NameLength = NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED) if (SubKeyObject != NULL)
{ {
CmiCopyPackedName(NodeInformation->Name, NodeInformation->NameLength = SubKeyObject->Name.Length;
SubKeyCell->Name, RtlCopyMemory(NodeInformation->Name,
SubKeyCell->NameSize); SubKeyObject->Name.Buffer,
SubKeyObject->Name.Length);
} }
else else
{ {
RtlCopyMemory(NodeInformation->Name, NodeInformation->NameLength = NameSize;
SubKeyCell->Name, if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
SubKeyCell->NameSize); {
CmiCopyPackedName(NodeInformation->Name,
SubKeyCell->Name,
SubKeyCell->NameSize);
}
else
{
RtlCopyMemory(NodeInformation->Name,
SubKeyCell->Name,
SubKeyCell->NameSize);
}
} }
if (SubKeyCell->ClassSize != 0) if (SubKeyCell->ClassSize != 0)
@ -502,7 +527,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
sizeof(WCHAR); sizeof(WCHAR);
FullInformation->ClassLength = SubKeyCell->ClassSize; FullInformation->ClassLength = SubKeyCell->ClassSize;
FullInformation->SubKeys = SubKeyCell->NumberOfSubKeys; FullInformation->SubKeys = CmiGetNumberOfSubKeys(KeyObject); //SubKeyCell->NumberOfSubKeys;
FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject); FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject); FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
FullInformation->Values = SubKeyCell->NumberOfValues; FullInformation->Values = SubKeyCell->NumberOfValues;
@ -914,18 +939,9 @@ NtQueryKey(IN HANDLE KeyHandle,
BasicInformation->TitleIndex = 0; BasicInformation->TitleIndex = 0;
BasicInformation->NameLength = KeyObject->Name.Length; BasicInformation->NameLength = KeyObject->Name.Length;
if (KeyCell->Flags & REG_KEY_NAME_PACKED) RtlCopyMemory(BasicInformation->Name,
{ KeyObject->Name.Buffer,
CmiCopyPackedName(BasicInformation->Name, KeyObject->Name.Length);
KeyCell->Name,
KeyCell->NameSize);
}
else
{
RtlCopyMemory(BasicInformation->Name,
KeyCell->Name,
KeyCell->NameSize);
}
} }
break; break;
@ -950,18 +966,9 @@ NtQueryKey(IN HANDLE KeyHandle,
NodeInformation->ClassLength = KeyCell->ClassSize; NodeInformation->ClassLength = KeyCell->ClassSize;
NodeInformation->NameLength = KeyObject->Name.Length; NodeInformation->NameLength = KeyObject->Name.Length;
if (KeyCell->Flags & REG_KEY_NAME_PACKED) RtlCopyMemory(NodeInformation->Name,
{ KeyObject->Name.Buffer,
CmiCopyPackedName(NodeInformation->Name, KeyObject->Name.Length);
KeyCell->Name,
KeyCell->NameSize);
}
else
{
RtlCopyMemory(NodeInformation->Name,
KeyCell->Name,
KeyCell->NameSize);
}
if (KeyCell->ClassSize != 0) if (KeyCell->ClassSize != 0)
{ {
@ -993,7 +1000,7 @@ NtQueryKey(IN HANDLE KeyHandle,
FullInformation->TitleIndex = 0; FullInformation->TitleIndex = 0;
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR); FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR);
FullInformation->ClassLength = KeyCell->ClassSize; FullInformation->ClassLength = KeyCell->ClassSize;
FullInformation->SubKeys = KeyCell->NumberOfSubKeys; FullInformation->SubKeys = CmiGetNumberOfSubKeys(KeyObject); //KeyCell->NumberOfSubKeys;
FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject); FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject); FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
FullInformation->Values = KeyCell->NumberOfValues; FullInformation->Values = KeyCell->NumberOfValues;

View file

@ -2026,6 +2026,36 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive)
} }
ULONG
CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject)
{
PKEY_OBJECT CurKey;
PKEY_CELL KeyCell;
ULONG SubKeyCount;
ULONG i;
VERIFY_KEY_OBJECT(KeyObject);
KeyCell = KeyObject->KeyCell;
VERIFY_KEY_CELL(KeyCell);
SubKeyCount = (KeyCell == NULL) ? 0 : KeyCell->NumberOfSubKeys;
/* Search for volatile or 'foreign' keys */
for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
{
CurKey = KeyObject->SubKeys[i];
if (CurKey->RegistryHive == CmiVolatileHive ||
CurKey->RegistryHive != KeyObject->RegistryHive)
{
SubKeyCount++;
}
}
return SubKeyCount;
}
ULONG ULONG
CmiGetMaxNameLength(PKEY_OBJECT KeyObject) CmiGetMaxNameLength(PKEY_OBJECT KeyObject)
{ {
@ -2053,8 +2083,8 @@ CmiGetMaxNameLength(PKEY_OBJECT KeyObject)
else else
{ {
for (i = 0; i < HashBlock->HashTableSize; i++) for (i = 0; i < HashBlock->HashTableSize; i++)
{ {
if (HashBlock->Table[i].KeyOffset != 0) if (HashBlock->Table[i].KeyOffset != 0)
{ {
CurSubKeyCell = CmiGetCell (KeyObject->RegistryHive, CurSubKeyCell = CmiGetCell (KeyObject->RegistryHive,
HashBlock->Table[i].KeyOffset, HashBlock->Table[i].KeyOffset,
@ -2064,7 +2094,7 @@ CmiGetMaxNameLength(PKEY_OBJECT KeyObject)
DPRINT("CmiGetBlock() failed\n"); DPRINT("CmiGetBlock() failed\n");
continue; continue;
} }
NameSize = CurSubKeyCell->NameSize; NameSize = CurSubKeyCell->NameSize;
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED) if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
{ {
NameSize *= sizeof(WCHAR); NameSize *= sizeof(WCHAR);
@ -2076,29 +2106,30 @@ CmiGetMaxNameLength(PKEY_OBJECT KeyObject)
} }
} }
} }
if (KeyObject->RegistryHive != CmiVolatileHive)
DPRINT("KeyObject->NumberOfSubKeys %d\n", KeyObject->NumberOfSubKeys);
for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
{ {
DPRINT("KeyObject->NumberOfSubKeys %d\n", KeyObject->NumberOfSubKeys); CurKey = KeyObject->SubKeys[i];
for (i = 0; i < KeyObject->NumberOfSubKeys; i++) if (CurKey->RegistryHive == CmiVolatileHive ||
{ CurKey->RegistryHive != KeyObject->RegistryHive)
CurKey = KeyObject->SubKeys[i]; {
if (CurKey->RegistryHive == CmiVolatileHive) CurSubKeyCell = CurKey->KeyCell;
if (CurSubKeyCell == NULL)
{ {
CurSubKeyCell = CurKey->KeyCell; DPRINT("CmiGetBlock() failed\n");
if (CurSubKeyCell == NULL) continue;
{ }
DPRINT("CmiGetBlock() failed\n");
continue; NameSize = CurSubKeyCell->NameSize;
} if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
NameSize = CurSubKeyCell->NameSize; {
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED) NameSize *= sizeof(WCHAR);
{ }
NameSize *= sizeof(WCHAR);
} if (MaxName < NameSize)
if (MaxName < NameSize) {
{ MaxName = NameSize;
MaxName = NameSize;
}
} }
} }
} }
@ -2133,8 +2164,8 @@ CmiGetMaxClassLength(PKEY_OBJECT KeyObject)
else else
{ {
for (i = 0; i < HashBlock->HashTableSize; i++) for (i = 0; i < HashBlock->HashTableSize; i++)
{ {
if (HashBlock->Table[i].KeyOffset != 0) if (HashBlock->Table[i].KeyOffset != 0)
{ {
CurSubKeyCell = CmiGetCell (KeyObject->RegistryHive, CurSubKeyCell = CmiGetCell (KeyObject->RegistryHive,
HashBlock->Table[i].KeyOffset, HashBlock->Table[i].KeyOffset,
@ -2152,24 +2183,24 @@ CmiGetMaxClassLength(PKEY_OBJECT KeyObject)
} }
} }
} }
if (KeyObject->RegistryHive != CmiVolatileHive)
DPRINT("KeyObject->NumberOfSubKeys %d\n", KeyObject->NumberOfSubKeys);
for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
{ {
DPRINT("KeyObject->NumberOfSubKeys %d\n", KeyObject->NumberOfSubKeys); CurKey = KeyObject->SubKeys[i];
for (i = 0; i < KeyObject->NumberOfSubKeys; i++) if (CurKey->RegistryHive == CmiVolatileHive ||
{ CurKey->RegistryHive != KeyObject->RegistryHive)
CurKey = KeyObject->SubKeys[i]; {
if (CurKey->RegistryHive == CmiVolatileHive) CurSubKeyCell = CurKey->KeyCell;
if (CurSubKeyCell == NULL)
{ {
CurSubKeyCell = CurKey->KeyCell; DPRINT("CmiGetBlock() failed\n");
if (CurSubKeyCell == NULL) continue;
{ }
DPRINT("CmiGetBlock() failed\n");
continue; if (MaxClass < CurSubKeyCell->ClassSize)
} {
if (MaxClass < CurSubKeyCell->ClassSize) MaxClass = CurSubKeyCell->ClassSize;
{
MaxClass = CurSubKeyCell->ClassSize;
}
} }
} }
} }
@ -2211,15 +2242,15 @@ CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive,
} }
if (CurValueCell != NULL) if (CurValueCell != NULL)
{ {
Size = CurValueCell->NameSize; Size = CurValueCell->NameSize;
if (CurValueCell->Flags & REG_VALUE_NAME_PACKED) if (CurValueCell->Flags & REG_VALUE_NAME_PACKED)
{ {
Size *= sizeof(WCHAR); Size *= sizeof(WCHAR);
} }
if (MaxValueName < Size) if (MaxValueName < Size)
{ {
MaxValueName = Size; MaxValueName = Size;
} }
} }
} }