{
BOOLEAN NameValid = TRUE;
+ ASSERT(RemainingName->Length % sizeof(WCHAR) == 0);
+
/* Check if there's nothing left in the name */
if (!(RemainingName->Buffer) ||
(!RemainingName->Length) ||
}
/* Check if we have a path separator */
- if (*RemainingName->Buffer == OBJ_NAME_PATH_SEPARATOR)
+ while ((RemainingName->Length) &&
+ (*RemainingName->Buffer == OBJ_NAME_PATH_SEPARATOR))
{
/* Skip it */
RemainingName->Buffer++;
/* Start loop at where the current buffer is */
NextName->Buffer = RemainingName->Buffer;
- while (TRUE)
+ while ((RemainingName->Length) &&
+ (*RemainingName->Buffer != OBJ_NAME_PATH_SEPARATOR))
{
- /* Break out if we ran out or hit a path separator */
- if (!(RemainingName->Length) ||
- (*RemainingName->Buffer == OBJ_NAME_PATH_SEPARATOR))
- {
- break;
- }
-
/* Move to the next character */
RemainingName->Buffer++;
RemainingName->Length -= sizeof(WCHAR);
if (!CmpGetValueData(Hive,
LinkValue,
&ValueLength,
- (PVOID)&LinkName,
+ (PVOID*)&LinkName,
&LinkNameAllocated,
&CellToRelease))
{
if (Length > 0xFFFF) goto Exit;
/* Check if we need a new buffer */
- if (Length > ObjectName->MaximumLength)
+ if (Length > ObjectName->MaximumLength)
{
/* We do -- allocate one */
NewBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
PCM_KEY_NODE KeyNode;
PCELL_DATA CellData;
ULONG StorageType;
- LARGE_INTEGER SystemTime;
PCM_KEY_CONTROL_BLOCK Kcb;
PSECURITY_DESCRIPTOR NewDescriptor;
/* Get the storage type */
StorageType = Stable;
- if (Flags & REG_OPTION_VOLATILE) StorageType = Volatile;
+ if (ParseContext->CreateOptions & REG_OPTION_VOLATILE) StorageType = Volatile;
/* Allocate the child */
*KeyCell = HvAllocateCell(Hive,
/* Setup the key body */
KeyBody = (PCM_KEY_BODY)(*Object);
- KeyBody->Type = '20yk';
+ KeyBody->Type = CM_KEY_BODY_TYPE;
KeyBody->KeyControlBlock = NULL;
/* Check if we had a class */
/* Fill out the key node */
KeyNode->Signature = CM_KEY_NODE_SIGNATURE;
- KeyNode->Flags = Flags &~ REG_OPTION_CREATE_LINK;
- KeQuerySystemTime(&SystemTime);
- KeyNode->LastWriteTime = SystemTime;
+ KeyNode->Flags = Flags;
+ KeQuerySystemTime(&KeyNode->LastWriteTime);
KeyNode->Spare = 0;
KeyNode->Parent = ParentCell;
KeyNode->SubKeyCounts[Stable] = 0;
KeyNode->MaxClassLen = 0;
KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, Name);
if (KeyNode->NameLength < Name->Length) KeyNode->Flags |= KEY_COMP_NAME;
-
+
/* Create the KCB */
Kcb = CmpCreateKeyControlBlock(Hive,
*KeyCell,
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Quickie;
}
-
+
/* Sanity check */
ASSERT(Kcb->RefCount == 1);
KeyBody->NotifyBlock = NULL;
KeyBody->ProcessID = PsGetCurrentProcessId();
KeyBody->KeyControlBlock = Kcb;
-
+
/* Link it with the KCB */
EnlistKeyBodyWithKCB(KeyBody, 0);
&CmpKeyObjectType->TypeInfo.GenericMapping);
}
+ /* Now that the security descriptor is copied in the hive, we can free the original */
+ SeDeassignSecurity(&NewDescriptor);
+
Quickie:
/* Check if we got here because of failure */
if (!NT_SUCCESS(Status))
AccessMode,
ParseContext,
ParentKcb,
- ParseContext->CreateOptions, // WRONG!
+ 0,
&KeyCell,
Object);
if (NT_SUCCESS(Status))
KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name->Length;
}
- /* Check if we need toupdate class length maximum */
+ /* Check if we need to update class length maximum */
if (KeyNode->MaxClassLen < ParseContext->Class.Length)
{
/* Update it */
/* Get the key body and fill it out */
KeyBody = (PCM_KEY_BODY)(*Object);
KeyBody->KeyControlBlock = Kcb;
- KeyBody->Type = '20yk';
+ KeyBody->Type = CM_KEY_BODY_TYPE;
KeyBody->ProcessID = PsGetCurrentProcessId();
KeyBody->NotifyBlock = NULL;
return Status;
}
-/* Remove calls to CmCreateRootNode once this is used! */
NTSTATUS
NTAPI
CmpCreateLinkNode(IN PHHIVE Hive,
DPRINT1("Invalid link node attempt\n");
return STATUS_ACCESS_DENIED;
}
-
+
/* Check if the parent is being deleted */
if (ParentKcb->Delete)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Exit;
}
-
+
/* Allocate a link node */
LinkCell = HvAllocateCell(Hive,
FIELD_OFFSET(CM_KEY_NODE, Name) +
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Get the key cell */
KeyCell = Context->ChildHive.KeyCell;
if (KeyCell != HCELL_NIL)
{
/* Hive exists! */
ChildCell = KeyCell;
-
+
/* Get the node data */
KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
if (!KeyNode)
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Fill out the data */
KeyNode->Parent = LinkCell;
KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
-
+
/* Now open the key cell */
KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, KeyCell);
if (!KeyNode)
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Open the parent */
Status = CmpDoOpen(Context->ChildHive.KeyHive,
KeyCell,
Context->ChildHive.KeyHive->BaseBlock->RootCell = ChildCell;
}
}
-
+
/* Check if open or create suceeded */
if (NT_SUCCESS(Status))
{
/* Mark the cell dirty */
HvMarkCellDirty(Context->ChildHive.KeyHive, ChildCell, FALSE);
-
+
/* Get the key node */
KeyNode = HvGetCell(Context->ChildHive.KeyHive, ChildCell);
if (!KeyNode)
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Release it */
HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
-
+
/* Set the parent and flags */
KeyNode->Parent = LinkCell;
KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
-
+
/* Get the link node */
KeyNode = HvGetCell(Hive, LinkCell);
if (!KeyNode)
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Set it up */
KeyNode->Signature = CM_LINK_NODE_SIGNATURE;
KeyNode->Flags = KEY_HIVE_EXIT | KEY_NO_DELETE;
if (KeyNode->NameLength < Name.Length) KeyNode->Flags |= KEY_COMP_NAME;
KeQuerySystemTime(&TimeStamp);
KeyNode->LastWriteTime = TimeStamp;
-
+
/* Clear out the rest */
KeyNode->SubKeyCounts[Stable] = 0;
KeyNode->SubKeyCounts[Volatile] = 0;
KeyNode->ValueList.Count = 0;
KeyNode->ValueList.List = HCELL_NIL;
KeyNode->ClassLength = 0;
-
+
/* Reference the root node */
KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
KeyNode->ChildHiveReference.KeyCell = ChildCell;
HvReleaseCell(Hive, LinkCell);
-
+
/* Get the parent node */
KeyNode = HvGetCell(Hive, Cell);
if (!KeyNode)
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
-
+
/* Now add the subkey */
if (!CmpAddSubKey(Hive, Cell, LinkCell))
{
/* Failure! We don't handle this yet! */
ASSERT(FALSE);
}
-
+
/* Get the key body */
KeyBody = (PCM_KEY_BODY)*Object;
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
-
+
/* Update the timestamp */
KeQuerySystemTime(&TimeStamp);
KeyNode->LastWriteTime = TimeStamp;
KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
-
+
/* Check if we need to update name maximum */
if (KeyNode->MaxNameLen < Name.Length)
{
KeyNode->MaxNameLen = Name.Length;
KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name.Length;
}
-
- /* Check if we need toupdate class length maximum */
+
+ /* Check if we need to update class length maximum */
if (KeyNode->MaxClassLen < Context->Class.Length)
{
/* Update it */
KeyNode->MaxClassLen = Context->Class.Length;
}
-
+
/* Release the cell */
HvReleaseCell(Hive, Cell);
}
/* Release the link cell */
HvReleaseCell(Hive, LinkCell);
}
-
+
Exit:
/* Release the flusher locks and return status */
return Status;
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)
/* Calculate hash values */
*TotalRemainingSubkeys = 0xBAADF00D;
-
+
/* Lock the registry */
CmpLockRegistry();
-
+
/* Return hive and cell data */
*Hive = (*Kcb)->KeyHive;
*Cell = (*Kcb)->KeyCell;
/* Fail if this isn't a key object */
if (ObjectType != CmpKeyObjectType) return STATUS_OBJECT_TYPE_MISMATCH;
-
+
/* Copy the remaining name */
Current = *RemainingName;
/* It isn't, so no context */
ParseContext = NULL;
}
-
+
/* Grab the KCB */
Kcb = ((PCM_KEY_BODY)ParseObject)->KeyControlBlock;
+ /* Sanity check */
+ ASSERT(Kcb != NULL);
+
+ /* Fail if the key was marked as deleted */
+ if (Kcb->Delete)
+ return STATUS_KEY_DELETED;
+
/* Lookup in the cache */
Status = CmpBuildHashStackAndLookupCache(ParseObject,
&Kcb,
&TotalSubkeys,
NULL,
&LockedKcbs);
-
+
/* This is now the parent */
ParentKcb = Kcb;
-
+
+ /* Sanity check */
+ ASSERT(ParentKcb != NULL);
+
/* Check if everything was found cached */
- if (!TotalRemainingSubkeys) ASSERTMSG("Caching not implemented", FALSE);
+ if (!TotalRemainingSubkeys)
+ ASSERTMSG("Caching not implemented\n", FALSE);
/* Don't do anything if we're being deleted */
if (Kcb->Delete)
goto Quickie;
}
Current.MaximumLength += NextName.MaximumLength;
-
+
/* Parse the symlink */
if (CmpGetSymbolicLink(Hive,
CompleteName,
/* We're done */
goto Quickie;
}
-
+
/* Get the key node */
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
if (!Node)
Cell = NextCell;
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
if (!Node) ASSERT(FALSE);
-
+
/* Check if this was the last key */
if (Last)
{
&CellToRelease);
if (!Node) ASSERT(FALSE);
}
-
+
/* Do the open */
Status = CmpDoOpen(Hive,
Cell,
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
}
-
+
/* We are done */
break;
}
-
+
/* Is this an exit node */
if (Node->Flags & KEY_HIVE_EXIT)
{
0,
&NextName);
if (!Kcb) ASSERT(FALSE);
-
+
/* Dereference the parent and set the new one */
CmpDereferenceKeyControlBlock(ParentKcb);
ParentKcb = Kcb;
ParentKcb,
Object);
}
+ else if (Hive == &CmiVolatileHive->Hive && CmpNoVolatileCreates)
+ {
+ /* Creating keys in the master hive is not allowed */
+ Status = STATUS_INVALID_PARAMETER;
+ }
else
{
/* Do the create */
ParentKcb,
Object);
}
-
+
/* Check for reparse (in this case, someone beat us) */
if (Status == STATUS_REPARSE) break;
{
/* Save the next name */
Current.Buffer = NextName.Buffer;
-
+
/* Validate the current name string length */
if (Current.Length + NextName.Length > MAXUSHORT)
{
break;
}
Current.Length += NextName.Length;
-
+
/* Validate the current name string maximum length */
if (Current.MaximumLength + NextName.MaximumLength > MAXUSHORT)
{
break;
}
Current.MaximumLength += NextName.MaximumLength;
-
+
/* Parse the symlink */
if (CmpGetSymbolicLink(Hive,
CompleteName,
{
/* Nothing to do */
}
-
+
/* We're done */
break;
}
/* Dereference the parent if it exists */
Quickie:
if (ParentKcb) CmpDereferenceKeyControlBlock(ParentKcb);
-
+
/* Unlock the registry */
CmpUnlockRegistry();
return Status;