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 <stddef.h> | |
6 | |
7 #include "base/strings/string16.h" | |
8 #include "base/test/test_reg_util_win.h" | |
9 #include "chrome_elf/nt_registry/nt_registry.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 namespace { | |
13 | |
14 void RegTestingRedirect(nt::ROOT_KEY key, | |
15 registry_util::RegistryOverrideManager& rom) { | |
16 base::string16 temp; | |
17 | |
18 if (key == nt::HKCU) { | |
19 rom.OverrideRegistry(HKEY_CURRENT_USER, &temp); | |
20 ::wcsncpy(nt::HKCU_override, temp.c_str(), nt::g_kRegMaxPathLen - 1); | |
21 } else if (key == nt::HKLM) { | |
22 rom.OverrideRegistry(HKEY_LOCAL_MACHINE, &temp); | |
23 ::wcsncpy(nt::HKLM_override, temp.c_str(), nt::g_kRegMaxPathLen - 1); | |
24 } | |
25 // nt::AUTO should not be passed into this function. | |
26 } | |
27 | |
28 void CancelRegTestingRedirect(nt::ROOT_KEY key) { | |
29 if (key == nt::HKCU) { | |
30 ::wcsncpy(nt::HKCU_override, L"", nt::g_kRegMaxPathLen - 1); | |
31 } else if (key == nt::HKLM) { | |
32 ::wcsncpy(nt::HKLM_override, L"", nt::g_kRegMaxPathLen - 1); | |
33 } | |
34 // nt::AUTO should not be passed into this function. | |
35 } | |
36 | |
37 //------------------------------------------------------------------------------ | |
38 // NT registry API tests | |
39 //------------------------------------------------------------------------------ | |
40 | |
41 TEST(NtRegistryTest, API) { | |
42 HANDLE key_handle; | |
43 const wchar_t* dword_val_name = L"DwordTestValue"; | |
44 DWORD dword_val = 1234; | |
45 const wchar_t* sz_val_name = L"SzTestValue"; | |
46 base::string16 sz_val = L"blah de blah de blahhhhh."; | |
47 const wchar_t* sz_val_name2 = L"SzTestValueEmpty"; | |
48 base::string16 sz_val2 = L""; | |
49 const wchar_t* multisz_val_name = L"SzmultiTestValue"; | |
50 std::vector<base::string16> multisz_val; | |
51 base::string16 multi1 = L"one"; | |
52 base::string16 multi2 = L"two"; | |
53 base::string16 multi3 = L"three"; | |
54 const wchar_t* multisz_val_name2 = L"SzmultiTestValueBad"; | |
55 base::string16 multi_empty = L""; | |
56 const wchar_t* sz_new_key_1 = L"test\\new\\subkey"; | |
57 const wchar_t* sz_new_key_2 = L"test\\new\\subkey\\blah\\"; | |
58 const wchar_t* sz_new_key_3 = L"\\test\\new\\subkey\\\\blah2"; | |
59 | |
60 // Set up registry override for this test. | |
61 registry_util::RegistryOverrideManager override_manager; | |
62 RegTestingRedirect(nt::HKCU, override_manager); | |
63 | |
64 // Create a temp key to play under. | |
65 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, | |
66 L"SOFTWARE\\Testing\\Chrome\\NTRegistry", | |
67 KEY_ALL_ACCESS, &key_handle)); | |
68 | |
69 // Exercise the supported getter & setter functions. | |
70 EXPECT_TRUE(nt::SetRegValueDWORD(key_handle, dword_val_name, dword_val)); | |
71 EXPECT_TRUE(nt::SetRegValueSZ(key_handle, sz_val_name, sz_val)); | |
72 EXPECT_TRUE(nt::SetRegValueSZ(key_handle, sz_val_name2, sz_val2)); | |
73 | |
74 DWORD get_dword = 0; | |
75 base::string16 get_sz; | |
76 EXPECT_TRUE(nt::QueryRegValueDWORD(key_handle, dword_val_name, &get_dword) && | |
77 get_dword == dword_val); | |
78 EXPECT_TRUE(nt::QueryRegValueSZ(key_handle, sz_val_name, &get_sz) && | |
79 get_sz.compare(sz_val) == 0); | |
80 EXPECT_TRUE(nt::QueryRegValueSZ(key_handle, sz_val_name2, &get_sz) && | |
81 get_sz.compare(sz_val2) == 0); | |
82 | |
83 multisz_val.push_back(multi1); | |
84 multisz_val.push_back(multi2); | |
85 multisz_val.push_back(multi3); | |
86 EXPECT_TRUE( | |
87 nt::SetRegValueMULTISZ(key_handle, multisz_val_name, multisz_val)); | |
88 multisz_val.clear(); | |
89 multisz_val.push_back(multi_empty); | |
90 EXPECT_TRUE( | |
91 nt::SetRegValueMULTISZ(key_handle, multisz_val_name2, multisz_val)); | |
92 multisz_val.clear(); | |
93 | |
94 EXPECT_TRUE( | |
95 nt::QueryRegValueMULTISZ(key_handle, multisz_val_name, &multisz_val)); | |
96 if (multisz_val.size() == 3) { | |
97 EXPECT_TRUE(multi1.compare(multisz_val.at(0)) == 0); | |
98 EXPECT_TRUE(multi2.compare(multisz_val.at(1)) == 0); | |
99 EXPECT_TRUE(multi3.compare(multisz_val.at(2)) == 0); | |
100 } else { | |
101 EXPECT_TRUE(false); | |
102 } | |
103 multisz_val.clear(); | |
104 | |
105 EXPECT_TRUE( | |
106 nt::QueryRegValueMULTISZ(key_handle, multisz_val_name2, &multisz_val)); | |
107 if (multisz_val.size() == 1) { | |
108 EXPECT_TRUE(multi_empty.compare(multisz_val.at(0)) == 0); | |
109 } else { | |
110 EXPECT_TRUE(false); | |
111 } | |
112 multisz_val.clear(); | |
113 | |
114 // Clean up | |
115 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
116 nt::CloseRegKey(key_handle); | |
117 | |
118 // More tests for CreateRegKey recursion. | |
119 ASSERT_TRUE( | |
120 nt::CreateRegKey(nt::HKCU, sz_new_key_1, KEY_ALL_ACCESS, nullptr)); | |
121 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, sz_new_key_1, KEY_ALL_ACCESS, | |
122 &key_handle, nullptr)); | |
123 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
124 nt::CloseRegKey(key_handle); | |
125 | |
126 ASSERT_TRUE( | |
127 nt::CreateRegKey(nt::HKCU, sz_new_key_2, KEY_ALL_ACCESS, nullptr)); | |
128 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, sz_new_key_2, KEY_ALL_ACCESS, | |
129 &key_handle, nullptr)); | |
130 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
131 nt::CloseRegKey(key_handle); | |
132 | |
133 ASSERT_TRUE( | |
134 nt::CreateRegKey(nt::HKCU, sz_new_key_3, KEY_ALL_ACCESS, nullptr)); | |
135 EXPECT_TRUE(nt::OpenRegKey(nt::HKCU, L"test\\new\\subkey\\blah2", | |
136 KEY_ALL_ACCESS, &key_handle, nullptr)); | |
137 EXPECT_TRUE(nt::DeleteRegKey(key_handle)); | |
138 nt::CloseRegKey(key_handle); | |
139 | |
140 ASSERT_TRUE(nt::CreateRegKey(nt::HKCU, nullptr, KEY_ALL_ACCESS, &key_handle)); | |
141 nt::CloseRegKey(key_handle); | |
142 | |
143 // Cancel registry override for this test. | |
144 CancelRegTestingRedirect(nt::HKCU); | |
145 } | |
146 | |
147 //------------------------------------------------------------------------------ | |
148 // WOW64 redirection tests | |
149 // | |
150 // - Only HKCU will be tested on the auto (try) bots. | |
151 // HKLM will be kept separate (and manual) for local testing only. | |
152 // | |
153 // NOTE: Currently no real WOW64 context testing, as building x86 projects | |
154 // during x64 builds is not currently supported for performance reasons. | |
155 // https://cs.chromium.org/chromium/src/build/toolchain/win/BUILD.gn?sq%3Dpackag e:chromium&l=314 | |
156 //------------------------------------------------------------------------------ | |
157 | |
158 // Utility function for the WOW64 redirection test suites. | |
159 // Note: Testing redirection through ADVAPI32 here as well, to get notice if | |
160 // expected behaviour changes! | |
161 // If |redirected_path| == nullptr, no redirection is expected in any case. | |
162 void DoRedirectTest(nt::ROOT_KEY nt_root_key, | |
163 const wchar_t* path, | |
164 const wchar_t* redirected_path OPTIONAL) { | |
165 HANDLE handle = INVALID_HANDLE_VALUE; | |
166 ACCESS_MASK access = KEY_WRITE | DELETE; | |
167 HKEY root_key = | |
168 (nt_root_key == nt::HKCU) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | |
169 | |
170 // Make sure clean before starting. | |
171 nt::DeleteRegKey(nt_root_key, nt::NONE, path); | |
172 if (redirected_path) | |
173 nt::DeleteRegKey(nt_root_key, nt::NONE, redirected_path); | |
174 | |
175 //---------------------------------------------------------------------------- | |
176 // No redirection through ADVAPI32 on straight x86 or x64. | |
177 base::win::RegKey key; | |
178 ASSERT_EQ(ERROR_SUCCESS, key.Create(root_key, path, access)); | |
179 ASSERT_TRUE(nt::OpenRegKey(nt_root_key, path, access, &handle, nullptr)); | |
180 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
181 nt::CloseRegKey(handle); | |
182 | |
183 #ifdef _WIN64 | |
184 //---------------------------------------------------------------------------- | |
185 // Try forcing WOW64 redirection on x64 through ADVAPI32. | |
186 base::win::RegKey wow64_key; | |
187 ASSERT_EQ(ERROR_SUCCESS, | |
188 wow64_key.Create(root_key, path, access | KEY_WOW64_32KEY)); | |
189 // Check path: | |
190 if (nt::OpenRegKey(nt_root_key, path, access, &handle, nullptr)) { | |
191 if (redirected_path) | |
192 ADD_FAILURE(); | |
193 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
194 nt::CloseRegKey(handle); | |
195 } else if (!redirected_path) { | |
196 // Should have succeeded. | |
197 ADD_FAILURE(); | |
198 } | |
199 if (redirected_path) { | |
200 // Check redirected path: | |
201 if (nt::OpenRegKey(nt_root_key, redirected_path, access, &handle, | |
202 nullptr)) { | |
203 if (!redirected_path) | |
204 ADD_FAILURE(); | |
205 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
206 nt::CloseRegKey(handle); | |
207 } else { | |
208 // Should have succeeded. | |
209 ADD_FAILURE(); | |
210 } | |
211 } | |
212 | |
213 //---------------------------------------------------------------------------- | |
214 // Try forcing WOW64 redirection on x64 through NTDLL. | |
215 ASSERT_TRUE( | |
216 nt::CreateRegKey(nt_root_key, path, access | KEY_WOW64_32KEY, nullptr)); | |
217 // Check path: | |
218 if (nt::OpenRegKey(nt_root_key, path, access, &handle, nullptr)) { | |
219 if (redirected_path) | |
220 ADD_FAILURE(); | |
221 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
222 nt::CloseRegKey(handle); | |
223 } else if (!redirected_path) { | |
224 // Should have succeeded. | |
225 ADD_FAILURE(); | |
226 } | |
227 if (redirected_path) { | |
228 // Check redirected path: | |
229 if (nt::OpenRegKey(nt_root_key, redirected_path, access, &handle, | |
230 nullptr)) { | |
231 if (!redirected_path) | |
232 ADD_FAILURE(); | |
233 ASSERT_TRUE(nt::DeleteRegKey(handle)); | |
234 nt::CloseRegKey(handle); | |
235 } else { | |
236 // Should have succeeded. | |
237 ADD_FAILURE(); | |
238 } | |
239 } | |
240 #endif // _WIN64 | |
241 } | |
242 | |
243 // Hard-coding array size to match nt_registry.cc. Easier to catch missing | |
244 // elements. | |
245 const wchar_t* classes_redirects[10] = { | |
246 L"SOFTWARE\\Classes\\CLSID\\chrome_testing", | |
247 L"SOFTWARE\\Classes\\WOW6432Node\\CLSID\\chrome_testing", | |
248 L"SOFTWARE\\Classes\\DirectShow\\chrome_testing", | |
249 L"SOFTWARE\\Classes\\WOW6432Node\\DirectShow\\chrome_testing", | |
250 L"SOFTWARE\\Classes\\Interface\\chrome_testing", | |
251 L"SOFTWARE\\Classes\\WOW6432Node\\Interface\\chrome_testing", | |
252 L"SOFTWARE\\Classes\\Media Type\\chrome_testing", | |
253 L"SOFTWARE\\Classes\\WOW6432Node\\Media Type\\chrome_testing", | |
254 L"SOFTWARE\\Classes\\MediaFoundation\\chrome_testing", | |
255 L"SOFTWARE\\Classes\\WOW6432Node\\MediaFoundation\\chrome_testing"}; | |
256 | |
257 // This test does not use a testing registry_util::RegistryOverrideManager. | |
258 // It requires Windows WOW64 redirection to take place, which would not | |
259 // happen with a testing redirection layer. | |
260 TEST(NtRegistryTest, Wow64RedirectionHKCU) { | |
261 size_t index = 0; | |
262 size_t array_size = sizeof(classes_redirects) / sizeof(classes_redirects[0]); | |
263 | |
264 // Using two elements for each loop. | |
265 while (index < array_size) { | |
266 DoRedirectTest(nt::HKCU, classes_redirects[index], | |
267 classes_redirects[index + 1]); | |
268 index += 2; | |
269 } | |
270 } | |
271 | |
272 // Hard-coding array size to match nt_registry.cc. Easier to catch missing | |
273 // elements. | |
274 const wchar_t* hklm_no_redirects[49] = { | |
275 L"SOFTWARE\\Classes\\chrome_testing", L"SOFTWARE\\Clients\\chrome_testing", | |
276 L"SOFTWARE\\Microsoft\\COM3\\chrome_testing", | |
277 L"SOFTWARE\\Microsoft\\Cryptography\\Calais\\Current\\chrome_testing", | |
278 L"SOFTWARE\\Microsoft\\Cryptography\\Calais\\Readers\\chrome_testing", | |
279 L"SOFTWARE\\Microsoft\\Cryptography\\Services\\chrome_testing", | |
280 L"SOFTWARE\\Microsoft\\CTF\\SystemShared\\chrome_testing", | |
281 L"SOFTWARE\\Microsoft\\CTF\\TIP\\chrome_testing", | |
282 L"SOFTWARE\\Microsoft\\DFS\\chrome_testing", | |
283 L"SOFTWARE\\Microsoft\\Driver Signing\\chrome_testing", | |
284 L"SOFTWARE\\Microsoft\\EnterpriseCertificates\\chrome_testing", | |
285 L"SOFTWARE\\Microsoft\\EventSystem\\chrome_testing", | |
286 L"SOFTWARE\\Microsoft\\MSMQ\\chrome_testing", | |
287 L"SOFTWARE\\Microsoft\\Non-Driver Signing\\chrome_testing", | |
288 L"SOFTWARE\\Microsoft\\Notepad\\DefaultFonts\\chrome_testing", | |
289 L"SOFTWARE\\Microsoft\\OLE\\chrome_testing", | |
290 L"SOFTWARE\\Microsoft\\RAS\\chrome_testing", | |
291 L"SOFTWARE\\Microsoft\\RPC\\chrome_testing", | |
292 L"SOFTWARE\\Microsoft\\SOFTWARE\\Microsoft\\Shared " | |
293 L"Tools\\MSInfo\\chrome_testing", | |
294 L"SOFTWARE\\Microsoft\\SystemCertificates\\chrome_testing", | |
295 L"SOFTWARE\\Microsoft\\TermServLicensing\\chrome_testing", | |
296 L"SOFTWARE\\Microsoft\\Transaction Server\\chrome_testing", | |
297 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome_testing", | |
298 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control " | |
299 L"Panel\\Cursors\\Schemes\\chrome_testing", | |
300 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers" | |
301 L"\\chrome_testing", | |
302 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\chrom" | |
303 L"e_testing", | |
304 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap\\chrome_" | |
305 L"testing", | |
306 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group " | |
307 L"Policy\\chrome_testing", | |
308 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\chrome_testing", | |
309 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers\\chrome_" | |
310 L"testing", | |
311 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\chrome_testing", | |
312 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Locations\\chrom" | |
313 L"e_testing", | |
314 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Console\\chrome_testing", | |
315 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDpi\\chrome_testing", | |
316 L"SOFTWARE\\Microsoft\\Windows " | |
317 L"NT\\CurrentVersion\\FontLink\\chrome_testing", | |
318 L"SOFTWARE\\Microsoft\\Windows " | |
319 L"NT\\CurrentVersion\\FontMapper\\chrome_testing", | |
320 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\chrome_testing", | |
321 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\\chrome_" | |
322 L"testing", | |
323 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Gre_initialize\\chrome_" | |
324 L"testing", | |
325 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution " | |
326 L"Options\\chrome_testing", | |
327 L"SOFTWARE\\Microsoft\\Windows " | |
328 L"NT\\CurrentVersion\\LanguagePack\\chrome_testing", | |
329 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\chrome_" | |
330 L"testing", | |
331 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\chrome_testing", | |
332 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports\\chrome_testing", | |
333 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\chrome_testing", | |
334 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\chrome_" | |
335 L"testing", | |
336 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time " | |
337 L"Zones\\chrome_testing", | |
338 L"SOFTWARE\\Policies\\chrome_testing", | |
339 L"SOFTWARE\\RegisteredApplications\\chrome_testing"}; | |
340 | |
341 // Run from administrator command prompt! | |
342 // Note: Disabled for automated testing (HKLM protection). Local testing only. | |
grt (UTC plus 2)
2016/09/20 10:39:55
the bots run tests as admin. can the HKLM tests ru
penny
2016/09/23 23:50:59
So I've previously been informed that we shouldn't
| |
343 TEST(NtRegistryTest, DISABLED_Wow64RedirectionHKLM) { | |
344 // 1) SOFTWARE is redirected. | |
345 DoRedirectTest(nt::HKLM, L"SOFTWARE\\chrome_testing", | |
346 L"SOFTWARE\\WOW6432Node\\chrome_testing"); | |
347 | |
348 // 2) Except some subkeys are not. | |
349 size_t index = 0; | |
350 size_t array_size = sizeof(hklm_no_redirects) / sizeof(hklm_no_redirects[0]); | |
351 while (index < array_size) { | |
352 DoRedirectTest(nt::HKLM, hklm_no_redirects[index], nullptr); | |
353 index++; | |
354 } | |
355 | |
356 // 3) But then some Classes subkeys are redirected. | |
357 index = 0; | |
358 array_size = sizeof(classes_redirects) / sizeof(classes_redirects[0]); | |
359 | |
360 // Using two elements for each loop. | |
361 while (index < array_size) { | |
362 DoRedirectTest(nt::HKLM, classes_redirects[index], | |
363 classes_redirects[index + 1]); | |
364 index += 2; | |
365 } | |
366 } | |
367 | |
368 //---------------------------------------------------------------------------- | |
369 } // namespace | |
OLD | NEW |