mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Finish correct definition of CM_KEY_NODE.
- Fix broken CmpTestRegistryLock functions, they could return FALSE even if the lock was held. - Enable some extra assertions. - Update KCB flags as well when updating keynode flags in CmpDoCreate. - Update KCB Last write time as well when updating keynode lastwritetime in CmpDoCreate. - Do CmpDoOpen with the registry lock held, and tell CmpCreateKeycontrolBlock to lock the KCB exclusively. - Enable link-node create code to set the ChildHiveRefernece values. This is used to "escape" the current Hive when a KEY_HIVE_EXIT node is detected (an internal symlink) and required for new parsing semantics. - Implement CmpHandleExitNode to test how "escaping" from an exit node into a link hive works (it does). - Plug that function into the new parse routine for testing purposes. - Enable CmpDoOpen path in the new parse routine, only used for link node creation for now. svn path=/trunk/; revision=31009
This commit is contained in:
parent
6117db4db0
commit
98a17200e4
3 changed files with 106 additions and 20 deletions
|
@ -103,7 +103,7 @@ typedef struct _CM_KEY_NODE
|
||||||
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
||||||
CHILD_LIST ValueList;
|
CHILD_LIST ValueList;
|
||||||
};
|
};
|
||||||
//CM_KEY_REFERENCE ChildHiveReference;
|
CM_KEY_REFERENCE ChildHiveReference;
|
||||||
};
|
};
|
||||||
HCELL_INDEX Security;
|
HCELL_INDEX Security;
|
||||||
HCELL_INDEX Class;
|
HCELL_INDEX Class;
|
||||||
|
|
|
@ -379,11 +379,12 @@ CmpDoCreate(IN PHHIVE Hive,
|
||||||
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
|
||||||
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
|
||||||
ASSERT(KeyBody->KeyControlBlock->ParentKcb == ParentKcb);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb == ParentKcb);
|
||||||
//ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
|
||||||
|
|
||||||
/* Update the timestamp */
|
/* Update the timestamp */
|
||||||
KeQuerySystemTime(&TimeStamp);
|
KeQuerySystemTime(&TimeStamp);
|
||||||
KeyNode->LastWriteTime = TimeStamp;
|
KeyNode->LastWriteTime = TimeStamp;
|
||||||
|
KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
|
||||||
|
|
||||||
/* Check if we need to update name maximum */
|
/* Check if we need to update name maximum */
|
||||||
if (KeyNode->MaxNameLen < Name->Length)
|
if (KeyNode->MaxNameLen < Name->Length)
|
||||||
|
@ -413,6 +414,7 @@ CmpDoCreate(IN PHHIVE Hive,
|
||||||
|
|
||||||
/* Update the flags */
|
/* Update the flags */
|
||||||
CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
|
CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
|
||||||
|
KeyBody->KeyControlBlock->Flags = CellData->u.KeyNode.Flags;
|
||||||
HvReleaseCell(Hive, KeyCell);
|
HvReleaseCell(Hive, KeyCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,6 +451,9 @@ CmpDoOpen(IN PHHIVE Hive,
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do this in the registry lock */
|
||||||
|
CmpLockRegistry();
|
||||||
|
|
||||||
/* If we have a KCB, make sure it's locked */
|
/* If we have a KCB, make sure it's locked */
|
||||||
//ASSERT(CmpIsKcbLockedExclusive(*CachedKcb));
|
//ASSERT(CmpIsKcbLockedExclusive(*CachedKcb));
|
||||||
|
|
||||||
|
@ -457,7 +462,7 @@ CmpDoOpen(IN PHHIVE Hive,
|
||||||
Cell,
|
Cell,
|
||||||
Node,
|
Node,
|
||||||
*CachedKcb,
|
*CachedKcb,
|
||||||
CMP_LOCK_HASHES_FOR_KCB,
|
0,
|
||||||
KeyName);
|
KeyName);
|
||||||
if (!Kcb) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Kcb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
@ -465,6 +470,9 @@ CmpDoOpen(IN PHHIVE Hive,
|
||||||
//ASSERT(CmpIsKcbLockedExclusive(Kcb));
|
//ASSERT(CmpIsKcbLockedExclusive(Kcb));
|
||||||
*CachedKcb = Kcb;
|
*CachedKcb = Kcb;
|
||||||
|
|
||||||
|
/* Release the registry lock */
|
||||||
|
CmpUnlockRegistry();
|
||||||
|
|
||||||
/* Allocate the key object */
|
/* Allocate the key object */
|
||||||
Status = ObCreateObject(AccessMode,
|
Status = ObCreateObject(AccessMode,
|
||||||
CmpKeyObjectType,
|
CmpKeyObjectType,
|
||||||
|
@ -671,8 +679,8 @@ CmpCreateLinkNode(IN PHHIVE Hive,
|
||||||
KeyNode->ClassLength = 0;
|
KeyNode->ClassLength = 0;
|
||||||
|
|
||||||
/* Reference the root node */
|
/* Reference the root node */
|
||||||
//KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
|
KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
|
||||||
//KeyNode->ChildHiveReference.KeyCell = ChildCell;
|
KeyNode->ChildHiveReference.KeyCell = ChildCell;
|
||||||
HvReleaseCell(Hive, LinkCell);
|
HvReleaseCell(Hive, LinkCell);
|
||||||
|
|
||||||
/* Get the parent node */
|
/* Get the parent node */
|
||||||
|
@ -698,7 +706,7 @@ CmpCreateLinkNode(IN PHHIVE Hive,
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
|
||||||
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
|
||||||
//ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
|
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
|
||||||
|
|
||||||
/* Update the timestamp */
|
/* Update the timestamp */
|
||||||
KeQuerySystemTime(&TimeStamp);
|
KeQuerySystemTime(&TimeStamp);
|
||||||
|
@ -727,6 +735,42 @@ Exit:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CmpHandleExitNode(IN OUT PHHIVE *Hive,
|
||||||
|
IN OUT HCELL_INDEX *Cell,
|
||||||
|
IN OUT PCM_KEY_NODE *KeyNode,
|
||||||
|
IN OUT PHHIVE *ReleaseHive,
|
||||||
|
IN OUT HCELL_INDEX *ReleaseCell)
|
||||||
|
{
|
||||||
|
/* Check if we have anything to release */
|
||||||
|
if (*ReleaseCell != HCELL_NIL)
|
||||||
|
{
|
||||||
|
/* Release it */
|
||||||
|
ASSERT(*ReleaseHive != NULL);
|
||||||
|
HvReleaseCell((*ReleaseHive), *ReleaseCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the link references */
|
||||||
|
*Hive = (*KeyNode)->ChildHiveReference.KeyHive;
|
||||||
|
*Cell = (*KeyNode)->ChildHiveReference.KeyCell;
|
||||||
|
|
||||||
|
/* Get the new node */
|
||||||
|
*KeyNode = (PCM_KEY_NODE)HvGetCell((*Hive), *Cell);
|
||||||
|
if (*KeyNode)
|
||||||
|
{
|
||||||
|
/* Set the new release values */
|
||||||
|
*ReleaseCell = *Cell;
|
||||||
|
*ReleaseHive = *Hive;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Nothing to release */
|
||||||
|
*ReleaseCell = HCELL_NIL;
|
||||||
|
*ReleaseHive = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CmpBuildHashStackAndLookupCache(IN PCM_KEY_BODY ParseObject,
|
CmpBuildHashStackAndLookupCache(IN PCM_KEY_BODY ParseObject,
|
||||||
|
@ -775,11 +819,13 @@ CmpParseKey2(IN PVOID ParseObject,
|
||||||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
||||||
OUT PVOID *Object)
|
OUT PVOID *Object)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status;
|
||||||
PCM_KEY_CONTROL_BLOCK Kcb, ParentKcb;
|
PCM_KEY_CONTROL_BLOCK Kcb, ParentKcb;
|
||||||
PHHIVE Hive = NULL;
|
PHHIVE Hive = NULL;
|
||||||
PCM_KEY_NODE Node = NULL;
|
PCM_KEY_NODE Node = NULL;
|
||||||
HCELL_INDEX Cell = HCELL_NIL, NextCell;
|
HCELL_INDEX Cell = HCELL_NIL, NextCell;
|
||||||
|
PHHIVE HiveToRelease = NULL;
|
||||||
|
HCELL_INDEX CellToRelease = HCELL_NIL;
|
||||||
UNICODE_STRING Current, NextName;
|
UNICODE_STRING Current, NextName;
|
||||||
PCM_PARSE_CONTEXT ParseContext = Context;
|
PCM_PARSE_CONTEXT ParseContext = Context;
|
||||||
ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0;
|
ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0;
|
||||||
|
@ -852,7 +898,7 @@ CmpParseKey2(IN PVOID ParseObject,
|
||||||
DPRINT1("Node Parse: %p\n", Node);
|
DPRINT1("Node Parse: %p\n", Node);
|
||||||
|
|
||||||
/* Start parsing */
|
/* Start parsing */
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* Get the next component */
|
/* Get the next component */
|
||||||
|
@ -865,7 +911,7 @@ CmpParseKey2(IN PVOID ParseObject,
|
||||||
{
|
{
|
||||||
/* Find the subkey */
|
/* Find the subkey */
|
||||||
NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
|
NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
|
||||||
DPRINT1("NextCell Parse: %lx\n", NextCell);
|
DPRINT1("NextCell Parse: %lx %wZ\n", NextCell, &NextName);
|
||||||
if (NextCell != HCELL_NIL)
|
if (NextCell != HCELL_NIL)
|
||||||
{
|
{
|
||||||
/* Get the new node */
|
/* Get the new node */
|
||||||
|
@ -877,17 +923,57 @@ CmpParseKey2(IN PVOID ParseObject,
|
||||||
/* Check if this was the last key */
|
/* Check if this was the last key */
|
||||||
if (Last)
|
if (Last)
|
||||||
{
|
{
|
||||||
/* Shouldn't happen yet */
|
/* Is this an exit node */
|
||||||
DPRINT1("Unhandled: Open of last key\n");
|
if (Node->Flags & KEY_HIVE_EXIT)
|
||||||
|
{
|
||||||
|
/* Handle it */
|
||||||
|
DPRINT1("Exit node\n");
|
||||||
|
CmpHandleExitNode(&Hive,
|
||||||
|
&Cell,
|
||||||
|
&Node,
|
||||||
|
&HiveToRelease,
|
||||||
|
&CellToRelease);
|
||||||
|
DPRINT1("Node Parse: %p\n", Node);
|
||||||
|
if (!Node) ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the open */
|
||||||
|
Status = CmpDoOpen(Hive,
|
||||||
|
Cell,
|
||||||
|
Node,
|
||||||
|
AccessState,
|
||||||
|
AccessMode,
|
||||||
|
Attributes,
|
||||||
|
ParseContext,
|
||||||
|
0,
|
||||||
|
&Kcb,
|
||||||
|
&NextName,
|
||||||
|
Object);
|
||||||
|
if (Status == STATUS_REPARSE)
|
||||||
|
{
|
||||||
|
/* Not implemented */
|
||||||
|
DPRINT1("Parsing sym link\n");
|
||||||
|
while (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are done */
|
||||||
|
DPRINT1("Open of last key\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get hive and cell from reference */
|
/* Is this an exit node */
|
||||||
//Hive = Node->ChildHiveReference.KeyHive;
|
if (Node->Flags & KEY_HIVE_EXIT)
|
||||||
//Cell = Node->ChildHiveReference.KeyCell;
|
{
|
||||||
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
|
/* Handle it */
|
||||||
DPRINT1("Node Parse: %p\n", Node);
|
DPRINT1("Exit node: %lx\n", Node->Flags);
|
||||||
if (!Node) ASSERT(FALSE);
|
CmpHandleExitNode(&Hive,
|
||||||
|
&Cell,
|
||||||
|
&Node,
|
||||||
|
&HiveToRelease,
|
||||||
|
&CellToRelease);
|
||||||
|
DPRINT1("Node Parse: %p\n", Node);
|
||||||
|
if (!Node) ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a KCB for this key */
|
/* Create a KCB for this key */
|
||||||
Kcb = CmpCreateKeyControlBlock(Hive,
|
Kcb = CmpCreateKeyControlBlock(Hive,
|
||||||
|
@ -959,5 +1045,5 @@ CmpParseKey2(IN PVOID ParseObject,
|
||||||
|
|
||||||
/* Unlock the registry */
|
/* Unlock the registry */
|
||||||
CmpUnlockRegistry();
|
CmpUnlockRegistry();
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1580,7 +1580,7 @@ NTAPI
|
||||||
CmpTestRegistryLock(VOID)
|
CmpTestRegistryLock(VOID)
|
||||||
{
|
{
|
||||||
/* Test the lock */
|
/* Test the lock */
|
||||||
return (BOOLEAN)ExIsResourceAcquiredSharedLite(&CmpRegistryLock);
|
return !ExIsResourceAcquiredSharedLite(&CmpRegistryLock) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -1588,7 +1588,7 @@ NTAPI
|
||||||
CmpTestRegistryLockExclusive(VOID)
|
CmpTestRegistryLockExclusive(VOID)
|
||||||
{
|
{
|
||||||
/* Test the lock */
|
/* Test the lock */
|
||||||
return ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock);
|
return !ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
Loading…
Reference in a new issue