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

Side by Side Diff: setup/setup_google_update_unittest.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « setup/setup_google_update.cc ('k') | setup/setup_metrics.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2007-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include <windows.h>
17 #include <msi.h>
18 #include <atlpath.h>
19 #include "base/scoped_ptr.h"
20 #include "omaha/base/app_util.h"
21 #include "omaha/base/atlregmapex.h"
22 #include "omaha/base/omaha_version.h"
23 #include "omaha/base/file.h"
24 #include "omaha/base/path.h"
25 #include "omaha/base/time.h"
26 #include "omaha/base/utils.h"
27 #include "omaha/base/vistautil.h"
28 #include "omaha/common/config_manager.h"
29 #include "omaha/common/const_cmd_line.h"
30 #include "omaha/common/const_goopdate.h"
31 #include "omaha/common/scheduled_task_utils.h"
32 #include "omaha/setup/msi_test_utils.h"
33 #include "omaha/setup/setup_google_update.h"
34 #include "omaha/testing/unit_test.h"
35
36 namespace omaha {
37
38 namespace {
39
40 const TCHAR kMsiInstallRegValue[] = _T("MsiStubRun");
41 const TCHAR kMsiUninstallKey[] =
42 _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\")
43 _T("Uninstall\\{A92DAB39-4E2C-4304-9AB6-BC44E68B55E2}");
44 const TCHAR kRunKey[] =
45 _T("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run");
46
47 const TCHAR* const kAppId1 = _T("{B7E61EF9-AAE5-4cdf-A2D3-E4C8DF975145}");
48 const TCHAR* const kAppId2 = _T("{35F1A986-417D-4039-8718-781DD418232A}");
49
50 const TCHAR kRegistryHiveOverrideRootInHklm[] =
51 _T("HKLM\\Software\\") _T(SHORT_COMPANY_NAME_ANSI)
52 _T("\\") _T(PRODUCT_NAME_ANSI)
53 _T("\\UnitTest\\");
54
55 // Copies the shell and DLLs that FinishInstall needs.
56 // Does not replace files if they already exist.
57 void CopyFilesRequiredByFinishInstall(bool is_machine, const CString& version) {
58 const CString omaha_path = is_machine ?
59 GetGoogleUpdateMachinePath() : GetGoogleUpdateUserPath();
60 const CString expected_shell_path =
61 ConcatenatePath(omaha_path, kOmahaShellFileName);
62 const CString version_path = ConcatenatePath(omaha_path, version);
63
64 ASSERT_SUCCEEDED(CreateDir(omaha_path, NULL));
65 ASSERT_SUCCEEDED(File::Copy(
66 ConcatenatePath(app_util::GetCurrentModuleDirectory(),
67 kOmahaShellFileName),
68 expected_shell_path,
69 false));
70
71 ASSERT_SUCCEEDED(CreateDir(version_path, NULL));
72
73 const TCHAR* files[] = {kOmahaDllName,
74 kHelperInstallerName,
75 // TODO(omaha3): Enable once this is being built.
76 #if 0
77 _T("GoopdateBho.dll"),
78 #endif
79 UPDATE_PLUGIN_FILENAME};
80 for (size_t i = 0; i < arraysize(files); ++i) {
81 ASSERT_SUCCEEDED(File::Copy(
82 ConcatenatePath(app_util::GetCurrentModuleDirectory(),
83 files[i]),
84 ConcatenatePath(version_path, files[i]),
85 false));
86 }
87 }
88
89 // RegisterOrUnregisterCOMLocalServer() called from FinishInstall() runs in a
90 // separate process. When using registry redirection in the test, the new
91 // process writes to the real registry, so the unit test fails. This function
92 // creates dummy entries that VerifyCOMLocalServerRegistration() verifies, and
93 // is happy about.
94 void SetupCOMLocalServerRegistration(bool is_machine) {
95 // Setup the following for the unit test:
96 // * LocalServer32 under CLSID_OnDemandMachineAppsClass or
97 // CLSID_OnDemandUserAppsClass should be the current exe's module path.
98 // * InProcServer32 under CLSID of IID_IGoogleUpdate should be the path of the
99 // current module.
100 // * ProxyStubClsid32 under IGoogleUpdate interface should be the CLSID of the
101 // proxy, which is PROXY_CLSID_IS.
102
103 CString base_clsid_key(is_machine ? _T("HKLM") : _T("HKCU"));
104 base_clsid_key += _T("\\Software\\Classes\\CLSID\\");
105 CString ondemand_clsid_key(base_clsid_key);
106 // TODO(omaha3): Implement this for Omaha 3.
107 #if 0
108 ondemand_clsid_key += GuidToString(is_machine ?
109 __uuidof(OnDemandMachineAppsClass) :
110 __uuidof(OnDemandUserAppsClass));
111 CString local_server_key(ondemand_clsid_key + _T("\\LocalServer32"));
112 CString expected_server(app_util::GetModulePath(NULL));
113 EnclosePath(&expected_server);
114 ASSERT_FALSE(expected_server.IsEmpty());
115 ASSERT_SUCCEEDED(RegKey::SetValue(local_server_key,
116 NULL,
117 expected_server));
118
119 const GUID proxy_clsid = PROXY_CLSID_IS;
120 CString ondemand_proxy_clsid_key(base_clsid_key);
121 ondemand_proxy_clsid_key += GuidToString(proxy_clsid);
122 CString inproc_server_key(ondemand_proxy_clsid_key + _T("\\InProcServer32"));
123 expected_server = app_util::GetCurrentModulePath();
124 ASSERT_FALSE(expected_server.IsEmpty());
125 ASSERT_SUCCEEDED(RegKey::SetValue(inproc_server_key,
126 NULL,
127 expected_server));
128
129 CString igoogleupdate_interface_key(is_machine ? _T("HKLM") : _T("HKCU"));
130 igoogleupdate_interface_key += _T("\\Software\\Classes\\Interface\\");
131 igoogleupdate_interface_key += GuidToString(__uuidof(IGoogleUpdate));
132 igoogleupdate_interface_key += _T("\\ProxyStubClsid32");
133 CString proxy_interface_value(GuidToString(proxy_clsid));
134 ASSERT_FALSE(proxy_interface_value.IsEmpty());
135 ASSERT_SUCCEEDED(RegKey::SetValue(igoogleupdate_interface_key,
136 NULL,
137 proxy_interface_value));
138 #endif
139 }
140
141 void VerifyAccessRightsForTrustee(const CString& key_name,
142 ACCESS_MASK expected_access_rights,
143 CDacl* dacl,
144 TRUSTEE* trustee) {
145 CString fail_message;
146 fail_message.Format(_T("Key: %s; Trustee: "), key_name);
147 if (TRUSTEE_IS_NAME == trustee->TrusteeForm) {
148 fail_message.Append(trustee->ptstrName);
149 } else {
150 EXPECT_TRUE(TRUSTEE_IS_SID == trustee->TrusteeForm);
151 fail_message.Append(_T("is a SID"));
152 }
153
154 // Cast away the const so the pointer can be passed to the API. This should
155 // be safe for these purposes and because this is a unit test.
156 PACL pacl = const_cast<PACL>(dacl->GetPACL());
157 ACCESS_MASK access_rights = 0;
158 EXPECT_EQ(ERROR_SUCCESS, ::GetEffectiveRightsFromAcl(pacl,
159 trustee,
160 &access_rights)) <<
161 fail_message.GetString();
162 EXPECT_EQ(expected_access_rights, access_rights) << fail_message.GetString();
163 }
164
165 // TODO(omaha): It would be nice to test the access for a non-admin process.
166 // The test requires admin privileges to run, so this would likely require
167 // running a de-elevated process.
168 void VerifyHklmKeyHasIntegrity(
169 const CString& key_name,
170 ACCESS_MASK expected_non_admin_interactive_access) {
171
172 // These checks can take a long time, so avoid them by default.
173 if (!ShouldRunEnormousTest()) {
174 return;
175 }
176
177 const ACCESS_MASK kExpectedPowerUsersAccess = vista_util::IsVistaOrLater() ?
178 0 : DELETE | READ_CONTROL | KEY_READ | KEY_WRITE;
179
180 CDacl dacl;
181 RegKey key;
182 EXPECT_SUCCEEDED(key.Open(key_name));
183 EXPECT_TRUE(::AtlGetDacl(key.Key(), SE_REGISTRY_KEY, &dacl));
184
185 CString current_user_sid_string;
186 EXPECT_SUCCEEDED(
187 user_info::GetProcessUser(NULL, NULL, &current_user_sid_string));
188 PSID current_user_sid = NULL;
189 EXPECT_TRUE(ConvertStringSidToSid(current_user_sid_string,
190 &current_user_sid));
191 TRUSTEE current_user = {0};
192 current_user.TrusteeForm = TRUSTEE_IS_SID;
193 current_user.TrusteeType = TRUSTEE_IS_USER;
194 current_user.ptstrName = static_cast<LPTSTR>(current_user_sid);
195 VerifyAccessRightsForTrustee(key_name, KEY_ALL_ACCESS, &dacl, &current_user);
196 EXPECT_FALSE(::LocalFree(current_user_sid));
197
198 PSID local_system_sid = NULL;
199 EXPECT_TRUE(ConvertStringSidToSid(kLocalSystemSid, &local_system_sid));
200 TRUSTEE local_system = {0};
201 local_system.TrusteeForm = TRUSTEE_IS_SID;
202 local_system.TrusteeType = TRUSTEE_IS_USER;
203 local_system.ptstrName = static_cast<LPTSTR>(local_system_sid);
204 VerifyAccessRightsForTrustee(key_name, KEY_ALL_ACCESS, &dacl, &local_system);
205 EXPECT_FALSE(::LocalFree(local_system_sid));
206
207 TRUSTEE administrators = {0};
208 administrators.TrusteeForm = TRUSTEE_IS_NAME;
209 administrators.TrusteeType = TRUSTEE_IS_GROUP;
210 administrators.ptstrName = _T("Administrators");
211 VerifyAccessRightsForTrustee(key_name,
212 KEY_ALL_ACCESS,
213 &dacl,
214 &administrators);
215
216 TRUSTEE users = {0};
217 users.TrusteeForm = TRUSTEE_IS_NAME;
218 users.TrusteeType = TRUSTEE_IS_GROUP;
219 users.ptstrName = _T("Users");
220 VerifyAccessRightsForTrustee(key_name, KEY_READ, &dacl, &users);
221
222 TRUSTEE power_users = {0};
223 power_users.TrusteeForm = TRUSTEE_IS_NAME;
224 power_users.TrusteeType = TRUSTEE_IS_GROUP;
225 power_users.ptstrName = _T("Power Users");
226 VerifyAccessRightsForTrustee(key_name,
227 kExpectedPowerUsersAccess,
228 &dacl,
229 &power_users);
230
231 TRUSTEE interactive = {0};
232 interactive.TrusteeForm = TRUSTEE_IS_NAME;
233 interactive.TrusteeType = TRUSTEE_IS_GROUP;
234 interactive.ptstrName = _T("INTERACTIVE");
235 VerifyAccessRightsForTrustee(key_name,
236 expected_non_admin_interactive_access,
237 &dacl,
238 &interactive);
239
240 TRUSTEE everyone = {0};
241 everyone.TrusteeForm = TRUSTEE_IS_NAME;
242 everyone.TrusteeType = TRUSTEE_IS_GROUP;
243 everyone.ptstrName = _T("Everyone");
244 VerifyAccessRightsForTrustee(key_name, 0, &dacl, &everyone);
245
246 TRUSTEE guest = {0};
247 guest.TrusteeForm = TRUSTEE_IS_NAME;
248 guest.TrusteeType = TRUSTEE_IS_USER;
249 guest.ptstrName = _T("Guest");
250 VerifyAccessRightsForTrustee(key_name, 0, &dacl, &guest);
251 }
252
253 } // namespace
254
255 // INTERACTIVE group inherits privileges from Users in the default case.
256 void VerifyHklmKeyHasDefaultIntegrity(const CString& key_full_name) {
257 VerifyHklmKeyHasIntegrity(key_full_name, KEY_READ);
258 }
259
260 void VerifyHklmKeyHasMediumIntegrity(const CString& key_full_name) {
261 VerifyHklmKeyHasIntegrity(key_full_name, KEY_READ | KEY_SET_VALUE);
262 }
263
264 class SetupGoogleUpdateTest : public testing::Test {
265 protected:
266 explicit SetupGoogleUpdateTest(bool is_machine)
267 : is_machine_(is_machine) {
268 }
269
270 virtual void SetUp() {
271 setup_google_update_.reset(new SetupGoogleUpdate(is_machine_));
272 }
273
274 HRESULT InstallRegistryValues() {
275 return setup_google_update_->InstallRegistryValues();
276 }
277
278 HRESULT InstallLaunchMechanisms() {
279 return setup_google_update_->InstallLaunchMechanisms();
280 }
281
282 void UninstallLaunchMechanisms() {
283 setup_google_update_->UninstallLaunchMechanisms();
284 }
285
286 HRESULT CreateClientStateMedium() {
287 return setup_google_update_->CreateClientStateMedium();
288 }
289
290 HRESULT InstallMsiHelper() {
291 return setup_google_update_->InstallMsiHelper();
292 }
293
294 HRESULT UninstallMsiHelper() {
295 return setup_google_update_->UninstallMsiHelper();
296 }
297
298 bool is_machine_;
299 scoped_ptr<SetupGoogleUpdate> setup_google_update_;
300 };
301
302 class SetupGoogleUpdateUserTest : public SetupGoogleUpdateTest {
303 protected:
304 SetupGoogleUpdateUserTest()
305 : SetupGoogleUpdateTest(false) {
306 }
307 };
308
309 class SetupGoogleUpdateMachineTest : public SetupGoogleUpdateTest {
310 protected:
311 SetupGoogleUpdateMachineTest()
312 : SetupGoogleUpdateTest(true) {
313 }
314 };
315
316 class SetupGoogleUpdateUserRegistryProtectedTest
317 : public SetupGoogleUpdateUserTest {
318 protected:
319 SetupGoogleUpdateUserRegistryProtectedTest()
320 : SetupGoogleUpdateUserTest(),
321 hive_override_key_name_(kRegistryHiveOverrideRoot) {
322 const CString expected_shell_path =
323 ConcatenatePath(GetGoogleUpdateUserPath(), kOmahaShellFileName);
324 expected_run_key_value_.Format(_T("\"%s\" /c"), expected_shell_path);
325 }
326
327 virtual void SetUp() {
328 RegKey::DeleteKey(hive_override_key_name_, true);
329 // Do not override HKLM because it contains the CSIDL_* definitions.
330 OverrideSpecifiedRegistryHives(hive_override_key_name_, false, true);
331
332 SetupGoogleUpdateUserTest::SetUp();
333 }
334
335 virtual void TearDown() {
336 SetupGoogleUpdateUserTest::TearDown();
337
338 RestoreRegistryHives();
339 ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true));
340 }
341
342 CString hive_override_key_name_;
343 CString expected_run_key_value_;
344 };
345
346 class SetupGoogleUpdateMachineRegistryProtectedTest
347 : public SetupGoogleUpdateMachineTest {
348 protected:
349 SetupGoogleUpdateMachineRegistryProtectedTest()
350 : SetupGoogleUpdateMachineTest(),
351 hive_override_key_name_(kRegistryHiveOverrideRoot) {
352 }
353
354 virtual void SetUp() {
355 RegKey::DeleteKey(hive_override_key_name_, true);
356 OverrideRegistryHives(hive_override_key_name_);
357
358 // Add CSIDL values needed by the tests.
359 ASSERT_SUCCEEDED(RegKey::SetValue(kCsidlSystemIdsRegKey,
360 kCsidlProgramFilesRegValue,
361 _T("C:\\Program Files")));
362
363 SetupGoogleUpdateMachineTest::SetUp();
364 }
365
366 virtual void TearDown() {
367 SetupGoogleUpdateMachineTest::TearDown();
368
369 RestoreRegistryHives();
370 ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true));
371 }
372
373 CString hive_override_key_name_;
374 };
375
376 // There are a few tests where keys need to inherit the HKLM privileges, so put
377 // the override root in HKLM. All tests using this framework must run as admin.
378 class SetupGoogleUpdateMachineRegistryProtectedInHklmTest
379 : public SetupGoogleUpdateMachineRegistryProtectedTest {
380 protected:
381 SetupGoogleUpdateMachineRegistryProtectedInHklmTest()
382 : SetupGoogleUpdateMachineRegistryProtectedTest() {
383 hive_override_key_name_ = kRegistryHiveOverrideRootInHklm;
384 }
385 };
386
387 // This test uninstalls all other versions of Omaha.
388 TEST_F(SetupGoogleUpdateUserRegistryProtectedTest,
389 FinishInstall_RunKeyDoesNotExist) {
390 if (!ShouldRunLargeTest()) {
391 return;
392 }
393
394 // The version in the real registry must be set because it is used by
395 // GoogleUpdate.exe during registrations.
396 RestoreRegistryHives();
397 const bool had_pv = RegKey::HasValue(USER_REG_CLIENTS_GOOPDATE,
398 kRegValueProductVersion);
399 EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE,
400 kRegValueProductVersion,
401 GetVersionString()));
402 OverrideSpecifiedRegistryHives(hive_override_key_name_, false, true);
403
404 CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString());
405 SetupCOMLocalServerRegistration(is_machine_);
406
407 EXPECT_SUCCEEDED(RegKey::CreateKey(_T("HKCU\\Software\\Classes")));
408
409 ASSERT_FALSE(RegKey::HasKey(kRunKey));
410
411 EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE,
412 _T("mi"),
413 _T("39980C99-CDD5-43A0-93C7-69D90C14729")));
414 EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE,
415 _T("mi"),
416 _T("39980C99-CDD5-43A0-93C7-69D90C14729")));
417 EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE,
418 _T("ui"),
419 _T("49980C99-CDD5-43A0-93C7-69D90C14729")));
420
421 EXPECT_SUCCEEDED(setup_google_update_->FinishInstall());
422
423 // Check the system state.
424
425 CPath expected_shell_path(GetGoogleUpdateUserPath());
426 expected_shell_path.Append(kOmahaShellFileName);
427 CString shell_path;
428 EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_UPDATE, _T("path"), &shell_path));
429 EXPECT_STREQ(expected_shell_path, shell_path);
430
431 CString value;
432 EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey,
433 _T(OMAHA_APP_NAME_ANSI),
434 &value));
435 EXPECT_STREQ(expected_run_key_value_, value);
436 EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
437 EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false));
438
439 EXPECT_SUCCEEDED(
440 RegKey::GetValue(USER_REG_UPDATE, kRegValueInstalledVersion, &value));
441 EXPECT_EQ(GetVersionString(), value);
442 EXPECT_FALSE(RegKey::HasValue(USER_REG_UPDATE, kRegValueLastChecked));
443
444 EXPECT_TRUE(RegKey::HasValue(USER_REG_UPDATE, _T("mi")));
445 EXPECT_FALSE(RegKey::HasValue(MACHINE_REG_UPDATE, _T("mi")));
446 EXPECT_FALSE(RegKey::HasValue(USER_REG_UPDATE, _T("ui")));
447
448 // TODO(omaha): Check for other state.
449
450 // Clean up the launch mechanisms, at least one of which is not in the
451 // overriding registry.
452 UninstallLaunchMechanisms();
453 EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI)));
454 EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
455
456 if (!had_pv) {
457 // Delete the pv value. Some tests or shell .exe instances may see this
458 // value and assume Omaha is correctly installed.
459 RestoreRegistryHives();
460 EXPECT_SUCCEEDED(RegKey::DeleteValue(USER_REG_CLIENTS_GOOPDATE,
461 kRegValueProductVersion));
462 }
463 }
464
465 // TODO(omaha): Assumes GoogleUpdate.exe exists in the installed location, which
466 // is not always true when run independently.
467 TEST_F(SetupGoogleUpdateUserRegistryProtectedTest, InstallRegistryValues) {
468 if (IsTestRunByLocalSystem()) {
469 return;
470 }
471
472 // For this test only, we must also override HKLM in order to check that
473 // MACHINE_REG_CLIENT_STATE_MEDIUM was not created.
474 // Get the correct value of and set the CSIDL value needed by the test.
475 CString profile_path;
476 EXPECT_SUCCEEDED(GetFolderPath(CSIDL_PROFILE, &profile_path));
477 OverrideSpecifiedRegistryHives(hive_override_key_name_, true, true);
478 CString user_sid;
479 EXPECT_SUCCEEDED(user_info::GetProcessUser(NULL, NULL, &user_sid));
480 const TCHAR* const kProfileListKey =
481 _T("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\")
482 _T("ProfileList\\");
483 const CString profile_path_key = kProfileListKey + user_sid;
484 EXPECT_SUCCEEDED(
485 RegKey::SetValue(profile_path_key, _T("ProfileImagePath"), profile_path));
486
487 EXPECT_SUCCEEDED(InstallRegistryValues());
488 const uint32 now = Time64ToInt32(GetCurrent100NSTime());
489
490 EXPECT_TRUE(RegKey::HasKey(USER_REG_GOOGLE));
491 EXPECT_TRUE(RegKey::HasKey(USER_REG_UPDATE));
492 EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENTS));
493 EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENT_STATE));
494 EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENTS_GOOPDATE));
495 EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENT_STATE_GOOPDATE));
496 EXPECT_FALSE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_MEDIUM));
497
498 // Ensure no unexpected keys were created.
499 RegKey google_key;
500 EXPECT_SUCCEEDED(google_key.Open(USER_REG_GOOGLE));
501 EXPECT_EQ(1, google_key.GetSubkeyCount());
502
503 RegKey update_key;
504 EXPECT_SUCCEEDED(update_key.Open(USER_REG_UPDATE));
505 EXPECT_EQ(2, update_key.GetSubkeyCount());
506
507 RegKey clients_key;
508 EXPECT_SUCCEEDED(clients_key.Open(USER_REG_CLIENTS));
509 EXPECT_EQ(1, clients_key.GetSubkeyCount());
510
511 RegKey client_state_key;
512 EXPECT_SUCCEEDED(client_state_key.Open(USER_REG_CLIENT_STATE));
513 EXPECT_EQ(1, client_state_key.GetSubkeyCount());
514
515 CPath expected_shell_path(GetGoogleUpdateUserPath());
516 expected_shell_path.Append(kOmahaShellFileName);
517 CString shell_path;
518 EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_UPDATE, _T("path"), &shell_path));
519 EXPECT_STREQ(expected_shell_path, shell_path);
520
521 CString product_version;
522 EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_CLIENT_STATE_GOOPDATE,
523 _T("pv"),
524 &product_version));
525 EXPECT_STREQ(GetVersionString(), product_version);
526 }
527
528 // TODO(omaha): Assumes GoogleUpdate.exe exists in the installed location, which
529 // is not always true when run independently.
530 // TODO(omaha): Fails when run by itself on Windows Vista.
531 TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest,
532 InstallRegistryValues) {
533 EXPECT_SUCCEEDED(InstallRegistryValues());
534 const uint32 now = Time64ToInt32(GetCurrent100NSTime());
535
536 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_GOOGLE));
537 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_UPDATE));
538 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENTS));
539 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE));
540 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENTS_GOOPDATE));
541 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_GOOPDATE));
542 EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_MEDIUM));
543
544 // Ensure no unexpected keys were created.
545 RegKey google_key;
546 EXPECT_SUCCEEDED(google_key.Open(MACHINE_REG_GOOGLE));
547 EXPECT_EQ(1, google_key.GetSubkeyCount());
548
549 RegKey update_key;
550 EXPECT_SUCCEEDED(update_key.Open(MACHINE_REG_UPDATE));
551 EXPECT_EQ(3, update_key.GetSubkeyCount());
552
553 RegKey clients_key;
554 EXPECT_SUCCEEDED(clients_key.Open(MACHINE_REG_CLIENTS));
555 EXPECT_EQ(1, clients_key.GetSubkeyCount());
556
557 RegKey client_state_key;
558 EXPECT_SUCCEEDED(client_state_key.Open(MACHINE_REG_CLIENT_STATE));
559 EXPECT_EQ(1, client_state_key.GetSubkeyCount());
560
561 RegKey client_state_medium_key;
562 EXPECT_SUCCEEDED(
563 client_state_medium_key.Open(MACHINE_REG_CLIENT_STATE_MEDIUM));
564 EXPECT_EQ(0, client_state_medium_key.GetSubkeyCount());
565 VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM);
566
567 CString expected_shell_path;
568 EXPECT_SUCCEEDED(GetFolderPath(CSIDL_PROGRAM_FILES, &expected_shell_path));
569 expected_shell_path.Append(_T("\\") SHORT_COMPANY_NAME
570 _T("\\") PRODUCT_NAME
571 _T("\\GoogleUpdate.exe"));
572 CString shell_path;
573 EXPECT_SUCCEEDED(
574 RegKey::GetValue(MACHINE_REG_UPDATE, _T("path"), &shell_path));
575 EXPECT_STREQ(expected_shell_path, shell_path);
576
577 CString product_version;
578 EXPECT_SUCCEEDED(RegKey::GetValue(MACHINE_REG_CLIENT_STATE_GOOPDATE,
579 _T("pv"),
580 &product_version));
581 EXPECT_STREQ(GetVersionString(), product_version);
582
583 // Test permission of Update and ClientState. ClientStateMedium checked above.
584 VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_UPDATE);
585 VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE);
586
587 // Test the permission inheritance for ClientStateMedium.
588 const CString app_client_state_medium_key_name = AppendRegKeyPath(
589 MACHINE_REG_CLIENT_STATE_MEDIUM,
590 kAppId1);
591 EXPECT_SUCCEEDED(RegKey::CreateKey(app_client_state_medium_key_name));
592
593 VerifyHklmKeyHasMediumIntegrity(app_client_state_medium_key_name);
594 }
595
596 TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest,
597 CreateClientStateMedium_KeyAlreadyExistsWithSamePermissions) {
598 EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_UPDATE));
599 EXPECT_SUCCEEDED(CreateClientStateMedium());
600 VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM);
601
602 EXPECT_SUCCEEDED(CreateClientStateMedium());
603 VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM);
604 }
605
606 // CreateClientStateMedium does not replace permissions on existing keys.
607 TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest,
608 CreateClientStateMedium_KeysAlreadyExistWithDifferentPermissions) {
609 // The checks in this test can take a long time, so avoid them by default.
610 if (!ShouldRunEnormousTest()) {
611 return;
612 }
613
614 const CString app1_client_state_medium_key_name = AppendRegKeyPath(
615 MACHINE_REG_CLIENT_STATE_MEDIUM,
616 kAppId1);
617 const CString app2_client_state_medium_key_name = AppendRegKeyPath(
618 MACHINE_REG_CLIENT_STATE_MEDIUM,
619 kAppId2);
620
621 TRUSTEE users = {0};
622 users.TrusteeForm = TRUSTEE_IS_NAME;
623 users.TrusteeType = TRUSTEE_IS_GROUP;
624 users.ptstrName = _T("Users");
625
626 TRUSTEE interactive = {0};
627 interactive.TrusteeForm = TRUSTEE_IS_NAME;
628 interactive.TrusteeType = TRUSTEE_IS_GROUP;
629 interactive.ptstrName = _T("INTERACTIVE");
630
631 EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_UPDATE));
632
633 CDacl dacl;
634 dacl.AddAllowedAce(Sids::Admins(), GENERIC_ALL);
635 // Interactive is not explicitly set.
636 dacl.AddAllowedAce(Sids::Users(), KEY_WRITE);
637
638 CSecurityDesc security_descriptor;
639 security_descriptor.SetDacl(dacl);
640 security_descriptor.MakeAbsolute();
641
642 CSecurityAttributes sa;
643 sa.Set(security_descriptor);
644
645 EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_CLIENT_STATE_MEDIUM,
646 REG_NONE,
647 REG_OPTION_NON_VOLATILE,
648 &sa));
649
650 EXPECT_SUCCEEDED(RegKey::CreateKey(app1_client_state_medium_key_name));
651
652
653 EXPECT_SUCCEEDED(CreateClientStateMedium());
654
655 // Verify the ACLs for the existing keys were not changed.
656 // INTERACTIVE appears to inherit the privileges of Users.
657 VerifyAccessRightsForTrustee(
658 MACHINE_REG_CLIENT_STATE_MEDIUM, KEY_WRITE, &dacl, &users);
659 VerifyAccessRightsForTrustee(
660 MACHINE_REG_CLIENT_STATE_MEDIUM, KEY_WRITE, &dacl, &interactive);
661 VerifyAccessRightsForTrustee(
662 app1_client_state_medium_key_name, KEY_WRITE, &dacl, &users);
663 VerifyAccessRightsForTrustee(
664 app1_client_state_medium_key_name, KEY_WRITE, &dacl, &interactive);
665
666 // Verify the ACLs of newly created subkeys.
667 EXPECT_SUCCEEDED(RegKey::CreateKey(app2_client_state_medium_key_name));
668 VerifyAccessRightsForTrustee(
669 app2_client_state_medium_key_name, KEY_WRITE, &dacl, &users);
670 VerifyAccessRightsForTrustee(
671 app2_client_state_medium_key_name, KEY_WRITE, &dacl, &interactive);
672 }
673
674 TEST_F(SetupGoogleUpdateUserRegistryProtectedTest,
675 InstallLaunchMechanisms_RunKeyValueExists) {
676 EXPECT_SUCCEEDED(RegKey::SetValue(kRunKey,
677 _T(OMAHA_APP_NAME_ANSI),
678 _T("fo /b")));
679
680 EXPECT_SUCCEEDED(InstallLaunchMechanisms());
681
682 CString value;
683 EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey,
684 _T(OMAHA_APP_NAME_ANSI),
685 &value));
686 EXPECT_STREQ(expected_run_key_value_, value);
687 EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
688 EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false));
689
690 UninstallLaunchMechanisms();
691 EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI)));
692 EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
693 }
694
695 TEST_F(SetupGoogleUpdateUserRegistryProtectedTest,
696 InstallLaunchMechanisms_RunKeyDoesNotExist) {
697 ASSERT_FALSE(RegKey::HasKey(kRunKey));
698
699 EXPECT_SUCCEEDED(InstallLaunchMechanisms());
700
701 CString value;
702 EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey,
703 _T(OMAHA_APP_NAME_ANSI),
704 &value));
705 EXPECT_STREQ(expected_run_key_value_, value);
706 EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
707 EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false));
708
709 UninstallLaunchMechanisms();
710 EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI)));
711 EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false));
712 }
713
714 // The helper can be installed when the test begins.
715 // It will not be installed when the test successfully completes.
716 TEST_F(SetupGoogleUpdateMachineTest, InstallAndUninstallMsiHelper) {
717 if (!ShouldRunLargeTest()) {
718 return;
719 }
720 const TCHAR* MsiInstallRegValueKey =
721 ConfigManager::Instance()->machine_registry_update();
722
723 CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString());
724
725 if (vista_util::IsUserAdmin()) {
726 // Prepare for the test - make sure the helper isn't installed.
727 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
728 EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
729 EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey));
730
731 // Verify installation.
732 DWORD reg_value = 0xffffffff;
733 EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper());
734 EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
735 EXPECT_HRESULT_SUCCEEDED(RegKey::GetValue(MsiInstallRegValueKey,
736 kMsiInstallRegValue,
737 &reg_value));
738 EXPECT_EQ(0, reg_value);
739 EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey));
740
741 // Verify over-install.
742 EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper());
743 EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
744 EXPECT_HRESULT_SUCCEEDED(RegKey::GetValue(MsiInstallRegValueKey,
745 kMsiInstallRegValue,
746 &reg_value));
747 EXPECT_EQ(0, reg_value);
748 EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey));
749
750 // Verify uninstall.
751 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
752 EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
753 EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey));
754
755 // Verify uninstall when not currently installed.
756 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
757 } else {
758 {
759 // This method expects to be called elevated and makes an assumption
760 // about a return value.
761 ExpectAsserts expect_asserts;
762 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_REJECTED),
763 InstallMsiHelper());
764 }
765 if (IsMsiHelperInstalled()) {
766 // If the MSI is installed UninstallMsiHelper returns
767 // ERROR_INSTALL_FAILURE.
768 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE),
769 UninstallMsiHelper());
770 } else {
771 // If the MSI is not installed UninstallMsiHelper returns S_OK.
772 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
773 }
774 }
775 }
776
777 // This test installs a different build of the helper installer then calls
778 // InstallMsiHelper to install the one that has been built.
779 // If run without the REINSTALL property, ERROR_PRODUCT_VERSION would occur.
780 // This test verifies that such overinstalls are correctly handled and that the
781 // registry value is correctly changed.
782 // Note: The name of the installer cannot be different. MSI tries to find the
783 // original filename in the new directory.
784 // The helper can be installed when the test begins.
785 // It will not be installed when the test successfully completes.
786 TEST_F(SetupGoogleUpdateMachineTest,
787 InstallMsiHelper_OverinstallDifferentMsiBuild) {
788 if (!ShouldRunLargeTest()) {
789 return;
790 }
791 if (!vista_util::IsUserAdmin()) {
792 std::wcout << _T("\tThis test did not run because it must be run as admin.")
793 << std::endl;
794 return;
795 }
796
797 const TCHAR kDifferentMsi[] =
798 _T("unittest_support\\GoogleUpdateHelper.msi");
799 const TCHAR* MsiInstallRegValueKey =
800 ConfigManager::Instance()->machine_registry_update();
801
802 CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString());
803
804 CString different_msi_path(app_util::GetCurrentModuleDirectory());
805 ASSERT_TRUE(::PathAppend(CStrBuf(different_msi_path, MAX_PATH),
806 kDifferentMsi));
807
808 // Prepare for the test - make sure the helper is not installed.
809 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
810 EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
811 EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey));
812
813 // Install an older version of the MSI.
814 DWORD reg_value = 0xffffffff;
815 ::MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
816 EXPECT_EQ(ERROR_SUCCESS, ::MsiInstallProduct(different_msi_path, _T("")));
817 EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
818 EXPECT_HRESULT_SUCCEEDED(
819 RegKey::GetValue(MsiInstallRegValueKey, kMsiInstallRegValue, &reg_value));
820 EXPECT_EQ(9, reg_value);
821 EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey));
822
823 // Over-install.
824 EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper());
825 EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
826 EXPECT_HRESULT_SUCCEEDED(
827 RegKey::GetValue(MsiInstallRegValueKey, kMsiInstallRegValue, &reg_value));
828 EXPECT_EQ(0, reg_value);
829 EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey));
830
831 // Clean up.
832 EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper());
833 EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue));
834 EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey));
835 }
836
837 } // namespace omaha
OLDNEW
« no previous file with comments | « setup/setup_google_update.cc ('k') | setup/setup_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698