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 |