- deleting a registry value requires the KEY_SET_VALUE right
- capture the value name
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-10-29 14:12:20 UTC (rev 18850)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-10-29 14:51:18 UTC (rev 18851)
@@ -1616,7 +1616,7 @@
 
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status);
+      DPRINT1("ObReferenceObjectByHandle() failed with status %x %p\n", Status, KeyHandle);
       return Status;
     }
   
@@ -2038,27 +2038,42 @@
   NTSTATUS Status;
   REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
   REG_POST_OPERATION_INFORMATION PostOperationInfo;
+  KPROCESSOR_MODE PreviousMode;
+  UNICODE_STRING CapturedValueName;
 
   PAGED_CODE();
+  
+  PreviousMode = KeGetPreviousMode();
 
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
-		KEY_QUERY_VALUE,
+		KEY_SET_VALUE,
 		CmiKeyType,
-		UserMode,
+		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 = ValueName;
+  DeleteValueKeyInfo.ValueName = &CapturedValueName;
 
+  /* FIXME - check if value exists before calling the callbacks? */
   Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey, &DeleteValueKeyInfo);
   if (!NT_SUCCESS(Status))
     {
+      ReleaseCapturedUnicodeString(&CapturedValueName,
+                                   PreviousMode);
+Fail:
       ObDereferenceObject(KeyObject);
       return Status;
     }
@@ -2081,6 +2096,9 @@
   ExReleaseResourceLite(&CmiRegistryLock);
   KeLeaveCriticalRegion();
 
+  ReleaseCapturedUnicodeString(&CapturedValueName,
+                               PreviousMode);
+
   PostOperationInfo.Object = (PVOID)KeyObject;
   PostOperationInfo.Status = Status;