- 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:
Aleksey Bragin 2007-12-04 21:39:15 +00:00
parent 6117db4db0
commit 98a17200e4
3 changed files with 106 additions and 20 deletions

View file

@ -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;

View file

@ -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;
} }

View file

@ -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