Author: ion
Date: Mon May 14 04:44:26 2007
New Revision: 26768
URL:
http://svn.reactos.org/svn/reactos?rev=26768&view=rev
Log:
- Implement NtDeleteValueKey as a simple wrapper around CmDeleteValueKey so that handles,
callbacks and SEH is abstracted away.
- Implement CmpRemoveValueFromList.
- Implement CmDeleteValueKey based on the old code, make it use CmpRemoveValueFromList.
- Remove CmiDeleteValueFromKey, CmiDestroyValueCell.
Modified:
trunk/reactos/ntoskrnl/cm/cm.h
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/regfile.c
trunk/reactos/ntoskrnl/config/cm.h
trunk/reactos/ntoskrnl/config/cmapi.c
trunk/reactos/ntoskrnl/config/cmvalue.c
Modified: trunk/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26768…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/cm.h (original)
+++ trunk/reactos/ntoskrnl/cm/cm.h Mon May 14 04:44:26 2007
@@ -261,10 +261,9 @@
OUT PCM_KEY_VALUE *ValueCell);
NTSTATUS
-CmiDeleteValueFromKey(IN PEREGISTRY_HIVE RegistryHive,
- IN PCM_KEY_NODE KeyCell,
- IN HCELL_INDEX KeyCellOffset,
- IN PUNICODE_STRING ValueName);
+NTAPI
+CmDeleteValueKey(IN PKEY_OBJECT KeyControlBlock,
+ IN UNICODE_STRING ValueName);
NTSTATUS
CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
@@ -307,10 +306,6 @@
NTSTATUS
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
PEREGISTRY_HIVE RegistryHive);
-
-NTSTATUS
-CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
- PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
CmiInitHives(BOOLEAN SetupBoot);
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon May 14 04:44:26 2007
@@ -1854,88 +1854,48 @@
return Status;
}
-NTSTATUS STDCALL
-NtDeleteValueKey (IN HANDLE KeyHandle,
- IN PUNICODE_STRING ValueName)
-{
- PKEY_OBJECT KeyObject;
- NTSTATUS Status;
- REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
- REG_POST_OPERATION_INFORMATION PostOperationInfo;
- KPROCESSOR_MODE PreviousMode;
- UNICODE_STRING CapturedValueName;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- /* Verify that the handle is valid and is a registry key */
- Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_SET_VALUE,
- CmpKeyObjectType,
- PreviousMode,
- (PVOID *)&KeyObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Status = ProbeAndCaptureUnicodeString(&CapturedValueName,
- PreviousMode,
- ValueName);
- if (!NT_SUCCESS(Status))
- {
- goto Fail;
- }
- DeleteValueKeyInfo.Object = (PVOID)KeyObject;
- DeleteValueKeyInfo.ValueName = &CapturedValueName;
-
- /* FIXME - check if value exists before calling the callbacks? */
- Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey, &DeleteValueKeyInfo);
- if (!NT_SUCCESS(Status))
- {
- PostOperationInfo.Object = (PVOID)KeyObject;
- PostOperationInfo.Status = Status;
- CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey, &PostOperationInfo);
- ReleaseCapturedUnicodeString(&CapturedValueName,
- PreviousMode);
-Fail:
- ObDereferenceObject(KeyObject);
- return Status;
- }
-
- /* Acquire hive lock */
- KeEnterCriticalRegion();
- ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
-
- VERIFY_KEY_OBJECT(KeyObject);
-
- Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
- KeyObject->KeyCell,
- KeyObject->KeyCellOffset,
- ValueName);
-
- KeQuerySystemTime (&KeyObject->KeyCell->LastWriteTime);
- HvMarkCellDirty (&KeyObject->RegistryHive->Hive,
KeyObject->KeyCellOffset);
-
- /* Release hive lock */
- ExReleaseResourceLite(&CmpRegistryLock);
- KeLeaveCriticalRegion();
-
- ReleaseCapturedUnicodeString(&CapturedValueName,
- PreviousMode);
-
- PostOperationInfo.Object = (PVOID)KeyObject;
- PostOperationInfo.Status = Status;
-
- CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey, &PostOperationInfo);
-
- ObDereferenceObject (KeyObject);
-
- CmiSyncHives ();
-
- return Status;
+NTSTATUS
+NTAPI
+NtDeleteValueKey(IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName)
+{
+ PKEY_OBJECT KeyObject;
+ NTSTATUS Status;
+ REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ PAGED_CODE();
+
+ /* Verify that the handle is valid and is a registry key */
+ Status = ObReferenceObjectByHandle(KeyHandle,
+ KEY_SET_VALUE,
+ CmpKeyObjectType,
+ PreviousMode,
+ (PVOID *)&KeyObject,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Do the callback */
+ DeleteValueKeyInfo.Object = (PVOID)KeyObject;
+ DeleteValueKeyInfo.ValueName = ValueName;
+ Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey,
+ &DeleteValueKeyInfo);
+ if (NT_SUCCESS(Status))
+ {
+ /* Call the internal API */
+ Status = CmDeleteValueKey(KeyObject, *ValueName);
+
+ /* Do the post callback */
+ PostOperationInfo.Object = (PVOID)KeyObject;
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey,
+ &PostOperationInfo);
+ }
+
+ /* Dereference the key body and synchronize the hives */
+ ObDereferenceObject(KeyObject);
+ CmiSyncHives();
+ return Status;
}
/*
Modified: trunk/reactos/ntoskrnl/cm/regfile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regfile.c (original)
+++ trunk/reactos/ntoskrnl/cm/regfile.c Mon May 14 04:44:26 2007
@@ -665,79 +665,6 @@
}
NTSTATUS
-CmiDeleteValueFromKey(IN PEREGISTRY_HIVE RegistryHive,
- IN PCM_KEY_NODE KeyCell,
- IN HCELL_INDEX KeyCellOffset,
- IN PUNICODE_STRING ValueName)
-{
- PVALUE_LIST_CELL ValueListCell;
- PCM_KEY_VALUE CurValueCell;
- ULONG i;
- NTSTATUS Status;
-
- if (KeyCell->ValueList.List == -1)
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- ValueListCell = HvGetCell (&RegistryHive->Hive, KeyCell->ValueList.List);
-
- VERIFY_VALUE_LIST_CELL(ValueListCell);
-
- for (i = 0; i < KeyCell->ValueList.Count; i++)
- {
- CurValueCell = HvGetCell (&RegistryHive->Hive,
ValueListCell->ValueOffset[i]);
-
- if (CmiComparePackedNames(ValueName,
- CurValueCell->Name,
- CurValueCell->NameSize,
- (BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
- {
- Status = CmiDestroyValueCell(RegistryHive,
- CurValueCell,
- ValueListCell->ValueOffset[i]);
- if (CurValueCell == NULL)
- {
- DPRINT1("CmiDestroyValueCell() failed\n");
- return Status;
- }
-
- if (i < (KeyCell->ValueList.Count - 1))
- {
- RtlMoveMemory(&ValueListCell->ValueOffset[i],
- &ValueListCell->ValueOffset[i + 1],
- sizeof(HCELL_INDEX) * (KeyCell->ValueList.Count - 1 - i));
- }
- ValueListCell->ValueOffset[KeyCell->ValueList.Count - 1] = 0;
-
-
- KeyCell->ValueList.Count--;
-
- if (KeyCell->ValueList.Count == 0)
- {
- HvFreeCell(&RegistryHive->Hive, KeyCell->ValueList.List);
- KeyCell->ValueList.List = -1;
- }
- else
- {
- HvMarkCellDirty(&RegistryHive->Hive,
- KeyCell->ValueList.List);
- }
-
- HvMarkCellDirty(&RegistryHive->Hive,
- KeyCellOffset);
-
- return STATUS_SUCCESS;
- }
- }
-
- DPRINT("Couldn't find the desired value\n");
-
- return STATUS_OBJECT_NAME_NOT_FOUND;
-}
-
-
-NTSTATUS
CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset,
@@ -831,31 +758,6 @@
return STATUS_UNSUCCESSFUL;
}
-NTSTATUS
-CmiDestroyValueCell(PEREGISTRY_HIVE RegistryHive,
- PCM_KEY_VALUE ValueCell,
- HCELL_INDEX ValueCellOffset)
-{
- DPRINT("CmiDestroyValueCell(Cell %p Offset %lx)\n",
- ValueCell, ValueCellOffset);
-
- VERIFY_VALUE_CELL(ValueCell);
-
- /* Destroy the data cell */
- if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET)
- && ValueCell->DataSize > sizeof(HCELL_INDEX)
- && ValueCell->DataOffset != HCELL_NULL)
- {
- HvFreeCell (&RegistryHive->Hive, ValueCell->DataOffset);
- }
-
- /* Destroy the value cell */
- HvFreeCell (&RegistryHive->Hive, ValueCellOffset);
-
- return STATUS_SUCCESS;
-}
-
-
ULONG
CmiGetPackedNameLength(IN PUNICODE_STRING Name,
OUT PBOOLEAN Packable)
Modified: trunk/reactos/ntoskrnl/config/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Mon May 14 04:44:26 2007
@@ -1064,6 +1064,14 @@
IN ULONG DataLength
);
+NTSTATUS
+NTAPI
+CmpRemoveValueFromList(
+ IN PHHIVE Hive,
+ IN ULONG Index,
+ IN OUT PCHILD_LIST ChildList
+);
+
//
// Boot Routines
//
Modified: trunk/reactos/ntoskrnl/config/cmapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmapi.c (original)
+++ trunk/reactos/ntoskrnl/config/cmapi.c Mon May 14 04:44:26 2007
@@ -86,7 +86,7 @@
/* Otherwise, set the data length, and make sure the data is dirty */
CellData->u.KeyValue.DataLength = DataSize;
- ASSERT(HvIsCellDirty(Hive,CellData->u.KeyValue.Data));
+ ASSERT(HvIsCellDirty(Hive, CellData->u.KeyValue.Data));
}
else
{
@@ -105,7 +105,7 @@
/* If we failed, free the entire cell, including the data */
if (!NT_SUCCESS(Status)) CmpFreeValue(Hive, ValueCell);
- /* Return status */
+ /* Return Status */
return Status;
}
@@ -340,3 +340,117 @@
return Status;
}
+NTSTATUS
+NTAPI
+CmDeleteValueKey(IN PKEY_OBJECT KeyObject,
+ IN UNICODE_STRING ValueName)
+{
+ NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ PHHIVE Hive;
+ PCM_KEY_NODE Parent;
+ HCELL_INDEX ChildCell, Cell;
+ PCHILD_LIST ChildList;
+ PCM_KEY_VALUE Value = NULL;
+ ULONG ChildIndex;
+ BOOLEAN Result;
+
+ /* Acquire hive lock */
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
+
+ /* Get the hive and the cell index */
+ Hive = &KeyObject->RegistryHive->Hive;
+ Cell = KeyObject->KeyCellOffset;
+
+ /* Get the parent key node */
+ Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
+ if (!Parent)
+ {
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Get the value list and check if it has any entries */
+ ChildList = &Parent->ValueList;
+ if (ChildList->Count)
+ {
+ /* Try to find this value */
+ Result = CmpFindNameInList(Hive,
+ ChildList,
+ &ValueName,
+ &ChildIndex,
+ &ChildCell);
+ if (!Result)
+ {
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Value not found, return error */
+ if (ChildCell == HCELL_NIL) goto Quickie;
+
+ /* We found the value, mark all relevant cells dirty */
+ HvMarkCellDirty(Hive, Cell);
+ HvMarkCellDirty(Hive, Parent->ValueList.List);
+ HvMarkCellDirty(Hive, ChildCell);
+
+ /* Get the key value */
+ Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell);
+ if (!Value) ASSERT(FALSE);
+
+ /* Mark it and all related data as dirty */
+ CmpMarkValueDataDirty(Hive, Value);
+
+ /* Ssanity checks */
+ ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
+ ASSERT(HvIsCellDirty(Hive, ChildCell));
+
+ /* Remove the value from the child list */
+ Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList);
+ if(!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Remove the value and its data itself */
+ if (!CmpFreeValue(Hive, ChildCell))
+ {
+ /* Failed to free the value, fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Set the last write time */
+ KeQuerySystemTime(&Parent->LastWriteTime);
+
+ /* Sanity check */
+ ASSERT(HvIsCellDirty(Hive, Cell));
+
+ /* Check if the value list is empty now */
+ if (!Parent->ValueList.Count)
+ {
+ /* Then clear key node data */
+ Parent->MaxValueNameLen = 0;
+ Parent->MaxValueDataLen = 0;
+ }
+
+ /* Change default status to success */
+ Status = STATUS_SUCCESS;
+ }
+
+Quickie:
+ /* Release the parent cell, if any */
+ if (Parent) HvReleaseCell(Hive, Cell);
+
+ /* Check if we had a value */
+ if (Value)
+ {
+ /* Release the child cell */
+ ASSERT(ChildCell != HCELL_NIL);
+ HvReleaseCell(Hive, ChildCell);
+ }
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&CmpRegistryLock);
+ KeLeaveCriticalRegion();
+ return Status;
+}
Modified: trunk/reactos/ntoskrnl/config/cmvalue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmvalue.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmvalue.c (original)
+++ trunk/reactos/ntoskrnl/config/cmvalue.c Mon May 14 04:44:26 2007
@@ -307,3 +307,58 @@
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+CmpRemoveValueFromList(IN PHHIVE Hive,
+ IN ULONG Index,
+ IN OUT PCHILD_LIST ChildList)
+{
+ ULONG Count;
+ PCELL_DATA CellData;
+ HCELL_INDEX NewCell;
+ PAGED_CODE();
+
+ /* Sanity check */
+ ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
+
+ /* Get the new count after removal */
+ Count = ChildList->Count - 1;
+ if (Count > 0)
+ {
+ /* Get the actual list array */
+ CellData = HvGetCell(Hive, ChildList->List);
+ if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Make sure cells data have been made dirty */
+ ASSERT(HvIsCellDirty(Hive, ChildList->List));
+ ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
+
+ /* Loop the list */
+ while (Index < Count)
+ {
+ /* Move everything up */
+ CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1];
+ Index++;
+ }
+
+ /* Re-allocate the cell for the list by decreasing the count */
+ NewCell = HvReallocateCell(Hive,
+ ChildList->List,
+ Count * sizeof(HCELL_INDEX));
+ ASSERT(NewCell != HCELL_NIL);
+ HvReleaseCell(Hive,ChildList->List);
+
+ /* Update the list cell */
+ ChildList->List = NewCell;
+ }
+ else
+ {
+ /* Otherwise, we were the last entry, so free the list entirely */
+ HvFreeCell(Hive, ChildList->List);
+ ChildList->List = HCELL_NIL;
+ }
+
+ /* Update the child list with the new count */
+ ChildList->Count = Count;
+ return STATUS_SUCCESS;
+}