Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_frame/ready_mode/internal/registry_ready_mode_state.h" | 5 #include "chrome_frame/ready_mode/internal/registry_ready_mode_state.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/process_util.h" | 10 #include "base/process_util.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/time.h" | 12 #include "base/time.h" |
| 13 #include "base/task.h" | 13 #include "base/task.h" |
| 14 #include "base/win/registry.h" | 14 #include "base/win/registry.h" |
| 15 #include "base/win/scoped_comptr.h" | 15 #include "base/win/scoped_comptr.h" |
| 16 #include "base/win/scoped_handle.h" | 16 #include "base/win/scoped_handle.h" |
| 17 #include "base/win/windows_version.h" | |
| 17 #include "chrome/installer/util/browser_distribution.h" | 18 #include "chrome/installer/util/browser_distribution.h" |
| 18 #include "chrome/installer/util/google_update_constants.h" | 19 #include "chrome/installer/util/google_update_constants.h" |
| 19 #include "chrome/installer/util/master_preferences.h" | 20 #include "chrome/installer/util/master_preferences.h" |
| 20 #include "chrome/installer/util/util_constants.h" | 21 #include "chrome/installer/util/util_constants.h" |
| 22 #include "chrome_frame/chrome_launcher_utils.h" | |
| 21 #include "chrome_frame/ready_mode/ready_mode.h" | 23 #include "chrome_frame/ready_mode/ready_mode.h" |
| 22 #include "google_update_idl.h" // NOLINT | |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 26 // Looks up a command entry in the registry and attempts to execute it directly. | 27 // Looks up a command entry in the registry and attempts to execute it directly. |
| 27 // Returns the new process handle, which the caller is responsible for closing, | 28 // Returns the new process handle, which the caller is responsible for closing, |
| 28 // or NULL upon failure. | 29 // or NULL upon failure. |
| 29 HANDLE LaunchCommandDirectly(const std::wstring& command_field) { | 30 HANDLE LaunchCommandDirectly(const std::wstring& command_field) { |
| 30 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 31 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 31 std::wstring version_key_name(dist->GetVersionKey()); | 32 std::wstring version_key_name(dist->GetVersionKey()); |
| 32 | 33 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 44 } | 45 } |
| 45 } | 46 } |
| 46 } | 47 } |
| 47 return NULL; | 48 return NULL; |
| 48 } | 49 } |
| 49 | 50 |
| 50 // Attempts to launch a command using the ProcessLauncher. Returns a handle to | 51 // Attempts to launch a command using the ProcessLauncher. Returns a handle to |
| 51 // the launched process, which the caller is responsible for closing, or NULL | 52 // the launched process, which the caller is responsible for closing, or NULL |
| 52 // upon failure. | 53 // upon failure. |
| 53 HANDLE LaunchCommandViaProcessLauncher(const std::wstring& command_field) { | 54 HANDLE LaunchCommandViaProcessLauncher(const std::wstring& command_field) { |
| 54 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 55 HANDLE launched_process = NULL; |
| 55 | 56 |
| 56 base::win::ScopedComPtr<IProcessLauncher> ipl; | 57 scoped_ptr<CommandLine> command_line( |
| 57 HRESULT hr = ipl.CreateInstance(__uuidof(ProcessLauncherClass)); | 58 chrome_launcher::CreateUpdateCommandLine(command_field)); |
| 58 | 59 |
| 59 if (FAILED(hr)) { | 60 if (command_line != NULL) |
| 60 DLOG(ERROR) << "Failed to instantiate IProcessLauncher: " | 61 base::LaunchApp(*command_line, false, true, &launched_process); |
| 61 << base::StringPrintf("0x%08x", hr); | |
| 62 } else { | |
| 63 ULONG_PTR phandle = NULL; | |
| 64 DWORD id = GetCurrentProcessId(); | |
| 65 | 62 |
| 66 hr = ipl->LaunchCmdElevated(dist->GetAppGuid().c_str(), | 63 return launched_process; |
| 67 command_field.c_str(), id, &phandle); | |
| 68 if (SUCCEEDED(hr)) | |
| 69 return reinterpret_cast<HANDLE>(phandle); | |
| 70 | |
| 71 DLOG(ERROR) << "Failed to invoke IProcessLauncher::LaunchCmdElevated: " | |
| 72 << base::StringPrintf("0x%08x", hr); | |
| 73 } | |
| 74 | |
| 75 return NULL; | |
| 76 } | 64 } |
| 77 | 65 |
| 78 // Waits for the provided process to exit, and verifies that its exit code | 66 // Waits for the provided process to exit, and verifies that its exit code |
| 79 // corresponds to one of the known "success" codes for the installer. If the | 67 // corresponds to one of the known "success" codes for the installer. If the |
| 80 // exit code cannot be retrieved, or if it signals failure, returns false. | 68 // exit code cannot be retrieved, or if it signals failure, returns false. |
| 81 bool CheckProcessExitCode(HANDLE handle) { | 69 bool CheckProcessExitCode(HANDLE handle) { |
| 82 // TODO(erikwright): Use RegisterWaitForSingleObject to wait | 70 // TODO(erikwright): Use RegisterWaitForSingleObject to wait |
| 83 // asynchronously. | 71 // asynchronously. |
| 84 DWORD wait_result = WaitForSingleObject(handle, 5000); // (ms) | 72 DWORD wait_result = WaitForSingleObject(handle, 5000); // (ms) |
| 85 | 73 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 105 | 93 |
| 106 if (wait_result == WAIT_ABANDONED) | 94 if (wait_result == WAIT_ABANDONED) |
| 107 DLOG(ERROR) << "Unexpeced WAIT_ABANDONED while waiting on child process."; | 95 DLOG(ERROR) << "Unexpeced WAIT_ABANDONED while waiting on child process."; |
| 108 | 96 |
| 109 if (wait_result == WAIT_TIMEOUT) | 97 if (wait_result == WAIT_TIMEOUT) |
| 110 DLOG(ERROR) << "Timeout while waiting on child process."; | 98 DLOG(ERROR) << "Timeout while waiting on child process."; |
| 111 | 99 |
| 112 return false; | 100 return false; |
| 113 } | 101 } |
| 114 | 102 |
| 103 bool CanLaunchDirectly() { | |
| 104 if (base::win::GetVersion() < base::win::VERSION_VISTA) | |
| 105 return true; | |
| 106 | |
| 107 base::IntegrityLevel integrity_level; | |
|
amit
2011/01/24 05:54:50
= 0 or some invalid value?
erikwright (departed)
2011/01/24 06:21:00
Done.
| |
| 108 if (!base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), | |
| 109 &integrity_level)) { | |
| 110 DLOG(ERROR) << "Failed to determine process integrity level."; | |
| 111 return false; | |
| 112 } | |
| 113 | |
| 114 return integrity_level == base::HIGH_INTEGRITY; | |
|
amit
2011/01/24 05:54:50
Shouldn't this check be for MEDIUM_INTEGRITY (in o
erikwright (departed)
2011/01/24 06:21:00
Done.
| |
| 115 } | |
| 116 | |
| 115 // Attempts to launch the specified command either directly or via the | 117 // Attempts to launch the specified command either directly or via the |
| 116 // ProcessLauncher. Returns true if the command is launched and returns a | 118 // ProcessLauncher. Returns true if the command is launched and returns a |
| 117 // success code. | 119 // success code. |
| 118 bool LaunchAndCheckCommand(const std::wstring& command_field) { | 120 bool LaunchAndCheckCommand(const std::wstring& command_field) { |
| 119 base::win::ScopedHandle handle; | 121 base::win::ScopedHandle handle; |
| 120 | 122 |
| 121 handle.Set(LaunchCommandDirectly(command_field)); | 123 if (CanLaunchDirectly()) |
| 124 handle.Set(LaunchCommandDirectly(command_field)); | |
| 125 else | |
| 126 handle.Set(LaunchCommandViaProcessLauncher(command_field)); | |
| 127 | |
| 122 if (handle.IsValid() && CheckProcessExitCode(handle)) | 128 if (handle.IsValid() && CheckProcessExitCode(handle)) |
| 123 return true; | 129 return true; |
| 124 | 130 |
| 125 handle.Set(LaunchCommandViaProcessLauncher(command_field)); | |
| 126 if (handle.IsValid() && CheckProcessExitCode(handle)) | |
| 127 return true; | |
| 128 | |
| 129 DLOG(ERROR) << "Command " << command_field << " could not be launched."; | 131 DLOG(ERROR) << "Command " << command_field << " could not be launched."; |
| 130 return false; | 132 return false; |
| 131 } | 133 } |
| 132 | 134 |
| 133 } // namespace | 135 } // namespace |
| 134 | 136 |
| 135 RegistryReadyModeState::RegistryReadyModeState( | 137 RegistryReadyModeState::RegistryReadyModeState( |
| 136 const std::wstring& key_name, base::TimeDelta temporary_decline_duration, | 138 const std::wstring& key_name, base::TimeDelta temporary_decline_duration, |
| 137 Observer* observer) | 139 Observer* observer) |
| 138 : key_name_(key_name), | 140 : key_name_(key_name), |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 | 246 |
| 245 void RegistryReadyModeState::PermanentlyDeclineChromeFrame() { | 247 void RegistryReadyModeState::PermanentlyDeclineChromeFrame() { |
| 246 if (LaunchAndCheckCommand(google_update::kRegCFOptOutCmdField)) | 248 if (LaunchAndCheckCommand(google_update::kRegCFOptOutCmdField)) |
| 247 RefreshStateAndNotify(); | 249 RefreshStateAndNotify(); |
| 248 } | 250 } |
| 249 | 251 |
| 250 void RegistryReadyModeState::AcceptChromeFrame() { | 252 void RegistryReadyModeState::AcceptChromeFrame() { |
| 251 if (LaunchAndCheckCommand(google_update::kRegCFOptInCmdField)) | 253 if (LaunchAndCheckCommand(google_update::kRegCFOptInCmdField)) |
| 252 NotifyObserver(); | 254 NotifyObserver(); |
| 253 } | 255 } |
| OLD | NEW |