| 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 |