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

Side by Side Diff: remoting/host/elevated_controller_win.cc

Issue 9953002: The me2me host is now configurable from the web UI on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed one or two nits. :-) 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
« no previous file with comments | « remoting/host/elevated_controller_win.h ('k') | remoting/host/host_service_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/elevated_controller_win.h" 5 #include "remoting/host/elevated_controller_win.h"
6 6
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/path_service.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "base/win/scoped_handle.h"
16 #include "remoting/host/branding.h"
17
7 // MIDL-generated definitions. 18 // MIDL-generated definitions.
8 #include <elevated_controller_i.c> 19 #include "elevated_controller_i.c"
9 20
10 using ATL::CComQIPtr; 21 namespace {
11 using ATL::CComPtr; 22
23 // ReadConfig() filters the configuration file stripping all variables except of
24 // the following two.
25 const char kHostId[] = "host_id";
26 const char kXmppLogin[] = "xmpp_login";
27
28 // Names of the configuration files.
29 const FilePath::CharType kAuthConfigFilename[] = FILE_PATH_LITERAL("auth.json");
30 const FilePath::CharType kHostConfigFilename[] = FILE_PATH_LITERAL("host.json");
31
32 // TODO(alexeypa): Remove the hardcoded undocumented paths and store
33 // the configuration in the registry.
34 #ifdef OFFICIAL_BUILD
35 const FilePath::CharType kConfigDir[] = FILE_PATH_LITERAL(
36 "config\\systemprofile\\AppData\\Local\\Google\\Chrome Remote Desktop");
37 #else
38 const FilePath::CharType kConfigDir[] =
39 FILE_PATH_LITERAL("config\\systemprofile\\AppData\\Local\\Chromoting");
40 #endif
41
42 // Reads and parses a JSON configuration file.
43 HRESULT ReadConfig(const FilePath& filename,
44 scoped_ptr<base::DictionaryValue>* config_out) {
45 // TODO(alexeypa): Remove 64KB limitation.
46 const size_t kMaxConfigFileSize = 64 * 1024;
47
48 // Read raw data from the configuration file.
49 base::win::ScopedHandle file(
50 CreateFileW(filename.value().c_str(),
51 GENERIC_READ,
52 FILE_SHARE_READ | FILE_SHARE_WRITE,
53 NULL,
54 OPEN_EXISTING,
55 FILE_FLAG_SEQUENTIAL_SCAN,
56 NULL));
57
58 if (!file.IsValid()) {
59 DWORD error = GetLastError();
60 LOG_GETLASTERROR(ERROR)
61 << "Failed to read '" << filename.value() << "'";
62 return HRESULT_FROM_WIN32(error);
63 }
64
65 std::vector<char> buffer(kMaxConfigFileSize);
66 DWORD size = static_cast<DWORD>(buffer.size());
67 if (!::ReadFile(file, &buffer[0], size, &size, NULL)) {
68 DWORD error = GetLastError();
69 LOG_GETLASTERROR(ERROR)
70 << "Failed to read '" << filename.value() << "'";
71 return HRESULT_FROM_WIN32(error);
72 }
73
74 // Parse the JSON configuration, expecting it to contain a dictionary.
75 std::string file_content(&buffer[0], size);
76 scoped_ptr<base::Value> value(base::JSONReader::Read(file_content, true));
77
78 base::DictionaryValue* dictionary;
79 if (value.get() == NULL || !value->GetAsDictionary(&dictionary)) {
80 LOG(ERROR) << "Failed to read '" << filename.value() << "'.";
81 return E_FAIL;
82 }
83
84 value.release();
85 config_out->reset(dictionary);
86 return S_OK;
87 }
88
89 } // namespace
12 90
13 namespace remoting { 91 namespace remoting {
14 92
15 ElevatedControllerWin::ElevatedControllerWin() { 93 ElevatedControllerWin::ElevatedControllerWin() {
16 } 94 }
17 95
18 HRESULT ElevatedControllerWin::FinalConstruct() { 96 HRESULT ElevatedControllerWin::FinalConstruct() {
19 return S_OK; 97 return S_OK;
20 } 98 }
21 99
22 void ElevatedControllerWin::FinalRelease() { 100 void ElevatedControllerWin::FinalRelease() {
23 } 101 }
24 102
25 STDMETHODIMP ElevatedControllerWin::get_State(DaemonState* state_out) { 103 STDMETHODIMP ElevatedControllerWin::GetConfig(BSTR* config_out) {
26 return E_NOTIMPL; 104 FilePath system_profile;
105 PathService::Get(base::DIR_SYSTEM, &system_profile);
106
107 // Read the host configuration.
108 scoped_ptr<base::DictionaryValue> config;
109 HRESULT hr = ReadConfig(
110 system_profile.Append(kConfigDir).Append(kHostConfigFilename),
111 &config);
112 if (FAILED(hr)) {
113 return hr;
114 }
115
116 // Build the filtered config.
117 scoped_ptr<base::DictionaryValue> filtered_config(
118 new base::DictionaryValue());
119
120 std::string value;
121 if (config->GetString(kHostId, &value)) {
122 filtered_config->SetString(kHostId, value);
123 }
124 if (config->GetString(kXmppLogin, &value)) {
125 filtered_config->SetString(kXmppLogin, value);
126 }
127
128 // Convert the filtered config back to a string and return it to the caller.
129 std::string file_content;
130 base::JSONWriter::Write(filtered_config.get(), &file_content);
131
132 *config_out = ::SysAllocString(UTF8ToUTF16(file_content).c_str());
133 if (config_out == NULL) {
134 return E_OUTOFMEMORY;
135 }
136
137 return S_OK;
27 } 138 }
28 139
29 STDMETHODIMP ElevatedControllerWin::ReadConfig(BSTR* config_out) { 140 STDMETHODIMP ElevatedControllerWin::SetConfig(BSTR config) {
30 return E_NOTIMPL; 141 // Determine the config directory path and create it if necessary.
31 } 142 // N.B. The configuration files are stored in LocalSystems's profile which is
143 // not readable by non administrators.
144 FilePath system_profile;
145 PathService::Get(base::DIR_SYSTEM, &system_profile);
146 FilePath config_dir = system_profile.Append(kConfigDir);
147 if (!file_util::CreateDirectory(config_dir)) {
148 return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
149 }
32 150
33 STDMETHODIMP ElevatedControllerWin::WriteConfig(BSTR config) { 151 std::string file_content = UTF16ToUTF8(
34 return E_NOTIMPL; 152 string16(static_cast<char16*>(config), ::SysStringLen(config)));
153
154 int written = file_util::WriteFile(
155 config_dir.Append(kAuthConfigFilename),
156 file_content.c_str(),
157 file_content.size());
158 if (written != static_cast<int>(file_content.size())) {
159 return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
160 }
161
162 // TODO(alexeypa): Store the authentication and host configurations in a
163 // single file.
164 written = file_util::WriteFile(
165 config_dir.Append(kHostConfigFilename),
166 file_content.c_str(),
167 file_content.size());
168 if (written != static_cast<int>(file_content.size())) {
169 return E_FAIL;
170 }
171
172 return S_OK;
35 } 173 }
36 174
37 STDMETHODIMP ElevatedControllerWin::StartDaemon() { 175 STDMETHODIMP ElevatedControllerWin::StartDaemon() {
38 return E_NOTIMPL; 176 ScopedScHandle service;
39 } 177 HRESULT hr = OpenService(&service);
40 178 if (FAILED(hr)) {
41 STDMETHODIMP ElevatedControllerWin::StopDaemon() { 179 return hr;
42 return E_NOTIMPL;
43 }
44
45 HRESULT ElevatedControllerWin::FireOnStateChange(DaemonState state) {
46 CComPtr<IConnectionPoint> connection_point;
47 FindConnectionPoint(__uuidof(IDaemonEvents), &connection_point);
48 if (!connection_point) {
49 return S_OK;
50 } 180 }
51 181
52 CComPtr<IEnumConnections> connections; 182 if (!StartService(service, 0, NULL)) {
53 if (FAILED(connection_point->EnumConnections(&connections))) { 183 DWORD error = GetLastError();
54 return S_OK; 184 if (error != ERROR_SERVICE_ALREADY_RUNNING) {
55 } 185 LOG_GETLASTERROR(ERROR)
186 << "Failed to start the '" << kWindowsServiceName << "'service";
56 187
57 CONNECTDATA connect_data; 188 return HRESULT_FROM_WIN32(error);
58 while (connections->Next(1, &connect_data, NULL) == S_OK) {
59 if (connect_data.pUnk != NULL) {
60 CComQIPtr<IDaemonEvents, &__uuidof(IDaemonEvents)> sink(
61 connect_data.pUnk);
62
63 if (sink != NULL) {
64 sink->OnStateChange(state);
65 }
66
67 connect_data.pUnk->Release();
68 } 189 }
69 } 190 }
70 191
71 return S_OK; 192 return S_OK;
72 } 193 }
73 194
195 STDMETHODIMP ElevatedControllerWin::StopDaemon() {
196 ScopedScHandle service;
197 HRESULT hr = OpenService(&service);
198 if (FAILED(hr)) {
199 return hr;
200 }
201
202 SERVICE_STATUS status;
203 if (!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
204 DWORD error = GetLastError();
205 if (error != ERROR_SERVICE_NOT_ACTIVE) {
206 LOG_GETLASTERROR(ERROR)
207 << "Failed to stop the '" << kWindowsServiceName << "'service";
208 return HRESULT_FROM_WIN32(error);
209 }
210 }
211
212 return S_OK;
213 }
214
215 HRESULT ElevatedControllerWin::OpenService(ScopedScHandle* service_out) {
216 DWORD error;
217
218 ScopedScHandle scmanager(
219 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE,
220 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE));
221 if (!scmanager.IsValid()) {
222 error = GetLastError();
223 LOG_GETLASTERROR(ERROR)
224 << "Failed to connect to the service control manager";
225
226 return HRESULT_FROM_WIN32(error);
227 }
228
229 ScopedScHandle service(
230 ::OpenServiceW(scmanager, UTF8ToUTF16(kWindowsServiceName).c_str(),
231 SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP));
232 if (!service.IsValid()) {
233 error = GetLastError();
234 LOG_GETLASTERROR(ERROR)
235 << "Failed to open to the '" << kWindowsServiceName << "' service";
236
237 return HRESULT_FROM_WIN32(error);
238 }
239
240 service_out->Set(service.Take());
241 return S_OK;
242 }
243
74 } // namespace remoting 244 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/elevated_controller_win.h ('k') | remoting/host/host_service_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698