- Moved the definition of REG_NOTIFY_CLASS from cm.h to winddk.h. - Release the rundown protection if the callback function returns an error (in CmiCallRegisteredCallbacks). - Call the registry callback functions in most of the Nt/ZW registry functions. Modified: trunk/reactos/ntoskrnl/cm/cm.h Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c Modified: trunk/reactos/w32api/include/ddk/winddk.h _____
Modified: trunk/reactos/ntoskrnl/cm/cm.h --- trunk/reactos/ntoskrnl/cm/cm.h 2005-09-24 18:28:04 UTC (rev 18030) +++ trunk/reactos/ntoskrnl/cm/cm.h 2005-09-24 18:42:37 UTC (rev 18031) @@ -378,55 +378,11 @@
extern ERESOURCE CmiRegistryLock;
-typedef enum _REG_NOTIFY_CLASS -{ - RegNtDeleteKey, - RegNtPreDeleteKey = RegNtDeleteKey, - RegNtSetValueKey, - RegNtPreSetValueKey = RegNtSetValueKey, - RegNtDeleteValueKey, - RegNtPreDeleteValueKey = RegNtDeleteValueKey, - RegNtSetInformationKey, - RegNtPreSetInformationKey = RegNtSetInformationKey, - RegNtRenameKey, - RegNtPreRenameKey = RegNtRenameKey, - RegNtEnumerateKey, - RegNtPreEnumerateKey = RegNtEnumerateKey, - RegNtEnumerateValueKey, - RegNtPreEnumerateValueKey = RegNtEnumerateValueKey, - RegNtQueryKey, - RegNtPreQueryKey = RegNtQueryKey, - RegNtQueryValueKey, - RegNtPreQueryValueKey = RegNtQueryValueKey, - RegNtQueryMultipleValueKey, - RegNtPreQueryMultipleValueKey = RegNtQueryMultipleValueKey, - RegNtPreCreateKey, - RegNtPostCreateKey, - RegNtPreOpenKey, - RegNtPostOpenKey, - RegNtKeyHandleClose, - RegNtPreKeyHandleClose = RegNtKeyHandleClose, - RegNtPostDeleteKey, - RegNtPostSetValueKey, - RegNtPostDeleteValueKey, - RegNtPostSetInformationKey, - RegNtPostRenameKey, - RegNtPostEnumerateKey, - RegNtPostEnumerateValueKey, - RegNtPostQueryKey, - RegNtPostQueryValueKey, - RegNtPostQueryMultipleValueKey, - RegNtPostKeyHandleClose, - RegNtPreCreateKeyEx, - RegNtPostCreateKeyEx, - RegNtPreOpenKeyEx, - RegNtPostOpenKeyEx -} REG_NOTIFY_CLASS, *PREG_NOTIFY_CLASS;
/* Registry Callback Function */ typedef NTSTATUS (STDCALL *PEX_CALLBACK_FUNCTION ) ( IN PVOID CallbackContext, - IN PVOID Argument1, + IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2 );
_____
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c --- trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-09-24 18:28:04 UTC (rev 18030) +++ trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-09-24 18:42:37 UTC (rev 18031) @@ -133,6 +133,7 @@
IN PVOID Argument2) { PLIST_ENTRY CurrentEntry; + NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
@@ -148,31 +149,29 @@ if(!CurrentCallback->PendingDelete && ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1)) { - NTSTATUS Status; - /* don't hold locks during the callbacks! */ ExReleaseFastMutex(&CmiCallbackLock);
Status = CurrentCallback->Function(CurrentCallback->Context, - (PVOID)Argument1, + Argument1, Argument2); - if(!NT_SUCCESS(Status)) - { - /* one callback returned failure, don't call any more callbacks */ - return Status; - }
ExAcquireFastMutex(&CmiCallbackLock); /* don't release the rundown protection before holding the callback lock so the pointer to the next callback isn't cleared in case this callback get's deleted */ ExReleaseRundownProtectionEx(&CurrentCallback->RundownRef, 1); + if(!NT_SUCCESS(Status)) + { + /* one callback returned failure, don't call any more callbacks */ + break; + } } }
ExReleaseFastMutex(&CmiCallbackLock);
- return STATUS_SUCCESS; + return Status; }
@@ -193,6 +192,8 @@ UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; unsigned i; + REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo; + REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
PAGED_CODE();
@@ -201,28 +202,41 @@ KeyHandle, ObjectAttributes->RootDirectory);
- /* Capture all the info */ - DPRINT("Capturing Create Info\n"); - Status = ObpCaptureObjectAttributes(ObjectAttributes, - KeGetPreviousMode(), - CmiKeyType, - &ObjectCreateInfo, - &ObjectName); - if (!NT_SUCCESS(Status)) - { - DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); - return Status; - } + /* Capture all the info */ + DPRINT("Capturing Create Info\n"); + Status = ObpCaptureObjectAttributes(ObjectAttributes, + KeGetPreviousMode(), + CmiKeyType, + &ObjectCreateInfo, + &ObjectName); + if (!NT_SUCCESS(Status)) + { + DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); + return Status; + }
+ PostCreateKeyInfo.CompleteName = &ObjectName; + PreCreateKeyInfo.CompleteName = &ObjectName; + Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObpReleaseCapturedAttributes(&ObjectCreateInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + return Status; + } + Status = ObFindObject(&ObjectCreateInfo, &ObjectName, - (PVOID*)&Object, + (PVOID*)&Object, &RemainingPath, CmiKeyType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo); if (!NT_SUCCESS(Status)) { + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); DPRINT("CmpFindObject failed, Status: 0x%x\n", Status); return(Status); } @@ -236,6 +250,10 @@ { ObDereferenceObject(Object); RtlFreeUnicodeString(&RemainingPath); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); DPRINT("Object marked for delete!\n"); return(STATUS_UNSUCCESSFUL); } @@ -252,6 +270,10 @@ DPRINT("ObpCreateHandle failed Status 0x%x\n", Status); ObDereferenceObject(Object); RtlFreeUnicodeString(&RemainingPath); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return Status; }
@@ -268,6 +290,10 @@ ObDereferenceObject(Object); DPRINT1("NtCreateKey() doesn't create trees! (found '\' in remaining path: "%wZ"!)\n", &RemainingPath); RtlFreeUnicodeString(&RemainingPath); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return STATUS_OBJECT_NAME_NOT_FOUND; } } @@ -286,6 +312,10 @@ if (!NT_SUCCESS(Status)) { DPRINT1("ObCreateObject() failed!\n"); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return(Status); }
@@ -300,6 +330,10 @@ ObDereferenceObject(KeyObject); RtlFreeUnicodeString(&RemainingPath); DPRINT1("ObInsertObject() failed!\n"); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return(Status); }
@@ -338,6 +372,10 @@ ObDereferenceObject(KeyObject); ObDereferenceObject(Object); RtlFreeUnicodeString(&RemainingPath); + PostCreateKeyInfo.Object = NULL; + PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); return STATUS_UNSUCCESSFUL; }
@@ -382,6 +420,11 @@ if (Disposition) *Disposition = REG_CREATED_NEW_KEY;
+ PostCreateKeyInfo.Object = KeyObject; + PostCreateKeyInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + CmiSyncHives();
return Status; @@ -394,6 +437,8 @@ KPROCESSOR_MODE PreviousMode; PKEY_OBJECT KeyObject; NTSTATUS Status; + REG_DELETE_KEY_INFORMATION DeleteKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -414,6 +459,17 @@ return Status; }
+ PostOperationInfo.Object = (PVOID)KeyObject; + DeleteKeyInfo.Object = (PVOID)KeyObject; + Status = CmiCallRegisteredCallbacks(RegNtPreSetValueKey, &DeleteKeyInfo); + if (!NT_SUCCESS(Status)) + { + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtDeleteKey, &PostOperationInfo); + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); @@ -438,14 +494,18 @@
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
- /* Dereference the object */ - ObDereferenceObject(KeyObject); /* Remove the keep-alive reference */ ObDereferenceObject(KeyObject);
if (KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive) ObDereferenceObject(KeyObject);
+ PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostDeleteKey, &PostOperationInfo); + + /* Dereference the object */ + ObDereferenceObject(KeyObject); + DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); DPRINT("HandleCount %lu\n", ObGetObjectHandleCount((PVOID)KeyObject));
@@ -480,6 +540,8 @@ ULONG NameSize, ClassSize; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; + REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -506,6 +568,20 @@ return(Status); }
+ PostOperationInfo.Object = (PVOID)KeyObject; + EnumerateKeyInfo.Object = (PVOID)KeyObject; + EnumerateKeyInfo.Index = Index; + EnumerateKeyInfo.KeyInformationClass = KeyInformationClass; + EnumerateKeyInfo.Length = Length; + EnumerateKeyInfo.ResultLength = ResultLength; + + Status = CmiCallRegisteredCallbacks(RegNtEnumerateKey, &EnumerateKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); @@ -523,6 +599,8 @@ { ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES; + CmiCallRegisteredCallbacks(RegNtPostDeleteKey, &PostOperationInfo); ObDereferenceObject(KeyObject); DPRINT("No more volatile entries\n"); return STATUS_NO_MORE_ENTRIES; @@ -552,6 +630,8 @@ { ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES; + CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo); ObDereferenceObject(KeyObject); DPRINT("No more non-volatile entries\n"); return STATUS_NO_MORE_ENTRIES; @@ -566,6 +646,8 @@ { ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES; + CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo); ObDereferenceObject(KeyObject); return STATUS_NO_MORE_ENTRIES; } @@ -576,6 +658,8 @@ DPRINT("CmiGetBlock() failed\n"); ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_UNSUCCESSFUL; + CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo); ObDereferenceObject(KeyObject); return STATUS_UNSUCCESSFUL; } @@ -589,6 +673,8 @@ { ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES; + CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo); ObDereferenceObject(KeyObject); DPRINT("No more entries\n"); return STATUS_NO_MORE_ENTRIES; @@ -804,6 +890,10 @@
ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo); + ObDereferenceObject(KeyObject);
DPRINT("Returning status %x\n", Status); @@ -1121,11 +1211,13 @@ { UNICODE_STRING RemainingPath; KPROCESSOR_MODE PreviousMode; - PVOID Object; + PVOID Object = NULL; HANDLE hKey; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; + REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo; + REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo;
PAGED_CODE();
@@ -1176,21 +1268,31 @@ return Status; }
+ PostOpenKeyInfo.CompleteName = &ObjectName; + PreOpenKeyInfo.CompleteName = &ObjectName; + Status = CmiCallRegisteredCallbacks(RegNtPreOpenKey, &PreOpenKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObpReleaseCapturedAttributes(&ObjectCreateInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + return Status; + } + + RemainingPath.Buffer = NULL;
Status = ObFindObject(&ObjectCreateInfo, &ObjectName, - (PVOID*)&Object, + (PVOID*)&Object, &RemainingPath, CmiKeyType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo); if (!NT_SUCCESS(Status)) { DPRINT("CmpFindObject() returned 0x%08lx\n", Status); - Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject returns STATUS_UNSUCCESSFUL */ - hKey = *KeyHandle; /* Preserve hkResult value */ - goto openkey_cleanup; + Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject returns STATUS_UNSUCCESSFUL */ + hKey = *KeyHandle; /* Preserve hkResult value */ + goto openkey_cleanup; }
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object); @@ -1199,11 +1301,10 @@
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) { - ObDereferenceObject(Object); RtlFreeUnicodeString(&RemainingPath); Status = STATUS_OBJECT_NAME_NOT_FOUND; hKey = NULL; - goto openkey_cleanup; + goto openkey_cleanup; }
RtlFreeUnicodeString(&RemainingPath); @@ -1211,10 +1312,9 @@ /* Fail if the key has been deleted */ if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE) { - ObDereferenceObject(Object); - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_UNSUCCESSFUL; hKey = NULL; - goto openkey_cleanup; + goto openkey_cleanup; }
Status = ObpCreateHandle(PsGetCurrentProcess(), @@ -1222,12 +1322,22 @@ DesiredAccess, TRUE, &hKey); - ObDereferenceObject(Object);
if (!NT_SUCCESS(Status)) hKey = NULL;
openkey_cleanup: + + PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL; + PostOpenKeyInfo.Status = Status; + CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo); + if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + + if (Object) + { + ObDereferenceObject(Object); + } + _SEH_TRY { *KeyHandle = hKey; @@ -1258,6 +1368,8 @@ PKEY_CELL KeyCell; ULONG NameSize, ClassSize; NTSTATUS Status; + REG_QUERY_KEY_INFORMATION QueryKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -1280,6 +1392,20 @@ return Status; }
+ PostOperationInfo.Object = (PVOID)KeyObject; + QueryKeyInfo.Object = (PVOID)KeyObject; + QueryKeyInfo.KeyInformationClass = KeyInformationClass; + QueryKeyInfo.KeyInformation = KeyInformation; + QueryKeyInfo.Length = Length; + QueryKeyInfo.ResultLength = ResultLength; + + Status = CmiCallRegisteredCallbacks(RegNtQueryKey, &QueryKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); @@ -1444,6 +1570,10 @@
ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo); + ObDereferenceObject(KeyObject);
return(Status); @@ -1468,6 +1598,8 @@ PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation; PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation; PKEY_VALUE_FULL_INFORMATION ValueFullInformation; + REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -1487,7 +1619,21 @@ DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status); return Status; } + + PostOperationInfo.Object = (PVOID)KeyObject; + QueryValueKeyInfo.Object = (PVOID)KeyObject; + QueryValueKeyInfo.ValueName = ValueName; + QueryValueKeyInfo.KeyValueInformationClass = KeyValueInformationClass; + QueryValueKeyInfo.Length = Length; + QueryValueKeyInfo.ResultLength = ResultLength;
+ Status = CmiCallRegisteredCallbacks(RegNtPreQueryValueKey, &QueryValueKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); @@ -1686,6 +1832,9 @@ ByeBye:; ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostQueryValueKey, &PostOperationInfo); ObDereferenceObject(KeyObject);
return Status; @@ -1710,6 +1859,8 @@ PDATA_CELL NewDataCell; PHBIN pBin; ULONG DesiredAccess; + REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -1728,6 +1879,20 @@ if (!NT_SUCCESS(Status)) return(Status);
+ PostOperationInfo.Object = (PVOID)KeyObject; + SetValueKeyInfo.Object = (PVOID)KeyObject; + SetValueKeyInfo.ValueName = ValueName; + SetValueKeyInfo.TitleIndex = TitleIndex; + SetValueKeyInfo.Type = Type; + SetValueKeyInfo.Data = Data; + SetValueKeyInfo.DataSize = DataSize; + Status = CmiCallRegisteredCallbacks(RegNtPreSetValueKey, &SetValueKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock exclucively */ KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); @@ -1759,6 +1924,8 @@
ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo); ObDereferenceObject(KeyObject); return Status; } @@ -1824,6 +1991,8 @@
ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo); ObDereferenceObject(KeyObject);
return Status; @@ -1849,6 +2018,8 @@
ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo); ObDereferenceObject(KeyObject);
CmiSyncHives(); @@ -1865,6 +2036,8 @@ { PKEY_OBJECT KeyObject; NTSTATUS Status; + REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -1879,7 +2052,17 @@ { return Status; } + + DeleteValueKeyInfo.Object = (PVOID)KeyObject; + DeleteValueKeyInfo.ValueName = ValueName;
+ Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey, &DeleteValueKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); @@ -1898,6 +2081,11 @@ ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion();
+ PostOperationInfo.Object = (PVOID)KeyObject; + PostOperationInfo.Status = Status; + + CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey, &PostOperationInfo); + ObDereferenceObject (KeyObject);
CmiSyncHives (); @@ -2106,6 +2294,8 @@ NTSTATUS Status; PUCHAR DataPtr; ULONG i; + REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION QueryMultipleValueKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
@@ -2122,6 +2312,21 @@ return(Status); }
+ PostOperationInfo.Object = (PVOID)KeyObject; + QueryMultipleValueKeyInfo.Object = (PVOID)KeyObject; + QueryMultipleValueKeyInfo.ValueEntries = ValueList; + QueryMultipleValueKeyInfo.EntryCount = NumberOfValues; + QueryMultipleValueKeyInfo.ValueBuffer = Buffer; + QueryMultipleValueKeyInfo.BufferLength = Length; + QueryMultipleValueKeyInfo.RequiredBufferLength = ReturnLength; + + Status = CmiCallRegisteredCallbacks(RegNtPreQueryMultipleValueKey, &QueryMultipleValueKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(KeyObject); + return Status; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); @@ -2201,6 +2406,9 @@ ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion();
+ PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostQueryMultipleValueKey, &PostOperationInfo); + ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status); @@ -2340,15 +2548,11 @@ { PKEY_OBJECT KeyObject; NTSTATUS Status; + REG_SET_INFORMATION_KEY_INFORMATION SetInformationKeyInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
- if (KeyInformationClass != KeyWriteTimeInformation) - return STATUS_INVALID_INFO_CLASS; - - if (KeyInformationLength != sizeof (KEY_WRITE_TIME_INFORMATION)) - return STATUS_INFO_LENGTH_MISMATCH; - /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle (KeyHandle, KEY_SET_VALUE, @@ -2362,25 +2566,56 @@ return Status; }
- /* Acquire hive lock */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); + PostOperationInfo.Object = (PVOID)KeyObject; + SetInformationKeyInfo.Object = (PVOID)KeyObject; + SetInformationKeyInfo.KeySetInformationClass = KeyInformationClass; + SetInformationKeyInfo.KeySetInformation = KeyInformation; + SetInformationKeyInfo.KeySetInformationLength = KeyInformationLength;
- VERIFY_KEY_OBJECT(KeyObject); + Status = CmiCallRegisteredCallbacks(RegNtSetInformationKey, &SetInformationKeyInfo); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject (KeyObject); + return Status; + }
- KeyObject->KeyCell->LastWriteTime.QuadPart = - ((PKEY_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart; + if (KeyInformationClass != KeyWriteTimeInformation) + { + Status = STATUS_INVALID_INFO_CLASS; + }
- CmiMarkBlockDirty (KeyObject->RegistryHive, - KeyObject->KeyCellOffset); + else if (KeyInformationLength != sizeof (KEY_WRITE_TIME_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + /* Acquire hive lock */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
- /* Release hive lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); + VERIFY_KEY_OBJECT(KeyObject);
+ KeyObject->KeyCell->LastWriteTime.QuadPart = + ((PKEY_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart; + + CmiMarkBlockDirty (KeyObject->RegistryHive, + KeyObject->KeyCellOffset); + + /* Release hive lock */ + ExReleaseResourceLite(&CmiRegistryLock); + KeLeaveCriticalRegion(); + } + + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostSetInformationKey, &PostOperationInfo); + ObDereferenceObject (KeyObject);
- CmiSyncHives (); + if (NT_SUCCESS(Status)) + { + CmiSyncHives (); + }
DPRINT ("NtSaveKey() done\n");
_____
Modified: trunk/reactos/w32api/include/ddk/winddk.h --- trunk/reactos/w32api/include/ddk/winddk.h 2005-09-24 18:28:04 UTC (rev 18030) +++ trunk/reactos/w32api/include/ddk/winddk.h 2005-09-24 18:42:37 UTC (rev 18031) @@ -4512,10 +4512,55 @@
TraceHandleByNameClass } TRACE_INFORMATION_CLASS;
+typedef enum _REG_NOTIFY_CLASS +{ + RegNtDeleteKey, + RegNtPreDeleteKey = RegNtDeleteKey, + RegNtSetValueKey, + RegNtPreSetValueKey = RegNtSetValueKey, + RegNtDeleteValueKey, + RegNtPreDeleteValueKey = RegNtDeleteValueKey, + RegNtSetInformationKey, + RegNtPreSetInformationKey = RegNtSetInformationKey, + RegNtRenameKey, + RegNtPreRenameKey = RegNtRenameKey, + RegNtEnumerateKey, + RegNtPreEnumerateKey = RegNtEnumerateKey, + RegNtEnumerateValueKey, + RegNtPreEnumerateValueKey = RegNtEnumerateValueKey, + RegNtQueryKey, + RegNtPreQueryKey = RegNtQueryKey, + RegNtQueryValueKey, + RegNtPreQueryValueKey = RegNtQueryValueKey, + RegNtQueryMultipleValueKey, + RegNtPreQueryMultipleValueKey = RegNtQueryMultipleValueKey, + RegNtPreCreateKey, + RegNtPostCreateKey, + RegNtPreOpenKey, + RegNtPostOpenKey, + RegNtKeyHandleClose, + RegNtPreKeyHandleClose = RegNtKeyHandleClose, + RegNtPostDeleteKey, + RegNtPostSetValueKey, + RegNtPostDeleteValueKey, + RegNtPostSetInformationKey, + RegNtPostRenameKey, + RegNtPostEnumerateKey, + RegNtPostEnumerateValueKey, + RegNtPostQueryKey, + RegNtPostQueryValueKey, + RegNtPostQueryMultipleValueKey, + RegNtPostKeyHandleClose, + RegNtPreCreateKeyEx, + RegNtPostCreateKeyEx, + RegNtPreOpenKeyEx, + RegNtPostOpenKeyEx +} REG_NOTIFY_CLASS, *PREG_NOTIFY_CLASS; + typedef NTSTATUS (DDKAPI *PEX_CALLBACK_FUNCTION)( IN PVOID CallbackContext, - IN PVOID Argument1, + IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);