mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 11:24:14 +00:00
[NTOS]: Improve a bit CmpDeepCopyKeyInternal():
- Normally getting the SrcNode and DestNode must succeed (checked with assert); - Set the DestNode Flags member, in particular when this is the new root node of the saved registry hive; - Copy the key class cell (OK), and the key security cell (currently done in a hackish way; proper way: call the CmpAssignSecurity* function); - Add more clean-up on failure; - Warn in code about the fact that CmpDeepCopyKeyInternal is recursive, and will easily exhaust kernel stack. This function will need to be reworked later... CORE-10793 CORE-10796 svn path=/trunk/; revision=75171
This commit is contained in:
parent
3dae17b0e7
commit
ab30fb1d60
1 changed files with 81 additions and 11 deletions
|
@ -993,7 +993,7 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ssanity checks */
|
/* Sanity checks */
|
||||||
ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
|
ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
|
||||||
ASSERT(HvIsCellDirty(Hive, ChildCell));
|
ASSERT(HvIsCellDirty(Hive, ChildCell));
|
||||||
|
|
||||||
|
@ -2376,7 +2376,6 @@ CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
|
||||||
CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
IN HCELL_INDEX SrcKeyCell,
|
IN HCELL_INDEX SrcKeyCell,
|
||||||
IN PHHIVE DestinationHive,
|
IN PHHIVE DestinationHive,
|
||||||
|
@ -2387,8 +2386,11 @@ CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCM_KEY_NODE SrcNode;
|
PCM_KEY_NODE SrcNode;
|
||||||
PCM_KEY_NODE DestNode = NULL;
|
PCM_KEY_NODE DestNode = NULL;
|
||||||
HCELL_INDEX NewKeyCell, SubKey, NewSubKey;
|
HCELL_INDEX NewKeyCell = HCELL_NIL;
|
||||||
|
HCELL_INDEX NewClassCell = HCELL_NIL, NewSecCell = HCELL_NIL;
|
||||||
|
HCELL_INDEX SubKey, NewSubKey;
|
||||||
ULONG Index, SubKeyCount;
|
ULONG Index, SubKeyCount;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("CmpDeepCopyKeyInternal(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",
|
DPRINT("CmpDeepCopyKeyInternal(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",
|
||||||
|
@ -2401,6 +2403,7 @@ CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
|
|
||||||
/* Get the source cell node */
|
/* Get the source cell node */
|
||||||
SrcNode = HvGetCell(SourceHive, SrcKeyCell);
|
SrcNode = HvGetCell(SourceHive, SrcKeyCell);
|
||||||
|
ASSERT(SrcNode);
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT(SrcNode->Signature == CM_KEY_NODE_SIGNATURE);
|
ASSERT(SrcNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||||
|
@ -2419,12 +2422,55 @@ CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
|
|
||||||
/* Get the destination cell node */
|
/* Get the destination cell node */
|
||||||
DestNode = HvGetCell(DestinationHive, NewKeyCell);
|
DestNode = HvGetCell(DestinationHive, NewKeyCell);
|
||||||
|
ASSERT(DestNode);
|
||||||
|
|
||||||
/* Set the parent */
|
/* Set the parent and copy the flags */
|
||||||
DestNode->Parent = Parent;
|
DestNode->Parent = Parent;
|
||||||
|
DestNode->Flags = (SrcNode->Flags & KEY_COMP_NAME); // Keep only the single permanent flag
|
||||||
|
if (Parent == HCELL_NIL)
|
||||||
|
{
|
||||||
|
/* This is the new root node */
|
||||||
|
DestNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: These should also be copied!
|
/* Copy the class cell */
|
||||||
DestNode->Security = DestNode->Class = HCELL_NIL;
|
if (SrcNode->ClassLength > 0)
|
||||||
|
{
|
||||||
|
NewClassCell = CmpCopyCell(SourceHive,
|
||||||
|
SrcNode->Class,
|
||||||
|
DestinationHive,
|
||||||
|
StorageType);
|
||||||
|
if (NewClassCell == HCELL_NIL)
|
||||||
|
{
|
||||||
|
/* Not enough storage space */
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
DestNode->Class = NewClassCell;
|
||||||
|
DestNode->ClassLength = SrcNode->ClassLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DestNode->Class = HCELL_NIL;
|
||||||
|
DestNode->ClassLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the security cell (FIXME: HACKish poor-man version) */
|
||||||
|
if (SrcNode->Security != HCELL_NIL)
|
||||||
|
{
|
||||||
|
NewSecCell = CmpCopyCell(SourceHive,
|
||||||
|
SrcNode->Security,
|
||||||
|
DestinationHive,
|
||||||
|
StorageType);
|
||||||
|
if (NewSecCell == HCELL_NIL)
|
||||||
|
{
|
||||||
|
/* Not enough storage space */
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DestNode->Security = NewSecCell;
|
||||||
|
|
||||||
/* Copy the value list */
|
/* Copy the value list */
|
||||||
Status = CmpCopyKeyValueList(SourceHive,
|
Status = CmpCopyKeyValueList(SourceHive,
|
||||||
|
@ -2432,7 +2478,8 @@ CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
DestinationHive,
|
DestinationHive,
|
||||||
&DestNode->ValueList,
|
&DestNode->ValueList,
|
||||||
StorageType);
|
StorageType);
|
||||||
if (!NT_SUCCESS(Status)) goto Cleanup;
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto Cleanup;
|
||||||
|
|
||||||
/* Clear the invalid subkey index */
|
/* Clear the invalid subkey index */
|
||||||
DestNode->SubKeyCounts[Stable] = DestNode->SubKeyCounts[Volatile] = 0;
|
DestNode->SubKeyCounts[Stable] = DestNode->SubKeyCounts[Volatile] = 0;
|
||||||
|
@ -2449,34 +2496,57 @@ CmpDeepCopyKeyInternal(IN PHHIVE SourceHive,
|
||||||
ASSERT(SubKey != HCELL_NIL);
|
ASSERT(SubKey != HCELL_NIL);
|
||||||
|
|
||||||
/* Call the function recursively for the subkey */
|
/* Call the function recursively for the subkey */
|
||||||
|
//
|
||||||
|
// FIXME: Danger!! Kernel stack exhaustion!!
|
||||||
|
//
|
||||||
Status = CmpDeepCopyKeyInternal(SourceHive,
|
Status = CmpDeepCopyKeyInternal(SourceHive,
|
||||||
SubKey,
|
SubKey,
|
||||||
DestinationHive,
|
DestinationHive,
|
||||||
NewKeyCell,
|
NewKeyCell,
|
||||||
StorageType,
|
StorageType,
|
||||||
&NewSubKey);
|
&NewSubKey);
|
||||||
if (!NT_SUCCESS(Status)) goto Cleanup;
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto Cleanup;
|
||||||
|
|
||||||
/* Add the copy of the subkey to the new key */
|
/* Add the copy of the subkey to the new key */
|
||||||
if (!CmpAddSubKey(DestinationHive,
|
if (!CmpAddSubKey(DestinationHive,
|
||||||
NewKeyCell,
|
NewKeyCell,
|
||||||
NewSubKey))
|
NewSubKey))
|
||||||
{
|
{
|
||||||
|
/* Cleanup allocated cell */
|
||||||
|
HvFreeCell(DestinationHive, NewSubKey);
|
||||||
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the cell index if requested and return success */
|
/* Set success */
|
||||||
if (DestKeyCell) *DestKeyCell = NewKeyCell;
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
||||||
/* Release the cells */
|
/* Release the cells */
|
||||||
if (SrcNode) HvReleaseCell(SourceHive, SrcKeyCell);
|
|
||||||
if (DestNode) HvReleaseCell(DestinationHive, NewKeyCell);
|
if (DestNode) HvReleaseCell(DestinationHive, NewKeyCell);
|
||||||
|
if (SrcNode) HvReleaseCell(SourceHive, SrcKeyCell);
|
||||||
|
|
||||||
|
/* Cleanup allocated cells in case of failure */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (NewSecCell != HCELL_NIL)
|
||||||
|
HvFreeCell(DestinationHive, NewSecCell);
|
||||||
|
|
||||||
|
if (NewClassCell != HCELL_NIL)
|
||||||
|
HvFreeCell(DestinationHive, NewClassCell);
|
||||||
|
|
||||||
|
if (NewKeyCell != HCELL_NIL)
|
||||||
|
HvFreeCell(DestinationHive, NewKeyCell);
|
||||||
|
|
||||||
|
NewKeyCell = HCELL_NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the cell index if requested and return status */
|
||||||
|
if (DestKeyCell) *DestKeyCell = NewKeyCell;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue