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

Side by Side Diff: remoting/host/plugin/daemon_installer_win.cc

Issue 10535082: /C++ readability/ - Make Chromoting Host report crashes to Breakpad (Windows only). The user must e… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removing omaha namespace. Created 8 years, 6 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 | Annotate | Revision Log
OLDNEW
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 "remoting/host/plugin/daemon_installer_win.h" 5 #include "remoting/host/plugin/daemon_installer_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/string16.h" 12 #include "base/string16.h"
13 #include "base/stringize_macros.h" 13 #include "base/stringize_macros.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/timer.h" 16 #include "base/timer.h"
17 #include "base/win/object_watcher.h" 17 #include "base/win/object_watcher.h"
18 #include "base/win/registry.h" 18 #include "base/win/registry.h"
19 #include "base/win/scoped_bstr.h" 19 #include "base/win/scoped_bstr.h"
20 #include "base/win/scoped_comptr.h" 20 #include "base/win/scoped_comptr.h"
21 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
22
23 namespace omaha {
24 #include "google_update/google_update_idl.h" 22 #include "google_update/google_update_idl.h"
25 } // namespace omaha 23 #include "remoting/host/constants.h"
26 24
27 using base::win::ScopedBstr; 25 using base::win::ScopedBstr;
28 using base::win::ScopedComPtr; 26 using base::win::ScopedComPtr;
29 27
30 namespace { 28 namespace {
31 29
32 // The COM elevation moniker for Omaha. 30 // The COM elevation moniker for Omaha.
33 const char16 kOmahaElevationMoniker[] = 31 const char16 kOmahaElevationMoniker[] =
34 TO_L_STRING("Elevation:Administrator!new:GoogleUpdate.Update3WebMachine"); 32 TO_L_STRING("Elevation:Administrator!new:GoogleUpdate.Update3WebMachine");
35 33
36 // The registry key where the configuration of Omaha is stored. 34 // The registry key where the configuration of Omaha is stored.
37 const char16 kOmahaUpdateKeyName[] = TO_L_STRING("Software\\Google\\Update"); 35 const char16 kOmahaUpdateKeyName[] = TO_L_STRING("Software\\Google\\Update");
38 36
39 // The name of the value where the full path to GoogleUpdate.exe is stored. 37 // The name of the value where the full path to GoogleUpdate.exe is stored.
40 const char16 kOmahaPathValueName[] = TO_L_STRING("path"); 38 const char16 kOmahaPathValueName[] = TO_L_STRING("path");
41 39
42 // The command line format string for GoogleUpdate.exe 40 // The command line format string for GoogleUpdate.exe
43 const char16 kGoogleUpdateCommandLineFormat[] = 41 const char16 kGoogleUpdateCommandLineFormat[] =
44 TO_L_STRING("\"%ls\" /install \"bundlename=Chromoting%%20Host&appguid=%ls&") 42 TO_L_STRING("\"%ls\" /install \"bundlename=Chromoting%%20Host&appguid=%ls&")
45 TO_L_STRING("appname=Chromoting%%20Host&needsadmin=True&lang=%ls\""); 43 TO_L_STRING("appname=Chromoting%%20Host&needsadmin=True&lang=%ls\"");
46 44
47 // The Omaha Appid of the host.
48 const char16 kOmahaAppid[] =
49 TO_L_STRING("{b210701e-ffc4-49e3-932b-370728c72662}");
50
51 // TODO(alexeypa): Get the desired laungage from the web app. 45 // TODO(alexeypa): Get the desired laungage from the web app.
52 const char16 kOmahaLanguage[] = TO_L_STRING("en"); 46 const char16 kOmahaLanguage[] = TO_L_STRING("en");
53 47
54 // An empty string for optional parameters. 48 // An empty string for optional parameters.
55 const char16 kOmahaEmpty[] = TO_L_STRING(""); 49 const char16 kOmahaEmpty[] = TO_L_STRING("");
56 50
57 // The installation status polling interval. 51 // The installation status polling interval.
58 const int kOmahaPollIntervalMs = 500; 52 const int kOmahaPollIntervalMs = 500;
59 53
60 } // namespace 54 } // namespace
61 55
62 namespace remoting { 56 namespace remoting {
63 57
64 // This class implements on-demand installation of the Chromoting Host via 58 // This class implements on-demand installation of the Chromoting Host via
65 // per-machine Omaha instance. 59 // per-machine Omaha instance.
66 class DaemonComInstallerWin : public DaemonInstallerWin { 60 class DaemonComInstallerWin : public DaemonInstallerWin {
67 public: 61 public:
68 DaemonComInstallerWin(const ScopedComPtr<omaha::IGoogleUpdate3Web>& update3, 62 DaemonComInstallerWin(const ScopedComPtr<IGoogleUpdate3Web>& update3,
69 const CompletionCallback& done); 63 const CompletionCallback& done);
70 64
71 // DaemonInstallerWin implementation. 65 // DaemonInstallerWin implementation.
72 virtual void Install() OVERRIDE; 66 virtual void Install() OVERRIDE;
73 67
74 private: 68 private:
75 // Polls the installation status performing state-specific actions (such as 69 // Polls the installation status performing state-specific actions (such as
76 // starting installation once download has finished). 70 // starting installation once download has finished).
77 void PollInstallationStatus(); 71 void PollInstallationStatus();
78 72
79 // Omaha interfaces. 73 // Omaha interfaces.
80 ScopedComPtr<omaha::IAppWeb> app_; 74 ScopedComPtr<IAppWeb> app_;
81 ScopedComPtr<omaha::IAppBundleWeb> bundle_; 75 ScopedComPtr<IAppBundleWeb> bundle_;
82 ScopedComPtr<omaha::IGoogleUpdate3Web> update3_; 76 ScopedComPtr<IGoogleUpdate3Web> update3_;
83 77
84 base::Timer polling_timer_; 78 base::Timer polling_timer_;
85 }; 79 };
86 80
87 // This class implements on-demand installation of the Chromoting Host by 81 // This class implements on-demand installation of the Chromoting Host by
88 // launching a per-user instance of Omaha and requesting elevation. 82 // launching a per-user instance of Omaha and requesting elevation.
89 class DaemonCommandLineInstallerWin 83 class DaemonCommandLineInstallerWin
90 : public DaemonInstallerWin, 84 : public DaemonInstallerWin,
91 public base::win::ObjectWatcher::Delegate { 85 public base::win::ObjectWatcher::Delegate {
92 public: 86 public:
93 DaemonCommandLineInstallerWin(const CompletionCallback& done); 87 DaemonCommandLineInstallerWin(const CompletionCallback& done);
94 ~DaemonCommandLineInstallerWin(); 88 ~DaemonCommandLineInstallerWin();
95 89
96 // DaemonInstallerWin implementation. 90 // DaemonInstallerWin implementation.
97 virtual void Install() OVERRIDE; 91 virtual void Install() OVERRIDE;
98 92
99 // base::win::ObjectWatcher::Delegate implementation. 93 // base::win::ObjectWatcher::Delegate implementation.
100 virtual void OnObjectSignaled(HANDLE object) OVERRIDE; 94 virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
101 95
102 private: 96 private:
103 // Handle of the launched process. 97 // Handle of the launched process.
104 base::win::ScopedHandle process_; 98 base::win::ScopedHandle process_;
105 99
106 // Used to determine when the launched process terminates. 100 // Used to determine when the launched process terminates.
107 base::win::ObjectWatcher process_watcher_; 101 base::win::ObjectWatcher process_watcher_;
108 }; 102 };
109 103
110 DaemonComInstallerWin::DaemonComInstallerWin( 104 DaemonComInstallerWin::DaemonComInstallerWin(
111 const ScopedComPtr<omaha::IGoogleUpdate3Web>& update3, 105 const ScopedComPtr<IGoogleUpdate3Web>& update3,
112 const CompletionCallback& done) 106 const CompletionCallback& done)
113 : DaemonInstallerWin(done), 107 : DaemonInstallerWin(done),
114 update3_(update3), 108 update3_(update3),
115 ALLOW_THIS_IN_INITIALIZER_LIST( 109 ALLOW_THIS_IN_INITIALIZER_LIST(
116 polling_timer_( 110 polling_timer_(
117 FROM_HERE, 111 FROM_HERE,
118 base::TimeDelta::FromMilliseconds(kOmahaPollIntervalMs), 112 base::TimeDelta::FromMilliseconds(kOmahaPollIntervalMs),
119 base::Bind(&DaemonComInstallerWin::PollInstallationStatus, 113 base::Bind(&DaemonComInstallerWin::PollInstallationStatus,
120 base::Unretained(this)), 114 base::Unretained(this)),
121 false)) { 115 false)) {
122 } 116 }
123 117
124 void DaemonComInstallerWin::Install() { 118 void DaemonComInstallerWin::Install() {
125 // Create an app bundle. 119 // Create an app bundle.
126 ScopedComPtr<IDispatch> dispatch; 120 ScopedComPtr<IDispatch> dispatch;
127 HRESULT hr = update3_->createAppBundleWeb(dispatch.Receive()); 121 HRESULT hr = update3_->createAppBundleWeb(dispatch.Receive());
128 if (FAILED(hr)) { 122 if (FAILED(hr)) {
129 Done(hr); 123 Done(hr);
130 return; 124 return;
131 } 125 }
132 126
133 hr = dispatch.QueryInterface(omaha::IID_IAppBundleWeb, bundle_.ReceiveVoid()); 127 hr = dispatch.QueryInterface(IID_IAppBundleWeb, bundle_.ReceiveVoid());
134 if (FAILED(hr)) { 128 if (FAILED(hr)) {
135 Done(hr); 129 Done(hr);
136 return; 130 return;
137 } 131 }
138 132
139 hr = bundle_->initialize(); 133 hr = bundle_->initialize();
140 if (FAILED(hr)) { 134 if (FAILED(hr)) {
141 Done(hr); 135 Done(hr);
142 return; 136 return;
143 } 137 }
144 138
145 // Add Chromoting Host to the bundle. 139 // Add Chromoting Host to the bundle.
146 ScopedBstr appid(kOmahaAppid); 140 ScopedBstr appid(kHostOmahaAppid);
147 ScopedBstr empty(kOmahaEmpty); 141 ScopedBstr empty(kOmahaEmpty);
148 ScopedBstr language(kOmahaLanguage); 142 ScopedBstr language(kOmahaLanguage);
149 hr = bundle_->createApp(appid, empty, language, empty); 143 hr = bundle_->createApp(appid, empty, language, empty);
150 if (FAILED(hr)) { 144 if (FAILED(hr)) {
151 Done(hr); 145 Done(hr);
152 return; 146 return;
153 } 147 }
154 148
155 hr = bundle_->checkForUpdate(); 149 hr = bundle_->checkForUpdate();
156 if (FAILED(hr)) { 150 if (FAILED(hr)) {
157 Done(hr); 151 Done(hr);
158 return; 152 return;
159 } 153 }
160 154
161 dispatch.Release(); 155 dispatch.Release();
162 hr = bundle_->get_appWeb(0, dispatch.Receive()); 156 hr = bundle_->get_appWeb(0, dispatch.Receive());
163 if (FAILED(hr)) { 157 if (FAILED(hr)) {
164 Done(hr); 158 Done(hr);
165 return; 159 return;
166 } 160 }
167 161
168 hr = dispatch.QueryInterface(omaha::IID_IAppWeb, 162 hr = dispatch.QueryInterface(IID_IAppWeb,
169 app_.ReceiveVoid()); 163 app_.ReceiveVoid());
170 if (FAILED(hr)) { 164 if (FAILED(hr)) {
171 Done(hr); 165 Done(hr);
172 return; 166 return;
173 } 167 }
174 168
175 // Now poll for the installation status. 169 // Now poll for the installation status.
176 PollInstallationStatus(); 170 PollInstallationStatus();
177 } 171 }
178 172
179 void DaemonComInstallerWin::PollInstallationStatus() { 173 void DaemonComInstallerWin::PollInstallationStatus() {
180 // Get the current application installation state. 174 // Get the current application installation state.
181 // N.B. The object underlying the ICurrentState interface has static data that 175 // N.B. The object underlying the ICurrentState interface has static data that
182 // does not get updated as the server state changes. To get the most "current" 176 // does not get updated as the server state changes. To get the most "current"
183 // state, the currentState property needs to be queried again. 177 // state, the currentState property needs to be queried again.
184 ScopedComPtr<IDispatch> dispatch; 178 ScopedComPtr<IDispatch> dispatch;
185 HRESULT hr = app_->get_currentState(dispatch.Receive()); 179 HRESULT hr = app_->get_currentState(dispatch.Receive());
186 if (FAILED(hr)) { 180 if (FAILED(hr)) {
187 Done(hr); 181 Done(hr);
188 return; 182 return;
189 } 183 }
190 184
191 ScopedComPtr<omaha::ICurrentState> current_state; 185 ScopedComPtr<ICurrentState> current_state;
192 hr = dispatch.QueryInterface(omaha::IID_ICurrentState, 186 hr = dispatch.QueryInterface(IID_ICurrentState,
193 current_state.ReceiveVoid()); 187 current_state.ReceiveVoid());
194 if (FAILED(hr)) { 188 if (FAILED(hr)) {
195 Done(hr); 189 Done(hr);
196 return; 190 return;
197 } 191 }
198 192
199 LONG state; 193 LONG state;
200 hr = current_state->get_stateValue(&state); 194 hr = current_state->get_stateValue(&state);
201 if (FAILED(hr)) { 195 if (FAILED(hr)) {
202 Done(hr); 196 Done(hr);
203 return; 197 return;
204 } 198 }
205 199
206 // Perform state-specific actions. 200 // Perform state-specific actions.
207 switch (state) { 201 switch (state) {
208 case omaha::STATE_INIT: 202 case STATE_INIT:
209 case omaha::STATE_WAITING_TO_CHECK_FOR_UPDATE: 203 case STATE_WAITING_TO_CHECK_FOR_UPDATE:
210 case omaha::STATE_CHECKING_FOR_UPDATE: 204 case STATE_CHECKING_FOR_UPDATE:
211 case omaha::STATE_WAITING_TO_DOWNLOAD: 205 case STATE_WAITING_TO_DOWNLOAD:
212 case omaha::STATE_RETRYING_DOWNLOAD: 206 case STATE_RETRYING_DOWNLOAD:
213 case omaha::STATE_DOWNLOADING: 207 case STATE_DOWNLOADING:
214 case omaha::STATE_WAITING_TO_INSTALL: 208 case STATE_WAITING_TO_INSTALL:
215 case omaha::STATE_INSTALLING: 209 case STATE_INSTALLING:
216 case omaha::STATE_PAUSED: 210 case STATE_PAUSED:
217 break; 211 break;
218 212
219 case omaha::STATE_UPDATE_AVAILABLE: 213 case STATE_UPDATE_AVAILABLE:
220 hr = bundle_->download(); 214 hr = bundle_->download();
221 if (FAILED(hr)) { 215 if (FAILED(hr)) {
222 Done(hr); 216 Done(hr);
223 return; 217 return;
224 } 218 }
225 break; 219 break;
226 220
227 case omaha::STATE_DOWNLOAD_COMPLETE: 221 case STATE_DOWNLOAD_COMPLETE:
228 case omaha::STATE_EXTRACTING: 222 case STATE_EXTRACTING:
229 case omaha::STATE_APPLYING_DIFFERENTIAL_PATCH: 223 case STATE_APPLYING_DIFFERENTIAL_PATCH:
230 case omaha::STATE_READY_TO_INSTALL: 224 case STATE_READY_TO_INSTALL:
231 hr = bundle_->install(); 225 hr = bundle_->install();
232 if (FAILED(hr)) { 226 if (FAILED(hr)) {
233 Done(hr); 227 Done(hr);
234 return; 228 return;
235 } 229 }
236 break; 230 break;
237 231
238 case omaha::STATE_INSTALL_COMPLETE: 232 case STATE_INSTALL_COMPLETE:
239 case omaha::STATE_NO_UPDATE: 233 case STATE_NO_UPDATE:
240 // Installation complete or not required. Report success. 234 // Installation complete or not required. Report success.
241 Done(S_OK); 235 Done(S_OK);
242 return; 236 return;
243 237
244 case omaha::STATE_ERROR: { 238 case STATE_ERROR: {
245 HRESULT error_code; 239 HRESULT error_code;
246 hr = current_state->get_errorCode(&error_code); 240 hr = current_state->get_errorCode(&error_code);
247 if (FAILED(hr)) { 241 if (FAILED(hr)) {
248 error_code = hr; 242 error_code = hr;
249 } 243 }
250 Done(error_code); 244 Done(error_code);
251 return; 245 return;
252 } 246 }
253 247
254 default: 248 default:
(...skipping 30 matching lines...) Expand all
285 &google_update); 279 &google_update);
286 if (result != ERROR_SUCCESS) { 280 if (result != ERROR_SUCCESS) {
287 Done(HRESULT_FROM_WIN32(result)); 281 Done(HRESULT_FROM_WIN32(result));
288 return; 282 return;
289 } 283 }
290 284
291 // Launch the updater process and wait for its termination. 285 // Launch the updater process and wait for its termination.
292 string16 command_line = 286 string16 command_line =
293 StringPrintf(kGoogleUpdateCommandLineFormat, 287 StringPrintf(kGoogleUpdateCommandLineFormat,
294 google_update.c_str(), 288 google_update.c_str(),
295 kOmahaAppid, 289 kHostOmahaAppid,
296 kOmahaLanguage); 290 kOmahaLanguage);
297 291
298 base::LaunchOptions options; 292 base::LaunchOptions options;
299 if (!base::LaunchProcess(command_line, options, process_.Receive())) { 293 if (!base::LaunchProcess(command_line, options, process_.Receive())) {
300 result = GetLastError(); 294 result = GetLastError();
301 Done(HRESULT_FROM_WIN32(result)); 295 Done(HRESULT_FROM_WIN32(result));
302 return; 296 return;
303 } 297 }
304 298
305 if (!process_watcher_.StartWatching(process_.Get(), this)) { 299 if (!process_watcher_.StartWatching(process_.Get(), this)) {
(...skipping 28 matching lines...) Expand all
334 scoped_ptr<DaemonInstallerWin> DaemonInstallerWin::Create( 328 scoped_ptr<DaemonInstallerWin> DaemonInstallerWin::Create(
335 HWND window_handle, 329 HWND window_handle,
336 CompletionCallback done) { 330 CompletionCallback done) {
337 // Check if the machine instance of Omaha is available. 331 // Check if the machine instance of Omaha is available.
338 BIND_OPTS3 bind_options; 332 BIND_OPTS3 bind_options;
339 memset(&bind_options, 0, sizeof(bind_options)); 333 memset(&bind_options, 0, sizeof(bind_options));
340 bind_options.cbStruct = sizeof(bind_options); 334 bind_options.cbStruct = sizeof(bind_options);
341 bind_options.hwnd = GetTopLevelWindow(window_handle); 335 bind_options.hwnd = GetTopLevelWindow(window_handle);
342 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; 336 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
343 337
344 ScopedComPtr<omaha::IGoogleUpdate3Web> update3; 338 ScopedComPtr<IGoogleUpdate3Web> update3;
345 HRESULT result = ::CoGetObject( 339 HRESULT result = ::CoGetObject(
346 kOmahaElevationMoniker, 340 kOmahaElevationMoniker,
347 &bind_options, 341 &bind_options,
348 omaha::IID_IGoogleUpdate3Web, 342 IID_IGoogleUpdate3Web,
349 update3.ReceiveVoid()); 343 update3.ReceiveVoid());
350 if (SUCCEEDED(result)) { 344 if (SUCCEEDED(result)) {
351 // The machine instance of Omaha is available and we successfully passed 345 // The machine instance of Omaha is available and we successfully passed
352 // the UAC prompt. 346 // the UAC prompt.
353 return scoped_ptr<DaemonInstallerWin>( 347 return scoped_ptr<DaemonInstallerWin>(
354 new DaemonComInstallerWin(update3, done)); 348 new DaemonComInstallerWin(update3, done));
355 } else if (result == CO_E_CLASSSTRING) { 349 } else if (result == CO_E_CLASSSTRING) {
356 // The machine instance of Omaha is not available so we will have to run 350 // The machine instance of Omaha is not available so we will have to run
357 // GoogleUpdate.exe manually passing "needsadmin=True". This will cause 351 // GoogleUpdate.exe manually passing "needsadmin=True". This will cause
358 // Omaha to install the machine instance first and then install Chromoting 352 // Omaha to install the machine instance first and then install Chromoting
(...skipping 22 matching lines...) Expand all
381 HWND parent = GetAncestor(window, GA_PARENT); 375 HWND parent = GetAncestor(window, GA_PARENT);
382 if (parent == NULL) { 376 if (parent == NULL) {
383 return window; 377 return window;
384 } 378 }
385 379
386 window = parent; 380 window = parent;
387 } 381 }
388 } 382 }
389 383
390 } // namespace remoting 384 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698