Chromium Code Reviews| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 const char kDaemonControllerThreadName[] = "Daemon Controller thread"; | 48 const char kDaemonControllerThreadName[] = "Daemon Controller thread"; |
| 49 | 49 |
| 50 // The maximum interval between showing UAC prompts. | 50 // The maximum interval between showing UAC prompts. |
| 51 const int kUacTimeoutSec = 15 * 60; | 51 const int kUacTimeoutSec = 15 * 60; |
| 52 | 52 |
| 53 // A base::Thread implementation that initializes COM on the new thread. | 53 // A base::Thread implementation that initializes COM on the new thread. |
| 54 class ComThread : public base::Thread { | 54 class ComThread : public base::Thread { |
| 55 public: | 55 public: |
| 56 explicit ComThread(const char* name); | 56 explicit ComThread(const char* name); |
| 57 | 57 |
| 58 // Activates an elevated instance of the controller and returns the pointer | |
| 59 // to the control interface in |control_out|. This class keeps the ownership | |
| 60 // of the pointer so the caller should not call call AddRef() or Release(). | |
| 61 HRESULT ActivateElevatedController(HWND window_handle, | |
| 62 IDaemonControl** control_out); | |
| 63 | |
| 64 bool Start(); | 58 bool Start(); |
| 65 | 59 |
| 66 protected: | 60 protected: |
| 67 virtual void Init() OVERRIDE; | 61 virtual void Init() OVERRIDE; |
| 68 virtual void CleanUp() OVERRIDE; | 62 virtual void CleanUp() OVERRIDE; |
| 69 | 63 |
| 70 void ReleaseElevatedController(); | |
| 71 | |
| 72 ScopedComPtr<IDaemonControl> control_; | |
| 73 | |
| 74 // This timer is used to release |control_| after a timeout. | |
| 75 base::OneShotTimer<ComThread> release_timer_; | |
| 76 | |
| 77 DISALLOW_COPY_AND_ASSIGN(ComThread); | 64 DISALLOW_COPY_AND_ASSIGN(ComThread); |
| 78 }; | 65 }; |
| 79 | 66 |
| 80 class DaemonControllerWin : public remoting::DaemonController { | 67 class DaemonControllerWin : public remoting::DaemonController { |
| 81 public: | 68 public: |
| 82 DaemonControllerWin(); | 69 DaemonControllerWin(); |
| 83 virtual ~DaemonControllerWin(); | 70 virtual ~DaemonControllerWin(); |
| 84 | 71 |
| 85 virtual State GetState() OVERRIDE; | 72 virtual State GetState() OVERRIDE; |
| 86 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; | 73 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; |
| 87 virtual void SetConfigAndStart( | 74 virtual void SetConfigAndStart( |
| 88 scoped_ptr<base::DictionaryValue> config, | 75 scoped_ptr<base::DictionaryValue> config, |
| 89 const CompletionCallback& done_callback) OVERRIDE; | 76 const CompletionCallback& done_callback) OVERRIDE; |
| 90 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 77 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
| 91 const CompletionCallback& done_callback) OVERRIDE; | 78 const CompletionCallback& done_callback) OVERRIDE; |
| 92 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; | 79 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; |
| 93 virtual void SetWindow(void* window_handle) OVERRIDE; | 80 virtual void SetWindow(void* window_handle) OVERRIDE; |
| 94 | 81 |
| 95 private: | 82 private: |
| 96 // Converts a Windows service status code to a Daemon state. | 83 // Activates an elevated instance of the controller and stores the pointer |
|
simonmorris
2012/05/01 17:29:12
"...and caches it." Or "stores" it?
alexeypa (please no reviews)
2012/05/01 18:00:01
Done.
| |
| 97 static State ConvertToDaemonState(DWORD service_state); | 84 // in |control_|. |
| 85 HRESULT ActivateElevatedController(); | |
| 98 | 86 |
| 99 // Converts HRESULT to the AsyncResult. | 87 // Releases the cached instance of the evelated controller. |
|
simonmorris
2012/05/01 17:29:12
evelated -> elevated
cached -> stored?
alexeypa (please no reviews)
2012/05/01 18:00:01
Done.
| |
| 100 static AsyncResult HResultToAsyncResult(HRESULT hr); | 88 void ReleaseElevatedController(); |
| 101 | 89 |
| 102 // Procedes with the daemon configuration if the installation succeeded, | 90 // Procedes with the daemon configuration if the installation succeeded, |
| 103 // otherwise reports the error. | 91 // otherwise reports the error. |
| 104 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, | 92 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, |
| 105 const CompletionCallback& done_callback, | 93 const CompletionCallback& done_callback, |
| 106 HRESULT result); | 94 HRESULT result); |
| 107 | 95 |
| 108 // Opens the Chromoting service returning its handle in |service_out|. | 96 // Opens the Chromoting service returning its handle in |service_out|. |
| 109 DWORD OpenService(ScopedScHandle* service_out); | 97 DWORD OpenService(ScopedScHandle* service_out); |
| 110 | 98 |
| 111 // Converts a config dictionary to a scoped BSTR. | 99 // Converts a config dictionary to a scoped BSTR. |
| 112 static void ConfigToString(const base::DictionaryValue& config, | 100 static void ConfigToString(const base::DictionaryValue& config, |
| 113 ScopedBstr* out); | 101 ScopedBstr* out); |
| 114 | 102 |
| 103 // Converts a Windows service status code to a Daemon state. | |
| 104 static State ConvertToDaemonState(DWORD service_state); | |
| 105 | |
| 106 // Converts HRESULT to the AsyncResult. | |
| 107 static AsyncResult HResultToAsyncResult(HRESULT hr); | |
| 108 | |
| 115 // The functions that actually do the work. They should be called in | 109 // The functions that actually do the work. They should be called in |
| 116 // the context of |worker_thread_|; | 110 // the context of |worker_thread_|; |
| 117 void DoGetConfig(const GetConfigCallback& callback); | 111 void DoGetConfig(const GetConfigCallback& callback); |
| 118 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, | 112 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, |
| 119 const CompletionCallback& done_callback); | 113 const CompletionCallback& done_callback); |
| 120 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, | 114 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, |
| 121 const CompletionCallback& done_callback); | 115 const CompletionCallback& done_callback); |
| 122 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, | 116 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, |
| 123 const CompletionCallback& done_callback); | 117 const CompletionCallback& done_callback); |
| 124 void DoStop(const CompletionCallback& done_callback); | 118 void DoStop(const CompletionCallback& done_callback); |
| 125 void DoSetWindow(void* window_handle); | 119 void DoSetWindow(void* window_handle); |
| 126 | 120 |
| 121 ScopedComPtr<IDaemonControl> control_; | |
| 122 | |
| 123 // This timer is used to release |control_| after a timeout. | |
| 124 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; | |
| 125 | |
| 127 // Handle of the plugin window. | 126 // Handle of the plugin window. |
| 128 HWND window_handle_; | 127 HWND window_handle_; |
| 129 | 128 |
| 130 // The worker thread used for servicing long running operations. | 129 // The worker thread used for servicing long running operations. |
| 131 ComThread worker_thread_; | 130 ComThread worker_thread_; |
| 132 | 131 |
| 133 scoped_ptr<DaemonInstallerWin> installer_; | 132 scoped_ptr<DaemonInstallerWin> installer_; |
| 134 | 133 |
| 135 DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin); | 134 DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin); |
| 136 }; | 135 }; |
| 137 | 136 |
| 138 ComThread::ComThread(const char* name) : base::Thread(name), control_(NULL) { | 137 ComThread::ComThread(const char* name) : base::Thread(name) { |
| 139 } | |
| 140 | |
| 141 HRESULT ComThread::ActivateElevatedController( | |
| 142 HWND window_handle, | |
| 143 IDaemonControl** control_out) { | |
| 144 // Cache an instance of the Elevated Controller to prevent a UAC prompt on | |
| 145 // every operation. | |
| 146 if (control_.get() == NULL) { | |
| 147 BIND_OPTS3 bind_options; | |
| 148 memset(&bind_options, 0, sizeof(bind_options)); | |
| 149 bind_options.cbStruct = sizeof(bind_options); | |
| 150 bind_options.hwnd = GetTopLevelWindow(window_handle); | |
| 151 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; | |
| 152 | |
| 153 HRESULT hr = ::CoGetObject( | |
| 154 kDaemonControllerElevationMoniker, | |
| 155 &bind_options, | |
| 156 IID_IDaemonControl, | |
| 157 control_.ReceiveVoid()); | |
| 158 if (FAILED(hr)) { | |
| 159 return hr; | |
| 160 } | |
| 161 | |
| 162 // Release |control_| upon expiration of the timeout. | |
| 163 release_timer_.Start(FROM_HERE, | |
| 164 base::TimeDelta::FromSeconds(kUacTimeoutSec), | |
| 165 this, &ComThread::ReleaseElevatedController); | |
| 166 } | |
| 167 | |
| 168 *control_out = control_.get(); | |
| 169 return S_OK; | |
| 170 } | 138 } |
| 171 | 139 |
| 172 bool ComThread::Start() { | 140 bool ComThread::Start() { |
| 173 // N.B. The single threaded COM apartment must be run on a UI message loop. | 141 // N.B. The single threaded COM apartment must be run on a UI message loop. |
| 174 base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0); | 142 base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0); |
| 175 return StartWithOptions(thread_options); | 143 return StartWithOptions(thread_options); |
| 176 } | 144 } |
| 177 | 145 |
| 178 void ComThread::Init() { | 146 void ComThread::Init() { |
| 179 CoInitialize(NULL); | 147 CoInitialize(NULL); |
| 180 } | 148 } |
| 181 | 149 |
| 182 void ComThread::CleanUp() { | 150 void ComThread::CleanUp() { |
| 183 ReleaseElevatedController(); | |
| 184 CoUninitialize(); | 151 CoUninitialize(); |
| 185 } | 152 } |
| 186 | 153 |
| 187 void ComThread::ReleaseElevatedController() { | |
| 188 control_.Release(); | |
| 189 } | |
| 190 | |
| 191 DaemonControllerWin::DaemonControllerWin() | 154 DaemonControllerWin::DaemonControllerWin() |
| 192 : window_handle_(NULL), | 155 : window_handle_(NULL), |
| 193 worker_thread_(kDaemonControllerThreadName) { | 156 worker_thread_(kDaemonControllerThreadName) { |
| 194 if (!worker_thread_.Start()) { | 157 if (!worker_thread_.Start()) { |
| 195 LOG(FATAL) << "Failed to start the Daemon Controller worker thread."; | 158 LOG(FATAL) << "Failed to start the Daemon Controller worker thread."; |
| 196 } | 159 } |
| 197 } | 160 } |
| 198 | 161 |
| 199 DaemonControllerWin::~DaemonControllerWin() { | 162 DaemonControllerWin::~DaemonControllerWin() { |
| 163 // Clean up resources allocated on the worker thread. | |
| 164 worker_thread_.message_loop_proxy()->PostTask( | |
| 165 FROM_HERE, | |
| 166 base::Bind(&DaemonControllerWin::ReleaseElevatedController, | |
| 167 base::Unretained(this))); | |
|
simonmorris
2012/05/01 17:29:12
How does this guarantee that ReleaseElevatedContro
alexeypa (please no reviews)
2012/05/01 18:00:01
worker_thread_.Stop() waits synchronously until al
| |
| 200 worker_thread_.Stop(); | 168 worker_thread_.Stop(); |
| 201 } | 169 } |
| 202 | 170 |
| 203 remoting::DaemonController::State DaemonControllerWin::GetState() { | 171 remoting::DaemonController::State DaemonControllerWin::GetState() { |
| 204 // TODO(alexeypa): Make the thread alertable, so we can switch to APC | 172 // TODO(alexeypa): Make the thread alertable, so we can switch to APC |
| 205 // notifications rather than polling. | 173 // notifications rather than polling. |
| 206 ScopedScHandle service; | 174 ScopedScHandle service; |
| 207 DWORD error = OpenService(&service); | 175 DWORD error = OpenService(&service); |
| 208 | 176 |
| 209 switch (error) { | 177 switch (error) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 done_callback)); | 226 done_callback)); |
| 259 } | 227 } |
| 260 | 228 |
| 261 void DaemonControllerWin::SetWindow(void* window_handle) { | 229 void DaemonControllerWin::SetWindow(void* window_handle) { |
| 262 worker_thread_.message_loop_proxy()->PostTask( | 230 worker_thread_.message_loop_proxy()->PostTask( |
| 263 FROM_HERE, base::Bind( | 231 FROM_HERE, base::Bind( |
| 264 &DaemonControllerWin::DoSetWindow, base::Unretained(this), | 232 &DaemonControllerWin::DoSetWindow, base::Unretained(this), |
| 265 window_handle)); | 233 window_handle)); |
| 266 } | 234 } |
| 267 | 235 |
| 268 // static | 236 HRESULT DaemonControllerWin::ActivateElevatedController() { |
| 269 remoting::DaemonController::State DaemonControllerWin::ConvertToDaemonState( | 237 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 270 DWORD service_state) { | |
| 271 switch (service_state) { | |
| 272 case SERVICE_RUNNING: | |
| 273 return STATE_STARTED; | |
| 274 | 238 |
| 275 case SERVICE_CONTINUE_PENDING: | 239 // Cache an instance of the Elevated Controller to prevent a UAC prompt on |
| 276 case SERVICE_START_PENDING: | 240 // every operation. |
| 277 return STATE_STARTING; | 241 if (control_.get() == NULL) { |
| 278 break; | 242 BIND_OPTS3 bind_options; |
| 243 memset(&bind_options, 0, sizeof(bind_options)); | |
| 244 bind_options.cbStruct = sizeof(bind_options); | |
| 245 bind_options.hwnd = GetTopLevelWindow(window_handle_); | |
| 246 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; | |
| 279 | 247 |
| 280 case SERVICE_PAUSE_PENDING: | 248 HRESULT hr = ::CoGetObject( |
| 281 case SERVICE_STOP_PENDING: | 249 kDaemonControllerElevationMoniker, |
| 282 return STATE_STOPPING; | 250 &bind_options, |
| 283 break; | 251 IID_IDaemonControl, |
| 252 control_.ReceiveVoid()); | |
| 253 if (FAILED(hr)) { | |
| 254 return hr; | |
| 255 } | |
| 284 | 256 |
| 285 case SERVICE_PAUSED: | 257 // Release |control_| upon expiration of the timeout. |
| 286 case SERVICE_STOPPED: | 258 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); |
|
Sergey Ulanov
2012/05/01 17:26:05
Maybe use DelayTimer here and reset it ever time t
alexeypa (please no reviews)
2012/05/01 17:32:30
I intentionally implemented it this way. I.e. it i
| |
| 287 return STATE_STOPPED; | 259 release_timer_->Start(FROM_HERE, |
| 288 break; | 260 base::TimeDelta::FromSeconds(kUacTimeoutSec), |
| 261 this, | |
| 262 &DaemonControllerWin::ReleaseElevatedController); | |
| 263 } | |
| 289 | 264 |
| 290 default: | 265 return S_OK; |
| 291 NOTREACHED(); | |
| 292 return STATE_UNKNOWN; | |
| 293 } | |
| 294 } | 266 } |
| 295 | 267 |
| 296 // static | 268 void DaemonControllerWin::ReleaseElevatedController() { |
| 297 DaemonController::AsyncResult DaemonControllerWin::HResultToAsyncResult( | 269 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 298 HRESULT hr) { | 270 |
| 299 // TODO(sergeyu): Report other errors to the webapp once it knows | 271 control_.Release(); |
| 300 // how to handle them. | 272 release_timer_.reset(); |
| 301 return FAILED(hr) ? RESULT_FAILED : RESULT_OK; | |
| 302 } | 273 } |
| 303 | 274 |
| 304 void DaemonControllerWin::OnInstallationComplete( | 275 void DaemonControllerWin::OnInstallationComplete( |
| 305 scoped_ptr<base::DictionaryValue> config, | 276 scoped_ptr<base::DictionaryValue> config, |
| 306 const CompletionCallback& done_callback, | 277 const CompletionCallback& done_callback, |
| 307 HRESULT result) { | 278 HRESULT result) { |
| 308 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 279 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 309 | 280 |
| 310 if (SUCCEEDED(result)) { | 281 if (SUCCEEDED(result)) { |
| 311 DoSetConfigAndStart(config.Pass(), done_callback); | 282 DoSetConfigAndStart(config.Pass(), done_callback); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 339 LOG_GETLASTERROR(ERROR) | 310 LOG_GETLASTERROR(ERROR) |
| 340 << "Failed to open to the '" << kWindowsServiceName << "' service"; | 311 << "Failed to open to the '" << kWindowsServiceName << "' service"; |
| 341 } | 312 } |
| 342 return error; | 313 return error; |
| 343 } | 314 } |
| 344 | 315 |
| 345 service_out->Set(service.Take()); | 316 service_out->Set(service.Take()); |
| 346 return ERROR_SUCCESS; | 317 return ERROR_SUCCESS; |
| 347 } | 318 } |
| 348 | 319 |
| 320 // static | |
| 349 void DaemonControllerWin::ConfigToString(const base::DictionaryValue& config, | 321 void DaemonControllerWin::ConfigToString(const base::DictionaryValue& config, |
| 350 ScopedBstr* out) { | 322 ScopedBstr* out) { |
| 351 std::string config_str; | 323 std::string config_str; |
| 352 base::JSONWriter::Write(&config, &config_str); | 324 base::JSONWriter::Write(&config, &config_str); |
| 353 ScopedBstr config_scoped_bstr(UTF8ToUTF16(config_str).c_str()); | 325 ScopedBstr config_scoped_bstr(UTF8ToUTF16(config_str).c_str()); |
| 354 out->Swap(config_scoped_bstr); | 326 out->Swap(config_scoped_bstr); |
| 355 } | 327 } |
| 356 | 328 |
| 329 // static | |
| 330 remoting::DaemonController::State DaemonControllerWin::ConvertToDaemonState( | |
| 331 DWORD service_state) { | |
| 332 switch (service_state) { | |
| 333 case SERVICE_RUNNING: | |
| 334 return STATE_STARTED; | |
| 335 | |
| 336 case SERVICE_CONTINUE_PENDING: | |
| 337 case SERVICE_START_PENDING: | |
| 338 return STATE_STARTING; | |
| 339 break; | |
| 340 | |
| 341 case SERVICE_PAUSE_PENDING: | |
| 342 case SERVICE_STOP_PENDING: | |
| 343 return STATE_STOPPING; | |
| 344 break; | |
| 345 | |
| 346 case SERVICE_PAUSED: | |
| 347 case SERVICE_STOPPED: | |
| 348 return STATE_STOPPED; | |
| 349 break; | |
| 350 | |
| 351 default: | |
| 352 NOTREACHED(); | |
| 353 return STATE_UNKNOWN; | |
| 354 } | |
| 355 } | |
| 356 | |
| 357 // static | |
| 358 DaemonController::AsyncResult DaemonControllerWin::HResultToAsyncResult( | |
| 359 HRESULT hr) { | |
| 360 // TODO(sergeyu): Report other errors to the webapp once it knows | |
| 361 // how to handle them. | |
| 362 return FAILED(hr) ? RESULT_FAILED : RESULT_OK; | |
| 363 } | |
| 364 | |
| 357 void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) { | 365 void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) { |
| 358 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 366 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 359 | 367 |
| 360 scoped_ptr<base::DictionaryValue> dictionary_null(NULL); | 368 scoped_ptr<base::DictionaryValue> dictionary_null(NULL); |
| 361 // Get the name of the configuration file. | 369 // Get the name of the configuration file. |
| 362 FilePath dir = remoting::GetConfigDir(); | 370 FilePath dir = remoting::GetConfigDir(); |
| 363 FilePath filename = dir.Append(kUnprivilegedConfigFileName); | 371 FilePath filename = dir.Append(kUnprivilegedConfigFileName); |
| 364 | 372 |
| 365 // Read raw data from the configuration file. | 373 // Read raw data from the configuration file. |
| 366 base::win::ScopedHandle file( | 374 base::win::ScopedHandle file( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 value.release(); | 413 value.release(); |
| 406 | 414 |
| 407 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); | 415 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); |
| 408 } | 416 } |
| 409 | 417 |
| 410 void DaemonControllerWin::DoInstallAsNeededAndStart( | 418 void DaemonControllerWin::DoInstallAsNeededAndStart( |
| 411 scoped_ptr<base::DictionaryValue> config, | 419 scoped_ptr<base::DictionaryValue> config, |
| 412 const CompletionCallback& done_callback) { | 420 const CompletionCallback& done_callback) { |
| 413 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 421 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 414 | 422 |
| 415 IDaemonControl* control = NULL; | 423 // Configure and start the Daemon Controller if it is installed already. |
| 416 HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_, | 424 HRESULT hr = ActivateElevatedController(); |
| 417 &control); | |
| 418 | |
| 419 // Just configure and start the Daemon Controller if it is installed already. | |
| 420 if (SUCCEEDED(hr)) { | 425 if (SUCCEEDED(hr)) { |
| 421 DoSetConfigAndStart(config.Pass(), done_callback); | 426 DoSetConfigAndStart(config.Pass(), done_callback); |
| 422 return; | 427 return; |
| 423 } | 428 } |
| 424 | 429 |
| 425 // Otherwise, install it if its COM registration entry is missing. | 430 // Otherwise, install it if its COM registration entry is missing. |
| 426 if (hr == CO_E_CLASSSTRING) { | 431 if (hr == CO_E_CLASSSTRING) { |
| 427 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( | 432 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( |
| 428 window_handle_, | 433 window_handle_, |
| 429 base::Bind(&DaemonControllerWin::OnInstallationComplete, | 434 base::Bind(&DaemonControllerWin::OnInstallationComplete, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 440 << "(error: 0x" << std::hex << hr << std::dec << ")."; | 445 << "(error: 0x" << std::hex << hr << std::dec << ")."; |
| 441 done_callback.Run(HResultToAsyncResult(hr)); | 446 done_callback.Run(HResultToAsyncResult(hr)); |
| 442 } | 447 } |
| 443 } | 448 } |
| 444 | 449 |
| 445 void DaemonControllerWin::DoSetConfigAndStart( | 450 void DaemonControllerWin::DoSetConfigAndStart( |
| 446 scoped_ptr<base::DictionaryValue> config, | 451 scoped_ptr<base::DictionaryValue> config, |
| 447 const CompletionCallback& done_callback) { | 452 const CompletionCallback& done_callback) { |
| 448 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 453 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 449 | 454 |
| 450 IDaemonControl* control = NULL; | 455 HRESULT hr = ActivateElevatedController(); |
| 451 HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_, | |
| 452 &control); | |
| 453 if (FAILED(hr)) { | 456 if (FAILED(hr)) { |
| 454 done_callback.Run(HResultToAsyncResult(hr)); | 457 done_callback.Run(HResultToAsyncResult(hr)); |
| 455 return; | 458 return; |
| 456 } | 459 } |
| 457 | 460 |
| 458 // Set the configuration. | 461 // Set the configuration. |
| 459 ScopedBstr config_str(NULL); | 462 ScopedBstr config_str(NULL); |
| 460 ConfigToString(*config, &config_str); | 463 ConfigToString(*config, &config_str); |
| 461 if (config_str == NULL) { | 464 if (config_str == NULL) { |
| 462 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); | 465 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); |
| 463 return; | 466 return; |
| 464 } | 467 } |
| 465 | 468 |
| 466 hr = control->SetConfig(config_str); | 469 hr = control_->SetConfig(config_str); |
| 467 if (FAILED(hr)) { | 470 if (FAILED(hr)) { |
| 468 done_callback.Run(HResultToAsyncResult(hr)); | 471 done_callback.Run(HResultToAsyncResult(hr)); |
| 469 return; | 472 return; |
| 470 } | 473 } |
| 471 | 474 |
| 472 // Start daemon. | 475 // Start daemon. |
| 473 hr = control->StartDaemon(); | 476 hr = control_->StartDaemon(); |
| 474 done_callback.Run(HResultToAsyncResult(hr)); | 477 done_callback.Run(HResultToAsyncResult(hr)); |
| 475 } | 478 } |
| 476 | 479 |
| 477 void DaemonControllerWin::DoUpdateConfig( | 480 void DaemonControllerWin::DoUpdateConfig( |
| 478 scoped_ptr<base::DictionaryValue> config, | 481 scoped_ptr<base::DictionaryValue> config, |
| 479 const CompletionCallback& done_callback) { | 482 const CompletionCallback& done_callback) { |
| 480 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 483 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 481 | 484 |
| 482 IDaemonControl* control = NULL; | 485 HRESULT hr = ActivateElevatedController(); |
| 483 HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_, | |
| 484 &control); | |
| 485 if (FAILED(hr)) { | 486 if (FAILED(hr)) { |
| 486 done_callback.Run(HResultToAsyncResult(hr)); | 487 done_callback.Run(HResultToAsyncResult(hr)); |
| 487 return; | 488 return; |
| 488 } | 489 } |
| 489 | 490 |
| 490 // Update the configuration. | 491 // Update the configuration. |
| 491 ScopedBstr config_str(NULL); | 492 ScopedBstr config_str(NULL); |
| 492 ConfigToString(*config, &config_str); | 493 ConfigToString(*config, &config_str); |
| 493 if (config_str == NULL) { | 494 if (config_str == NULL) { |
| 494 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); | 495 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); |
| 495 return; | 496 return; |
| 496 } | 497 } |
| 497 | 498 |
| 498 hr = control->UpdateConfig(config_str); | 499 hr = control_->UpdateConfig(config_str); |
| 499 done_callback.Run(HResultToAsyncResult(hr)); | 500 done_callback.Run(HResultToAsyncResult(hr)); |
| 500 } | 501 } |
| 501 | 502 |
| 502 void DaemonControllerWin::DoStop(const CompletionCallback& done_callback) { | 503 void DaemonControllerWin::DoStop(const CompletionCallback& done_callback) { |
| 503 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 504 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 504 | 505 |
| 505 IDaemonControl* control = NULL; | 506 HRESULT hr = ActivateElevatedController(); |
| 506 HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_, | |
| 507 &control); | |
| 508 if (FAILED(hr)) { | 507 if (FAILED(hr)) { |
| 509 done_callback.Run(HResultToAsyncResult(hr)); | 508 done_callback.Run(HResultToAsyncResult(hr)); |
| 510 return; | 509 return; |
| 511 } | 510 } |
| 512 | 511 |
| 513 hr = control->StopDaemon(); | 512 hr = control_->StopDaemon(); |
| 514 done_callback.Run(HResultToAsyncResult(hr)); | 513 done_callback.Run(HResultToAsyncResult(hr)); |
| 515 } | 514 } |
| 516 | 515 |
| 517 void DaemonControllerWin::DoSetWindow(void* window_handle) { | 516 void DaemonControllerWin::DoSetWindow(void* window_handle) { |
| 518 window_handle_ = reinterpret_cast<HWND>(window_handle); | 517 window_handle_ = reinterpret_cast<HWND>(window_handle); |
| 519 } | 518 } |
| 520 | 519 |
| 521 } // namespace | 520 } // namespace |
| 522 | 521 |
| 523 scoped_ptr<DaemonController> remoting::DaemonController::Create() { | 522 scoped_ptr<DaemonController> remoting::DaemonController::Create() { |
| 524 return scoped_ptr<DaemonController>(new DaemonControllerWin()); | 523 return scoped_ptr<DaemonController>(new DaemonControllerWin()); |
| 525 } | 524 } |
| 526 | 525 |
| 527 } // namespace remoting | 526 } // namespace remoting |
| OLD | NEW |