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