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

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

Issue 10191007: [Chromoting] Let the Windows daemon controller read the unprivileged part of the config without ele… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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 #include <sddl.h>
alexeypa (please no reviews) 2012/04/23 17:35:10 I don't think you need to include sddl.h here
simonmorris 2012/04/23 19:39:49 Done.
8 9
9 #include "base/basictypes.h" 10 #include "base/basictypes.h"
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
13 #include "base/file_path.h" 14 #include "base/file_path.h"
14 #include "base/file_util.h" 15 #include "base/file_util.h"
15 #include "base/json/json_reader.h" 16 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h" 17 #include "base/json/json_writer.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/string16.h" 19 #include "base/string16.h"
19 #include "base/stringize_macros.h" 20 #include "base/stringize_macros.h"
20 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
21 #include "base/utf_string_conversions.h" 22 #include "base/utf_string_conversions.h"
22 #include "base/values.h" 23 #include "base/values.h"
23 #include "base/win/scoped_bstr.h" 24 #include "base/win/scoped_bstr.h"
24 #include "base/win/scoped_comptr.h" 25 #include "base/win/scoped_comptr.h"
25 #include "remoting/base/scoped_sc_handle_win.h" 26 #include "remoting/base/scoped_sc_handle_win.h"
26 #include "remoting/host/branding.h" 27 #include "remoting/host/branding.h"
28 #include "remoting/host/daemon_controller_common_win.h"
alexeypa (please no reviews) 2012/04/23 17:35:10 Is it a new file? I don't see it in the CL.
simonmorris 2012/04/23 19:39:49 Done.
27 #include "remoting/host/plugin/daemon_installer_win.h" 29 #include "remoting/host/plugin/daemon_installer_win.h"
28 30
29 // MIDL-generated declarations and definitions. 31 // MIDL-generated declarations and definitions.
30 #include "remoting/host/elevated_controller.h" 32 #include "remoting/host/elevated_controller.h"
31 33
32 using base::win::ScopedBstr; 34 using base::win::ScopedBstr;
33 using base::win::ScopedComPtr; 35 using base::win::ScopedComPtr;
34 36
35 namespace remoting { 37 namespace remoting {
36 38
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 // The functions that actually do the work. They should be called in 100 // The functions that actually do the work. They should be called in
99 // the context of |worker_thread_|; 101 // the context of |worker_thread_|;
100 void DoGetConfig(const GetConfigCallback& callback); 102 void DoGetConfig(const GetConfigCallback& callback);
101 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, 103 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config,
102 const CompletionCallback& done_callback); 104 const CompletionCallback& done_callback);
103 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, 105 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
104 const CompletionCallback& done_callback); 106 const CompletionCallback& done_callback);
105 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, 107 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
106 const CompletionCallback& done_callback); 108 const CompletionCallback& done_callback);
107 void DoStop(const CompletionCallback& done_callback); 109 void DoStop(const CompletionCallback& done_callback);
110 base::DictionaryValue* ReadConfig();
108 111
109 // The worker thread used for servicing long running operations. 112 // The worker thread used for servicing long running operations.
110 ComThread worker_thread_; 113 ComThread worker_thread_;
111 114
112 scoped_ptr<DaemonInstallerWin> installer_; 115 scoped_ptr<DaemonInstallerWin> installer_;
113 116
114 DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin); 117 DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin);
115 }; 118 };
116 119
117 ComThread::ComThread(const char* name) : base::Thread(name), control_(NULL) { 120 ComThread::ComThread(const char* name) : base::Thread(name), control_(NULL) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 return error; 306 return error;
304 } 307 }
305 308
306 service_out->Set(service.Take()); 309 service_out->Set(service.Take());
307 return ERROR_SUCCESS; 310 return ERROR_SUCCESS;
308 } 311 }
309 312
310 void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) { 313 void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) {
311 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 314 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
312 315
313 IDaemonControl* control = NULL; 316 callback.Run(scoped_ptr<base::DictionaryValue>(ReadConfig()));
alexeypa (please no reviews) 2012/04/23 17:35:10 Why is a separate private method? DoXxx methods ar
simonmorris 2012/04/23 19:39:49 Only because ReadConfig forms a pair with WriteCon
alexeypa (please no reviews) 2012/04/24 16:54:56 WriteConfig belongs to the privileged code so I gu
simonmorris 2012/04/25 00:33:32 Done.
314 HRESULT hr = worker_thread_.ActivateElevatedController(&control);
315 if (FAILED(hr)) {
316 callback.Run(scoped_ptr<base::DictionaryValue>());
317 return;
318 }
319
320 // Get the host configuration.
321 ScopedBstr host_config;
322 hr = control->GetConfig(host_config.Receive());
323 if (FAILED(hr)) {
324 callback.Run(scoped_ptr<base::DictionaryValue>());
325 return;
326 }
327
328 string16 file_content(static_cast<BSTR>(host_config), host_config.Length());
329
330 // Parse the string into a dictionary.
331 scoped_ptr<base::Value> config(
332 base::JSONReader::Read(UTF16ToUTF8(file_content),
333 base::JSON_ALLOW_TRAILING_COMMAS));
334
335 base::DictionaryValue* dictionary;
336 if (config.get() == NULL || !config->GetAsDictionary(&dictionary)) {
337 callback.Run(scoped_ptr<base::DictionaryValue>());
338 return;
339 }
340
341 config.release();
342 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary));
343 } 317 }
344 318
345 void DaemonControllerWin::DoInstallAsNeededAndStart( 319 void DaemonControllerWin::DoInstallAsNeededAndStart(
346 scoped_ptr<base::DictionaryValue> config, 320 scoped_ptr<base::DictionaryValue> config,
347 const CompletionCallback& done_callback) { 321 const CompletionCallback& done_callback) {
348 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); 322 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
349 323
350 IDaemonControl* control = NULL; 324 IDaemonControl* control = NULL;
351 HRESULT hr = worker_thread_.ActivateElevatedController(&control); 325 HRESULT hr = worker_thread_.ActivateElevatedController(&control);
352 326
353 // Just configure and start the Daemon Controller if it is installed already. 327 // Just configure and start the Daemon Controller if it is installed already.
354 if (SUCCEEDED(hr)) { 328 if (SUCCEEDED(hr)) {
355 DoSetConfigAndStart(config.Pass(), done_callback); 329 DoSetConfigAndStart(config.Pass(), done_callback);
356 return; 330 return;
357 } 331 }
358 332
359 // Otherwise, install it if it's COM registration entry is missing. 333 // Otherwise, install it if its COM registration entry is missing.
360 if (hr == CO_E_CLASSSTRING) { 334 if (hr == CO_E_CLASSSTRING) {
361 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( 335 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create(
362 base::Bind(&DaemonControllerWin::OnInstallationComplete, 336 base::Bind(&DaemonControllerWin::OnInstallationComplete,
363 base::Unretained(this), 337 base::Unretained(this),
364 base::Passed(&config), 338 base::Passed(&config),
365 done_callback)); 339 done_callback));
366 if (installer.get()) { 340 if (installer.get()) {
367 DCHECK(!installer_.get()); 341 DCHECK(!installer_.get());
368 installer_ = installer.Pass(); 342 installer_ = installer.Pass();
369 installer_->Install(); 343 installer_->Install();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 HRESULT hr = worker_thread_.ActivateElevatedController(&control); 417 HRESULT hr = worker_thread_.ActivateElevatedController(&control);
444 if (FAILED(hr)) { 418 if (FAILED(hr)) {
445 done_callback.Run(HResultToAsyncResult(hr)); 419 done_callback.Run(HResultToAsyncResult(hr));
446 return; 420 return;
447 } 421 }
448 422
449 hr = control->StopDaemon(); 423 hr = control->StopDaemon();
450 done_callback.Run(HResultToAsyncResult(hr)); 424 done_callback.Run(HResultToAsyncResult(hr));
451 } 425 }
452 426
427 // Reads and parses the configuration file up to |kMaxConfigFileSize| in
428 // size. On error, it logs a message and returns NULL.
429 base::DictionaryValue* DaemonControllerWin::ReadConfig() {
430 // Get the name of the configuration file.
431 FilePath dir = remoting::GetConfigDir();
432 FilePath filename = dir.Append(kUnprivilegedConfigFileName);
alexeypa (please no reviews) 2012/04/23 17:35:10 This is a leaking abstraction. The COM component i
alexeypa (please no reviews) 2012/04/24 16:54:56 We have decided to file a bug to tracking fixing i
simonmorris 2012/04/25 00:33:32 crbug.com/124937
433
434 // Read raw data from the configuration file.
435 base::win::ScopedHandle file(
436 CreateFileW(filename.value().c_str(),
437 GENERIC_READ,
438 FILE_SHARE_READ | FILE_SHARE_WRITE,
439 NULL,
440 OPEN_EXISTING,
441 FILE_FLAG_SEQUENTIAL_SCAN,
442 NULL));
443
444 if (!file.IsValid()) {
445 DWORD error = GetLastError();
446 LOG_GETLASTERROR(ERROR)
447 << "Failed to open '" << filename.value() << "'";
448 return NULL;
449 }
450
451 scoped_array<char> buffer(new char[kMaxConfigFileSize]);
452 DWORD size = kMaxConfigFileSize;
453 if (!::ReadFile(file, &buffer[0], size, &size, NULL)) {
454 DWORD error = GetLastError();
455 LOG_GETLASTERROR(ERROR)
456 << "Failed to read '" << filename.value() << "'";
457 return NULL;
458 }
459
460 // Parse the JSON configuration, expecting it to contain a dictionary.
461 std::string file_content(buffer.get(), size);
462 scoped_ptr<base::Value> value(
463 base::JSONReader::Read(file_content, base::JSON_ALLOW_TRAILING_COMMAS));
464
465 base::DictionaryValue* dictionary = NULL;
466 if (value.get() == NULL || !value->GetAsDictionary(&dictionary)) {
467 LOG(ERROR) << "Failed to read '" << filename.value() << "'";
468 return NULL;
469 }
470 // Release value, because dictionary points to the same object.
471 value.release();
472 return dictionary;
473 }
474
453 } // namespace 475 } // namespace
454 476
455 scoped_ptr<DaemonController> remoting::DaemonController::Create() { 477 scoped_ptr<DaemonController> remoting::DaemonController::Create() {
456 return scoped_ptr<DaemonController>(new DaemonControllerWin()); 478 return scoped_ptr<DaemonController>(new DaemonControllerWin());
457 } 479 }
458 480
459 } // namespace remoting 481 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698