- Update cached KCB values when necessary.

- Update Node Maximum values when necessary.
- Return data from the node instead of calling 3rd-party functions to loop around the entire key until they find something appropriate.
- Get rid of CmiScanForSubKey, CmiGetMaxValueDataLength, CmiGetMaxValueNameLength, CmiGetMaxClassLength, CmiGetMaxNameLength.

svn path=/trunk/; revision=30028
This commit is contained in:
Aleksey Bragin 2007-10-31 22:33:43 +00:00
parent f366d38ae8
commit c5f01afb3d
2 changed files with 24 additions and 188 deletions

View file

@ -101,157 +101,6 @@ CmiFlushRegistryHive(PCMHIVE RegistryHive)
return Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
ULONG
CmiGetMaxNameLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PCM_KEY_FAST_INDEX HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxName;
ULONG NameLength;
ULONG i;
ULONG Storage;
MaxName = 0;
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
{
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
HashBlock->List[i].Cell);
NameLength = CurSubKeyCell->NameLength;
if (CurSubKeyCell->Flags & KEY_COMP_NAME)
NameLength *= sizeof(WCHAR);
if (NameLength > MaxName)
MaxName = NameLength;
}
}
}
DPRINT ("MaxName %lu\n", MaxName);
return MaxName;
}
ULONG
CmiGetMaxClassLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PCM_KEY_FAST_INDEX HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxClass;
ULONG i;
ULONG Storage;
MaxClass = 0;
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
{
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (Hive,
KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
HashBlock->List[i].Cell);
if (MaxClass < CurSubKeyCell->ClassLength)
{
MaxClass = CurSubKeyCell->ClassLength;
}
}
}
}
return MaxClass;
}
ULONG
CmiGetMaxValueNameLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
ULONG MaxValueName;
ULONG Size;
ULONG i;
VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NIL)
{
return 0;
}
MaxValueName = 0;
ValueListCell = (PVALUE_LIST_CELL)HvGetCell (Hive,
KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++)
{
CurValueCell = (PCM_KEY_VALUE)HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if (CurValueCell == NULL)
{
DPRINT("CmiGetBlock() failed\n");
}
if (CurValueCell != NULL)
{
Size = CurValueCell->NameLength;
if (CurValueCell->Flags & VALUE_COMP_NAME)
{
Size *= sizeof(WCHAR);
}
if (MaxValueName < Size)
{
MaxValueName = Size;
}
}
}
return MaxValueName;
}
ULONG
CmiGetMaxValueDataLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
LONG MaxValueData;
ULONG i;
VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NIL)
{
return 0;
}
MaxValueData = 0;
ValueListCell = (PVALUE_LIST_CELL)HvGetCell (Hive, KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++)
{
CurValueCell = (PCM_KEY_VALUE)HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if ((MaxValueData < (LONG)(CurValueCell->DataLength & REG_DATA_SIZE_MASK)))
{
MaxValueData = CurValueCell->DataLength & REG_DATA_SIZE_MASK;
}
}
return MaxValueData;
}
NTSTATUS
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
IN PCM_KEY_NODE KeyCell,
@ -275,28 +124,4 @@ CmiScanKeyForValue(IN PCMHIVE RegistryHive,
return STATUS_SUCCESS;
}
NTSTATUS
CmiScanForSubKey(IN PCMHIVE RegistryHive,
IN PCM_KEY_NODE KeyCell,
OUT PCM_KEY_NODE *SubKeyCell,
OUT HCELL_INDEX *BlockOffset,
IN PCUNICODE_STRING KeyName,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes)
{
HCELL_INDEX CellIndex;
/* Assume failure */
*SubKeyCell = NULL;
/* Call newer Cm API */
CellIndex = CmpFindSubKeyByName(&RegistryHive->Hive, KeyCell, KeyName);
if (CellIndex == HCELL_NIL) return STATUS_OBJECT_NAME_NOT_FOUND;
/* Otherwise, get the cell data back too */
*BlockOffset = CellIndex;
*SubKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive, CellIndex);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -331,8 +331,23 @@ CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
Quickie:
if (NT_SUCCESS(Status))
{
ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
if (Parent->MaxValueNameLen < ValueName->Length)
{
Parent->MaxValueNameLen = ValueName->Length;
Kcb->KcbMaxValueNameLen = ValueName->Length;
}
ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
if (Parent->MaxValueDataLen < DataLength)
{
Parent->MaxValueDataLen = DataLength;
Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
}
/* Save the write time */
KeQuerySystemTime(&Parent->LastWriteTime);
KeQuerySystemTime(&Kcb->KcbLastWriteTime);
}
/* Release the lock */
@ -422,8 +437,11 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
/* Set the last write time */
KeQuerySystemTime(&Parent->LastWriteTime);
KeQuerySystemTime(&Kcb->KcbLastWriteTime);
/* Sanity check */
ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
ASSERT(HvIsCellDirty(Hive, Cell));
/* Check if the value list is empty now */
@ -432,6 +450,8 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
/* Then clear key node data */
Parent->MaxValueNameLen = 0;
Parent->MaxValueDataLen = 0;
Kcb->KcbMaxValueNameLen = 0;
Kcb->KcbMaxValueDataLen = 0;
}
/* Change default Status to success */
@ -811,19 +831,10 @@ CmpQueryKeyData(IN PHHIVE Hive,
Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] +
Node->SubKeyCounts[Volatile];
Info->KeyFullInformation.Values = Node->ValueList.Count;
Info->KeyFullInformation.MaxNameLen = CmiGetMaxNameLength(Hive, Node);
Info->KeyFullInformation.MaxClassLen = CmiGetMaxClassLength(Hive, Node);
Info->KeyFullInformation.MaxValueNameLen = CmiGetMaxValueNameLength(Hive, Node);
Info->KeyFullInformation.MaxValueDataLen = CmiGetMaxValueDataLength(Hive, Node);
DPRINT("%d %d %d %d\n",
CmiGetMaxNameLength(Hive, Node),
CmiGetMaxValueDataLength(Hive, Node),
CmiGetMaxValueNameLength(Hive, Node),
CmiGetMaxClassLength(Hive, Node));
//Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
//Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
//Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
//Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
/* Check if we have a class */
if (Node->ClassLength > 0)