REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
- DPRINT("NtEnumerateKey() KH 0x%x, Index 0x%x, KIC %d, Length %d\n",
+ DPRINT("NtEnumerateKey() KH 0x%p, Index 0x%x, KIC %d, Length %lu\n",
KeyHandle, Index, KeyInformationClass, Length);
/* Reject classes we don't know about */
REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
PAGED_CODE();
- DPRINT("NtEnumerateValueKey() KH 0x%x, Index 0x%x, KVIC %d, Length %d\n",
+ DPRINT("NtEnumerateValueKey() KH 0x%p, Index 0x%x, KVIC %d, Length %lu\n",
KeyHandle, Index, KeyValueInformationClass, Length);
/* Reject classes we don't know about */
REG_POST_OPERATION_INFORMATION PostOperationInfo;
OBJECT_HANDLE_INFORMATION HandleInfo;
PAGED_CODE();
- DPRINT("NtQueryKey() KH 0x%x, KIC %d, Length %d\n",
+ DPRINT("NtQueryKey() KH 0x%p, KIC %d, Length %lu\n",
KeyHandle, KeyInformationClass, Length);
/* Reject invalid classes */
REG_POST_OPERATION_INFORMATION PostOperationInfo;
UNICODE_STRING ValueNameCopy = *ValueName;
PAGED_CODE();
- DPRINT("NtQueryValueKey() KH 0x%x, VN '%wZ', KVIC %d, Length %d\n",
+ DPRINT("NtQueryValueKey() KH 0x%p, VN '%wZ', KVIC %d, Length %lu\n",
KeyHandle, ValueName, KeyValueInformationClass, Length);
/* Verify that the handle is valid and is a registry key */
REG_POST_OPERATION_INFORMATION PostOperationInfo;
UNICODE_STRING ValueNameCopy = *ValueName;
PAGED_CODE();
- DPRINT("NtSetValueKey() KH 0x%x, VN '%wZ', TI %x, T %d, DS %d\n",
+ DPRINT("NtSetValueKey() KH 0x%p, VN '%wZ', TI %x, T %lu, DS %lu\n",
KeyHandle, ValueName, TitleIndex, Type, DataSize);
/* Verify that the handle is valid and is a registry key */
NtSaveKey(IN HANDLE KeyHandle,
IN HANDLE FileHandle)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* Call the extended API */
+ return NtSaveKeyEx(KeyHandle, FileHandle, REG_STANDARD_FORMAT);
}
NTSTATUS
IN HANDLE FileHandle,
IN ULONG Flags)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PCM_KEY_BODY KeyObject;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+ PAGED_CODE();
+
+ DPRINT("NtSaveKeyEx(0x%08X, 0x%08X, %lu)\n", KeyHandle, FileHandle, Flags);
+
+ /* Verify the flags */
+ if ((Flags != REG_STANDARD_FORMAT)
+ && (Flags != REG_LATEST_FORMAT)
+ && (Flags != REG_NO_COMPRESSION))
+ {
+ /* Only one of these values can be specified */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Check for the SeBackupPrivilege */
+ if (!SeSinglePrivilegeCheck(SeBackupPrivilege, PreviousMode))
+ {
+ return STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ /* Verify that the handle is valid and is a registry key */
+ Status = ObReferenceObjectByHandle(KeyHandle,
+ KEY_READ,
+ CmpKeyObjectType,
+ PreviousMode,
+ (PVOID*)&KeyObject,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Call the internal API */
+ Status = CmSaveKey(KeyObject->KeyControlBlock, FileHandle, Flags);
+
+ ObDereferenceObject(KeyObject);
+ return Status;
}
NTSTATUS