Index: apitests/ntdll/CMakeLists.txt
===================================================================
--- apitests/ntdll/CMakeLists.txt	(revision 59938)
+++ apitests/ntdll/CMakeLists.txt	(working copy)
@@ -6,6 +6,7 @@
     NtMapViewOfSection.c
     NtProtectVirtualMemory.c
     NtQuerySystemEnvironmentValue.c
+    NtSetValueKey.c
     RtlBitmap.c
     RtlDetermineDosPathNameType.c
     RtlDoesFileExists.c
Index: apitests/ntdll/NtSetValueKey.c
===================================================================
--- apitests/ntdll/NtSetValueKey.c	(revision 0)
+++ apitests/ntdll/NtSetValueKey.c	(working copy)
@@ -0,0 +1,226 @@
+#define WIN32_NO_STATUS
+#include <wine/test.h>
+
+/* PSDK/NDK Headers */
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+
+#include <ndk/cmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/rtlfuncs.h>
+
+#include <stdio.h>
+
+NTSTATUS NTAPI RtlGetLastNtStatus(void);
+
+static VOID
+Test_VerifyValueWritten(HANDLE KeyHandle,
+                        UNICODE_STRING* ValueName,
+                        ULONG ValueType,
+                        PVOID Buffer, ULONG BufferSize)
+{
+    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+    ULONG KeyInfoSize;
+    ULONG ReturnSize;
+    NTSTATUS Status;
+
+    KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + BufferSize;
+    KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize);
+
+    ok(KeyInfo != NULL,
+       "RtlAllocateHeap failed, LastStatus=0x%08lx\n",
+       RtlGetLastNtStatus());
+    if (KeyInfo == NULL)
+    {
+        return;
+    }
+
+    Status = NtQueryValueKey(KeyHandle, ValueName,
+                             KeyValuePartialInformation,
+                             KeyInfo, KeyInfoSize,
+                             &ReturnSize);
+
+    ok(NT_SUCCESS(Status), "NtQueryValueKey failed : 0x%08lx\n", Status);
+    if (!NT_SUCCESS(Status))
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+        return;
+    }
+
+    ok(KeyInfo->Type == ValueType,
+       "Unexpected KeyInfo->Type 0x%08lx (expected 0x%08lx)\n",
+       KeyInfo->Type, ValueType);
+
+    ok(KeyInfo->DataLength == BufferSize,
+       "Unexpected KeyInfo->DataLength 0x%08lx (expected 0x%08lx)\n",
+       KeyInfo->DataLength, BufferSize);
+
+    if (BufferSize != KeyInfo->DataLength)
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+        return;
+    }
+
+    ok(memcmp(Buffer, KeyInfo->Data, BufferSize) == 0,
+       "The returned KeyInfo->Data does not match the expected data.\n");
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+}
+
+static VOID
+Test_NtSetValueKey(HANDLE KeyHandle,
+                   UNICODE_STRING* ValueName,
+                   ULONG ValueType,
+                   PVOID Buffer, ULONG BufferSize,
+                   NTSTATUS ExpectedStatus)
+{
+    NTSTATUS Status;
+
+    Status = NtSetValueKey(KeyHandle, ValueName, 0, ValueType,
+                           Buffer, BufferSize);
+
+    ok(Status == ExpectedStatus,
+       "NtSetValueKey(KeyHandle, ValueName=%S, 0, ValueType=0x%08lx,"
+       " Buffer=0x%08p, BufferSize=0x%08lx) "
+       "returned an unexpected Status code: 0x%08lx (expected 0x%08lx)\n", 
+       ValueName->Buffer, ValueType, Buffer, BufferSize,
+       Status, ExpectedStatus);
+}
+
+static VOID
+Test_BeginTest(ULONG ValueType, PCWSTR Value,
+               PVOID Buffer, ULONG BufferSize,
+               ULONG Expected)
+{
+    PCWSTR Key = L"\\Registry\\Machine\\Software\\ApiTest";
+
+    UNICODE_STRING KeyName;
+    UNICODE_STRING ValueName;
+
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+
+    ULONG Disposition;
+
+    /* Initialization */
+    {
+        RtlInitUnicodeString(&KeyName, Key);
+
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL, NULL);
+
+        Status = NtCreateKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0,
+                             NULL, REG_OPTION_VOLATILE, &Disposition);
+
+        ok(NT_SUCCESS(Status), "NtCreateKey failed : 0x%08lx\n", Status);
+        if (!NT_SUCCESS(Status))
+        {
+            return;
+        }
+
+        if(Disposition != REG_CREATED_NEW_KEY)
+            printf("WARNING: The Registry key '%s' already existed.\n", Key);
+    }
+
+    RtlInitUnicodeString(&ValueName, Value);
+
+    /* Test 1: NULL / Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName, 
+                       ValueType, NULL, 0,
+                       STATUS_SUCCESS);        
+
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, 0);
+
+    ok(ValueName.Buffer == Value,
+       "ValueName.Buffer does not point to the expected string.\n");
+
+    /* Test 2: Not-NULL / Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName,
+                       ValueType, Buffer, 0,
+                       STATUS_SUCCESS);
+
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, 0);
+
+    /* Test 3: Not-NULL / Non-Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName,
+                       ValueType, Buffer, BufferSize,
+                       STATUS_SUCCESS);
+
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, BufferSize);
+
+    /* Test 4: NULL / Non-Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName,
+                       ValueType, NULL, BufferSize,
+                       Expected);
+
+    /* The previous call to NtSetValueKey is expected to fail.
+       The returned value should still match the previous content. */
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, BufferSize);
+
+    /* Test 5: INVALID / Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName,
+                       ValueType, (PVOID)0xBADBAD00, 0,
+                       STATUS_SUCCESS);
+
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, 0);
+
+    /* Test 5: INVALID / Non-Zero */
+    Test_NtSetValueKey(KeyHandle, &ValueName,
+                       ValueType, (PVOID)0xBADBAD00, BufferSize,
+                       STATUS_ACCESS_VIOLATION);
+
+    /* The previous call to NtSetValueKey is expected to fail.
+       The returned value should still match the previous content. */
+    Test_VerifyValueWritten(KeyHandle, &ValueName,
+                            ValueType, Buffer, 0);
+
+    /* Cleanup */
+    {
+        Status = NtFlushKey(KeyHandle);
+        ok(NT_SUCCESS(Status), "NtFlushKey failed : 0x%08lx\n", Status);
+
+        Status = NtDeleteKey(KeyHandle);
+        ok(NT_SUCCESS(Status), "NtDeleteKey failed : 0x%08lx\n", Status);
+
+        NtClose(KeyHandle);
+    }
+}
+
+START_TEST(NtSetValueKey)
+{
+    DWORD ValueContentDWord = 0x7E577E57; /* TESTTEST */
+    BYTE  ValueContentBinary[] = "BinaryValue";
+    WCHAR ValueContentString[] = L"StringValue";
+
+    /* TODO:
+     *  1. Test other parameter combinations
+     *  2. Test ther data types
+     */
+
+    Test_BeginTest(REG_DWORD, L"ValueDWord",
+                   &ValueContentDWord, sizeof(DWORD),
+                   STATUS_ACCESS_VIOLATION);
+    Test_BeginTest(REG_BINARY, L"ValueBinary",
+                   ValueContentBinary, sizeof(ValueContentBinary),
+                   STATUS_INVALID_PARAMETER);
+    Test_BeginTest(REG_SZ, L"ValueString",
+                   ValueContentString, sizeof(ValueContentString),
+                   STATUS_INVALID_PARAMETER);
+
+    /* TODO: Use a string with variables and
+     *  compare with the right expanded value. */
+    Test_BeginTest(REG_EXPAND_SZ, L"ValueExpandString",
+                   ValueContentString, sizeof(ValueContentString),
+                   STATUS_INVALID_PARAMETER);
+}
\ No newline at end of file
Index: apitests/ntdll/testlist.c
===================================================================
--- apitests/ntdll/testlist.c	(revision 59938)
+++ apitests/ntdll/testlist.c	(working copy)
@@ -10,6 +10,7 @@
 extern void func_NtProtectVirtualMemory(void);
 extern void func_NtQuerySystemEnvironmentValue(void);
 extern void func_NtSystemInformation(void);
+extern void func_NtSetValueKey(void);
 extern void func_RtlBitmap(void);
 extern void func_RtlDetermineDosPathNameType(void);
 extern void func_RtlDoesFileExists(void);
@@ -33,6 +34,7 @@
     { "NtProtectVirtualMemory",         func_NtProtectVirtualMemory },
     { "NtQuerySystemEnvironmentValue",  func_NtQuerySystemEnvironmentValue },
     { "NtSystemInformation",            func_NtSystemInformation },
+    { "NtSetValueKey",                  func_NtSetValueKey },
     { "RtlBitmapApi",                   func_RtlBitmap },
     { "RtlDetermineDosPathNameType",    func_RtlDetermineDosPathNameType },
     { "RtlDoesFileExists",              func_RtlDoesFileExists },
