2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for NtSetValueKey
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
12 START_TEST(NtSetValueKey
)
15 HANDLE ParentKeyHandle
;
17 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"SOFTWARE\\ntdll-apitest-NtSetValueKey");
18 OBJECT_ATTRIBUTES ObjectAttributes
;
19 UNICODE_STRING ValueName
;
20 WCHAR Default
[] = L
"Default";
21 WCHAR Hello
[] = L
"Hello";
24 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo
;
25 ULONG PartialInfoLength
;
32 NTSTATUS StatusExisting
;
34 NTSTATUS StatusExisting2
;
38 { REG_NONE
, NULL
, 0, STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Empty REG_NONE value */
39 { REG_SZ
, Hello
, sizeof(Hello
), STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Regular string */
40 { REG_SZ
, Empty
, sizeof(Empty
), STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Empty string */
41 { REG_SZ
, NULL
, 0, STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Zero length */
42 { REG_SZ
, Hello
, 0, STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Zero length, non-null data */
43 { REG_SZ
, (PVOID
)(LONG_PTR
)-4, 0, STATUS_SUCCESS
, STATUS_SUCCESS
}, /* Zero length, kernel data */
44 { REG_SZ
, NULL
, 1, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
}, /* Non-zero length (odd), null data */
45 { REG_SZ
, NULL
, 2, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
}, /* Non-zero length (even), null data */
46 { REG_SZ
, NULL
, 4, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
}, /* CM_KEY_VALUE_SMALL, null data */
47 { REG_SZ
, NULL
, 5, STATUS_INVALID_PARAMETER
, STATUS_ACCESS_VIOLATION
, /* CM_KEY_VALUE_SMALL+1, null data */
48 STATUS_ACCESS_VIOLATION
, STATUS_INSUFFICIENT_RESOURCES
}, /* win7 */
49 { REG_SZ
, NULL
, 6, STATUS_INVALID_PARAMETER
, STATUS_ACCESS_VIOLATION
, /* CM_KEY_VALUE_SMALL+2, null data */
50 STATUS_ACCESS_VIOLATION
, STATUS_INSUFFICIENT_RESOURCES
}, /* win7 */
51 { REG_SZ
, NULL
, 0x7fff0000, STATUS_INVALID_PARAMETER
, STATUS_INSUFFICIENT_RESOURCES
, /* MI_USER_PROBE_ADDRESS, null data */
52 STATUS_INSUFFICIENT_RESOURCES
, STATUS_INSUFFICIENT_RESOURCES
}, /* win7 */
53 { REG_SZ
, NULL
, 0x7fff0001, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
, /* MI_USER_PROBE_ADDRESS+1, null data */
54 STATUS_INSUFFICIENT_RESOURCES
, STATUS_INSUFFICIENT_RESOURCES
}, /* win7 */
55 { REG_SZ
, NULL
, 0x7fffffff, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
, /* <2GB, null data */
56 STATUS_INVALID_PARAMETER
, STATUS_INVALID_PARAMETER
}, /* win7 */
57 { REG_SZ
, NULL
, 0x80000000, STATUS_ACCESS_VIOLATION
, STATUS_ACCESS_VIOLATION
, /* 2GB, null data */
58 STATUS_INVALID_PARAMETER
, STATUS_INVALID_PARAMETER
}, /* win7 */
59 { REG_BINARY
, NULL
, 5, STATUS_INVALID_PARAMETER
, STATUS_ACCESS_VIOLATION
, /* ROSTESTS-200 */
60 STATUS_ACCESS_VIOLATION
, STATUS_INSUFFICIENT_RESOURCES
}, /* win7 */
64 Status
= RtlOpenCurrentUser(READ_CONTROL
, &ParentKeyHandle
);
65 ok(Status
== STATUS_SUCCESS
, "RtlOpenCurrentUser returned %lx\n", Status
);
66 if (!NT_SUCCESS(Status
))
68 skip("No user key handle\n");
72 InitializeObjectAttributes(&ObjectAttributes
,
77 Status
= NtCreateKey(&KeyHandle
,
78 KEY_QUERY_VALUE
| KEY_SET_VALUE
| DELETE
,
84 ok(Status
== STATUS_SUCCESS
, "NtCreateKey returned %lx\n", Status
);
85 if (!NT_SUCCESS(Status
))
87 NtClose(ParentKeyHandle
);
88 skip("No key handle\n");
92 PartialInfoLength
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[128]);
93 PartialInfo
= HeapAlloc(GetProcessHeap(), 0, PartialInfoLength
);
94 if (PartialInfo
== NULL
)
96 NtDeleteKey(KeyHandle
);
98 NtClose(ParentKeyHandle
);
99 skip("No key handle\n");
103 for (i
= 0; i
< RTL_NUMBER_OF(Tests
); i
++)
108 /* Make sure it exists */
109 RtlInitUnicodeString(&ValueName
, L
"ExistingValue");
110 Status
= NtSetValueKey(KeyHandle
, &ValueName
, 0, REG_SZ
, Default
, sizeof(Default
));
111 ok(Status
== STATUS_SUCCESS
, "[%lu] NtSetValueKey failed with %lx", i
, Status
);
114 Status
= NtSetValueKey(KeyHandle
, &ValueName
, 0, Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
);
115 if (Status
== Tests
[i
].StatusExisting2
)
116 ok(Status
== Tests
[i
].StatusExisting
|| Status
== Tests
[i
].StatusExisting2
, "[%lu, %p, %lu] NtSetValueKey returned %lx, expected %lx or %lx\n",
117 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, Status
, Tests
[i
].StatusExisting
, Tests
[i
].StatusExisting2
);
119 ok(Status
== Tests
[i
].StatusExisting
, "[%lu, %p, %lu] NtSetValueKey returned %lx, expected %lx\n",
120 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, Status
, Tests
[i
].StatusExisting
);
123 RtlZeroMemory(PartialInfo
, PartialInfoLength
);
124 QueryStatus
= NtQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
, PartialInfo
, PartialInfoLength
, &ResultLength
);
125 ok(QueryStatus
== STATUS_SUCCESS
, "[%lu, %p, %lu] NtQueryValueKey failed with %lx\n",
126 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, QueryStatus
);
127 if (NT_SUCCESS(QueryStatus
))
129 if (NT_SUCCESS(Status
))
131 ok(PartialInfo
->TitleIndex
== 0, "[%lu, %p, %lu] TitleIndex = %lu\n",
132 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->TitleIndex
);
133 ok(PartialInfo
->Type
== Tests
[i
].Type
, "[%lu, %p, %lu] Type = %lu\n",
134 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->Type
);
135 ok(PartialInfo
->DataLength
== Tests
[i
].DataSize
, "[%lu, %p, %lu] DataLength = %lu\n",
136 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->DataLength
);
137 ok(!memcmp(PartialInfo
->Data
, Tests
[i
].Data
, Tests
[i
].DataSize
), "[%lu, %p, %lu] Data does not match set value\n",
138 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
);
142 ok(PartialInfo
->TitleIndex
== 0, "[%lu, %p, %lu] TitleIndex = %lu\n",
143 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->TitleIndex
);
144 ok(PartialInfo
->Type
== REG_SZ
, "[%lu, %p, %lu] Type = %lu\n",
145 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->Type
);
146 ok(PartialInfo
->DataLength
== sizeof(Default
), "[%lu, %p, %lu] DataLength = %lu\n",
147 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->DataLength
);
148 ok(!memcmp(PartialInfo
->Data
, Default
, sizeof(Default
)), "[%lu, %p, %lu] Data does not match default\n",
149 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
);
156 /* Make sure it doesn't exist */
157 RtlInitUnicodeString(&ValueName
, L
"NewValue");
158 Status
= NtDeleteValueKey(KeyHandle
, &ValueName
);
159 ok(Status
== STATUS_SUCCESS
|| Status
== STATUS_OBJECT_NAME_NOT_FOUND
,
160 "[%lu] NtDeleteValueKey failed with %lx", i
, Status
);
163 Status
= NtSetValueKey(KeyHandle
, &ValueName
, 0, Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
);
164 if (Tests
[i
].StatusNew2
)
165 ok(Status
== Tests
[i
].StatusNew
|| Status
== Tests
[i
].StatusNew2
, "[%lu, %p, %lu] NtSetValueKey returned %lx, expected %lx or %lx\n",
166 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, Status
, Tests
[i
].StatusNew
, Tests
[i
].StatusNew2
);
168 ok(Status
== Tests
[i
].StatusNew
, "[%lu, %p, %lu] NtSetValueKey returned %lx, expected %lx\n",
169 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, Status
, Tests
[i
].StatusNew
);
172 RtlZeroMemory(PartialInfo
, PartialInfoLength
);
173 QueryStatus
= NtQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
, PartialInfo
, PartialInfoLength
, &ResultLength
);
174 if (NT_SUCCESS(Status
))
176 ok(QueryStatus
== STATUS_SUCCESS
, "[%lu, %p, %lu] NtQueryValueKey failed with %lx\n",
177 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, QueryStatus
);
178 if (NT_SUCCESS(QueryStatus
))
180 ok(PartialInfo
->TitleIndex
== 0, "[%lu, %p, %lu] TitleIndex = %lu\n",
181 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->TitleIndex
);
182 ok(PartialInfo
->Type
== Tests
[i
].Type
, "[%lu, %p, %lu] Type = %lu\n",
183 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->Type
);
184 ok(PartialInfo
->DataLength
== Tests
[i
].DataSize
, "[%lu, %p, %lu] DataLength = %lu\n",
185 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, PartialInfo
->DataLength
);
186 ok(!memcmp(PartialInfo
->Data
, Tests
[i
].Data
, Tests
[i
].DataSize
), "[%lu, %p, %lu] Data does not match set value\n",
187 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
);
192 ok(QueryStatus
== STATUS_OBJECT_NAME_NOT_FOUND
, "[%lu, %p, %lu] QueryStatus = %lx\n",
193 Tests
[i
].Type
, Tests
[i
].Data
, Tests
[i
].DataSize
, QueryStatus
);
197 HeapFree(GetProcessHeap(), 0, PartialInfo
);
198 Status
= NtDeleteKey(KeyHandle
);
199 ok(Status
== STATUS_SUCCESS
, "NtDeleteKey returned %lx\n", Status
);
200 Status
= NtClose(KeyHandle
);
201 ok(Status
== STATUS_SUCCESS
, "NtClose returned %lx\n", Status
);
202 Status
= NtClose(ParentKeyHandle
);
203 ok(Status
== STATUS_SUCCESS
, "NtClose returned %lx\n", Status
);