Chromium Code Reviews| Index: remoting/host/plugin/daemon_controller_win.cc |
| diff --git a/remoting/host/plugin/daemon_controller_win.cc b/remoting/host/plugin/daemon_controller_win.cc |
| index cb9bebfd83660fdcb58fcf90d224d334e21ad95b..48e2839cace9da9b9a4d71e29cfdc5ec0d34233e 100644 |
| --- a/remoting/host/plugin/daemon_controller_win.cc |
| +++ b/remoting/host/plugin/daemon_controller_win.cc |
| @@ -5,6 +5,7 @@ |
| #include "remoting/host/plugin/daemon_controller.h" |
| #include <objbase.h> |
| +#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.
|
| #include "base/basictypes.h" |
| #include "base/bind.h" |
| @@ -24,6 +25,7 @@ |
| #include "base/win/scoped_comptr.h" |
| #include "remoting/base/scoped_sc_handle_win.h" |
| #include "remoting/host/branding.h" |
| +#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.
|
| #include "remoting/host/plugin/daemon_installer_win.h" |
| // MIDL-generated declarations and definitions. |
| @@ -105,6 +107,7 @@ class DaemonControllerWin : public remoting::DaemonController { |
| void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, |
| const CompletionCallback& done_callback); |
| void DoStop(const CompletionCallback& done_callback); |
| + base::DictionaryValue* ReadConfig(); |
| // The worker thread used for servicing long running operations. |
| ComThread worker_thread_; |
| @@ -310,36 +313,7 @@ DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) { |
| void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) { |
| DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| - IDaemonControl* control = NULL; |
| - HRESULT hr = worker_thread_.ActivateElevatedController(&control); |
| - if (FAILED(hr)) { |
| - callback.Run(scoped_ptr<base::DictionaryValue>()); |
| - return; |
| - } |
| - |
| - // Get the host configuration. |
| - ScopedBstr host_config; |
| - hr = control->GetConfig(host_config.Receive()); |
| - if (FAILED(hr)) { |
| - callback.Run(scoped_ptr<base::DictionaryValue>()); |
| - return; |
| - } |
| - |
| - string16 file_content(static_cast<BSTR>(host_config), host_config.Length()); |
| - |
| - // Parse the string into a dictionary. |
| - scoped_ptr<base::Value> config( |
| - base::JSONReader::Read(UTF16ToUTF8(file_content), |
| - base::JSON_ALLOW_TRAILING_COMMAS)); |
| - |
| - base::DictionaryValue* dictionary; |
| - if (config.get() == NULL || !config->GetAsDictionary(&dictionary)) { |
| - callback.Run(scoped_ptr<base::DictionaryValue>()); |
| - return; |
| - } |
| - |
| - config.release(); |
| - callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); |
| + 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.
|
| } |
| void DaemonControllerWin::DoInstallAsNeededAndStart( |
| @@ -356,7 +330,7 @@ void DaemonControllerWin::DoInstallAsNeededAndStart( |
| return; |
| } |
| - // Otherwise, install it if it's COM registration entry is missing. |
| + // Otherwise, install it if its COM registration entry is missing. |
| if (hr == CO_E_CLASSSTRING) { |
| scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( |
| base::Bind(&DaemonControllerWin::OnInstallationComplete, |
| @@ -450,6 +424,54 @@ void DaemonControllerWin::DoStop(const CompletionCallback& done_callback) { |
| done_callback.Run(HResultToAsyncResult(hr)); |
| } |
| +// Reads and parses the configuration file up to |kMaxConfigFileSize| in |
| +// size. On error, it logs a message and returns NULL. |
| +base::DictionaryValue* DaemonControllerWin::ReadConfig() { |
| + // Get the name of the configuration file. |
| + FilePath dir = remoting::GetConfigDir(); |
| + 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
|
| + |
| + // Read raw data from the configuration file. |
| + base::win::ScopedHandle file( |
| + CreateFileW(filename.value().c_str(), |
| + GENERIC_READ, |
| + FILE_SHARE_READ | FILE_SHARE_WRITE, |
| + NULL, |
| + OPEN_EXISTING, |
| + FILE_FLAG_SEQUENTIAL_SCAN, |
| + NULL)); |
| + |
| + if (!file.IsValid()) { |
| + DWORD error = GetLastError(); |
| + LOG_GETLASTERROR(ERROR) |
| + << "Failed to open '" << filename.value() << "'"; |
| + return NULL; |
| + } |
| + |
| + scoped_array<char> buffer(new char[kMaxConfigFileSize]); |
| + DWORD size = kMaxConfigFileSize; |
| + if (!::ReadFile(file, &buffer[0], size, &size, NULL)) { |
| + DWORD error = GetLastError(); |
| + LOG_GETLASTERROR(ERROR) |
| + << "Failed to read '" << filename.value() << "'"; |
| + return NULL; |
| + } |
| + |
| + // Parse the JSON configuration, expecting it to contain a dictionary. |
| + std::string file_content(buffer.get(), size); |
| + scoped_ptr<base::Value> value( |
| + base::JSONReader::Read(file_content, base::JSON_ALLOW_TRAILING_COMMAS)); |
| + |
| + base::DictionaryValue* dictionary = NULL; |
| + if (value.get() == NULL || !value->GetAsDictionary(&dictionary)) { |
| + LOG(ERROR) << "Failed to read '" << filename.value() << "'"; |
| + return NULL; |
| + } |
| + // Release value, because dictionary points to the same object. |
| + value.release(); |
| + return dictionary; |
| +} |
| + |
| } // namespace |
| scoped_ptr<DaemonController> remoting::DaemonController::Create() { |