Index: setup/setup_google_update_unittest.cc |
diff --git a/setup/setup_google_update_unittest.cc b/setup/setup_google_update_unittest.cc |
deleted file mode 100644 |
index aeeffa8ba4f5b67212a453c672e9c3ce28b9ba14..0000000000000000000000000000000000000000 |
--- a/setup/setup_google_update_unittest.cc |
+++ /dev/null |
@@ -1,837 +0,0 @@ |
-// Copyright 2007-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
- |
-#include <windows.h> |
-#include <msi.h> |
-#include <atlpath.h> |
-#include "base/scoped_ptr.h" |
-#include "omaha/base/app_util.h" |
-#include "omaha/base/atlregmapex.h" |
-#include "omaha/base/omaha_version.h" |
-#include "omaha/base/file.h" |
-#include "omaha/base/path.h" |
-#include "omaha/base/time.h" |
-#include "omaha/base/utils.h" |
-#include "omaha/base/vistautil.h" |
-#include "omaha/common/config_manager.h" |
-#include "omaha/common/const_cmd_line.h" |
-#include "omaha/common/const_goopdate.h" |
-#include "omaha/common/scheduled_task_utils.h" |
-#include "omaha/setup/msi_test_utils.h" |
-#include "omaha/setup/setup_google_update.h" |
-#include "omaha/testing/unit_test.h" |
- |
-namespace omaha { |
- |
-namespace { |
- |
-const TCHAR kMsiInstallRegValue[] = _T("MsiStubRun"); |
-const TCHAR kMsiUninstallKey[] = |
- _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\") |
- _T("Uninstall\\{A92DAB39-4E2C-4304-9AB6-BC44E68B55E2}"); |
-const TCHAR kRunKey[] = |
- _T("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"); |
- |
-const TCHAR* const kAppId1 = _T("{B7E61EF9-AAE5-4cdf-A2D3-E4C8DF975145}"); |
-const TCHAR* const kAppId2 = _T("{35F1A986-417D-4039-8718-781DD418232A}"); |
- |
-const TCHAR kRegistryHiveOverrideRootInHklm[] = |
- _T("HKLM\\Software\\") _T(SHORT_COMPANY_NAME_ANSI) |
- _T("\\") _T(PRODUCT_NAME_ANSI) |
- _T("\\UnitTest\\"); |
- |
-// Copies the shell and DLLs that FinishInstall needs. |
-// Does not replace files if they already exist. |
-void CopyFilesRequiredByFinishInstall(bool is_machine, const CString& version) { |
- const CString omaha_path = is_machine ? |
- GetGoogleUpdateMachinePath() : GetGoogleUpdateUserPath(); |
- const CString expected_shell_path = |
- ConcatenatePath(omaha_path, kOmahaShellFileName); |
- const CString version_path = ConcatenatePath(omaha_path, version); |
- |
- ASSERT_SUCCEEDED(CreateDir(omaha_path, NULL)); |
- ASSERT_SUCCEEDED(File::Copy( |
- ConcatenatePath(app_util::GetCurrentModuleDirectory(), |
- kOmahaShellFileName), |
- expected_shell_path, |
- false)); |
- |
- ASSERT_SUCCEEDED(CreateDir(version_path, NULL)); |
- |
- const TCHAR* files[] = {kOmahaDllName, |
- kHelperInstallerName, |
-// TODO(omaha3): Enable once this is being built. |
-#if 0 |
- _T("GoopdateBho.dll"), |
-#endif |
- UPDATE_PLUGIN_FILENAME}; |
- for (size_t i = 0; i < arraysize(files); ++i) { |
- ASSERT_SUCCEEDED(File::Copy( |
- ConcatenatePath(app_util::GetCurrentModuleDirectory(), |
- files[i]), |
- ConcatenatePath(version_path, files[i]), |
- false)); |
- } |
-} |
- |
-// RegisterOrUnregisterCOMLocalServer() called from FinishInstall() runs in a |
-// separate process. When using registry redirection in the test, the new |
-// process writes to the real registry, so the unit test fails. This function |
-// creates dummy entries that VerifyCOMLocalServerRegistration() verifies, and |
-// is happy about. |
-void SetupCOMLocalServerRegistration(bool is_machine) { |
- // Setup the following for the unit test: |
- // * LocalServer32 under CLSID_OnDemandMachineAppsClass or |
- // CLSID_OnDemandUserAppsClass should be the current exe's module path. |
- // * InProcServer32 under CLSID of IID_IGoogleUpdate should be the path of the |
- // current module. |
- // * ProxyStubClsid32 under IGoogleUpdate interface should be the CLSID of the |
- // proxy, which is PROXY_CLSID_IS. |
- |
- CString base_clsid_key(is_machine ? _T("HKLM") : _T("HKCU")); |
- base_clsid_key += _T("\\Software\\Classes\\CLSID\\"); |
- CString ondemand_clsid_key(base_clsid_key); |
-// TODO(omaha3): Implement this for Omaha 3. |
-#if 0 |
- ondemand_clsid_key += GuidToString(is_machine ? |
- __uuidof(OnDemandMachineAppsClass) : |
- __uuidof(OnDemandUserAppsClass)); |
- CString local_server_key(ondemand_clsid_key + _T("\\LocalServer32")); |
- CString expected_server(app_util::GetModulePath(NULL)); |
- EnclosePath(&expected_server); |
- ASSERT_FALSE(expected_server.IsEmpty()); |
- ASSERT_SUCCEEDED(RegKey::SetValue(local_server_key, |
- NULL, |
- expected_server)); |
- |
- const GUID proxy_clsid = PROXY_CLSID_IS; |
- CString ondemand_proxy_clsid_key(base_clsid_key); |
- ondemand_proxy_clsid_key += GuidToString(proxy_clsid); |
- CString inproc_server_key(ondemand_proxy_clsid_key + _T("\\InProcServer32")); |
- expected_server = app_util::GetCurrentModulePath(); |
- ASSERT_FALSE(expected_server.IsEmpty()); |
- ASSERT_SUCCEEDED(RegKey::SetValue(inproc_server_key, |
- NULL, |
- expected_server)); |
- |
- CString igoogleupdate_interface_key(is_machine ? _T("HKLM") : _T("HKCU")); |
- igoogleupdate_interface_key += _T("\\Software\\Classes\\Interface\\"); |
- igoogleupdate_interface_key += GuidToString(__uuidof(IGoogleUpdate)); |
- igoogleupdate_interface_key += _T("\\ProxyStubClsid32"); |
- CString proxy_interface_value(GuidToString(proxy_clsid)); |
- ASSERT_FALSE(proxy_interface_value.IsEmpty()); |
- ASSERT_SUCCEEDED(RegKey::SetValue(igoogleupdate_interface_key, |
- NULL, |
- proxy_interface_value)); |
-#endif |
-} |
- |
-void VerifyAccessRightsForTrustee(const CString& key_name, |
- ACCESS_MASK expected_access_rights, |
- CDacl* dacl, |
- TRUSTEE* trustee) { |
- CString fail_message; |
- fail_message.Format(_T("Key: %s; Trustee: "), key_name); |
- if (TRUSTEE_IS_NAME == trustee->TrusteeForm) { |
- fail_message.Append(trustee->ptstrName); |
- } else { |
- EXPECT_TRUE(TRUSTEE_IS_SID == trustee->TrusteeForm); |
- fail_message.Append(_T("is a SID")); |
- } |
- |
- // Cast away the const so the pointer can be passed to the API. This should |
- // be safe for these purposes and because this is a unit test. |
- PACL pacl = const_cast<PACL>(dacl->GetPACL()); |
- ACCESS_MASK access_rights = 0; |
- EXPECT_EQ(ERROR_SUCCESS, ::GetEffectiveRightsFromAcl(pacl, |
- trustee, |
- &access_rights)) << |
- fail_message.GetString(); |
- EXPECT_EQ(expected_access_rights, access_rights) << fail_message.GetString(); |
-} |
- |
-// TODO(omaha): It would be nice to test the access for a non-admin process. |
-// The test requires admin privileges to run, so this would likely require |
-// running a de-elevated process. |
-void VerifyHklmKeyHasIntegrity( |
- const CString& key_name, |
- ACCESS_MASK expected_non_admin_interactive_access) { |
- |
- // These checks can take a long time, so avoid them by default. |
- if (!ShouldRunEnormousTest()) { |
- return; |
- } |
- |
- const ACCESS_MASK kExpectedPowerUsersAccess = vista_util::IsVistaOrLater() ? |
- 0 : DELETE | READ_CONTROL | KEY_READ | KEY_WRITE; |
- |
- CDacl dacl; |
- RegKey key; |
- EXPECT_SUCCEEDED(key.Open(key_name)); |
- EXPECT_TRUE(::AtlGetDacl(key.Key(), SE_REGISTRY_KEY, &dacl)); |
- |
- CString current_user_sid_string; |
- EXPECT_SUCCEEDED( |
- user_info::GetProcessUser(NULL, NULL, ¤t_user_sid_string)); |
- PSID current_user_sid = NULL; |
- EXPECT_TRUE(ConvertStringSidToSid(current_user_sid_string, |
- ¤t_user_sid)); |
- TRUSTEE current_user = {0}; |
- current_user.TrusteeForm = TRUSTEE_IS_SID; |
- current_user.TrusteeType = TRUSTEE_IS_USER; |
- current_user.ptstrName = static_cast<LPTSTR>(current_user_sid); |
- VerifyAccessRightsForTrustee(key_name, KEY_ALL_ACCESS, &dacl, ¤t_user); |
- EXPECT_FALSE(::LocalFree(current_user_sid)); |
- |
- PSID local_system_sid = NULL; |
- EXPECT_TRUE(ConvertStringSidToSid(kLocalSystemSid, &local_system_sid)); |
- TRUSTEE local_system = {0}; |
- local_system.TrusteeForm = TRUSTEE_IS_SID; |
- local_system.TrusteeType = TRUSTEE_IS_USER; |
- local_system.ptstrName = static_cast<LPTSTR>(local_system_sid); |
- VerifyAccessRightsForTrustee(key_name, KEY_ALL_ACCESS, &dacl, &local_system); |
- EXPECT_FALSE(::LocalFree(local_system_sid)); |
- |
- TRUSTEE administrators = {0}; |
- administrators.TrusteeForm = TRUSTEE_IS_NAME; |
- administrators.TrusteeType = TRUSTEE_IS_GROUP; |
- administrators.ptstrName = _T("Administrators"); |
- VerifyAccessRightsForTrustee(key_name, |
- KEY_ALL_ACCESS, |
- &dacl, |
- &administrators); |
- |
- TRUSTEE users = {0}; |
- users.TrusteeForm = TRUSTEE_IS_NAME; |
- users.TrusteeType = TRUSTEE_IS_GROUP; |
- users.ptstrName = _T("Users"); |
- VerifyAccessRightsForTrustee(key_name, KEY_READ, &dacl, &users); |
- |
- TRUSTEE power_users = {0}; |
- power_users.TrusteeForm = TRUSTEE_IS_NAME; |
- power_users.TrusteeType = TRUSTEE_IS_GROUP; |
- power_users.ptstrName = _T("Power Users"); |
- VerifyAccessRightsForTrustee(key_name, |
- kExpectedPowerUsersAccess, |
- &dacl, |
- &power_users); |
- |
- TRUSTEE interactive = {0}; |
- interactive.TrusteeForm = TRUSTEE_IS_NAME; |
- interactive.TrusteeType = TRUSTEE_IS_GROUP; |
- interactive.ptstrName = _T("INTERACTIVE"); |
- VerifyAccessRightsForTrustee(key_name, |
- expected_non_admin_interactive_access, |
- &dacl, |
- &interactive); |
- |
- TRUSTEE everyone = {0}; |
- everyone.TrusteeForm = TRUSTEE_IS_NAME; |
- everyone.TrusteeType = TRUSTEE_IS_GROUP; |
- everyone.ptstrName = _T("Everyone"); |
- VerifyAccessRightsForTrustee(key_name, 0, &dacl, &everyone); |
- |
- TRUSTEE guest = {0}; |
- guest.TrusteeForm = TRUSTEE_IS_NAME; |
- guest.TrusteeType = TRUSTEE_IS_USER; |
- guest.ptstrName = _T("Guest"); |
- VerifyAccessRightsForTrustee(key_name, 0, &dacl, &guest); |
-} |
- |
-} // namespace |
- |
-// INTERACTIVE group inherits privileges from Users in the default case. |
-void VerifyHklmKeyHasDefaultIntegrity(const CString& key_full_name) { |
- VerifyHklmKeyHasIntegrity(key_full_name, KEY_READ); |
-} |
- |
-void VerifyHklmKeyHasMediumIntegrity(const CString& key_full_name) { |
- VerifyHklmKeyHasIntegrity(key_full_name, KEY_READ | KEY_SET_VALUE); |
-} |
- |
-class SetupGoogleUpdateTest : public testing::Test { |
- protected: |
- explicit SetupGoogleUpdateTest(bool is_machine) |
- : is_machine_(is_machine) { |
- } |
- |
- virtual void SetUp() { |
- setup_google_update_.reset(new SetupGoogleUpdate(is_machine_)); |
- } |
- |
- HRESULT InstallRegistryValues() { |
- return setup_google_update_->InstallRegistryValues(); |
- } |
- |
- HRESULT InstallLaunchMechanisms() { |
- return setup_google_update_->InstallLaunchMechanisms(); |
- } |
- |
- void UninstallLaunchMechanisms() { |
- setup_google_update_->UninstallLaunchMechanisms(); |
- } |
- |
- HRESULT CreateClientStateMedium() { |
- return setup_google_update_->CreateClientStateMedium(); |
- } |
- |
- HRESULT InstallMsiHelper() { |
- return setup_google_update_->InstallMsiHelper(); |
- } |
- |
- HRESULT UninstallMsiHelper() { |
- return setup_google_update_->UninstallMsiHelper(); |
- } |
- |
- bool is_machine_; |
- scoped_ptr<SetupGoogleUpdate> setup_google_update_; |
-}; |
- |
-class SetupGoogleUpdateUserTest : public SetupGoogleUpdateTest { |
- protected: |
- SetupGoogleUpdateUserTest() |
- : SetupGoogleUpdateTest(false) { |
- } |
-}; |
- |
-class SetupGoogleUpdateMachineTest : public SetupGoogleUpdateTest { |
- protected: |
- SetupGoogleUpdateMachineTest() |
- : SetupGoogleUpdateTest(true) { |
- } |
-}; |
- |
-class SetupGoogleUpdateUserRegistryProtectedTest |
- : public SetupGoogleUpdateUserTest { |
- protected: |
- SetupGoogleUpdateUserRegistryProtectedTest() |
- : SetupGoogleUpdateUserTest(), |
- hive_override_key_name_(kRegistryHiveOverrideRoot) { |
- const CString expected_shell_path = |
- ConcatenatePath(GetGoogleUpdateUserPath(), kOmahaShellFileName); |
- expected_run_key_value_.Format(_T("\"%s\" /c"), expected_shell_path); |
- } |
- |
- virtual void SetUp() { |
- RegKey::DeleteKey(hive_override_key_name_, true); |
- // Do not override HKLM because it contains the CSIDL_* definitions. |
- OverrideSpecifiedRegistryHives(hive_override_key_name_, false, true); |
- |
- SetupGoogleUpdateUserTest::SetUp(); |
- } |
- |
- virtual void TearDown() { |
- SetupGoogleUpdateUserTest::TearDown(); |
- |
- RestoreRegistryHives(); |
- ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true)); |
- } |
- |
- CString hive_override_key_name_; |
- CString expected_run_key_value_; |
-}; |
- |
-class SetupGoogleUpdateMachineRegistryProtectedTest |
- : public SetupGoogleUpdateMachineTest { |
- protected: |
- SetupGoogleUpdateMachineRegistryProtectedTest() |
- : SetupGoogleUpdateMachineTest(), |
- hive_override_key_name_(kRegistryHiveOverrideRoot) { |
- } |
- |
- virtual void SetUp() { |
- RegKey::DeleteKey(hive_override_key_name_, true); |
- OverrideRegistryHives(hive_override_key_name_); |
- |
- // Add CSIDL values needed by the tests. |
- ASSERT_SUCCEEDED(RegKey::SetValue(kCsidlSystemIdsRegKey, |
- kCsidlProgramFilesRegValue, |
- _T("C:\\Program Files"))); |
- |
- SetupGoogleUpdateMachineTest::SetUp(); |
- } |
- |
- virtual void TearDown() { |
- SetupGoogleUpdateMachineTest::TearDown(); |
- |
- RestoreRegistryHives(); |
- ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true)); |
- } |
- |
- CString hive_override_key_name_; |
-}; |
- |
-// There are a few tests where keys need to inherit the HKLM privileges, so put |
-// the override root in HKLM. All tests using this framework must run as admin. |
-class SetupGoogleUpdateMachineRegistryProtectedInHklmTest |
- : public SetupGoogleUpdateMachineRegistryProtectedTest { |
- protected: |
- SetupGoogleUpdateMachineRegistryProtectedInHklmTest() |
- : SetupGoogleUpdateMachineRegistryProtectedTest() { |
- hive_override_key_name_ = kRegistryHiveOverrideRootInHklm; |
- } |
-}; |
- |
-// This test uninstalls all other versions of Omaha. |
-TEST_F(SetupGoogleUpdateUserRegistryProtectedTest, |
- FinishInstall_RunKeyDoesNotExist) { |
- if (!ShouldRunLargeTest()) { |
- return; |
- } |
- |
- // The version in the real registry must be set because it is used by |
- // GoogleUpdate.exe during registrations. |
- RestoreRegistryHives(); |
- const bool had_pv = RegKey::HasValue(USER_REG_CLIENTS_GOOPDATE, |
- kRegValueProductVersion); |
- EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, |
- kRegValueProductVersion, |
- GetVersionString())); |
- OverrideSpecifiedRegistryHives(hive_override_key_name_, false, true); |
- |
- CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString()); |
- SetupCOMLocalServerRegistration(is_machine_); |
- |
- EXPECT_SUCCEEDED(RegKey::CreateKey(_T("HKCU\\Software\\Classes"))); |
- |
- ASSERT_FALSE(RegKey::HasKey(kRunKey)); |
- |
- EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, |
- _T("mi"), |
- _T("39980C99-CDD5-43A0-93C7-69D90C14729"))); |
- EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE, |
- _T("mi"), |
- _T("39980C99-CDD5-43A0-93C7-69D90C14729"))); |
- EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, |
- _T("ui"), |
- _T("49980C99-CDD5-43A0-93C7-69D90C14729"))); |
- |
- EXPECT_SUCCEEDED(setup_google_update_->FinishInstall()); |
- |
- // Check the system state. |
- |
- CPath expected_shell_path(GetGoogleUpdateUserPath()); |
- expected_shell_path.Append(kOmahaShellFileName); |
- CString shell_path; |
- EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_UPDATE, _T("path"), &shell_path)); |
- EXPECT_STREQ(expected_shell_path, shell_path); |
- |
- CString value; |
- EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey, |
- _T(OMAHA_APP_NAME_ANSI), |
- &value)); |
- EXPECT_STREQ(expected_run_key_value_, value); |
- EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
- EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false)); |
- |
- EXPECT_SUCCEEDED( |
- RegKey::GetValue(USER_REG_UPDATE, kRegValueInstalledVersion, &value)); |
- EXPECT_EQ(GetVersionString(), value); |
- EXPECT_FALSE(RegKey::HasValue(USER_REG_UPDATE, kRegValueLastChecked)); |
- |
- EXPECT_TRUE(RegKey::HasValue(USER_REG_UPDATE, _T("mi"))); |
- EXPECT_FALSE(RegKey::HasValue(MACHINE_REG_UPDATE, _T("mi"))); |
- EXPECT_FALSE(RegKey::HasValue(USER_REG_UPDATE, _T("ui"))); |
- |
- // TODO(omaha): Check for other state. |
- |
- // Clean up the launch mechanisms, at least one of which is not in the |
- // overriding registry. |
- UninstallLaunchMechanisms(); |
- EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI))); |
- EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
- |
- if (!had_pv) { |
- // Delete the pv value. Some tests or shell .exe instances may see this |
- // value and assume Omaha is correctly installed. |
- RestoreRegistryHives(); |
- EXPECT_SUCCEEDED(RegKey::DeleteValue(USER_REG_CLIENTS_GOOPDATE, |
- kRegValueProductVersion)); |
- } |
-} |
- |
-// TODO(omaha): Assumes GoogleUpdate.exe exists in the installed location, which |
-// is not always true when run independently. |
-TEST_F(SetupGoogleUpdateUserRegistryProtectedTest, InstallRegistryValues) { |
- if (IsTestRunByLocalSystem()) { |
- return; |
- } |
- |
- // For this test only, we must also override HKLM in order to check that |
- // MACHINE_REG_CLIENT_STATE_MEDIUM was not created. |
- // Get the correct value of and set the CSIDL value needed by the test. |
- CString profile_path; |
- EXPECT_SUCCEEDED(GetFolderPath(CSIDL_PROFILE, &profile_path)); |
- OverrideSpecifiedRegistryHives(hive_override_key_name_, true, true); |
- CString user_sid; |
- EXPECT_SUCCEEDED(user_info::GetProcessUser(NULL, NULL, &user_sid)); |
- const TCHAR* const kProfileListKey = |
- _T("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\") |
- _T("ProfileList\\"); |
- const CString profile_path_key = kProfileListKey + user_sid; |
- EXPECT_SUCCEEDED( |
- RegKey::SetValue(profile_path_key, _T("ProfileImagePath"), profile_path)); |
- |
- EXPECT_SUCCEEDED(InstallRegistryValues()); |
- const uint32 now = Time64ToInt32(GetCurrent100NSTime()); |
- |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_GOOGLE)); |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_UPDATE)); |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENTS)); |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENT_STATE)); |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENTS_GOOPDATE)); |
- EXPECT_TRUE(RegKey::HasKey(USER_REG_CLIENT_STATE_GOOPDATE)); |
- EXPECT_FALSE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_MEDIUM)); |
- |
- // Ensure no unexpected keys were created. |
- RegKey google_key; |
- EXPECT_SUCCEEDED(google_key.Open(USER_REG_GOOGLE)); |
- EXPECT_EQ(1, google_key.GetSubkeyCount()); |
- |
- RegKey update_key; |
- EXPECT_SUCCEEDED(update_key.Open(USER_REG_UPDATE)); |
- EXPECT_EQ(2, update_key.GetSubkeyCount()); |
- |
- RegKey clients_key; |
- EXPECT_SUCCEEDED(clients_key.Open(USER_REG_CLIENTS)); |
- EXPECT_EQ(1, clients_key.GetSubkeyCount()); |
- |
- RegKey client_state_key; |
- EXPECT_SUCCEEDED(client_state_key.Open(USER_REG_CLIENT_STATE)); |
- EXPECT_EQ(1, client_state_key.GetSubkeyCount()); |
- |
- CPath expected_shell_path(GetGoogleUpdateUserPath()); |
- expected_shell_path.Append(kOmahaShellFileName); |
- CString shell_path; |
- EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_UPDATE, _T("path"), &shell_path)); |
- EXPECT_STREQ(expected_shell_path, shell_path); |
- |
- CString product_version; |
- EXPECT_SUCCEEDED(RegKey::GetValue(USER_REG_CLIENT_STATE_GOOPDATE, |
- _T("pv"), |
- &product_version)); |
- EXPECT_STREQ(GetVersionString(), product_version); |
-} |
- |
-// TODO(omaha): Assumes GoogleUpdate.exe exists in the installed location, which |
-// is not always true when run independently. |
-// TODO(omaha): Fails when run by itself on Windows Vista. |
-TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest, |
- InstallRegistryValues) { |
- EXPECT_SUCCEEDED(InstallRegistryValues()); |
- const uint32 now = Time64ToInt32(GetCurrent100NSTime()); |
- |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_GOOGLE)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_UPDATE)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENTS)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENTS_GOOPDATE)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_GOOPDATE)); |
- EXPECT_TRUE(RegKey::HasKey(MACHINE_REG_CLIENT_STATE_MEDIUM)); |
- |
- // Ensure no unexpected keys were created. |
- RegKey google_key; |
- EXPECT_SUCCEEDED(google_key.Open(MACHINE_REG_GOOGLE)); |
- EXPECT_EQ(1, google_key.GetSubkeyCount()); |
- |
- RegKey update_key; |
- EXPECT_SUCCEEDED(update_key.Open(MACHINE_REG_UPDATE)); |
- EXPECT_EQ(3, update_key.GetSubkeyCount()); |
- |
- RegKey clients_key; |
- EXPECT_SUCCEEDED(clients_key.Open(MACHINE_REG_CLIENTS)); |
- EXPECT_EQ(1, clients_key.GetSubkeyCount()); |
- |
- RegKey client_state_key; |
- EXPECT_SUCCEEDED(client_state_key.Open(MACHINE_REG_CLIENT_STATE)); |
- EXPECT_EQ(1, client_state_key.GetSubkeyCount()); |
- |
- RegKey client_state_medium_key; |
- EXPECT_SUCCEEDED( |
- client_state_medium_key.Open(MACHINE_REG_CLIENT_STATE_MEDIUM)); |
- EXPECT_EQ(0, client_state_medium_key.GetSubkeyCount()); |
- VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM); |
- |
- CString expected_shell_path; |
- EXPECT_SUCCEEDED(GetFolderPath(CSIDL_PROGRAM_FILES, &expected_shell_path)); |
- expected_shell_path.Append(_T("\\") SHORT_COMPANY_NAME |
- _T("\\") PRODUCT_NAME |
- _T("\\GoogleUpdate.exe")); |
- CString shell_path; |
- EXPECT_SUCCEEDED( |
- RegKey::GetValue(MACHINE_REG_UPDATE, _T("path"), &shell_path)); |
- EXPECT_STREQ(expected_shell_path, shell_path); |
- |
- CString product_version; |
- EXPECT_SUCCEEDED(RegKey::GetValue(MACHINE_REG_CLIENT_STATE_GOOPDATE, |
- _T("pv"), |
- &product_version)); |
- EXPECT_STREQ(GetVersionString(), product_version); |
- |
- // Test permission of Update and ClientState. ClientStateMedium checked above. |
- VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_UPDATE); |
- VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE); |
- |
- // Test the permission inheritance for ClientStateMedium. |
- const CString app_client_state_medium_key_name = AppendRegKeyPath( |
- MACHINE_REG_CLIENT_STATE_MEDIUM, |
- kAppId1); |
- EXPECT_SUCCEEDED(RegKey::CreateKey(app_client_state_medium_key_name)); |
- |
- VerifyHklmKeyHasMediumIntegrity(app_client_state_medium_key_name); |
-} |
- |
-TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest, |
- CreateClientStateMedium_KeyAlreadyExistsWithSamePermissions) { |
- EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_UPDATE)); |
- EXPECT_SUCCEEDED(CreateClientStateMedium()); |
- VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM); |
- |
- EXPECT_SUCCEEDED(CreateClientStateMedium()); |
- VerifyHklmKeyHasDefaultIntegrity(MACHINE_REG_CLIENT_STATE_MEDIUM); |
-} |
- |
-// CreateClientStateMedium does not replace permissions on existing keys. |
-TEST_F(SetupGoogleUpdateMachineRegistryProtectedInHklmTest, |
- CreateClientStateMedium_KeysAlreadyExistWithDifferentPermissions) { |
- // The checks in this test can take a long time, so avoid them by default. |
- if (!ShouldRunEnormousTest()) { |
- return; |
- } |
- |
- const CString app1_client_state_medium_key_name = AppendRegKeyPath( |
- MACHINE_REG_CLIENT_STATE_MEDIUM, |
- kAppId1); |
- const CString app2_client_state_medium_key_name = AppendRegKeyPath( |
- MACHINE_REG_CLIENT_STATE_MEDIUM, |
- kAppId2); |
- |
- TRUSTEE users = {0}; |
- users.TrusteeForm = TRUSTEE_IS_NAME; |
- users.TrusteeType = TRUSTEE_IS_GROUP; |
- users.ptstrName = _T("Users"); |
- |
- TRUSTEE interactive = {0}; |
- interactive.TrusteeForm = TRUSTEE_IS_NAME; |
- interactive.TrusteeType = TRUSTEE_IS_GROUP; |
- interactive.ptstrName = _T("INTERACTIVE"); |
- |
- EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_UPDATE)); |
- |
- CDacl dacl; |
- dacl.AddAllowedAce(Sids::Admins(), GENERIC_ALL); |
- // Interactive is not explicitly set. |
- dacl.AddAllowedAce(Sids::Users(), KEY_WRITE); |
- |
- CSecurityDesc security_descriptor; |
- security_descriptor.SetDacl(dacl); |
- security_descriptor.MakeAbsolute(); |
- |
- CSecurityAttributes sa; |
- sa.Set(security_descriptor); |
- |
- EXPECT_SUCCEEDED(RegKey::CreateKey(MACHINE_REG_CLIENT_STATE_MEDIUM, |
- REG_NONE, |
- REG_OPTION_NON_VOLATILE, |
- &sa)); |
- |
- EXPECT_SUCCEEDED(RegKey::CreateKey(app1_client_state_medium_key_name)); |
- |
- |
- EXPECT_SUCCEEDED(CreateClientStateMedium()); |
- |
- // Verify the ACLs for the existing keys were not changed. |
- // INTERACTIVE appears to inherit the privileges of Users. |
- VerifyAccessRightsForTrustee( |
- MACHINE_REG_CLIENT_STATE_MEDIUM, KEY_WRITE, &dacl, &users); |
- VerifyAccessRightsForTrustee( |
- MACHINE_REG_CLIENT_STATE_MEDIUM, KEY_WRITE, &dacl, &interactive); |
- VerifyAccessRightsForTrustee( |
- app1_client_state_medium_key_name, KEY_WRITE, &dacl, &users); |
- VerifyAccessRightsForTrustee( |
- app1_client_state_medium_key_name, KEY_WRITE, &dacl, &interactive); |
- |
- // Verify the ACLs of newly created subkeys. |
- EXPECT_SUCCEEDED(RegKey::CreateKey(app2_client_state_medium_key_name)); |
- VerifyAccessRightsForTrustee( |
- app2_client_state_medium_key_name, KEY_WRITE, &dacl, &users); |
- VerifyAccessRightsForTrustee( |
- app2_client_state_medium_key_name, KEY_WRITE, &dacl, &interactive); |
-} |
- |
-TEST_F(SetupGoogleUpdateUserRegistryProtectedTest, |
- InstallLaunchMechanisms_RunKeyValueExists) { |
- EXPECT_SUCCEEDED(RegKey::SetValue(kRunKey, |
- _T(OMAHA_APP_NAME_ANSI), |
- _T("fo /b"))); |
- |
- EXPECT_SUCCEEDED(InstallLaunchMechanisms()); |
- |
- CString value; |
- EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey, |
- _T(OMAHA_APP_NAME_ANSI), |
- &value)); |
- EXPECT_STREQ(expected_run_key_value_, value); |
- EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
- EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false)); |
- |
- UninstallLaunchMechanisms(); |
- EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI))); |
- EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
-} |
- |
-TEST_F(SetupGoogleUpdateUserRegistryProtectedTest, |
- InstallLaunchMechanisms_RunKeyDoesNotExist) { |
- ASSERT_FALSE(RegKey::HasKey(kRunKey)); |
- |
- EXPECT_SUCCEEDED(InstallLaunchMechanisms()); |
- |
- CString value; |
- EXPECT_SUCCEEDED(RegKey::GetValue(kRunKey, |
- _T(OMAHA_APP_NAME_ANSI), |
- &value)); |
- EXPECT_STREQ(expected_run_key_value_, value); |
- EXPECT_TRUE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
- EXPECT_FALSE(scheduled_task_utils::IsDisabledGoopdateTaskUA(false)); |
- |
- UninstallLaunchMechanisms(); |
- EXPECT_FALSE(RegKey::HasValue(kRunKey, _T(OMAHA_APP_NAME_ANSI))); |
- EXPECT_FALSE(scheduled_task_utils::IsInstalledGoopdateTaskUA(false)); |
-} |
- |
-// The helper can be installed when the test begins. |
-// It will not be installed when the test successfully completes. |
-TEST_F(SetupGoogleUpdateMachineTest, InstallAndUninstallMsiHelper) { |
- if (!ShouldRunLargeTest()) { |
- return; |
- } |
- const TCHAR* MsiInstallRegValueKey = |
- ConfigManager::Instance()->machine_registry_update(); |
- |
- CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString()); |
- |
- if (vista_util::IsUserAdmin()) { |
- // Prepare for the test - make sure the helper isn't installed. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Verify installation. |
- DWORD reg_value = 0xffffffff; |
- EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper()); |
- EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_HRESULT_SUCCEEDED(RegKey::GetValue(MsiInstallRegValueKey, |
- kMsiInstallRegValue, |
- ®_value)); |
- EXPECT_EQ(0, reg_value); |
- EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Verify over-install. |
- EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper()); |
- EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_HRESULT_SUCCEEDED(RegKey::GetValue(MsiInstallRegValueKey, |
- kMsiInstallRegValue, |
- ®_value)); |
- EXPECT_EQ(0, reg_value); |
- EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Verify uninstall. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Verify uninstall when not currently installed. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- } else { |
- { |
- // This method expects to be called elevated and makes an assumption |
- // about a return value. |
- ExpectAsserts expect_asserts; |
- EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_REJECTED), |
- InstallMsiHelper()); |
- } |
- if (IsMsiHelperInstalled()) { |
- // If the MSI is installed UninstallMsiHelper returns |
- // ERROR_INSTALL_FAILURE. |
- EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE), |
- UninstallMsiHelper()); |
- } else { |
- // If the MSI is not installed UninstallMsiHelper returns S_OK. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- } |
- } |
-} |
- |
-// This test installs a different build of the helper installer then calls |
-// InstallMsiHelper to install the one that has been built. |
-// If run without the REINSTALL property, ERROR_PRODUCT_VERSION would occur. |
-// This test verifies that such overinstalls are correctly handled and that the |
-// registry value is correctly changed. |
-// Note: The name of the installer cannot be different. MSI tries to find the |
-// original filename in the new directory. |
-// The helper can be installed when the test begins. |
-// It will not be installed when the test successfully completes. |
-TEST_F(SetupGoogleUpdateMachineTest, |
- InstallMsiHelper_OverinstallDifferentMsiBuild) { |
- if (!ShouldRunLargeTest()) { |
- return; |
- } |
- if (!vista_util::IsUserAdmin()) { |
- std::wcout << _T("\tThis test did not run because it must be run as admin.") |
- << std::endl; |
- return; |
- } |
- |
- const TCHAR kDifferentMsi[] = |
- _T("unittest_support\\GoogleUpdateHelper.msi"); |
- const TCHAR* MsiInstallRegValueKey = |
- ConfigManager::Instance()->machine_registry_update(); |
- |
- CopyFilesRequiredByFinishInstall(is_machine_, GetVersionString()); |
- |
- CString different_msi_path(app_util::GetCurrentModuleDirectory()); |
- ASSERT_TRUE(::PathAppend(CStrBuf(different_msi_path, MAX_PATH), |
- kDifferentMsi)); |
- |
- // Prepare for the test - make sure the helper is not installed. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Install an older version of the MSI. |
- DWORD reg_value = 0xffffffff; |
- ::MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); |
- EXPECT_EQ(ERROR_SUCCESS, ::MsiInstallProduct(different_msi_path, _T(""))); |
- EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_HRESULT_SUCCEEDED( |
- RegKey::GetValue(MsiInstallRegValueKey, kMsiInstallRegValue, ®_value)); |
- EXPECT_EQ(9, reg_value); |
- EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Over-install. |
- EXPECT_HRESULT_SUCCEEDED(InstallMsiHelper()); |
- EXPECT_TRUE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_HRESULT_SUCCEEDED( |
- RegKey::GetValue(MsiInstallRegValueKey, kMsiInstallRegValue, ®_value)); |
- EXPECT_EQ(0, reg_value); |
- EXPECT_TRUE(RegKey::HasKey(kMsiUninstallKey)); |
- |
- // Clean up. |
- EXPECT_HRESULT_SUCCEEDED(UninstallMsiHelper()); |
- EXPECT_FALSE(RegKey::HasValue(MsiInstallRegValueKey, kMsiInstallRegValue)); |
- EXPECT_FALSE(RegKey::HasKey(kMsiUninstallKey)); |
-} |
- |
-} // namespace omaha |