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/win/elevated_controller.h" | 5 #include "remoting/host/win/elevated_controller.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/file_version_info.h" | 8 #include "base/file_version_info.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 CreateFileW(filename.value().c_str(), | 101 CreateFileW(filename.value().c_str(), |
102 GENERIC_READ, | 102 GENERIC_READ, |
103 FILE_SHARE_READ | FILE_SHARE_WRITE, | 103 FILE_SHARE_READ | FILE_SHARE_WRITE, |
104 NULL, | 104 NULL, |
105 OPEN_EXISTING, | 105 OPEN_EXISTING, |
106 FILE_FLAG_SEQUENTIAL_SCAN, | 106 FILE_FLAG_SEQUENTIAL_SCAN, |
107 NULL)); | 107 NULL)); |
108 | 108 |
109 if (!file.IsValid()) { | 109 if (!file.IsValid()) { |
110 DWORD error = GetLastError(); | 110 DWORD error = GetLastError(); |
111 LOG_GETLASTERROR(ERROR) | 111 PLOG(ERROR) << "Failed to open '" << filename.value() << "'"; |
112 << "Failed to open '" << filename.value() << "'"; | |
113 return HRESULT_FROM_WIN32(error); | 112 return HRESULT_FROM_WIN32(error); |
114 } | 113 } |
115 | 114 |
116 scoped_ptr<char[]> buffer(new char[kMaxConfigFileSize]); | 115 scoped_ptr<char[]> buffer(new char[kMaxConfigFileSize]); |
117 DWORD size = kMaxConfigFileSize; | 116 DWORD size = kMaxConfigFileSize; |
118 if (!::ReadFile(file, &buffer[0], size, &size, NULL)) { | 117 if (!::ReadFile(file, &buffer[0], size, &size, NULL)) { |
119 DWORD error = GetLastError(); | 118 DWORD error = GetLastError(); |
120 LOG_GETLASTERROR(ERROR) | 119 PLOG(ERROR) << "Failed to read '" << filename.value() << "'"; |
121 << "Failed to read '" << filename.value() << "'"; | |
122 return HRESULT_FROM_WIN32(error); | 120 return HRESULT_FROM_WIN32(error); |
123 } | 121 } |
124 | 122 |
125 // Parse the JSON configuration, expecting it to contain a dictionary. | 123 // Parse the JSON configuration, expecting it to contain a dictionary. |
126 std::string file_content(buffer.get(), size); | 124 std::string file_content(buffer.get(), size); |
127 scoped_ptr<base::Value> value( | 125 scoped_ptr<base::Value> value( |
128 base::JSONReader::Read(file_content, base::JSON_ALLOW_TRAILING_COMMAS)); | 126 base::JSONReader::Read(file_content, base::JSON_ALLOW_TRAILING_COMMAS)); |
129 | 127 |
130 base::DictionaryValue* dictionary; | 128 base::DictionaryValue* dictionary; |
131 if (value.get() == NULL || !value->GetAsDictionary(&dictionary)) { | 129 if (value.get() == NULL || !value->GetAsDictionary(&dictionary)) { |
(...skipping 12 matching lines...) Expand all Loading... |
144 | 142 |
145 // Writes a config file to a temporary location. | 143 // Writes a config file to a temporary location. |
146 HRESULT WriteConfigFileToTemp(const base::FilePath& filename, | 144 HRESULT WriteConfigFileToTemp(const base::FilePath& filename, |
147 const char* security_descriptor, | 145 const char* security_descriptor, |
148 const char* content, | 146 const char* content, |
149 size_t length) { | 147 size_t length) { |
150 // Create the security descriptor for the configuration file. | 148 // Create the security descriptor for the configuration file. |
151 ScopedSd sd = ConvertSddlToSd(security_descriptor); | 149 ScopedSd sd = ConvertSddlToSd(security_descriptor); |
152 if (!sd) { | 150 if (!sd) { |
153 DWORD error = GetLastError(); | 151 DWORD error = GetLastError(); |
154 LOG_GETLASTERROR(ERROR) << | 152 PLOG(ERROR) |
155 "Failed to create a security descriptor for the configuration file"; | 153 << "Failed to create a security descriptor for the configuration file"; |
156 return HRESULT_FROM_WIN32(error); | 154 return HRESULT_FROM_WIN32(error); |
157 } | 155 } |
158 | 156 |
159 SECURITY_ATTRIBUTES security_attributes = {0}; | 157 SECURITY_ATTRIBUTES security_attributes = {0}; |
160 security_attributes.nLength = sizeof(security_attributes); | 158 security_attributes.nLength = sizeof(security_attributes); |
161 security_attributes.lpSecurityDescriptor = sd.get(); | 159 security_attributes.lpSecurityDescriptor = sd.get(); |
162 security_attributes.bInheritHandle = FALSE; | 160 security_attributes.bInheritHandle = FALSE; |
163 | 161 |
164 // Create a temporary file and write configuration to it. | 162 // Create a temporary file and write configuration to it. |
165 base::FilePath tempname = GetTempLocationFor(filename); | 163 base::FilePath tempname = GetTempLocationFor(filename); |
166 base::win::ScopedHandle file( | 164 base::win::ScopedHandle file( |
167 CreateFileW(tempname.value().c_str(), | 165 CreateFileW(tempname.value().c_str(), |
168 GENERIC_WRITE, | 166 GENERIC_WRITE, |
169 0, | 167 0, |
170 &security_attributes, | 168 &security_attributes, |
171 CREATE_ALWAYS, | 169 CREATE_ALWAYS, |
172 FILE_FLAG_SEQUENTIAL_SCAN, | 170 FILE_FLAG_SEQUENTIAL_SCAN, |
173 NULL)); | 171 NULL)); |
174 | 172 |
175 if (!file.IsValid()) { | 173 if (!file.IsValid()) { |
176 DWORD error = GetLastError(); | 174 DWORD error = GetLastError(); |
177 LOG_GETLASTERROR(ERROR) | 175 PLOG(ERROR) << "Failed to create '" << filename.value() << "'"; |
178 << "Failed to create '" << filename.value() << "'"; | |
179 return HRESULT_FROM_WIN32(error); | 176 return HRESULT_FROM_WIN32(error); |
180 } | 177 } |
181 | 178 |
182 DWORD written; | 179 DWORD written; |
183 if (!WriteFile(file, content, static_cast<DWORD>(length), &written, NULL)) { | 180 if (!WriteFile(file, content, static_cast<DWORD>(length), &written, NULL)) { |
184 DWORD error = GetLastError(); | 181 DWORD error = GetLastError(); |
185 LOG_GETLASTERROR(ERROR) | 182 PLOG(ERROR) << "Failed to write to '" << filename.value() << "'"; |
186 << "Failed to write to '" << filename.value() << "'"; | |
187 return HRESULT_FROM_WIN32(error); | 183 return HRESULT_FROM_WIN32(error); |
188 } | 184 } |
189 | 185 |
190 return S_OK; | 186 return S_OK; |
191 } | 187 } |
192 | 188 |
193 // Moves a config file from its temporary location to its permanent location. | 189 // Moves a config file from its temporary location to its permanent location. |
194 HRESULT MoveConfigFileFromTemp(const base::FilePath& filename) { | 190 HRESULT MoveConfigFileFromTemp(const base::FilePath& filename) { |
195 // Now that the configuration is stored successfully replace the actual | 191 // Now that the configuration is stored successfully replace the actual |
196 // configuration file. | 192 // configuration file. |
197 base::FilePath tempname = GetTempLocationFor(filename); | 193 base::FilePath tempname = GetTempLocationFor(filename); |
198 if (!MoveFileExW(tempname.value().c_str(), | 194 if (!MoveFileExW(tempname.value().c_str(), |
199 filename.value().c_str(), | 195 filename.value().c_str(), |
200 MOVEFILE_REPLACE_EXISTING)) { | 196 MOVEFILE_REPLACE_EXISTING)) { |
201 DWORD error = GetLastError(); | 197 DWORD error = GetLastError(); |
202 LOG_GETLASTERROR(ERROR) | 198 PLOG(ERROR) << "Failed to rename '" << tempname.value() << "' to '" |
203 << "Failed to rename '" << tempname.value() << "' to '" | 199 << filename.value() << "'"; |
204 << filename.value() << "'"; | |
205 return HRESULT_FROM_WIN32(error); | 200 return HRESULT_FROM_WIN32(error); |
206 } | 201 } |
207 | 202 |
208 return S_OK; | 203 return S_OK; |
209 } | 204 } |
210 | 205 |
211 // Writes the configuration file up to |kMaxConfigFileSize| in size. | 206 // Writes the configuration file up to |kMaxConfigFileSize| in size. |
212 HRESULT WriteConfig(const char* content, size_t length, HWND owner_window) { | 207 HRESULT WriteConfig(const char* content, size_t length, HWND owner_window) { |
213 if (length > kMaxConfigFileSize) { | 208 if (length > kMaxConfigFileSize) { |
214 return E_FAIL; | 209 return E_FAIL; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 SERVICE_AUTO_START, | 377 SERVICE_AUTO_START, |
383 SERVICE_NO_CHANGE, | 378 SERVICE_NO_CHANGE, |
384 NULL, | 379 NULL, |
385 NULL, | 380 NULL, |
386 NULL, | 381 NULL, |
387 NULL, | 382 NULL, |
388 NULL, | 383 NULL, |
389 NULL, | 384 NULL, |
390 NULL)) { | 385 NULL)) { |
391 DWORD error = GetLastError(); | 386 DWORD error = GetLastError(); |
392 LOG_GETLASTERROR(ERROR) | 387 PLOG(ERROR) << "Failed to change the '" << kWindowsServiceName |
393 << "Failed to change the '" << kWindowsServiceName | 388 << "'service start type to 'auto'"; |
394 << "'service start type to 'auto'"; | |
395 return HRESULT_FROM_WIN32(error); | 389 return HRESULT_FROM_WIN32(error); |
396 } | 390 } |
397 | 391 |
398 // Start the service. | 392 // Start the service. |
399 if (!StartService(service, 0, NULL)) { | 393 if (!StartService(service, 0, NULL)) { |
400 DWORD error = GetLastError(); | 394 DWORD error = GetLastError(); |
401 if (error != ERROR_SERVICE_ALREADY_RUNNING) { | 395 if (error != ERROR_SERVICE_ALREADY_RUNNING) { |
402 LOG_GETLASTERROR(ERROR) | 396 PLOG(ERROR) << "Failed to start the '" << kWindowsServiceName |
403 << "Failed to start the '" << kWindowsServiceName << "'service"; | 397 << "'service"; |
404 | 398 |
405 return HRESULT_FROM_WIN32(error); | 399 return HRESULT_FROM_WIN32(error); |
406 } | 400 } |
407 } | 401 } |
408 | 402 |
409 return S_OK; | 403 return S_OK; |
410 } | 404 } |
411 | 405 |
412 STDMETHODIMP ElevatedController::StopDaemon() { | 406 STDMETHODIMP ElevatedController::StopDaemon() { |
413 ScopedScHandle service; | 407 ScopedScHandle service; |
414 HRESULT hr = OpenService(&service); | 408 HRESULT hr = OpenService(&service); |
415 if (FAILED(hr)) { | 409 if (FAILED(hr)) { |
416 return hr; | 410 return hr; |
417 } | 411 } |
418 | 412 |
419 // Change the service start type to 'manual'. | 413 // Change the service start type to 'manual'. |
420 if (!::ChangeServiceConfigW(service, | 414 if (!::ChangeServiceConfigW(service, |
421 SERVICE_NO_CHANGE, | 415 SERVICE_NO_CHANGE, |
422 SERVICE_DEMAND_START, | 416 SERVICE_DEMAND_START, |
423 SERVICE_NO_CHANGE, | 417 SERVICE_NO_CHANGE, |
424 NULL, | 418 NULL, |
425 NULL, | 419 NULL, |
426 NULL, | 420 NULL, |
427 NULL, | 421 NULL, |
428 NULL, | 422 NULL, |
429 NULL, | 423 NULL, |
430 NULL)) { | 424 NULL)) { |
431 DWORD error = GetLastError(); | 425 DWORD error = GetLastError(); |
432 LOG_GETLASTERROR(ERROR) | 426 PLOG(ERROR) << "Failed to change the '" << kWindowsServiceName |
433 << "Failed to change the '" << kWindowsServiceName | 427 << "'service start type to 'manual'"; |
434 << "'service start type to 'manual'"; | |
435 return HRESULT_FROM_WIN32(error); | 428 return HRESULT_FROM_WIN32(error); |
436 } | 429 } |
437 | 430 |
438 // Stop the service. | 431 // Stop the service. |
439 SERVICE_STATUS status; | 432 SERVICE_STATUS status; |
440 if (!ControlService(service, SERVICE_CONTROL_STOP, &status)) { | 433 if (!ControlService(service, SERVICE_CONTROL_STOP, &status)) { |
441 DWORD error = GetLastError(); | 434 DWORD error = GetLastError(); |
442 if (error != ERROR_SERVICE_NOT_ACTIVE) { | 435 if (error != ERROR_SERVICE_NOT_ACTIVE) { |
443 LOG_GETLASTERROR(ERROR) | 436 PLOG(ERROR) << "Failed to stop the '" << kWindowsServiceName |
444 << "Failed to stop the '" << kWindowsServiceName << "'service"; | 437 << "'service"; |
445 return HRESULT_FROM_WIN32(error); | 438 return HRESULT_FROM_WIN32(error); |
446 } | 439 } |
447 } | 440 } |
448 | 441 |
449 return S_OK; | 442 return S_OK; |
450 } | 443 } |
451 | 444 |
452 STDMETHODIMP ElevatedController::UpdateConfig(BSTR config) { | 445 STDMETHODIMP ElevatedController::UpdateConfig(BSTR config) { |
453 // Parse the config. | 446 // Parse the config. |
454 std::string config_str = base::UTF16ToUTF8( | 447 std::string config_str = base::UTF16ToUTF8( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 } | 498 } |
506 | 499 |
507 HRESULT ElevatedController::OpenService(ScopedScHandle* service_out) { | 500 HRESULT ElevatedController::OpenService(ScopedScHandle* service_out) { |
508 DWORD error; | 501 DWORD error; |
509 | 502 |
510 ScopedScHandle scmanager( | 503 ScopedScHandle scmanager( |
511 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, | 504 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, |
512 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); | 505 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); |
513 if (!scmanager.IsValid()) { | 506 if (!scmanager.IsValid()) { |
514 error = GetLastError(); | 507 error = GetLastError(); |
515 LOG_GETLASTERROR(ERROR) | 508 PLOG(ERROR) << "Failed to connect to the service control manager"; |
516 << "Failed to connect to the service control manager"; | |
517 | 509 |
518 return HRESULT_FROM_WIN32(error); | 510 return HRESULT_FROM_WIN32(error); |
519 } | 511 } |
520 | 512 |
521 DWORD desired_access = SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | | 513 DWORD desired_access = SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | |
522 SERVICE_START | SERVICE_STOP; | 514 SERVICE_START | SERVICE_STOP; |
523 ScopedScHandle service( | 515 ScopedScHandle service( |
524 ::OpenServiceW(scmanager, kWindowsServiceName, desired_access)); | 516 ::OpenServiceW(scmanager, kWindowsServiceName, desired_access)); |
525 if (!service.IsValid()) { | 517 if (!service.IsValid()) { |
526 error = GetLastError(); | 518 error = GetLastError(); |
527 LOG_GETLASTERROR(ERROR) | 519 PLOG(ERROR) << "Failed to open to the '" << kWindowsServiceName |
528 << "Failed to open to the '" << kWindowsServiceName << "' service"; | 520 << "' service"; |
529 | 521 |
530 return HRESULT_FROM_WIN32(error); | 522 return HRESULT_FROM_WIN32(error); |
531 } | 523 } |
532 | 524 |
533 service_out->Set(service.Take()); | 525 service_out->Set(service.Take()); |
534 return S_OK; | 526 return S_OK; |
535 } | 527 } |
536 | 528 |
537 } // namespace remoting | 529 } // namespace remoting |
OLD | NEW |