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() { |