{
PCM_KEY_NODE Node;
UNICODE_STRING SearchName;
BOOLEAN IsCompressed;
ULONG i, Result;
PCM_KEY_INDEX Index;
HCELL_INDEX IndexCell, Child = HCELL_NIL, CellToRelease = HCELL_NIL;
/* Get the target key node */
Node = (PCM_KEY_NODE)HvGetCell(Hive, TargetKey);
if (!Node) returnFALSE;
/* Check if it's compressed */if (Node->Flags & KEY_COMP_NAME)
{
/* Remember this for later */
IsCompressed = TRUE;
/* Build the search name */
SearchName.Length = CmpCompressedNameSize(Node->Name,
Node->NameLength);
SearchName.MaximumLength = SearchName.Length;
SearchName.Buffer = CmpAllocate(SearchName.Length,
TRUE,
TAG_CM);
if (!SearchName.Buffer)
{
/* Fail */HvReleaseCell(Hive, TargetKey);
returnFALSE;
}
/* Copy it */CmpCopyCompressedName(SearchName.Buffer,
SearchName.MaximumLength,
Node->Name,
Node->NameLength);
}
else
{
/* Name isn't compressed, build it directly from the node */
IsCompressed = FALSE;
SearchName.Length = Node->NameLength;
SearchName.MaximumLength = Node->NameLength;
SearchName.Buffer = Node->Name;
}
/* We can release the target key now */HvReleaseCell(Hive, TargetKey);
/* Now get the parent key node */
Node = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey);
if (!Node) goto Quickie;
/* Loop all hive storage */for (i = 0; i < Hive->StorageTypeCount; i++)
{
/* Check if any subkeys are in this index */if (Node->SubKeyCounts[i])
{
/* Get the cell index *///ASSERT(HvIsCellAllocated(Hive, Node->SubKeyLists[i]));
IndexCell = Node->SubKeyLists[i];
/* Check if we had anything to release from before */if (CellToRelease != HCELL_NIL)
{
/* Release it now */HvReleaseCell(Hive, CellToRelease);
CellToRelease = HCELL_NIL;
}
/* Get the key index for the cell */
Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell);
if (!Index) goto Quickie;
/* Release it at the next iteration or below */
CellToRelease = IndexCell;
/* Check if this is a root */if (Index->Signature == CM_KEY_INDEX_ROOT)
{
/* Get the child inside the root */
Result = CmpFindSubKeyInRoot(Hive, Index, &SearchName, &Child);
if (Result & 0x80000000) goto Quickie;
if (Child == HCELL_NIL) continue;
/* We found it, mark the cell dirty */HvMarkCellDirty(Hive, IndexCell, FALSE);
/* Check if we had anything to release from before */if (CellToRelease != HCELL_NIL)
{
/* Release it now */HvReleaseCell(Hive, CellToRelease);
CellToRelease = HCELL_NIL;
}
/* Now this child is the index, get the actual key index */
IndexCell = Child;
Index = (PCM_KEY_INDEX)HvGetCell(Hive, Child);
if (!Index) goto Quickie;
/* Release it later */
CellToRelease = Child;
}
/* Make sure this is a valid index */ASSERT((Index->Signature == CM_KEY_INDEX_LEAF) ||
(Index->Signature == CM_KEY_FAST_LEAF) ||
(Index->Signature == CM_KEY_HASH_LEAF));
/* Find the child in the leaf */
Result = CmpFindSubKeyInLeaf(Hive, Index, &SearchName, &Child);
if (Result & 0x80000000) goto Quickie;
if (Child != HCELL_NIL)
{
/* We found it, free the name now */if (IsCompressed) CmpFree(SearchName.Buffer, 0);
/* Release the parent key */HvReleaseCell(Hive, ParentKey);
/* Check if we had a left over cell to release */if (CellToRelease != HCELL_NIL)
{
/* Release it */HvReleaseCell(Hive, CellToRelease);
}
/* And mark the index cell dirty */HvMarkCellDirty(Hive, IndexCell, FALSE);
returnTRUE;
}
}
}
Quickie:
/* Release any cells that we still hold */if (Node) HvReleaseCell(Hive, ParentKey);
if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
/* Free the search name and return failure */if (IsCompressed) CmpFree(SearchName.Buffer, 0);
returnFALSE;
}
Generated on Fri May 25 2012 06:04:32 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.