IN PVOID Argument2)
{
PLIST_ENTRY CurrentEntry;
+ NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
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;
}
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
- UNICODE_STRING RemainingPath;
+ UNICODE_STRING RemainingPath = {0};
+ BOOLEAN FreeRemainingPath = TRUE;
+ ULONG LocalDisposition;
PKEY_OBJECT KeyObject;
- NTSTATUS Status;
- PVOID Object;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID Object = NULL;
PWSTR Start;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
unsigned i;
+ REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
+ REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
+ KPROCESSOR_MODE PreviousMode;
+ UNICODE_STRING CapturedClass = {0};
+ HANDLE hKey;
PAGED_CODE();
- DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n",
- ObjectAttributes->ObjectName,
- KeyHandle,
- ObjectAttributes->RootDirectory);
+ PreviousMode = KeGetPreviousMode();
- /* 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;
- }
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWriteHandle(KeyHandle);
+ if (Disposition != NULL)
+ {
+ ProbeForWriteUlong(Disposition);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ if (Class != NULL)
+ {
+ Status = ProbeAndCaptureUnicodeString(&CapturedClass,
+ PreviousMode,
+ Class);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ /* Capture all the info */
+ DPRINT("Capturing Create Info\n");
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ PreviousMode,
+ CmiKeyType,
+ &ObjectCreateInfo,
+ &ObjectName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+ goto Cleanup;
+ }
+
+ PostCreateKeyInfo.CompleteName = &ObjectName;
+ PreCreateKeyInfo.CompleteName = &ObjectName;
+ Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ goto Cleanup;
+ }
+
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);
+
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
- return(Status);
+ goto Cleanup;
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
/* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
DPRINT("Object marked for delete!\n");
- return(STATUS_UNSUCCESSFUL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Cleanup;
}
- if (Disposition)
- *Disposition = REG_OPENED_EXISTING_KEY;
-
Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
TRUE,
- KeyHandle);
+ &hKey);
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
- return Status;
+
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ LocalDisposition = REG_OPENED_EXISTING_KEY;
+ goto SuccessReturn;
}
/* If RemainingPath contains \ we must return error
{
if (L'\\' == RemainingPath.Buffer[i])
{
- ObDereferenceObject(Object);
- DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
- RtlFreeUnicodeString(&RemainingPath);
- return STATUS_OBJECT_NAME_NOT_FOUND;
+ DPRINT("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
+
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto Cleanup;
}
}
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object);
- Status = ObCreateObject(ExGetPreviousMode(),
+ Status = ObCreateObject(PreviousMode,
CmiKeyType,
NULL,
- ExGetPreviousMode(),
+ PreviousMode,
NULL,
sizeof(KEY_OBJECT),
0,
if (!NT_SUCCESS(Status))
{
DPRINT1("ObCreateObject() failed!\n");
- return(Status);
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ goto Cleanup;
}
Status = ObInsertObject((PVOID)KeyObject,
DesiredAccess,
0,
NULL,
- KeyHandle);
+ &hKey);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(KeyObject);
- RtlFreeUnicodeString(&RemainingPath);
DPRINT1("ObInsertObject() failed!\n");
- return(Status);
+
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ goto Cleanup;
}
KeyObject->ParentKey = Object;
KeyObject,
&RemainingPath,
TitleIndex,
- Class,
+ &CapturedClass,
CreateOptions);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject);
- ObDereferenceObject(Object);
- RtlFreeUnicodeString(&RemainingPath);
- return STATUS_UNSUCCESSFUL;
+
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ Status = STATUS_UNSUCCESSFUL;
+ goto Cleanup;
}
if (Start == RemainingPath.Buffer)
{
KeyObject->Name = RemainingPath;
+ FreeRemainingPath = FALSE;
}
else
{
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
- RtlFreeUnicodeString(&RemainingPath);
}
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must remain in memory unless it is deleted
or file is unloaded */
- ObReferenceObjectByPointer(KeyObject,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- UserMode);
+ ObReferenceObject(KeyObject);
}
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostCreateKeyInfo.Object = KeyObject;
+ PostCreateKeyInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
- ObDereferenceObject(Object);
+ CmiSyncHives();
+
+ LocalDisposition = REG_CREATED_NEW_KEY;
- if (Disposition)
- *Disposition = REG_CREATED_NEW_KEY;
+SuccessReturn:
+ _SEH_TRY
+ {
+ *KeyHandle = hKey;
+ if (Disposition != NULL)
+ {
+ *Disposition = LocalDisposition;
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
- CmiSyncHives();
+Cleanup:
+ if (Class != NULL)
+ {
+ ReleaseCapturedUnicodeString(&CapturedClass,
+ PreviousMode);
+ }
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath);
+ if (Object != NULL) ObDereferenceObject(Object);
return Status;
}
KPROCESSOR_MODE PreviousMode;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
+ REG_DELETE_KEY_INFORMATION DeleteKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
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);
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));
ULONG NameSize, ClassSize;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
+ REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
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);
{
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;
{
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;
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
+ CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return STATUS_NO_MORE_ENTRIES;
}
DPRINT("CmiGetBlock() failed\n");
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = STATUS_UNSUCCESSFUL;
+ CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return STATUS_UNSUCCESSFUL;
}
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
+ CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
DPRINT("No more entries\n");
return STATUS_NO_MORE_ENTRIES;
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
+
ObDereferenceObject(KeyObject);
DPRINT("Returning status %x\n", Status);
ROUND_UP(ValueFullInformation->DataOffset, sizeof(PVOID));
ValueFullInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK;
- if (Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) <
- NameSize)
+ if (Length < ValueFullInformation->DataOffset)
{
NameSize = Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]);
DataSize = 0;
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
- else if (ROUND_UP(Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION,
- Name[0]) - NameSize, sizeof(PVOID)) < DataSize)
+ else if (Length - ValueFullInformation->DataOffset < DataSize)
{
- DataSize = ROUND_UP(Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) - NameSize, sizeof(PVOID));
+ DataSize = Length - ValueFullInformation->DataOffset;
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
{
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();
{
_SEH_TRY
{
- ProbeForWrite(KeyHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
+ ProbeForWriteHandle(KeyHandle);
}
_SEH_HANDLE
{
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);
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);
/* 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(),
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;
PKEY_CELL KeyCell;
ULONG NameSize, ClassSize;
NTSTATUS Status;
+ REG_QUERY_KEY_INFORMATION QueryKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
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);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo);
+
ObDereferenceObject(KeyObject);
return(Status);
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();
if (!NT_SUCCESS(Status))
{
- DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status);
+ DPRINT1("ObReferenceObjectByHandle() failed with status %x %p\n", Status, KeyHandle);
+ 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;
}
ByeBye:;
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostQueryValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return Status;
PDATA_CELL NewDataCell;
PHBIN pBin;
ULONG DesiredAccess;
+ REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
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);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return Status;
}
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
ValueCell->DataType = Type;
- RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
CmiMarkBlockDirty(RegistryHive, ValueCellOffset);
}
else if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET) &&
RtlCopyMemory(DataCell->Data, Data, DataSize);
ValueCell->DataSize = DataSize;
ValueCell->DataType = Type;
+ CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
+ CmiMarkBlockDirty(RegistryHive, ValueCellOffset);
}
else
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return Status;
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostSetValueKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
CmiSyncHives();
{
PKEY_OBJECT KeyObject;
NTSTATUS Status;
+ REG_DELETE_VALUE_KEY_INFORMATION DeleteValueKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
+ KPROCESSOR_MODE PreviousMode;
+ UNICODE_STRING CapturedValueName;
PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_QUERY_VALUE,
+ KEY_SET_VALUE,
CmiKeyType,
- UserMode,
+ PreviousMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
return Status;
}
+ Status = ProbeAndCaptureUnicodeString(&CapturedValueName,
+ PreviousMode,
+ ValueName);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Fail;
+ }
+ DeleteValueKeyInfo.Object = (PVOID)KeyObject;
+ DeleteValueKeyInfo.ValueName = &CapturedValueName;
+
+ /* FIXME - check if value exists before calling the callbacks? */
+ Status = CmiCallRegisteredCallbacks(RegNtPreDeleteValueKey, &DeleteValueKeyInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ReleaseCapturedUnicodeString(&CapturedValueName,
+ PreviousMode);
+Fail:
+ ObDereferenceObject(KeyObject);
+ return Status;
+ }
+
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ ReleaseCapturedUnicodeString(&CapturedValueName,
+ PreviousMode);
+
+ PostOperationInfo.Object = (PVOID)KeyObject;
+ PostOperationInfo.Status = Status;
+
+ CmiCallRegisteredCallbacks(RegNtPostDeleteValueKey, &PostOperationInfo);
+
ObDereferenceObject (KeyObject);
CmiSyncHives ();
NTSTATUS Status;
PUCHAR DataPtr;
ULONG i;
+ REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION QueryMultipleValueKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
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);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostQueryMultipleValueKey, &PostOperationInfo);
+
ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status);
{
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,
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");