| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/installer/util/google_update_util.h" | 5 #include "chrome/installer/util/google_update_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 } | 43 } |
| 44 | 44 |
| 45 // Returns GoogleUpdateSetup.exe's executable path at specified level. | 45 // Returns GoogleUpdateSetup.exe's executable path at specified level. |
| 46 // or an empty path if none is found. | 46 // or an empty path if none is found. |
| 47 base::FilePath GetGoogleUpdateSetupExe(bool system_install) { | 47 base::FilePath GetGoogleUpdateSetupExe(bool system_install) { |
| 48 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 48 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 49 RegKey update_key; | 49 RegKey update_key; |
| 50 | 50 |
| 51 if (update_key.Open(root_key, kRegPathGoogleUpdate, KEY_QUERY_VALUE) == | 51 if (update_key.Open(root_key, kRegPathGoogleUpdate, KEY_QUERY_VALUE) == |
| 52 ERROR_SUCCESS) { | 52 ERROR_SUCCESS) { |
| 53 string16 path_str; | 53 base::string16 path_str; |
| 54 string16 version_str; | 54 base::string16 version_str; |
| 55 if ((update_key.ReadValue(kRegPathField, &path_str) == ERROR_SUCCESS) && | 55 if ((update_key.ReadValue(kRegPathField, &path_str) == ERROR_SUCCESS) && |
| 56 (update_key.ReadValue(kRegGoogleUpdateVersion, &version_str) == | 56 (update_key.ReadValue(kRegGoogleUpdateVersion, &version_str) == |
| 57 ERROR_SUCCESS)) { | 57 ERROR_SUCCESS)) { |
| 58 return base::FilePath(path_str).DirName().Append(version_str). | 58 return base::FilePath(path_str).DirName().Append(version_str). |
| 59 Append(kGoogleUpdateSetupExe); | 59 Append(kGoogleUpdateSetupExe); |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 return base::FilePath(); | 62 return base::FilePath(); |
| 63 } | 63 } |
| 64 | 64 |
| 65 // If Google Update is present at system-level, sets |cmd_string| to the command | 65 // If Google Update is present at system-level, sets |cmd_string| to the command |
| 66 // line to install Google Update at user-level and returns true. | 66 // line to install Google Update at user-level and returns true. |
| 67 // Otherwise, clears |cmd_string| and returns false. | 67 // Otherwise, clears |cmd_string| and returns false. |
| 68 bool GetUserLevelGoogleUpdateInstallCommandLine(string16* cmd_string) { | 68 bool GetUserLevelGoogleUpdateInstallCommandLine(base::string16* cmd_string) { |
| 69 cmd_string->clear(); | 69 cmd_string->clear(); |
| 70 base::FilePath google_update_setup( | 70 base::FilePath google_update_setup( |
| 71 GetGoogleUpdateSetupExe(true)); // system-level. | 71 GetGoogleUpdateSetupExe(true)); // system-level. |
| 72 if (!google_update_setup.empty()) { | 72 if (!google_update_setup.empty()) { |
| 73 CommandLine cmd(google_update_setup); | 73 CommandLine cmd(google_update_setup); |
| 74 // Appends "/install runtime=true&needsadmin=false /silent /nomitag". | 74 // Appends "/install runtime=true&needsadmin=false /silent /nomitag". |
| 75 // NB: /nomitag needs to be at the end. | 75 // NB: /nomitag needs to be at the end. |
| 76 // Constants are found in code.google.com/p/omaha/common/const_cmd_line.h. | 76 // Constants are found in code.google.com/p/omaha/common/const_cmd_line.h. |
| 77 cmd.AppendArg("/install"); | 77 cmd.AppendArg("/install"); |
| 78 // The "&" can be used in base::LaunchProcess() without quotation | 78 // The "&" can be used in base::LaunchProcess() without quotation |
| 79 // (this is problematic only if run from command prompt). | 79 // (this is problematic only if run from command prompt). |
| 80 cmd.AppendArg("runtime=true&needsadmin=false"); | 80 cmd.AppendArg("runtime=true&needsadmin=false"); |
| 81 cmd.AppendArg("/silent"); | 81 cmd.AppendArg("/silent"); |
| 82 cmd.AppendArg("/nomitag"); | 82 cmd.AppendArg("/nomitag"); |
| 83 *cmd_string = cmd.GetCommandLineString(); | 83 *cmd_string = cmd.GetCommandLineString(); |
| 84 } | 84 } |
| 85 return !cmd_string->empty(); | 85 return !cmd_string->empty(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 // Launches command |cmd_string|, and waits for |timeout| milliseconds before | 88 // Launches command |cmd_string|, and waits for |timeout| milliseconds before |
| 89 // timing out. To wait indefinitely, one can set | 89 // timing out. To wait indefinitely, one can set |
| 90 // |timeout| to be base::TimeDelta::FromMilliseconds(INFINITE). | 90 // |timeout| to be base::TimeDelta::FromMilliseconds(INFINITE). |
| 91 // Returns true if this executes successfully. | 91 // Returns true if this executes successfully. |
| 92 // Returns false if command execution fails to execute, or times out. | 92 // Returns false if command execution fails to execute, or times out. |
| 93 bool LaunchProcessAndWaitWithTimeout(const string16& cmd_string, | 93 bool LaunchProcessAndWaitWithTimeout(const base::string16& cmd_string, |
| 94 base::TimeDelta timeout) { | 94 base::TimeDelta timeout) { |
| 95 bool success = false; | 95 bool success = false; |
| 96 base::win::ScopedHandle process; | 96 base::win::ScopedHandle process; |
| 97 int exit_code = 0; | 97 int exit_code = 0; |
| 98 VLOG(0) << "Launching: " << cmd_string; | 98 VLOG(0) << "Launching: " << cmd_string; |
| 99 if (!base::LaunchProcess(cmd_string, base::LaunchOptions(), | 99 if (!base::LaunchProcess(cmd_string, base::LaunchOptions(), |
| 100 &process)) { | 100 &process)) { |
| 101 PLOG(ERROR) << "Failed to launch (" << cmd_string << ")"; | 101 PLOG(ERROR) << "Failed to launch (" << cmd_string << ")"; |
| 102 } else if (!base::WaitForExitCodeWithTimeout(process, &exit_code, timeout)) { | 102 } else if (!base::WaitForExitCodeWithTimeout(process, &exit_code, timeout)) { |
| 103 // The GetExitCodeProcess failed or timed-out. | 103 // The GetExitCodeProcess failed or timed-out. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 173 |
| 174 } // namespace | 174 } // namespace |
| 175 | 175 |
| 176 bool EnsureUserLevelGoogleUpdatePresent() { | 176 bool EnsureUserLevelGoogleUpdatePresent() { |
| 177 VLOG(0) << "Ensuring Google Update is present at user-level."; | 177 VLOG(0) << "Ensuring Google Update is present at user-level."; |
| 178 | 178 |
| 179 bool success = false; | 179 bool success = false; |
| 180 if (IsGoogleUpdatePresent(false)) { | 180 if (IsGoogleUpdatePresent(false)) { |
| 181 success = true; | 181 success = true; |
| 182 } else { | 182 } else { |
| 183 string16 cmd_string; | 183 base::string16 cmd_string; |
| 184 if (!GetUserLevelGoogleUpdateInstallCommandLine(&cmd_string)) { | 184 if (!GetUserLevelGoogleUpdateInstallCommandLine(&cmd_string)) { |
| 185 LOG(ERROR) << "Cannot find Google Update at system-level."; | 185 LOG(ERROR) << "Cannot find Google Update at system-level."; |
| 186 // Ideally we should return false. However, this case should not be | 186 // Ideally we should return false. However, this case should not be |
| 187 // encountered by regular users, and developers (who often installs | 187 // encountered by regular users, and developers (who often installs |
| 188 // Chrome without Google Update) may be unduly impeded by this case. | 188 // Chrome without Google Update) may be unduly impeded by this case. |
| 189 // Therefore we return true. | 189 // Therefore we return true. |
| 190 success = true; | 190 success = true; |
| 191 } else { | 191 } else { |
| 192 success = LaunchProcessAndWaitWithTimeout(cmd_string, | 192 success = LaunchProcessAndWaitWithTimeout(cmd_string, |
| 193 base::TimeDelta::FromMilliseconds(INFINITE)); | 193 base::TimeDelta::FromMilliseconds(INFINITE)); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 return success; | 196 return success; |
| 197 } | 197 } |
| 198 | 198 |
| 199 bool UninstallGoogleUpdate(bool system_install) { | 199 bool UninstallGoogleUpdate(bool system_install) { |
| 200 bool success = false; | 200 bool success = false; |
| 201 string16 cmd_string( | 201 base::string16 cmd_string( |
| 202 GoogleUpdateSettings::GetUninstallCommandLine(system_install)); | 202 GoogleUpdateSettings::GetUninstallCommandLine(system_install)); |
| 203 if (cmd_string.empty()) { | 203 if (cmd_string.empty()) { |
| 204 success = true; // Nothing to; vacuous success. | 204 success = true; // Nothing to; vacuous success. |
| 205 } else { | 205 } else { |
| 206 success = LaunchProcessAndWaitWithTimeout(cmd_string, | 206 success = LaunchProcessAndWaitWithTimeout(cmd_string, |
| 207 base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs)); | 207 base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs)); |
| 208 } | 208 } |
| 209 return success; | 209 return success; |
| 210 } | 210 } |
| 211 | 211 |
| 212 std::string GetUntrustedDataValue(const std::string& key) { | 212 std::string GetUntrustedDataValue(const std::string& key) { |
| 213 std::map<std::string, std::string> untrusted_data; | 213 std::map<std::string, std::string> untrusted_data; |
| 214 if (GetGoogleUpdateUntrustedData(&untrusted_data)) { | 214 if (GetGoogleUpdateUntrustedData(&untrusted_data)) { |
| 215 std::map<std::string, std::string>::const_iterator data_it( | 215 std::map<std::string, std::string>::const_iterator data_it( |
| 216 untrusted_data.find(key)); | 216 untrusted_data.find(key)); |
| 217 if (data_it != untrusted_data.end()) | 217 if (data_it != untrusted_data.end()) |
| 218 return data_it->second; | 218 return data_it->second; |
| 219 } | 219 } |
| 220 | 220 |
| 221 return std::string(); | 221 return std::string(); |
| 222 } | 222 } |
| 223 | 223 |
| 224 } // namespace google_update | 224 } // namespace google_update |
| OLD | NEW |