Author: tfaber
Date: Mon May 2 13:19:44 2016
New Revision: 71232
URL:
http://svn.reactos.org/svn/reactos?rev=71232&view=rev
Log:
[NTOS:CM]
- Correctly handle NULL Data with nonzero DataSize in NtSetValueKey
ROSTESTS-200 #resolve
Added:
trunk/rostests/apitests/ntdll/NtSetValueKey.c (with props)
Modified:
trunk/reactos/ntoskrnl/config/ntapi.c
trunk/rostests/apitests/ntdll/CMakeLists.txt
trunk/rostests/apitests/ntdll/testlist.c
Modified: trunk/reactos/ntoskrnl/config/ntapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/ntapi.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/config/ntapi.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/ntapi.c [iso-8859-1] Mon May 2 13:19:44 2016
@@ -630,11 +630,11 @@
Data = NULL;
/* Probe and copy the data */
- if ((PreviousMode != KernelMode) && Data)
+ if ((PreviousMode != KernelMode) && (DataSize != 0))
{
PVOID DataCopy = ExAllocatePoolWithTag(PagedPool, DataSize, TAG_CM);
if (!DataCopy)
- return STATUS_NO_MEMORY;
+ return STATUS_INSUFFICIENT_RESOURCES;
_SEH2_TRY
{
ProbeForRead(Data, DataSize, 1);
Modified: trunk/rostests/apitests/ntdll/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/CMakeLists…
==============================================================================
--- trunk/rostests/apitests/ntdll/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/ntdll/CMakeLists.txt [iso-8859-1] Mon May 2 13:19:44 2016
@@ -18,6 +18,7 @@
NtQuerySystemEnvironmentValue.c
NtQueryVolumeInformationFile.c
NtSaveKey.c
+ NtSetValueKey.c
RtlAllocateHeap.c
RtlBitmap.c
RtlCopyMappedMemory.c
Added: trunk/rostests/apitests/ntdll/NtSetValueKey.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/NtSetValue…
==============================================================================
--- trunk/rostests/apitests/ntdll/NtSetValueKey.c (added)
+++ trunk/rostests/apitests/ntdll/NtSetValueKey.c [iso-8859-1] Mon May 2 13:19:44 2016
@@ -0,0 +1,209 @@
+/*
+ * PROJECT: ReactOS API tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: Test for NtSetValueKey
+ * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org>
+ */
+
+#include <apitest.h>
+
+#include <winreg.h>
+#define WIN32_NO_STATUS
+#include <ndk/cmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/rtlfuncs.h>
+#include <strsafe.h>
+
+START_TEST(NtSetValueKey)
+{
+ NTSTATUS Status;
+ HANDLE ParentKeyHandle;
+ HANDLE KeyHandle;
+ UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"SOFTWARE\\ntdll-apitest-NtSetValueKey");
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING ValueName;
+ WCHAR Default[] = L"Default";
+ WCHAR Hello[] = L"Hello";
+ WCHAR Empty[] = L"";
+ NTSTATUS QueryStatus;
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
+ ULONG PartialInfoLength;
+ ULONG ResultLength;
+ const struct
+ {
+ ULONG Type;
+ PVOID Data;
+ ULONG DataSize;
+ NTSTATUS StatusExisting;
+ NTSTATUS StatusNew;
+ NTSTATUS StatusExisting2;
+ NTSTATUS StatusNew2;
+ } Tests[] =
+ {
+ { REG_NONE, NULL, 0, STATUS_SUCCESS,
STATUS_SUCCESS }, /* Empty REG_NONE value */
+ { REG_SZ, Hello, sizeof(Hello), STATUS_SUCCESS,
STATUS_SUCCESS }, /* Regular string */
+ { REG_SZ, Empty, sizeof(Empty), STATUS_SUCCESS,
STATUS_SUCCESS }, /* Empty string */
+ { REG_SZ, NULL, 0, STATUS_SUCCESS,
STATUS_SUCCESS }, /* Zero length */
+ { REG_SZ, Hello, 0, STATUS_SUCCESS,
STATUS_SUCCESS }, /* Zero length, non-null data */
+ { REG_SZ, (PVOID)(LONG_PTR)-4, 0, STATUS_SUCCESS,
STATUS_SUCCESS }, /* Zero length, kernel data */
+ { REG_SZ, NULL, 1, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION }, /* Non-zero length (odd), null data */
+ { REG_SZ, NULL, 2, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION }, /* Non-zero length (even), null data */
+ { REG_SZ, NULL, 4, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION }, /* CM_KEY_VALUE_SMALL, null data */
+ { REG_SZ, NULL, 5, STATUS_INVALID_PARAMETER,
STATUS_ACCESS_VIOLATION, /* CM_KEY_VALUE_SMALL+1, null data */
+ STATUS_ACCESS_VIOLATION,
STATUS_INSUFFICIENT_RESOURCES }, /* win7 */
+ { REG_SZ, NULL, 6, STATUS_INVALID_PARAMETER,
STATUS_ACCESS_VIOLATION, /* CM_KEY_VALUE_SMALL+2, null data */
+ STATUS_ACCESS_VIOLATION,
STATUS_INSUFFICIENT_RESOURCES }, /* win7 */
+ { REG_SZ, NULL, 0x7fff0000, STATUS_INVALID_PARAMETER,
STATUS_INSUFFICIENT_RESOURCES, /* MI_USER_PROBE_ADDRESS, null data */
+ STATUS_INSUFFICIENT_RESOURCES,
STATUS_INSUFFICIENT_RESOURCES }, /* win7 */
+ { REG_SZ, NULL, 0x7fff0001, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION, /* MI_USER_PROBE_ADDRESS+1, null data */
+ STATUS_INSUFFICIENT_RESOURCES,
STATUS_INSUFFICIENT_RESOURCES }, /* win7 */
+ { REG_SZ, NULL, 0x7fffffff, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION, /* <2GB, null data */
+ STATUS_INVALID_PARAMETER,
STATUS_INVALID_PARAMETER }, /* win7 */
+ { REG_SZ, NULL, 0x80000000, STATUS_ACCESS_VIOLATION,
STATUS_ACCESS_VIOLATION, /* 2GB, null data */
+ STATUS_INVALID_PARAMETER,
STATUS_INVALID_PARAMETER }, /* win7 */
+ { REG_BINARY, NULL, 5, STATUS_INVALID_PARAMETER,
STATUS_ACCESS_VIOLATION, /* ROSTESTS-200 */
+ STATUS_ACCESS_VIOLATION,
STATUS_INSUFFICIENT_RESOURCES }, /* win7 */
+ };
+ ULONG i;
+
+ Status = RtlOpenCurrentUser(READ_CONTROL, &ParentKeyHandle);
+ ok(Status == STATUS_SUCCESS, "RtlOpenCurrentUser returned %lx\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ skip("No user key handle\n");
+ return;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ ParentKeyHandle,
+ NULL);
+ Status = NtCreateKey(&KeyHandle,
+ KEY_QUERY_VALUE | KEY_SET_VALUE | DELETE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ ok(Status == STATUS_SUCCESS, "NtCreateKey returned %lx\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ NtClose(ParentKeyHandle);
+ skip("No key handle\n");
+ return;
+ }
+
+ PartialInfoLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[128]);
+ PartialInfo = HeapAlloc(GetProcessHeap(), 0, PartialInfoLength);
+ if (PartialInfo == NULL)
+ {
+ NtDeleteKey(KeyHandle);
+ NtClose(KeyHandle);
+ NtClose(ParentKeyHandle);
+ skip("No key handle\n");
+ return;
+ }
+
+ for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
+ {
+ /*
+ * Existing value
+ */
+ /* Make sure it exists */
+ RtlInitUnicodeString(&ValueName, L"ExistingValue");
+ Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, Default,
sizeof(Default));
+ ok(Status == STATUS_SUCCESS, "[%lu] NtSetValueKey failed with %lx", i,
Status);
+
+ /* Set it */
+ Status = NtSetValueKey(KeyHandle, &ValueName, 0, Tests[i].Type,
Tests[i].Data, Tests[i].DataSize);
+ if (Status == Tests[i].StatusExisting2)
+ ok(Status == Tests[i].StatusExisting || Status == Tests[i].StatusExisting2,
"[%lu, %p, %lu] NtSetValueKey returned %lx, expected %lx or %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, Status,
Tests[i].StatusExisting, Tests[i].StatusExisting2);
+ else
+ ok(Status == Tests[i].StatusExisting, "[%lu, %p, %lu] NtSetValueKey
returned %lx, expected %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, Status,
Tests[i].StatusExisting);
+
+ /* Check it */
+ RtlZeroMemory(PartialInfo, PartialInfoLength);
+ QueryStatus = NtQueryValueKey(KeyHandle, &ValueName,
KeyValuePartialInformation, PartialInfo, PartialInfoLength, &ResultLength);
+ ok(QueryStatus == STATUS_SUCCESS, "[%lu, %p, %lu] NtQueryValueKey failed
with %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, QueryStatus);
+ if (NT_SUCCESS(QueryStatus))
+ {
+ if (NT_SUCCESS(Status))
+ {
+ ok(PartialInfo->TitleIndex == 0, "[%lu, %p, %lu] TitleIndex =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->TitleIndex);
+ ok(PartialInfo->Type == Tests[i].Type, "[%lu, %p, %lu] Type =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->Type);
+ ok(PartialInfo->DataLength == Tests[i].DataSize, "[%lu, %p, %lu]
DataLength = %lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->DataLength);
+ ok(!memcmp(PartialInfo->Data, Tests[i].Data, Tests[i].DataSize),
"[%lu, %p, %lu] Data does not match set value\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize);
+ }
+ else
+ {
+ ok(PartialInfo->TitleIndex == 0, "[%lu, %p, %lu] TitleIndex =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->TitleIndex);
+ ok(PartialInfo->Type == REG_SZ, "[%lu, %p, %lu] Type =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->Type);
+ ok(PartialInfo->DataLength == sizeof(Default), "[%lu, %p, %lu]
DataLength = %lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->DataLength);
+ ok(!memcmp(PartialInfo->Data, Default, sizeof(Default)), "[%lu,
%p, %lu] Data does not match default\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize);
+ }
+ }
+
+ /*
+ * New value
+ */
+ /* Make sure it doesn't exist */
+ RtlInitUnicodeString(&ValueName, L"NewValue");
+ Status = NtDeleteValueKey(KeyHandle, &ValueName);
+ ok(Status == STATUS_SUCCESS || Status == STATUS_OBJECT_NAME_NOT_FOUND,
+ "[%lu] NtDeleteValueKey failed with %lx", i, Status);
+
+ /* Set it */
+ Status = NtSetValueKey(KeyHandle, &ValueName, 0, Tests[i].Type,
Tests[i].Data, Tests[i].DataSize);
+ if (Tests[i].StatusNew2)
+ ok(Status == Tests[i].StatusNew || Status == Tests[i].StatusNew2, "[%lu,
%p, %lu] NtSetValueKey returned %lx, expected %lx or %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, Status,
Tests[i].StatusNew, Tests[i].StatusNew2);
+ else
+ ok(Status == Tests[i].StatusNew, "[%lu, %p, %lu] NtSetValueKey returned
%lx, expected %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, Status,
Tests[i].StatusNew);
+
+ /* Check it */
+ RtlZeroMemory(PartialInfo, PartialInfoLength);
+ QueryStatus = NtQueryValueKey(KeyHandle, &ValueName,
KeyValuePartialInformation, PartialInfo, PartialInfoLength, &ResultLength);
+ if (NT_SUCCESS(Status))
+ {
+ ok(QueryStatus == STATUS_SUCCESS, "[%lu, %p, %lu] NtQueryValueKey failed
with %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, QueryStatus);
+ if (NT_SUCCESS(QueryStatus))
+ {
+ ok(PartialInfo->TitleIndex == 0, "[%lu, %p, %lu] TitleIndex =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->TitleIndex);
+ ok(PartialInfo->Type == Tests[i].Type, "[%lu, %p, %lu] Type =
%lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->Type);
+ ok(PartialInfo->DataLength == Tests[i].DataSize, "[%lu, %p, %lu]
DataLength = %lu\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize,
PartialInfo->DataLength);
+ ok(!memcmp(PartialInfo->Data, Tests[i].Data, Tests[i].DataSize),
"[%lu, %p, %lu] Data does not match set value\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize);
+ }
+ }
+ else
+ {
+ ok(QueryStatus == STATUS_OBJECT_NAME_NOT_FOUND, "[%lu, %p, %lu]
QueryStatus = %lx\n",
+ Tests[i].Type, Tests[i].Data, Tests[i].DataSize, QueryStatus);
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, PartialInfo);
+ Status = NtDeleteKey(KeyHandle);
+ ok(Status == STATUS_SUCCESS, "NtDeleteKey returned %lx\n", Status);
+ Status = NtClose(KeyHandle);
+ ok(Status == STATUS_SUCCESS, "NtClose returned %lx\n", Status);
+ Status = NtClose(ParentKeyHandle);
+ ok(Status == STATUS_SUCCESS, "NtClose returned %lx\n", Status);
+}
Propchange: trunk/rostests/apitests/ntdll/NtSetValueKey.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/ntdll/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/testlist.c…
==============================================================================
--- trunk/rostests/apitests/ntdll/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/ntdll/testlist.c [iso-8859-1] Mon May 2 13:19:44 2016
@@ -21,6 +21,7 @@
extern void func_NtQuerySystemEnvironmentValue(void);
extern void func_NtQueryVolumeInformationFile(void);
extern void func_NtSaveKey(void);
+extern void func_NtSetValueKey(void);
extern void func_NtSystemInformation(void);
extern void func_RtlAllocateHeap(void);
extern void func_RtlBitmap(void);
@@ -63,6 +64,7 @@
{ "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue },
{ "NtQueryVolumeInformationFile", func_NtQueryVolumeInformationFile },
{ "NtSaveKey", func_NtSaveKey},
+ { "NtSetValueKey", func_NtSetValueKey},
{ "NtSystemInformation", func_NtSystemInformation },
{ "RtlAllocateHeap", func_RtlAllocateHeap },
{ "RtlBitmapApi", func_RtlBitmap },