mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- 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:
parent
262c303ffb
commit
33ad8f2571
3 changed files with 344 additions and 108 deletions
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
@ -201,28 +202,41 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
KeyHandle,
|
KeyHandle,
|
||||||
ObjectAttributes->RootDirectory);
|
ObjectAttributes->RootDirectory);
|
||||||
|
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
KeGetPreviousMode(),
|
KeGetPreviousMode(),
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ObFindObject(&ObjectCreateInfo,
|
|
||||||
&ObjectName,
|
|
||||||
(PVOID*)&Object,
|
|
||||||
&RemainingPath,
|
|
||||||
CmiKeyType);
|
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
if (!NT_SUCCESS(Status))
|
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,
|
||||||
|
&RemainingPath,
|
||||||
|
CmiKeyType);
|
||||||
|
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);
|
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,21 +1268,31 @@ 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,
|
||||||
&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))
|
||||||
{
|
{
|
||||||
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
||||||
Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject returns STATUS_UNSUCCESSFUL */
|
Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject returns STATUS_UNSUCCESSFUL */
|
||||||
hKey = *KeyHandle; /* Preserve hkResult value */
|
hKey = *KeyHandle; /* Preserve hkResult value */
|
||||||
goto openkey_cleanup;
|
goto openkey_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
|
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
|
||||||
|
@ -1199,11 +1301,10 @@ 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;
|
||||||
goto openkey_cleanup;
|
goto openkey_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
RtlFreeUnicodeString(&RemainingPath);
|
||||||
|
@ -1211,10 +1312,9 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -1487,6 +1619,20 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
||||||
DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
||||||
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();
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -1879,6 +2052,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();
|
||||||
|
@ -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,25 +2566,56 @@ NtSetInformationKey (IN HANDLE KeyHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acquire hive lock */
|
PostOperationInfo.Object = (PVOID)KeyObject;
|
||||||
KeEnterCriticalRegion();
|
SetInformationKeyInfo.Object = (PVOID)KeyObject;
|
||||||
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
|
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 =
|
if (KeyInformationClass != KeyWriteTimeInformation)
|
||||||
((PKEY_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart;
|
{
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
CmiMarkBlockDirty (KeyObject->RegistryHive,
|
else if (KeyInformationLength != sizeof (KEY_WRITE_TIME_INFORMATION))
|
||||||
KeyObject->KeyCellOffset);
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Acquire hive lock */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
|
||||||
|
|
||||||
/* Release hive lock */
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
ExReleaseResourceLite(&CmiRegistryLock);
|
|
||||||
KeLeaveCriticalRegion();
|
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);
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
CmiSyncHives ();
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
CmiSyncHives ();
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT ("NtSaveKey() done\n");
|
DPRINT ("NtSaveKey() done\n");
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue