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

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

Issue 10537182: The user's consent to crash dumps reporting can now be set via the UI (Windows only). The checkbox … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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_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"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/file_path.h" 13 #include "base/file_path.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/json/json_reader.h" 15 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/string16.h" 18 #include "base/string16.h"
19 #include "base/stringize_macros.h" 19 #include "base/stringize_macros.h"
20 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
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/breakpad.h"
30 #include "remoting/host/plugin/daemon_installer_win.h" 31 #include "remoting/host/plugin/daemon_installer_win.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
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 const CompletionCallback& done_callback) OVERRIDE;
81 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, 82 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
82 const CompletionCallback& done_callback) OVERRIDE; 83 const CompletionCallback& done_callback) OVERRIDE;
83 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; 84 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
84 virtual void SetWindow(void* window_handle) OVERRIDE; 85 virtual void SetWindow(void* window_handle) OVERRIDE;
85 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE; 86 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
87 virtual void GetUsageStatsConsent(
88 const GetUsageStatsConsentCallback& done_callback) OVERRIDE;
89 virtual void SetUsageStatsConsent(bool consent) 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();
(...skipping 22 matching lines...) Expand all
118 void DoGetConfig(const GetConfigCallback& callback); 122 void DoGetConfig(const GetConfigCallback& callback);
119 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, 123 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config,
120 const CompletionCallback& done_callback); 124 const CompletionCallback& done_callback);
121 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, 125 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
122 const CompletionCallback& done_callback); 126 const CompletionCallback& done_callback);
123 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, 127 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
124 const CompletionCallback& done_callback); 128 const CompletionCallback& done_callback);
125 void DoStop(const CompletionCallback& done_callback); 129 void DoStop(const CompletionCallback& done_callback);
126 void DoSetWindow(void* window_handle); 130 void DoSetWindow(void* window_handle);
127 void DoGetVersion(const GetVersionCallback& callback); 131 void DoGetVersion(const GetVersionCallback& callback);
132 void DoGetUsageStatsConsent(
133 const GetUsageStatsConsentCallback& callback);
134 void DoSetUsageStatsConsent(bool consent);
128 135
129 // |control_| holds a reference to an instance of the daemon controller 136 // |control_| and |control2_| hold references to an instance of the daemon
130 // to prevent a UAC prompt on every operation. 137 // controller to prevent a UAC prompt on every operation.
131 ScopedComPtr<IDaemonControl> control_; 138 ScopedComPtr<IDaemonControl> control_;
139 ScopedComPtr<IDaemonControl2> control2_;
132 140
133 // True if |control_| holds a reference to an elevated instance of the daemon 141 // True if |control_| holds a reference to an elevated instance of the daemon
134 // controller. 142 // controller.
135 bool control_is_elevated_; 143 bool control_is_elevated_;
136 144
137 // This timer is used to release |control_| after a timeout. 145 // This timer is used to release |control_| after a timeout.
138 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; 146 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_;
139 147
140 // Handle of the plugin window. 148 // Handle of the plugin window.
141 HWND window_handle_; 149 HWND window_handle_;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 window_handle)); 259 window_handle));
252 } 260 }
253 261
254 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) { 262 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) {
255 worker_thread_.message_loop_proxy()->PostTask( 263 worker_thread_.message_loop_proxy()->PostTask(
256 FROM_HERE, 264 FROM_HERE,
257 base::Bind(&DaemonControllerWin::DoGetVersion, 265 base::Bind(&DaemonControllerWin::DoGetVersion,
258 base::Unretained(this), callback)); 266 base::Unretained(this), callback));
259 } 267 }
260 268
269 void DaemonControllerWin::GetUsageStatsConsent(
270 const GetUsageStatsConsentCallback& callback) {
271 worker_thread_.message_loop_proxy()->PostTask(
272 FROM_HERE,
273 base::Bind(&DaemonControllerWin::DoGetUsageStatsConsent,
274 base::Unretained(this), callback));
275 }
276
277 void DaemonControllerWin::SetUsageStatsConsent(bool consent) {
278 worker_thread_.message_loop_proxy()->PostTask(
279 FROM_HERE,
280 base::Bind(&DaemonControllerWin::DoSetUsageStatsConsent,
281 base::Unretained(this), consent));
282 }
283
261 HRESULT DaemonControllerWin::ActivateController() { 284 HRESULT DaemonControllerWin::ActivateController() {
262 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 285 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
263 286
264 if (control_.get() == NULL) { 287 if (control_.get() == NULL) {
265 CLSID class_id; 288 CLSID class_id;
266 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); 289 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id);
267 if (FAILED(hr)) { 290 if (FAILED(hr)) {
268 return hr; 291 return hr;
269 } 292 }
270 293
271 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, 294 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER,
272 IID_IDaemonControl, control_.ReceiveVoid()); 295 IID_IDaemonControl, control_.ReceiveVoid());
273 if (FAILED(hr)) { 296 if (FAILED(hr)) {
274 return hr; 297 return hr;
275 } 298 }
299
300 // Ignore the error. IID_IDaemonControl2 is optional.
301 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid());
276 } 302 }
277 303
278 return S_OK; 304 return S_OK;
279 } 305 }
280 306
281 HRESULT DaemonControllerWin::ActivateElevatedController() { 307 HRESULT DaemonControllerWin::ActivateElevatedController() {
282 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 308 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
283 309
284 // Release an unprivileged instance of the daemon controller if any. 310 // Release an unprivileged instance of the daemon controller if any.
285 if (!control_is_elevated_) { 311 if (!control_is_elevated_) {
286 ReleaseController(); 312 ReleaseController();
287 } 313 }
288 314
289 if (control_.get() == NULL) { 315 if (control_.get() == NULL) {
290 BIND_OPTS3 bind_options; 316 BIND_OPTS3 bind_options;
291 memset(&bind_options, 0, sizeof(bind_options)); 317 memset(&bind_options, 0, sizeof(bind_options));
292 bind_options.cbStruct = sizeof(bind_options); 318 bind_options.cbStruct = sizeof(bind_options);
293 bind_options.hwnd = GetTopLevelWindow(window_handle_); 319 bind_options.hwnd = GetTopLevelWindow(window_handle_);
294 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; 320 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
295 321
296 HRESULT hr = ::CoGetObject( 322 HRESULT hr = ::CoGetObject(
297 kDaemonControllerElevationMoniker, 323 kDaemonControllerElevationMoniker,
298 &bind_options, 324 &bind_options,
299 IID_IDaemonControl, 325 IID_IDaemonControl,
300 control_.ReceiveVoid()); 326 control_.ReceiveVoid());
301 if (FAILED(hr)) { 327 if (FAILED(hr)) {
302 return hr; 328 return hr;
303 } 329 }
304 330
331 // Ignore the error. IID_IDaemonControl2 is optional.
332 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid());
Jamie 2012/06/14 23:43:56 Does this result in an elevated IDaemonControl2 in
alexeypa (please no reviews) 2012/06/19 23:27:29 Yes, but the UAC prompt has been shown to the user
Jamie 2012/06/21 18:47:52 My point is that if the code is designed to be run
alexeypa (please no reviews) 2012/06/21 23:30:25 The code was designed to be running as either non-
333
305 // Note that we hold a reference to an elevated instance now. 334 // Note that we hold a reference to an elevated instance now.
306 control_is_elevated_ = true; 335 control_is_elevated_ = true;
307 336
308 // Release |control_| upon expiration of the timeout. 337 // Release |control_| upon expiration of the timeout.
309 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); 338 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>());
310 release_timer_->Start(FROM_HERE, 339 release_timer_->Start(FROM_HERE,
311 base::TimeDelta::FromSeconds(kUacTimeoutSec), 340 base::TimeDelta::FromSeconds(kUacTimeoutSec),
312 this, 341 this,
313 &DaemonControllerWin::ReleaseController); 342 &DaemonControllerWin::ReleaseController);
314 } 343 }
315 344
316 return S_OK; 345 return S_OK;
317 } 346 }
318 347
319 void DaemonControllerWin::ReleaseController() { 348 void DaemonControllerWin::ReleaseController() {
320 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 349 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
321 350
322 control_.Release(); 351 control_.Release();
352 control2_.Release();
323 release_timer_.reset(); 353 release_timer_.reset();
324 control_is_elevated_ = false; 354 control_is_elevated_ = false;
325 } 355 }
326 356
327 void DaemonControllerWin::OnInstallationComplete( 357 void DaemonControllerWin::OnInstallationComplete(
328 scoped_ptr<base::DictionaryValue> config, 358 scoped_ptr<base::DictionaryValue> config,
329 const CompletionCallback& done_callback, 359 const CompletionCallback& done_callback,
330 HRESULT result) { 360 HRESULT result) {
331 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 361 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
332 362
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 hr = control_->GetVersion(version.Receive()); 615 hr = control_->GetVersion(version.Receive());
586 if (FAILED(hr)) { 616 if (FAILED(hr)) {
587 callback.Run(version_null); 617 callback.Run(version_null);
588 return; 618 return;
589 } 619 }
590 620
591 callback.Run(UTF16ToUTF8( 621 callback.Run(UTF16ToUTF8(
592 string16(static_cast<BSTR>(version), version.Length()))); 622 string16(static_cast<BSTR>(version), version.Length())));
593 } 623 }
594 624
625 void DaemonControllerWin::DoGetUsageStatsConsent(
626 const GetUsageStatsConsentCallback& callback) {
627 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
628
629 // Activate the Daemon Controller and see if it supports |IDaemonControl2|.
630 HRESULT hr = ActivateController();
631 if (FAILED(hr) || control2_.get() == NULL) {
632 callback.Run(false, false);
Jamie 2012/06/14 23:43:56 There should be a mechanism for reporting "not imp
alexeypa (please no reviews) 2012/06/19 23:27:29 Done.
633 return;
634 }
635
636 // Get the recorded user's consent.
637 BOOL set_by_policy;
638 BOOL allowed;
639 hr = control2_->GetUsageStatsConsent(&set_by_policy, &allowed);
640 if (FAILED(hr)) {
641 callback.Run(false, false);
642 return;
643 }
644
645 callback.Run(!!set_by_policy, !!allowed);
646 }
647
648 void DaemonControllerWin::DoSetUsageStatsConsent(bool consent) {
649 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
650
651 // Activate the Daemon Controller and see if it supports |IDaemonControl2|.
652 HRESULT hr = ActivateController();
653 if (FAILED(hr) || control2_.get() == NULL) {
654 return;
Jamie 2012/06/14 23:43:56 It would be better to report failure to the caller
alexeypa (please no reviews) 2012/06/19 23:27:29 Done.
655 }
656
657 // Record the user's consent.
658 hr = control2_->SetUsageStatsConsent(consent);
659 if (FAILED(hr)) {
660 return;
661 }
662 }
663
595 } // namespace 664 } // namespace
596 665
597 scoped_ptr<DaemonController> remoting::DaemonController::Create() { 666 scoped_ptr<DaemonController> remoting::DaemonController::Create() {
598 return scoped_ptr<DaemonController>(new DaemonControllerWin()); 667 return scoped_ptr<DaemonController>(new DaemonControllerWin());
599 } 668 }
600 669
601 } // namespace remoting 670 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698