[ros-diffs] [ion] 26768: - 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.

ion at svn.reactos.org ion at svn.reactos.org
Mon May 14 02:44:27 CEST 2007


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&r1=26767&r2=26768&view=diff
==============================================================================
--- 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=26768&r1=26767&r2=26768&view=diff
==============================================================================
--- 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=26768&r1=26767&r2=26768&view=diff
==============================================================================
--- 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=26768&r1=26767&r2=26768&view=diff
==============================================================================
--- 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?rev=26768&r1=26767&r2=26768&view=diff
==============================================================================
--- 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?rev=26768&r1=26767&r2=26768&view=diff
==============================================================================
--- 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;
+}




More information about the Ros-diffs mailing list