OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome_elf/nt_registry/nt_registry.h" | |
6 | |
7 #include <windows.h> | |
8 #include <rpc.h> | |
9 #include <stddef.h> | |
10 | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace { | |
14 | |
15 //------------------------------------------------------------------------------ | |
16 // WOW64 redirection tests | |
17 // | |
18 // - Only HKCU will be tested on the auto (try) bots. | |
19 // HKLM will be kept separate (and manual) for local testing only. | |
20 // | |
21 // NOTE: Currently no real WOW64 context testing, as building x86 projects | |
22 // during x64 builds is not currently supported for performance reasons. | |
23 // https://cs.chromium.org/chromium/src/build/toolchain/win/BUILD.gn?sq%3Dpackag e:chromium&l=314 | |
24 //------------------------------------------------------------------------------ | |
25 | |
26 // Utility function for the WOW64 redirection test suites. | |
27 // Note: Testing redirection through ADVAPI32 here as well, to get notice if | |
28 // expected behaviour changes! | |
29 // If |redirected_path| == nullptr, no redirection is expected in any case. | |
30 void DoRedirectTest(nt::ROOT_KEY nt_root_key, | |
31 const wchar_t* path, | |
32 const wchar_t* redirected_path OPTIONAL) { | |
33 HANDLE handle = INVALID_HANDLE_VALUE; | |
34 HKEY key_handle = nullptr; | |
35 constexpr ACCESS_MASK kAccess = KEY_WRITE | DELETE; | |
36 const HKEY root_key = | |
37 (nt_root_key == nt::HKCU) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | |
38 | |
39 // Make sure clean before starting. | |
40 nt::DeleteRegKey(nt_root_key, nt::NONE, path); | |
41 if (redirected_path) | |
42 nt::DeleteRegKey(nt_root_key, nt::NONE, redirected_path); | |
43 | |
44 //---------------------------------------------------------------------------- | |
45 // No redirection through ADVAPI32 on straight x86 or x64. | |
46 ASSERT_EQ(ERROR_SUCCESS, | |
47 RegCreateKeyExW(root_key, path, 0, nullptr, REG_OPTION_NON_VOLATILE, | |
48 kAccess, nullptr, &key_handle, nullptr)); | |
49 ASSERT_EQ(ERROR_SUCCESS, RegCloseKey(key_handle)); | |
50 ASSERT_TRUE(nt::OpenRegKey(nt_root_key, path, kAccess, &handle, nullptr)); | |
51 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
52 nt::CloseRegKey(handle); | |
53 | |
54 #ifdef _WIN64 | |
55 //---------------------------------------------------------------------------- | |
56 // Try forcing WOW64 redirection on x64 through ADVAPI32. | |
57 ASSERT_EQ(ERROR_SUCCESS, | |
58 RegCreateKeyExW(root_key, path, 0, nullptr, REG_OPTION_NON_VOLATILE, | |
59 kAccess | KEY_WOW64_32KEY, nullptr, &key_handle, | |
60 nullptr)); | |
61 ASSERT_EQ(ERROR_SUCCESS, RegCloseKey(key_handle)); | |
62 // Check path: | |
63 if (nt::OpenRegKey(nt_root_key, path, kAccess, &handle, nullptr)) { | |
64 if (redirected_path) | |
65 ADD_FAILURE(); | |
66 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
67 nt::CloseRegKey(handle); | |
68 } else if (!redirected_path) { | |
69 // Should have succeeded. | |
70 ADD_FAILURE(); | |
71 } | |
72 if (redirected_path) { | |
73 // Check redirected path: | |
74 if (nt::OpenRegKey(nt_root_key, redirected_path, kAccess, &handle, | |
75 nullptr)) { | |
76 if (!redirected_path) | |
77 ADD_FAILURE(); | |
78 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
79 nt::CloseRegKey(handle); | |
80 } else { | |
81 // Should have succeeded. | |
82 ADD_FAILURE(); | |
83 } | |
84 } | |
85 | |
86 //---------------------------------------------------------------------------- | |
87 // Try forcing WOW64 redirection on x64 through NTDLL. | |
88 ASSERT_TRUE( | |
89 nt::CreateRegKey(nt_root_key, path, kAccess | KEY_WOW64_32KEY, nullptr)); | |
90 // Check path: | |
91 if (nt::OpenRegKey(nt_root_key, path, kAccess, &handle, nullptr)) { | |
92 if (redirected_path) | |
93 ADD_FAILURE(); | |
94 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
95 nt::CloseRegKey(handle); | |
96 } else if (!redirected_path) { | |
97 // Should have succeeded. | |
98 ADD_FAILURE(); | |
99 } | |
100 if (redirected_path) { | |
101 // Check redirected path: | |
102 if (nt::OpenRegKey(nt_root_key, redirected_path, kAccess, &handle, | |
103 nullptr)) { | |
104 if (!redirected_path) | |
105 ADD_FAILURE(); | |
106 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
107 nt::CloseRegKey(handle); | |
108 } else { | |
109 // Should have succeeded. | |
110 ADD_FAILURE(); | |
111 } | |
112 } | |
113 #endif // _WIN64 | |
114 } | |
115 | |
116 // These test reg paths match |kClassesSubtree| in nt_registry.cc. | |
117 constexpr const wchar_t* kClassesRedirects[] = { | |
118 L"SOFTWARE\\Classes\\CLSID\\chrome_testing", | |
119 L"SOFTWARE\\Classes\\WOW6432Node\\CLSID\\chrome_testing", | |
120 L"SOFTWARE\\Classes\\DirectShow\\chrome_testing", | |
121 L"SOFTWARE\\Classes\\WOW6432Node\\DirectShow\\chrome_testing", | |
122 L"SOFTWARE\\Classes\\Interface\\chrome_testing", | |
123 L"SOFTWARE\\Classes\\WOW6432Node\\Interface\\chrome_testing", | |
124 L"SOFTWARE\\Classes\\Media Type\\chrome_testing", | |
125 L"SOFTWARE\\Classes\\WOW6432Node\\Media Type\\chrome_testing", | |
126 L"SOFTWARE\\Classes\\MediaFoundation\\chrome_testing", | |
127 L"SOFTWARE\\Classes\\WOW6432Node\\MediaFoundation\\chrome_testing"}; | |
128 | |
129 static_assert((_countof(kClassesRedirects) & 0x01) == 0, | |
130 "Must have an even number of kClassesRedirects."); | |
131 | |
132 // This test does NOT use NtRegistryTest class. It requires Windows WOW64 | |
133 // redirection to take place, which would not happen with a testing redirection | |
134 // layer. | |
135 TEST(NtRegistryTestRedirection, Wow64RedirectionHKCU) { | |
136 // Using two elements for each loop. | |
137 for (size_t index = 0; index < _countof(kClassesRedirects); index += 2) { | |
138 DoRedirectTest(nt::HKCU, kClassesRedirects[index], | |
139 kClassesRedirects[index + 1]); | |
140 } | |
141 } | |
142 | |
143 // These test reg paths match |kHklmSoftwareSubtree| in nt_registry.cc. | |
144 constexpr const wchar_t* kHKLMNoRedirects[] = { | |
145 L"SOFTWARE\\Classes\\chrome_testing", L"SOFTWARE\\Clients\\chrome_testing", | |
146 L"SOFTWARE\\Microsoft\\COM3\\chrome_testing", | |
147 L"SOFTWARE\\Microsoft\\Cryptography\\Calais\\Current\\chrome_testing", | |
148 L"SOFTWARE\\Microsoft\\Cryptography\\Calais\\Readers\\chrome_testing", | |
149 L"SOFTWARE\\Microsoft\\Cryptography\\Services\\chrome_testing", | |
150 L"SOFTWARE\\Microsoft\\CTF\\SystemShared\\chrome_testing", | |
151 L"SOFTWARE\\Microsoft\\CTF\\TIP\\chrome_testing", | |
152 L"SOFTWARE\\Microsoft\\DFS\\chrome_testing", | |
153 L"SOFTWARE\\Microsoft\\Driver Signing\\chrome_testing", | |
154 L"SOFTWARE\\Microsoft\\EnterpriseCertificates\\chrome_testing", | |
155 L"SOFTWARE\\Microsoft\\EventSystem\\chrome_testing", | |
156 L"SOFTWARE\\Microsoft\\MSMQ\\chrome_testing", | |
157 L"SOFTWARE\\Microsoft\\Non-Driver Signing\\chrome_testing", | |
158 L"SOFTWARE\\Microsoft\\Notepad\\DefaultFonts\\chrome_testing", | |
159 L"SOFTWARE\\Microsoft\\OLE\\chrome_testing", | |
160 L"SOFTWARE\\Microsoft\\RAS\\chrome_testing", | |
161 L"SOFTWARE\\Microsoft\\RPC\\chrome_testing", | |
162 L"SOFTWARE\\Microsoft\\SOFTWARE\\Microsoft\\Shared " | |
163 L"Tools\\MSInfo\\chrome_testing", | |
164 L"SOFTWARE\\Microsoft\\SystemCertificates\\chrome_testing", | |
165 L"SOFTWARE\\Microsoft\\TermServLicensing\\chrome_testing", | |
166 L"SOFTWARE\\Microsoft\\Transaction Server\\chrome_testing", | |
167 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App " | |
168 L"Paths\\chrome_testing", | |
169 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control " | |
170 L"Panel\\Cursors\\Schemes\\chrome_testing", | |
171 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers" | |
172 L"\\chrome_testing", | |
173 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons" | |
174 L"\\chrome_testing", | |
175 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap" | |
176 L"\\chrome_testing", | |
177 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group " | |
178 L"Policy\\chrome_testing", | |
179 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\chrome_testing", | |
180 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers" | |
181 L"\\chrome_testing", | |
182 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\chrome_testing", | |
183 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Locations" | |
184 L"\\chrome_testing", | |
185 L"SOFTWARE\\Microsoft\\Windows " | |
186 L"NT\\CurrentVersion\\Console\\chrome_testing", | |
187 L"SOFTWARE\\Microsoft\\Windows " | |
188 L"NT\\CurrentVersion\\FontDpi\\chrome_testing", | |
189 L"SOFTWARE\\Microsoft\\Windows " | |
190 L"NT\\CurrentVersion\\FontLink\\chrome_testing", | |
191 L"SOFTWARE\\Microsoft\\Windows " | |
192 L"NT\\CurrentVersion\\FontMapper\\chrome_testing", | |
193 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\chrome_testing", | |
194 L"SOFTWARE\\Microsoft\\Windows " | |
195 L"NT\\CurrentVersion\\FontSubstitutes\\chrome_testing", | |
196 L"SOFTWARE\\Microsoft\\Windows " | |
197 L"NT\\CurrentVersion\\Gre_initialize\\chrome_testing", | |
198 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution " | |
199 L"Options\\chrome_testing", | |
200 L"SOFTWARE\\Microsoft\\Windows " | |
201 L"NT\\CurrentVersion\\LanguagePack\\chrome_testing", | |
202 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards" | |
203 L"\\chrome_testing", | |
204 L"SOFTWARE\\Microsoft\\Windows " | |
205 L"NT\\CurrentVersion\\Perflib\\chrome_testing", | |
206 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports\\chrome_testing", | |
207 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\chrome_testing", | |
208 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList" | |
209 L"\\chrome_testing", | |
210 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time " | |
211 L"Zones\\chrome_testing", | |
212 L"SOFTWARE\\Policies\\chrome_testing", | |
213 L"SOFTWARE\\RegisteredApplications\\chrome_testing"}; | |
214 | |
215 // Run from administrator command prompt! | |
216 // Note: Disabled for automated testing (HKLM protection). Local testing | |
217 // only. | |
218 // | |
219 // This test does NOT use NtRegistryTest class. It requires Windows WOW64 | |
220 // redirection to take place, which would not happen with a testing redirection | |
221 // layer. | |
222 TEST(NtRegistryTestRedirection, DISABLED_Wow64RedirectionHKLM) { | |
223 // 1) SOFTWARE is redirected. | |
224 DoRedirectTest(nt::HKLM, L"SOFTWARE\\chrome_testing", | |
225 L"SOFTWARE\\WOW6432Node\\chrome_testing"); | |
226 | |
227 // 2) Except some subkeys are not. | |
228 for (size_t index = 0; index < _countof(kHKLMNoRedirects); ++index) { | |
229 DoRedirectTest(nt::HKLM, kHKLMNoRedirects[index], nullptr); | |
230 } | |
231 | |
232 // 3) But then some Classes subkeys are redirected. | |
233 // Using two elements for each loop. | |
234 for (size_t index = 0; index < _countof(kClassesRedirects); index += 2) { | |
235 DoRedirectTest(nt::HKLM, kClassesRedirects[index], | |
236 kClassesRedirects[index + 1]); | |
237 } | |
238 | |
239 // 4) And just make sure other Classes subkeys are shared. | |
240 DoRedirectTest(nt::HKLM, L"SOFTWARE\\Classes\\chrome_testing", nullptr); | |
241 } | |
242 | |
243 //------------------------------------------------------------------------------ | |
244 // NtRegistryTest class | |
245 // | |
246 // Only use this class for tests that need testing registry redirection. | |
247 //------------------------------------------------------------------------------ | |
248 | |
249 constexpr wchar_t kTempTestKeys[] = L"SOFTWARE\\Chromium\\NtRegistryTestKeys\\"; | |
250 | |
251 class NtRegistryTest : public testing::Test { | |
252 protected: | |
253 static void SetUpTestCase() { NtRegDeleteStaleTestKeys(); } | |
254 | |
255 NtRegistryTest() { | |
256 NtRegTestingRedirect(nt::HKCU); | |
257 NtRegTestingRedirect(nt::HKLM); | |
258 } | |
259 | |
260 ~NtRegistryTest() override { | |
261 CancelNtRegTestingRedirect(nt::HKCU); | |
262 CancelNtRegTestingRedirect(nt::HKLM); | |
263 } | |
264 | |
265 private: | |
266 static void NtRegDeleteStaleTestKeys() { | |
267 HKEY key = nullptr; | |
268 | |
269 // Only open the key if it already exists. | |
270 if (RegOpenKeyExW(HKEY_CURRENT_USER, kTempTestKeys, 0, KEY_ALL_ACCESS, | |
271 &key) != ERROR_SUCCESS) | |
272 return; | |
273 | |
274 std::vector<std::wstring> to_delete; | |
275 DWORD index = 0; | |
276 DWORD name_size = 0; | |
277 wchar_t key_name[nt::g_kRegMaxPathLen + 1] = {}; | |
278 FILETIME last_write_time = {}; | |
279 LONG status = ERROR_GEN_FAILURE; | |
280 // Get the current system time. | |
281 FILETIME current = {}; | |
282 GetSystemTimeAsFileTime(¤t); | |
283 ULONGLONG current_ticks = | |
284 (static_cast<ULONGLONG>(current.dwHighDateTime) << 32) + | |
285 current.dwLowDateTime; | |
286 | |
287 // Collect the names of all subkeys that have not been modified in at least | |
288 // 12 hours. Delete them after enumeration is done. | |
289 do { | |
290 // RegEnumKeyExW wants the size of the buffer in chars, including null. | |
291 name_size = _countof(key_name); | |
292 status = RegEnumKeyExW(key, index, key_name, &name_size, nullptr, nullptr, | |
293 nullptr, &last_write_time); | |
294 if (status == ERROR_SUCCESS) { | |
295 ULONGLONG key_ticks = | |
296 (static_cast<ULONGLONG>(last_write_time.dwHighDateTime) << 32) + | |
297 last_write_time.dwLowDateTime; | |
298 ULONGLONG diffInSecs = ((current_ticks - key_ticks) / 10000) / 1000; | |
299 if (diffInSecs > (60 * 60 * 12)) | |
300 to_delete.emplace_back(key_name); | |
grt (UTC plus 2)
2016/09/30 09:32:17
(key_name, name_size)? this avoids an extra strlen
| |
301 } | |
302 ++index; | |
303 } while (status != ERROR_NO_MORE_ITEMS); | |
304 | |
305 // Best effort. If any tree deletion fails, just keep going. | |
306 for (const auto& subkey_name : to_delete) | |
307 RegDeleteTreeW(key, subkey_name.c_str()); | |
308 | |
309 RegCloseKey(key); | |
310 } | |
311 | |
312 void NtRegTestingRedirect(nt::ROOT_KEY key) { | |
313 ASSERT_TRUE(key != nt::AUTO); | |
grt (UTC plus 2)
2016/09/30 09:32:17
ASSERT_NE
| |
314 | |
315 UUID uuid = {}; | |
316 RPC_STATUS status = UuidCreateSequential(&uuid); | |
317 if (status != RPC_S_OK && status != RPC_S_UUID_NO_ADDRESS) | |
318 return; | |
319 RPC_WSTR guid = nullptr; | |
320 if (UuidToStringW(&uuid, &guid) != RPC_S_OK) | |
321 return; | |
322 | |
323 std::wstring temp_path = kTempTestKeys; | |
324 temp_path.append(reinterpret_cast<wchar_t*>(guid)); | |
325 RpcStringFreeW(&guid); | |
326 | |
327 if (key == nt::HKCU) { | |
328 ASSERT_TRUE(nt::SetTestingOverride(key, temp_path)); | |
329 override_key_hkcu_ = temp_path; | |
330 } else if (key == nt::HKLM) { | |
331 ASSERT_TRUE(nt::SetTestingOverride(key, temp_path)); | |
332 override_key_hklm_ = temp_path; | |
333 } | |
334 } | |
335 | |
336 void CancelNtRegTestingRedirect(nt::ROOT_KEY key) { | |
337 ASSERT_TRUE(key != nt::AUTO); | |
grt (UTC plus 2)
2016/09/30 09:32:17
ASSERT_NE
| |
338 | |
339 std::wstring temp_path = L""; | |
340 nt::GetTestingOverride(nt::HKCU, &temp_path); | |
341 | |
342 if (key == nt::HKCU) { | |
343 ASSERT_TRUE(nt::SetTestingOverride(key, temp_path)); | |
344 RegDeleteTreeW(HKEY_CURRENT_USER, override_key_hkcu_.c_str()); | |
345 override_key_hkcu_.clear(); | |
346 } else if (key == nt::HKLM) { | |
347 ASSERT_TRUE(nt::SetTestingOverride(key, temp_path)); | |
348 RegDeleteTreeW(HKEY_CURRENT_USER, override_key_hklm_.c_str()); | |
349 override_key_hklm_.clear(); | |
350 } | |
351 } | |
352 | |
353 std::wstring override_key_hkcu_; | |
354 std::wstring override_key_hklm_; | |
355 }; | |
356 | |
357 //------------------------------------------------------------------------------ | |
358 // NT registry API tests | |
359 //------------------------------------------------------------------------------ | |
360 | |
361 TEST_F(NtRegistryTest, API_DWORD) { | |
362 HANDLE key_handle; | |
363 const wchar_t* dword_val_name = L"DwordTestValue"; | |
364 DWORD dword_val = 1234; | |
365 | |
366 // Create a subkey to play under. | |
367 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, L"NTRegistry\\dword", KEY_ALL_ACCESS, | |
368 &key_handle)); | |
369 ASSERT_NE(key_handle, INVALID_HANDLE_VALUE); | |
370 ASSERT_NE(key_handle, nullptr); | |
371 | |
372 DWORD get_dword = 0; | |
373 EXPECT_FALSE(nt::QueryRegValueDWORD(key_handle, dword_val_name, &get_dword)); | |
374 | |
375 // Set | |
376 EXPECT_TRUE(nt::SetRegValueDWORD(key_handle, dword_val_name, dword_val)); | |
377 | |
378 // Get | |
379 EXPECT_TRUE(nt::QueryRegValueDWORD(key_handle, dword_val_name, &get_dword)); | |
380 EXPECT_TRUE(get_dword == dword_val); | |
381 | |
382 // Clean up | |
383 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
384 nt::CloseRegKey(key_handle); | |
385 } | |
386 | |
387 TEST_F(NtRegistryTest, API_SZ) { | |
388 HANDLE key_handle; | |
389 const wchar_t* sz_val_name = L"SzTestValue"; | |
390 std::wstring sz_val = L"blah de blah de blahhhhh."; | |
391 const wchar_t* sz_val_name2 = L"SzTestValueEmpty"; | |
392 std::wstring sz_val2 = L""; | |
393 | |
394 // Create a subkey to play under. | |
395 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, L"NTRegistry\\sz", KEY_ALL_ACCESS, | |
396 &key_handle)); | |
397 ASSERT_NE(key_handle, INVALID_HANDLE_VALUE); | |
398 ASSERT_NE(key_handle, nullptr); | |
399 | |
400 std::wstring get_sz; | |
401 EXPECT_FALSE(nt::QueryRegValueSZ(key_handle, sz_val_name, &get_sz)); | |
402 | |
403 // Set | |
404 EXPECT_TRUE(nt::SetRegValueSZ(key_handle, sz_val_name, sz_val)); | |
405 EXPECT_TRUE(nt::SetRegValueSZ(key_handle, sz_val_name2, sz_val2)); | |
406 | |
407 // Get | |
408 EXPECT_TRUE(nt::QueryRegValueSZ(key_handle, sz_val_name, &get_sz)); | |
409 EXPECT_TRUE(get_sz.compare(sz_val) == 0); | |
410 EXPECT_TRUE(nt::QueryRegValueSZ(key_handle, sz_val_name2, &get_sz)); | |
411 EXPECT_TRUE(get_sz.compare(sz_val2) == 0); | |
412 | |
413 // Clean up | |
414 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
415 nt::CloseRegKey(key_handle); | |
416 } | |
417 | |
418 TEST_F(NtRegistryTest, API_MULTISZ) { | |
419 HANDLE key_handle; | |
420 const wchar_t* multisz_val_name = L"SzmultiTestValue"; | |
421 std::vector<std::wstring> multisz_val; | |
422 std::wstring multi1 = L"one"; | |
423 std::wstring multi2 = L"two"; | |
424 std::wstring multi3 = L"three"; | |
425 const wchar_t* multisz_val_name2 = L"SzmultiTestValueBad"; | |
426 std::wstring multi_empty = L""; | |
427 | |
428 // Create a subkey to play under. | |
429 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, L"NTRegistry\\multisz", KEY_ALL_ACCESS, | |
430 &key_handle)); | |
431 ASSERT_NE(key_handle, INVALID_HANDLE_VALUE); | |
432 ASSERT_NE(key_handle, nullptr); | |
433 | |
434 multisz_val.push_back(multi1); | |
435 multisz_val.push_back(multi2); | |
436 multisz_val.push_back(multi3); | |
437 // Set | |
438 EXPECT_TRUE( | |
439 nt::SetRegValueMULTISZ(key_handle, multisz_val_name, multisz_val)); | |
440 multisz_val.clear(); | |
441 multisz_val.push_back(multi_empty); | |
442 // Set | |
443 EXPECT_TRUE( | |
444 nt::SetRegValueMULTISZ(key_handle, multisz_val_name2, multisz_val)); | |
445 multisz_val.clear(); | |
446 | |
447 // Get | |
448 EXPECT_TRUE( | |
449 nt::QueryRegValueMULTISZ(key_handle, multisz_val_name, &multisz_val)); | |
450 if (multisz_val.size() == 3) { | |
451 EXPECT_TRUE(multi1.compare(multisz_val.at(0)) == 0); | |
452 EXPECT_TRUE(multi2.compare(multisz_val.at(1)) == 0); | |
453 EXPECT_TRUE(multi3.compare(multisz_val.at(2)) == 0); | |
454 } else { | |
455 EXPECT_TRUE(false); | |
456 } | |
457 multisz_val.clear(); | |
458 | |
459 // Get | |
460 EXPECT_TRUE( | |
461 nt::QueryRegValueMULTISZ(key_handle, multisz_val_name2, &multisz_val)); | |
462 if (multisz_val.size() == 1) { | |
463 EXPECT_TRUE(multi_empty.compare(multisz_val.at(0)) == 0); | |
464 } else { | |
465 EXPECT_TRUE(false); | |
466 } | |
467 multisz_val.clear(); | |
468 | |
469 // Clean up | |
470 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
471 nt::CloseRegKey(key_handle); | |
472 } | |
473 | |
474 TEST_F(NtRegistryTest, CreateRegKeyRecursion) { | |
475 HANDLE key_handle; | |
476 const wchar_t* sz_new_key_1 = L"test1\\new\\subkey"; | |
477 const wchar_t* sz_new_key_2 = L"test2\\new\\subkey\\blah\\"; | |
478 const wchar_t* sz_new_key_3 = L"\\test3\\new\\subkey\\\\blah2"; | |
479 | |
480 // Tests for CreateRegKey recursion. | |
481 ASSERT_TRUE( | |
482 nt::CreateRegKey(nt::HKCU, sz_new_key_1, KEY_ALL_ACCESS, nullptr)); | |
483 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, sz_new_key_1, KEY_ALL_ACCESS, | |
484 &key_handle, nullptr)); | |
485 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
486 nt::CloseRegKey(key_handle); | |
487 | |
488 ASSERT_TRUE( | |
489 nt::CreateRegKey(nt::HKCU, sz_new_key_2, KEY_ALL_ACCESS, nullptr)); | |
490 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, sz_new_key_2, KEY_ALL_ACCESS, | |
491 &key_handle, nullptr)); | |
492 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
493 nt::CloseRegKey(key_handle); | |
494 | |
495 ASSERT_TRUE( | |
496 nt::CreateRegKey(nt::HKCU, sz_new_key_3, KEY_ALL_ACCESS, nullptr)); | |
497 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, L"test3\\new\\subkey\\blah2", | |
498 KEY_ALL_ACCESS, &key_handle, nullptr)); | |
499 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
500 nt::CloseRegKey(key_handle); | |
501 | |
502 // Subkey path can be null. | |
503 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, nullptr, KEY_ALL_ACCESS, &key_handle)); | |
504 ASSERT_NE(key_handle, INVALID_HANDLE_VALUE); | |
505 ASSERT_NE(key_handle, nullptr); | |
506 nt::CloseRegKey(key_handle); | |
507 } | |
508 | |
509 } // namespace | |
OLD | NEW |