- 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.

svn path=/trunk/; revision=18031
This commit is contained in:
Hartmut Birr 2005-09-24 18:42:37 +00:00
parent 262c303ffb
commit 33ad8f2571
3 changed files with 344 additions and 108 deletions

View file

@ -378,55 +378,11 @@ extern LIST_ENTRY CmiHiveListHead;
extern ERESOURCE CmiRegistryLock; 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 */ /* Registry Callback Function */
typedef NTSTATUS (STDCALL *PEX_CALLBACK_FUNCTION ) ( typedef NTSTATUS (STDCALL *PEX_CALLBACK_FUNCTION ) (
IN PVOID CallbackContext, IN PVOID CallbackContext,
IN PVOID Argument1, IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2 IN PVOID Argument2
); );

View file

@ -133,6 +133,7 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2) IN PVOID Argument2)
{ {
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
@ -148,31 +149,29 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
if(!CurrentCallback->PendingDelete && if(!CurrentCallback->PendingDelete &&
ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1)) ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
{ {
NTSTATUS Status;
/* don't hold locks during the callbacks! */ /* don't hold locks during the callbacks! */
ExReleaseFastMutex(&CmiCallbackLock); ExReleaseFastMutex(&CmiCallbackLock);
Status = CurrentCallback->Function(CurrentCallback->Context, Status = CurrentCallback->Function(CurrentCallback->Context,
(PVOID)Argument1, Argument1,
Argument2); Argument2);
if(!NT_SUCCESS(Status))
{
/* one callback returned failure, don't call any more callbacks */
return Status;
}
ExAcquireFastMutex(&CmiCallbackLock); ExAcquireFastMutex(&CmiCallbackLock);
/* don't release the rundown protection before holding the callback lock /* 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 so the pointer to the next callback isn't cleared in case this callback
get's deleted */ get's deleted */
ExReleaseRundownProtectionEx(&CurrentCallback->RundownRef, 1); ExReleaseRundownProtectionEx(&CurrentCallback->RundownRef, 1);
if(!NT_SUCCESS(Status))
{
/* one callback returned failure, don't call any more callbacks */
break;
}
} }
} }
ExReleaseFastMutex(&CmiCallbackLock); ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_SUCCESS; return Status;
} }
@ -193,6 +192,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
UNICODE_STRING ObjectName; UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo; OBJECT_CREATE_INFORMATION ObjectCreateInfo;
unsigned i; unsigned i;
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
PAGED_CODE(); PAGED_CODE();
@ -214,15 +215,28 @@ NtCreateKey(OUT PHANDLE KeyHandle,
return 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, Status = ObFindObject(&ObjectCreateInfo,
&ObjectName, &ObjectName,
(PVOID*)&Object, (PVOID*)&Object,
&RemainingPath, &RemainingPath,
CmiKeyType); CmiKeyType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo); ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status)) 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); DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
return(Status); return(Status);
} }
@ -236,6 +250,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
{ {
ObDereferenceObject(Object); ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
DPRINT("Object marked for delete!\n"); DPRINT("Object marked for delete!\n");
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -252,6 +270,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status); DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
ObDereferenceObject(Object); ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status; return Status;
} }
@ -268,6 +290,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ObDereferenceObject(Object); ObDereferenceObject(Object);
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath); DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
RtlFreeUnicodeString(&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; return STATUS_OBJECT_NAME_NOT_FOUND;
} }
} }
@ -286,6 +312,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ObCreateObject() failed!\n"); DPRINT1("ObCreateObject() failed!\n");
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status); return(Status);
} }
@ -300,6 +330,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
DPRINT1("ObInsertObject() failed!\n"); DPRINT1("ObInsertObject() failed!\n");
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status); return(Status);
} }
@ -338,6 +372,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
ObDereferenceObject(Object); ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -382,6 +420,11 @@ NtCreateKey(OUT PHANDLE KeyHandle,
if (Disposition) if (Disposition)
*Disposition = REG_CREATED_NEW_KEY; *Disposition = REG_CREATED_NEW_KEY;
PostCreateKeyInfo.Object = KeyObject;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
CmiSyncHives(); CmiSyncHives();
return Status; return Status;
@ -394,6 +437,8 @@ NtDeleteKey(IN HANDLE KeyHandle)
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status;
REG_DELETE_KEY_INFORMATION DeleteKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -414,6 +459,17 @@ NtDeleteKey(IN HANDLE KeyHandle)
return Status; 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 */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
@ -438,14 +494,18 @@ NtDeleteKey(IN HANDLE KeyHandle)
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
/* Dereference the object */
ObDereferenceObject(KeyObject);
/* Remove the keep-alive reference */ /* Remove the keep-alive reference */
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
if (KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive) if (KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostDeleteKey, &PostOperationInfo);
/* Dereference the object */
ObDereferenceObject(KeyObject);
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
DPRINT("HandleCount %lu\n", ObGetObjectHandleCount((PVOID)KeyObject)); DPRINT("HandleCount %lu\n", ObGetObjectHandleCount((PVOID)KeyObject));
@ -480,6 +540,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
ULONG NameSize, ClassSize; ULONG NameSize, ClassSize;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -506,6 +568,20 @@ NtEnumerateKey(IN HANDLE KeyHandle,
return(Status); 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 */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE);
@ -523,6 +599,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
{ {
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostDeleteKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
DPRINT("No more volatile entries\n"); DPRINT("No more volatile entries\n");
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
@ -552,6 +630,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
{ {
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
DPRINT("No more non-volatile entries\n"); DPRINT("No more non-volatile entries\n");
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
@ -566,6 +646,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
{ {
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
} }
@ -576,6 +658,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
DPRINT("CmiGetBlock() failed\n"); DPRINT("CmiGetBlock() failed\n");
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -589,6 +673,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
{ {
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
DPRINT("No more entries\n"); DPRINT("No more entries\n");
return STATUS_NO_MORE_ENTRIES; return STATUS_NO_MORE_ENTRIES;
@ -804,6 +890,10 @@ NtEnumerateKey(IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
DPRINT("Returning status %x\n", Status); DPRINT("Returning status %x\n", Status);
@ -1121,11 +1211,13 @@ NtOpenKey(OUT PHANDLE KeyHandle,
{ {
UNICODE_STRING RemainingPath; UNICODE_STRING RemainingPath;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
PVOID Object; PVOID Object = NULL;
HANDLE hKey; HANDLE hKey;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ObjectName; UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo; OBJECT_CREATE_INFORMATION ObjectCreateInfo;
REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo;
REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo;
PAGED_CODE(); PAGED_CODE();
@ -1176,6 +1268,17 @@ NtOpenKey(OUT PHANDLE KeyHandle,
return Status; 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; RemainingPath.Buffer = NULL;
Status = ObFindObject(&ObjectCreateInfo, Status = ObFindObject(&ObjectCreateInfo,
@ -1184,7 +1287,6 @@ NtOpenKey(OUT PHANDLE KeyHandle,
&RemainingPath, &RemainingPath,
CmiKeyType); CmiKeyType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo); ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("CmpFindObject() returned 0x%08lx\n", Status); DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
@ -1199,7 +1301,6 @@ NtOpenKey(OUT PHANDLE KeyHandle,
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
{ {
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
Status = STATUS_OBJECT_NAME_NOT_FOUND; Status = STATUS_OBJECT_NAME_NOT_FOUND;
hKey = NULL; hKey = NULL;
@ -1211,7 +1312,6 @@ NtOpenKey(OUT PHANDLE KeyHandle,
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE)
{ {
ObDereferenceObject(Object);
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
hKey = NULL; hKey = NULL;
goto openkey_cleanup; goto openkey_cleanup;
@ -1222,12 +1322,22 @@ NtOpenKey(OUT PHANDLE KeyHandle,
DesiredAccess, DesiredAccess,
TRUE, TRUE,
&hKey); &hKey);
ObDereferenceObject(Object);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
hKey = NULL; hKey = NULL;
openkey_cleanup: 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 _SEH_TRY
{ {
*KeyHandle = hKey; *KeyHandle = hKey;
@ -1258,6 +1368,8 @@ NtQueryKey(IN HANDLE KeyHandle,
PKEY_CELL KeyCell; PKEY_CELL KeyCell;
ULONG NameSize, ClassSize; ULONG NameSize, ClassSize;
NTSTATUS Status; NTSTATUS Status;
REG_QUERY_KEY_INFORMATION QueryKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -1280,6 +1392,20 @@ NtQueryKey(IN HANDLE KeyHandle,
return Status; 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 */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE);
@ -1444,6 +1570,10 @@ NtQueryKey(IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return(Status); return(Status);
@ -1468,6 +1598,8 @@ NtQueryValueKey(IN HANDLE KeyHandle,
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation; PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation; PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation; PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
REG_QUERY_VALUE_KEY_INFORMATION QueryValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -1488,6 +1620,20 @@ NtQueryValueKey(IN HANDLE KeyHandle,
return 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 */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE);
@ -1686,6 +1832,9 @@ NtQueryValueKey(IN HANDLE KeyHandle,
ByeBye:; ByeBye:;
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostQueryValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return Status; return Status;
@ -1710,6 +1859,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
PDATA_CELL NewDataCell; PDATA_CELL NewDataCell;
PHBIN pBin; PHBIN pBin;
ULONG DesiredAccess; ULONG DesiredAccess;
REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -1728,6 +1879,20 @@ NtSetValueKey(IN HANDLE KeyHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return(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 */ /* Acquire hive lock exclucively */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
@ -1759,6 +1924,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return Status; return Status;
} }
@ -1824,6 +1991,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return Status; return Status;
@ -1849,6 +2018,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
CmiSyncHives(); CmiSyncHives();
@ -1865,6 +2036,8 @@ NtDeleteValueKey (IN HANDLE KeyHandle,
{ {
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status;
REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -1880,6 +2053,16 @@ NtDeleteValueKey (IN HANDLE KeyHandle,
return Status; return Status;
} }
DeleteValueKeyInfo.Object = (PVOID)KeyObject;
DeleteValueKeyInfo.ValueName = ValueName;
Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey, &DeleteValueKeyInfo);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(KeyObject);
return Status;
}
/* Acquire hive lock */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
@ -1898,6 +2081,11 @@ NtDeleteValueKey (IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Object = (PVOID)KeyObject;
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey, &PostOperationInfo);
ObDereferenceObject (KeyObject); ObDereferenceObject (KeyObject);
CmiSyncHives (); CmiSyncHives ();
@ -2106,6 +2294,8 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
NTSTATUS Status; NTSTATUS Status;
PUCHAR DataPtr; PUCHAR DataPtr;
ULONG i; ULONG i;
REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION QueryMultipleValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); PAGED_CODE();
@ -2122,6 +2312,21 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
return(Status); 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 */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE); ExAcquireResourceSharedLite(&CmiRegistryLock, TRUE);
@ -2201,6 +2406,9 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostQueryMultipleValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status); DPRINT("Return Status 0x%X\n", Status);
@ -2340,15 +2548,11 @@ NtSetInformationKey (IN HANDLE KeyHandle,
{ {
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status;
REG_SET_INFORMATION_KEY_INFORMATION SetInformationKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE(); 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 */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle (KeyHandle, Status = ObReferenceObjectByHandle (KeyHandle,
KEY_SET_VALUE, KEY_SET_VALUE,
@ -2362,6 +2566,30 @@ NtSetInformationKey (IN HANDLE KeyHandle,
return Status; return Status;
} }
PostOperationInfo.Object = (PVOID)KeyObject;
SetInformationKeyInfo.Object = (PVOID)KeyObject;
SetInformationKeyInfo.KeySetInformationClass = KeyInformationClass;
SetInformationKeyInfo.KeySetInformation = KeyInformation;
SetInformationKeyInfo.KeySetInformationLength = KeyInformationLength;
Status = CmiCallRegisteredCallbacks(RegNtSetInformationKey, &SetInformationKeyInfo);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (KeyObject);
return Status;
}
if (KeyInformationClass != KeyWriteTimeInformation)
{
Status = STATUS_INVALID_INFO_CLASS;
}
else if (KeyInformationLength != sizeof (KEY_WRITE_TIME_INFORMATION))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
/* Acquire hive lock */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
@ -2377,10 +2605,17 @@ NtSetInformationKey (IN HANDLE KeyHandle,
/* Release hive lock */ /* Release hive lock */
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
}
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostSetInformationKey, &PostOperationInfo);
ObDereferenceObject (KeyObject); ObDereferenceObject (KeyObject);
if (NT_SUCCESS(Status))
{
CmiSyncHives (); CmiSyncHives ();
}
DPRINT ("NtSaveKey() done\n"); DPRINT ("NtSaveKey() done\n");

View file

@ -4512,10 +4512,55 @@ typedef enum _TRACE_INFORMATION_CLASS {
TraceHandleByNameClass TraceHandleByNameClass
} TRACE_INFORMATION_CLASS; } 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 typedef NTSTATUS
(DDKAPI *PEX_CALLBACK_FUNCTION)( (DDKAPI *PEX_CALLBACK_FUNCTION)(
IN PVOID CallbackContext, IN PVOID CallbackContext,
IN PVOID Argument1, IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2); IN PVOID Argument2);