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 "remoting/host/plugin/daemon_controller.h" | 5 #include "remoting/host/plugin/daemon_controller.h" |
6 | 6 |
7 #include <objbase.h> | 7 #include <objbase.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/time.h" | 21 #include "base/time.h" |
22 #include "base/timer.h" | 22 #include "base/timer.h" |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
24 #include "base/values.h" | 24 #include "base/values.h" |
25 #include "base/win/scoped_bstr.h" | 25 #include "base/win/scoped_bstr.h" |
26 #include "base/win/scoped_comptr.h" | 26 #include "base/win/scoped_comptr.h" |
27 #include "base/win/windows_version.h" | 27 #include "base/win/windows_version.h" |
28 #include "remoting/base/scoped_sc_handle_win.h" | 28 #include "remoting/base/scoped_sc_handle_win.h" |
29 #include "remoting/host/branding.h" | 29 #include "remoting/host/branding.h" |
30 #include "remoting/host/plugin/daemon_installer_win.h" | 30 #include "remoting/host/plugin/daemon_installer_win.h" |
| 31 #include "remoting/host/usage_stats_consent.h" |
31 | 32 |
32 // MIDL-generated declarations and definitions. | 33 // MIDL-generated declarations and definitions. |
33 #include "remoting/host/elevated_controller.h" | 34 #include "remoting/host/elevated_controller.h" |
34 | 35 |
35 using base::win::ScopedBstr; | 36 using base::win::ScopedBstr; |
36 using base::win::ScopedComPtr; | 37 using base::win::ScopedComPtr; |
37 | 38 |
38 namespace remoting { | 39 namespace remoting { |
39 | 40 |
40 namespace { | 41 namespace { |
(...skipping 29 matching lines...) Expand all Loading... |
70 | 71 |
71 class DaemonControllerWin : public remoting::DaemonController { | 72 class DaemonControllerWin : public remoting::DaemonController { |
72 public: | 73 public: |
73 DaemonControllerWin(); | 74 DaemonControllerWin(); |
74 virtual ~DaemonControllerWin(); | 75 virtual ~DaemonControllerWin(); |
75 | 76 |
76 virtual State GetState() OVERRIDE; | 77 virtual State GetState() OVERRIDE; |
77 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; | 78 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; |
78 virtual void SetConfigAndStart( | 79 virtual void SetConfigAndStart( |
79 scoped_ptr<base::DictionaryValue> config, | 80 scoped_ptr<base::DictionaryValue> config, |
80 const CompletionCallback& done_callback) OVERRIDE; | 81 bool consent, |
| 82 const CompletionCallback& done) OVERRIDE; |
81 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 83 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
82 const CompletionCallback& done_callback) OVERRIDE; | 84 const CompletionCallback& done_callback) OVERRIDE; |
83 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; | 85 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; |
84 virtual void SetWindow(void* window_handle) OVERRIDE; | 86 virtual void SetWindow(void* window_handle) OVERRIDE; |
85 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE; | 87 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE; |
| 88 virtual void GetUsageStatsConsent( |
| 89 const GetUsageStatsConsentCallback& done) OVERRIDE; |
86 | 90 |
87 private: | 91 private: |
88 // Activates an unprivileged instance of the daemon controller and caches it. | 92 // Activates an unprivileged instance of the daemon controller and caches it. |
89 HRESULT ActivateController(); | 93 HRESULT ActivateController(); |
90 | 94 |
91 // Activates an elevated instance of the daemon controller and caches it. | 95 // Activates an elevated instance of the daemon controller and caches it. |
92 HRESULT ActivateElevatedController(); | 96 HRESULT ActivateElevatedController(); |
93 | 97 |
94 // Releases the cached instance of the controller. | 98 // Releases the cached instance of the controller. |
95 void ReleaseController(); | 99 void ReleaseController(); |
96 | 100 |
97 // Procedes with the daemon configuration if the installation succeeded, | 101 // Procedes with the daemon configuration if the installation succeeded, |
98 // otherwise reports the error. | 102 // otherwise reports the error. |
99 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, | 103 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, |
100 const CompletionCallback& done_callback, | 104 bool consent, |
| 105 const CompletionCallback& done, |
101 HRESULT result); | 106 HRESULT result); |
102 | 107 |
103 // Opens the Chromoting service returning its handle in |service_out|. | 108 // Opens the Chromoting service returning its handle in |service_out|. |
104 DWORD OpenService(ScopedScHandle* service_out); | 109 DWORD OpenService(ScopedScHandle* service_out); |
105 | 110 |
106 // Converts a config dictionary to a scoped BSTR. | 111 // Converts a config dictionary to a scoped BSTR. |
107 static void ConfigToString(const base::DictionaryValue& config, | 112 static void ConfigToString(const base::DictionaryValue& config, |
108 ScopedBstr* out); | 113 ScopedBstr* out); |
109 | 114 |
110 // Converts a Windows service status code to a Daemon state. | 115 // Converts a Windows service status code to a Daemon state. |
111 static State ConvertToDaemonState(DWORD service_state); | 116 static State ConvertToDaemonState(DWORD service_state); |
112 | 117 |
113 // Converts HRESULT to the AsyncResult. | 118 // Converts HRESULT to the AsyncResult. |
114 static AsyncResult HResultToAsyncResult(HRESULT hr); | 119 static AsyncResult HResultToAsyncResult(HRESULT hr); |
115 | 120 |
116 // The functions that actually do the work. They should be called in | 121 // The functions that actually do the work. They should be called in |
117 // the context of |worker_thread_|; | 122 // the context of |worker_thread_|; |
118 void DoGetConfig(const GetConfigCallback& callback); | 123 void DoGetConfig(const GetConfigCallback& callback); |
119 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, | 124 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, |
| 125 bool consent, |
120 const CompletionCallback& done_callback); | 126 const CompletionCallback& done_callback); |
121 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, | 127 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, |
122 const CompletionCallback& done_callback); | 128 bool consent, |
| 129 const CompletionCallback& done); |
123 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, | 130 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, |
124 const CompletionCallback& done_callback); | 131 const CompletionCallback& done_callback); |
125 void DoStop(const CompletionCallback& done_callback); | 132 void DoStop(const CompletionCallback& done_callback); |
126 void DoSetWindow(void* window_handle); | 133 void DoSetWindow(void* window_handle); |
127 void DoGetVersion(const GetVersionCallback& callback); | 134 void DoGetVersion(const GetVersionCallback& callback); |
| 135 void DoGetUsageStatsConsent( |
| 136 const GetUsageStatsConsentCallback& done); |
128 | 137 |
129 // |control_| holds a reference to an instance of the daemon controller | 138 // |control_| and |control2_| hold references to an instance of the daemon |
130 // to prevent a UAC prompt on every operation. | 139 // controller to prevent a UAC prompt on every operation. |
131 ScopedComPtr<IDaemonControl> control_; | 140 ScopedComPtr<IDaemonControl> control_; |
| 141 ScopedComPtr<IDaemonControl2> control2_; |
132 | 142 |
133 // True if |control_| holds a reference to an elevated instance of the daemon | 143 // True if |control_| holds a reference to an elevated instance of the daemon |
134 // controller. | 144 // controller. |
135 bool control_is_elevated_; | 145 bool control_is_elevated_; |
136 | 146 |
137 // This timer is used to release |control_| after a timeout. | 147 // This timer is used to release |control_| after a timeout. |
138 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; | 148 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; |
139 | 149 |
140 // Handle of the plugin window. | 150 // Handle of the plugin window. |
141 HWND window_handle_; | 151 HWND window_handle_; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 224 |
215 void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) { | 225 void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) { |
216 worker_thread_.message_loop_proxy()->PostTask( | 226 worker_thread_.message_loop_proxy()->PostTask( |
217 FROM_HERE, | 227 FROM_HERE, |
218 base::Bind(&DaemonControllerWin::DoGetConfig, | 228 base::Bind(&DaemonControllerWin::DoGetConfig, |
219 base::Unretained(this), callback)); | 229 base::Unretained(this), callback)); |
220 } | 230 } |
221 | 231 |
222 void DaemonControllerWin::SetConfigAndStart( | 232 void DaemonControllerWin::SetConfigAndStart( |
223 scoped_ptr<base::DictionaryValue> config, | 233 scoped_ptr<base::DictionaryValue> config, |
224 const CompletionCallback& done_callback) { | 234 bool consent, |
| 235 const CompletionCallback& done) { |
225 worker_thread_.message_loop_proxy()->PostTask( | 236 worker_thread_.message_loop_proxy()->PostTask( |
226 FROM_HERE, base::Bind( | 237 FROM_HERE, base::Bind( |
227 &DaemonControllerWin::DoInstallAsNeededAndStart, | 238 &DaemonControllerWin::DoInstallAsNeededAndStart, |
228 base::Unretained(this), base::Passed(&config), done_callback)); | 239 base::Unretained(this), base::Passed(&config), consent, done)); |
229 } | 240 } |
230 | 241 |
231 void DaemonControllerWin::UpdateConfig( | 242 void DaemonControllerWin::UpdateConfig( |
232 scoped_ptr<base::DictionaryValue> config, | 243 scoped_ptr<base::DictionaryValue> config, |
233 const CompletionCallback& done_callback) { | 244 const CompletionCallback& done_callback) { |
234 worker_thread_.message_loop_proxy()->PostTask( | 245 worker_thread_.message_loop_proxy()->PostTask( |
235 FROM_HERE, base::Bind( | 246 FROM_HERE, base::Bind( |
236 &DaemonControllerWin::DoUpdateConfig, | 247 &DaemonControllerWin::DoUpdateConfig, |
237 base::Unretained(this), base::Passed(&config), done_callback)); | 248 base::Unretained(this), base::Passed(&config), done_callback)); |
238 } | 249 } |
(...skipping 12 matching lines...) Expand all Loading... |
251 window_handle)); | 262 window_handle)); |
252 } | 263 } |
253 | 264 |
254 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) { | 265 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) { |
255 worker_thread_.message_loop_proxy()->PostTask( | 266 worker_thread_.message_loop_proxy()->PostTask( |
256 FROM_HERE, | 267 FROM_HERE, |
257 base::Bind(&DaemonControllerWin::DoGetVersion, | 268 base::Bind(&DaemonControllerWin::DoGetVersion, |
258 base::Unretained(this), callback)); | 269 base::Unretained(this), callback)); |
259 } | 270 } |
260 | 271 |
| 272 void DaemonControllerWin::GetUsageStatsConsent( |
| 273 const GetUsageStatsConsentCallback& done) { |
| 274 worker_thread_.message_loop_proxy()->PostTask( |
| 275 FROM_HERE, |
| 276 base::Bind(&DaemonControllerWin::DoGetUsageStatsConsent, |
| 277 base::Unretained(this), done)); |
| 278 } |
| 279 |
261 HRESULT DaemonControllerWin::ActivateController() { | 280 HRESULT DaemonControllerWin::ActivateController() { |
262 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 281 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
263 | 282 |
264 if (control_.get() == NULL) { | 283 if (control_.get() == NULL) { |
265 CLSID class_id; | 284 CLSID class_id; |
266 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); | 285 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); |
267 if (FAILED(hr)) { | 286 if (FAILED(hr)) { |
268 return hr; | 287 return hr; |
269 } | 288 } |
270 | 289 |
271 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, | 290 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, |
272 IID_IDaemonControl, control_.ReceiveVoid()); | 291 IID_IDaemonControl, control_.ReceiveVoid()); |
273 if (FAILED(hr)) { | 292 if (FAILED(hr)) { |
274 return hr; | 293 return hr; |
275 } | 294 } |
| 295 |
| 296 // Ignore the error. IID_IDaemonControl2 is optional. |
| 297 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); |
276 } | 298 } |
277 | 299 |
278 return S_OK; | 300 return S_OK; |
279 } | 301 } |
280 | 302 |
281 HRESULT DaemonControllerWin::ActivateElevatedController() { | 303 HRESULT DaemonControllerWin::ActivateElevatedController() { |
282 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 304 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
283 | 305 |
284 // Release an unprivileged instance of the daemon controller if any. | 306 // Release an unprivileged instance of the daemon controller if any. |
285 if (!control_is_elevated_) { | 307 if (!control_is_elevated_) { |
286 ReleaseController(); | 308 ReleaseController(); |
287 } | 309 } |
288 | 310 |
289 if (control_.get() == NULL) { | 311 if (control_.get() == NULL) { |
290 BIND_OPTS3 bind_options; | 312 BIND_OPTS3 bind_options; |
291 memset(&bind_options, 0, sizeof(bind_options)); | 313 memset(&bind_options, 0, sizeof(bind_options)); |
292 bind_options.cbStruct = sizeof(bind_options); | 314 bind_options.cbStruct = sizeof(bind_options); |
293 bind_options.hwnd = GetTopLevelWindow(window_handle_); | 315 bind_options.hwnd = GetTopLevelWindow(window_handle_); |
294 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; | 316 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; |
295 | 317 |
296 HRESULT hr = ::CoGetObject( | 318 HRESULT hr = ::CoGetObject( |
297 kDaemonControllerElevationMoniker, | 319 kDaemonControllerElevationMoniker, |
298 &bind_options, | 320 &bind_options, |
299 IID_IDaemonControl, | 321 IID_IDaemonControl, |
300 control_.ReceiveVoid()); | 322 control_.ReceiveVoid()); |
301 if (FAILED(hr)) { | 323 if (FAILED(hr)) { |
302 return hr; | 324 return hr; |
303 } | 325 } |
304 | 326 |
| 327 // Ignore the error. IID_IDaemonControl2 is optional. |
| 328 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); |
| 329 |
305 // Note that we hold a reference to an elevated instance now. | 330 // Note that we hold a reference to an elevated instance now. |
306 control_is_elevated_ = true; | 331 control_is_elevated_ = true; |
307 | 332 |
308 // Release |control_| upon expiration of the timeout. | 333 // Release |control_| upon expiration of the timeout. |
309 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); | 334 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); |
310 release_timer_->Start(FROM_HERE, | 335 release_timer_->Start(FROM_HERE, |
311 base::TimeDelta::FromSeconds(kUacTimeoutSec), | 336 base::TimeDelta::FromSeconds(kUacTimeoutSec), |
312 this, | 337 this, |
313 &DaemonControllerWin::ReleaseController); | 338 &DaemonControllerWin::ReleaseController); |
314 } | 339 } |
315 | 340 |
316 return S_OK; | 341 return S_OK; |
317 } | 342 } |
318 | 343 |
319 void DaemonControllerWin::ReleaseController() { | 344 void DaemonControllerWin::ReleaseController() { |
320 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 345 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
321 | 346 |
322 control_.Release(); | 347 control_.Release(); |
| 348 control2_.Release(); |
323 release_timer_.reset(); | 349 release_timer_.reset(); |
324 control_is_elevated_ = false; | 350 control_is_elevated_ = false; |
325 } | 351 } |
326 | 352 |
327 void DaemonControllerWin::OnInstallationComplete( | 353 void DaemonControllerWin::OnInstallationComplete( |
328 scoped_ptr<base::DictionaryValue> config, | 354 scoped_ptr<base::DictionaryValue> config, |
329 const CompletionCallback& done_callback, | 355 bool consent, |
| 356 const CompletionCallback& done, |
330 HRESULT result) { | 357 HRESULT result) { |
331 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 358 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
332 | 359 |
333 if (SUCCEEDED(result)) { | 360 if (SUCCEEDED(result)) { |
334 DoSetConfigAndStart(config.Pass(), done_callback); | 361 DoSetConfigAndStart(config.Pass(), consent, done); |
335 } else { | 362 } else { |
336 LOG(ERROR) << "Failed to install the Chromoting Host " | 363 LOG(ERROR) << "Failed to install the Chromoting Host " |
337 << "(error: 0x" << std::hex << result << std::dec << ")."; | 364 << "(error: 0x" << std::hex << result << std::dec << ")."; |
338 done_callback.Run(HResultToAsyncResult(result)); | 365 done.Run(HResultToAsyncResult(result)); |
339 } | 366 } |
340 | 367 |
341 DCHECK(installer_.get() != NULL); | 368 DCHECK(installer_.get() != NULL); |
342 installer_.reset(); | 369 installer_.reset(); |
343 } | 370 } |
344 | 371 |
345 DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) { | 372 DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) { |
346 // Open the service and query its current state. | 373 // Open the service and query its current state. |
347 ScopedScHandle scmanager( | 374 ScopedScHandle scmanager( |
348 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, | 375 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 return; | 473 return; |
447 } | 474 } |
448 // Release |config|, because dictionary points to the same object. | 475 // Release |config|, because dictionary points to the same object. |
449 config.release(); | 476 config.release(); |
450 | 477 |
451 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); | 478 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); |
452 } | 479 } |
453 | 480 |
454 void DaemonControllerWin::DoInstallAsNeededAndStart( | 481 void DaemonControllerWin::DoInstallAsNeededAndStart( |
455 scoped_ptr<base::DictionaryValue> config, | 482 scoped_ptr<base::DictionaryValue> config, |
456 const CompletionCallback& done_callback) { | 483 bool consent, |
| 484 const CompletionCallback& done) { |
457 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 485 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
458 | 486 |
459 // Configure and start the Daemon Controller if it is installed already. | 487 // Configure and start the Daemon Controller if it is installed already. |
460 HRESULT hr = ActivateElevatedController(); | 488 HRESULT hr = ActivateElevatedController(); |
461 if (SUCCEEDED(hr)) { | 489 if (SUCCEEDED(hr)) { |
462 DoSetConfigAndStart(config.Pass(), done_callback); | 490 DoSetConfigAndStart(config.Pass(), consent, done); |
463 return; | 491 return; |
464 } | 492 } |
465 | 493 |
466 // Otherwise, install it if its COM registration entry is missing. | 494 // Otherwise, install it if its COM registration entry is missing. |
467 if (hr == CO_E_CLASSSTRING) { | 495 if (hr == CO_E_CLASSSTRING) { |
468 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( | 496 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( |
469 GetTopLevelWindow(window_handle_), | 497 GetTopLevelWindow(window_handle_), |
470 base::Bind(&DaemonControllerWin::OnInstallationComplete, | 498 base::Bind(&DaemonControllerWin::OnInstallationComplete, |
471 base::Unretained(this), | 499 base::Unretained(this), |
472 base::Passed(&config), | 500 base::Passed(&config), |
473 done_callback)); | 501 consent, |
| 502 done)); |
474 if (installer.get()) { | 503 if (installer.get()) { |
475 DCHECK(!installer_.get()); | 504 DCHECK(!installer_.get()); |
476 installer_ = installer.Pass(); | 505 installer_ = installer.Pass(); |
477 installer_->Install(); | 506 installer_->Install(); |
478 } | 507 } |
479 } else { | 508 } else { |
480 LOG(ERROR) << "Failed to initiate the Chromoting Host installation " | 509 LOG(ERROR) << "Failed to initiate the Chromoting Host installation " |
481 << "(error: 0x" << std::hex << hr << std::dec << ")."; | 510 << "(error: 0x" << std::hex << hr << std::dec << ")."; |
482 done_callback.Run(HResultToAsyncResult(hr)); | 511 done.Run(HResultToAsyncResult(hr)); |
483 } | 512 } |
484 } | 513 } |
485 | 514 |
486 void DaemonControllerWin::DoSetConfigAndStart( | 515 void DaemonControllerWin::DoSetConfigAndStart( |
487 scoped_ptr<base::DictionaryValue> config, | 516 scoped_ptr<base::DictionaryValue> config, |
488 const CompletionCallback& done_callback) { | 517 bool consent, |
| 518 const CompletionCallback& done) { |
489 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 519 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
490 | 520 |
491 HRESULT hr = ActivateElevatedController(); | 521 HRESULT hr = ActivateElevatedController(); |
492 if (FAILED(hr)) { | 522 if (FAILED(hr)) { |
493 done_callback.Run(HResultToAsyncResult(hr)); | 523 done.Run(HResultToAsyncResult(hr)); |
494 return; | 524 return; |
495 } | 525 } |
496 | 526 |
| 527 // Record the user's consent. |
| 528 if (control2_.get()) { |
| 529 hr = control2_->SetUsageStatsConsent(consent); |
| 530 if (FAILED(hr)) { |
| 531 done.Run(HResultToAsyncResult(hr)); |
| 532 return; |
| 533 } |
| 534 } |
| 535 |
497 // Set the configuration. | 536 // Set the configuration. |
498 ScopedBstr config_str(NULL); | 537 ScopedBstr config_str(NULL); |
499 ConfigToString(*config, &config_str); | 538 ConfigToString(*config, &config_str); |
500 if (config_str == NULL) { | 539 if (config_str == NULL) { |
501 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); | 540 done.Run(HResultToAsyncResult(E_OUTOFMEMORY)); |
502 return; | 541 return; |
503 } | 542 } |
504 | 543 |
505 hr = control_->SetOwnerWindow( | 544 hr = control_->SetOwnerWindow( |
506 reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); | 545 reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); |
507 if (FAILED(hr)) { | 546 if (FAILED(hr)) { |
508 done_callback.Run(HResultToAsyncResult(hr)); | 547 done.Run(HResultToAsyncResult(hr)); |
509 return; | 548 return; |
510 } | 549 } |
511 | 550 |
512 hr = control_->SetConfig(config_str); | 551 hr = control_->SetConfig(config_str); |
513 if (FAILED(hr)) { | 552 if (FAILED(hr)) { |
514 done_callback.Run(HResultToAsyncResult(hr)); | 553 done.Run(HResultToAsyncResult(hr)); |
515 return; | 554 return; |
516 } | 555 } |
517 | 556 |
518 // Start daemon. | 557 // Start daemon. |
519 hr = control_->StartDaemon(); | 558 hr = control_->StartDaemon(); |
520 done_callback.Run(HResultToAsyncResult(hr)); | 559 done.Run(HResultToAsyncResult(hr)); |
521 } | 560 } |
522 | 561 |
523 void DaemonControllerWin::DoUpdateConfig( | 562 void DaemonControllerWin::DoUpdateConfig( |
524 scoped_ptr<base::DictionaryValue> config, | 563 scoped_ptr<base::DictionaryValue> config, |
525 const CompletionCallback& done_callback) { | 564 const CompletionCallback& done_callback) { |
526 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 565 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
527 | 566 |
528 HRESULT hr = ActivateElevatedController(); | 567 HRESULT hr = ActivateElevatedController(); |
529 if (FAILED(hr)) { | 568 if (FAILED(hr)) { |
530 done_callback.Run(HResultToAsyncResult(hr)); | 569 done_callback.Run(HResultToAsyncResult(hr)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 hr = control_->GetVersion(version.Receive()); | 624 hr = control_->GetVersion(version.Receive()); |
586 if (FAILED(hr)) { | 625 if (FAILED(hr)) { |
587 callback.Run(version_null); | 626 callback.Run(version_null); |
588 return; | 627 return; |
589 } | 628 } |
590 | 629 |
591 callback.Run(UTF16ToUTF8( | 630 callback.Run(UTF16ToUTF8( |
592 string16(static_cast<BSTR>(version), version.Length()))); | 631 string16(static_cast<BSTR>(version), version.Length()))); |
593 } | 632 } |
594 | 633 |
| 634 void DaemonControllerWin::DoGetUsageStatsConsent( |
| 635 const GetUsageStatsConsentCallback& done) { |
| 636 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 637 |
| 638 // Activate the Daemon Controller and see if it supports |IDaemonControl2|. |
| 639 HRESULT hr = ActivateController(); |
| 640 if (FAILED(hr) || control2_.get() == NULL) { |
| 641 done.Run(false, false, false); |
| 642 return; |
| 643 } |
| 644 |
| 645 // Get the recorded user's consent. |
| 646 BOOL allowed; |
| 647 BOOL set_by_policy; |
| 648 hr = control2_->GetUsageStatsConsent(&allowed, &set_by_policy); |
| 649 if (FAILED(hr)) { |
| 650 done.Run(true, false, false); |
| 651 return; |
| 652 } |
| 653 |
| 654 done.Run(true, !!allowed, !!set_by_policy); |
| 655 } |
| 656 |
595 } // namespace | 657 } // namespace |
596 | 658 |
597 scoped_ptr<DaemonController> remoting::DaemonController::Create() { | 659 scoped_ptr<DaemonController> remoting::DaemonController::Create() { |
598 return scoped_ptr<DaemonController>(new DaemonControllerWin()); | 660 return scoped_ptr<DaemonController>(new DaemonControllerWin()); |
599 } | 661 } |
600 | 662 |
601 } // namespace remoting | 663 } // namespace remoting |
OLD | NEW |