Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: chrome_elf/nt_registry/nt_registry_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698