OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "cloud_print/service/win/service_controller.h" | 5 #include "cloud_print/service/win/service_controller.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlcom.h> | 8 #include <atlcom.h> |
9 #include <atlctl.h> | 9 #include <atlctl.h> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/win/scoped_handle.h" | 15 #include "base/win/scoped_handle.h" |
16 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
17 #include "cloud_print/common/win/cloud_print_utils.h" | 17 #include "cloud_print/common/win/cloud_print_utils.h" |
| 18 #include "cloud_print/service/service_constants.h" |
18 #include "cloud_print/service/service_switches.h" | 19 #include "cloud_print/service/service_switches.h" |
19 #include "cloud_print/service/win/chrome_launcher.h" | 20 #include "cloud_print/service/win/chrome_launcher.h" |
20 #include "cloud_print/service/win/local_security_policy.h" | 21 #include "cloud_print/service/win/local_security_policy.h" |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
24 const wchar_t kServiceExeName[] = L"cloud_print_service.exe"; | 25 const wchar_t kServiceExeName[] = L"cloud_print_service.exe"; |
25 | 26 |
26 // The traits class for Windows Service. | 27 // The traits class for Windows Service. |
27 class ServiceHandleTraits { | 28 class ServiceHandleTraits { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 74 |
74 if (!service->IsValid()) | 75 if (!service->IsValid()) |
75 return cloud_print::GetLastHResult(); | 76 return cloud_print::GetLastHResult(); |
76 | 77 |
77 return S_OK; | 78 return S_OK; |
78 } | 79 } |
79 | 80 |
80 } // namespace | 81 } // namespace |
81 | 82 |
82 ServiceController::ServiceController(const string16& name) | 83 ServiceController::ServiceController(const string16& name) |
83 : name_(name) { | 84 : name_(name), command_line_(CommandLine::NO_PROGRAM) { |
84 } | 85 } |
85 | 86 |
86 ServiceController::~ServiceController() { | 87 ServiceController::~ServiceController() { |
87 } | 88 } |
88 | 89 |
89 HRESULT ServiceController::StartService() { | 90 HRESULT ServiceController::StartService() { |
90 ServiceHandle service; | 91 ServiceHandle service; |
91 HRESULT hr = OpenService(name_, SERVICE_START| SERVICE_QUERY_STATUS, | 92 HRESULT hr = OpenService(name_, SERVICE_START| SERVICE_QUERY_STATUS, |
92 &service); | 93 &service); |
93 if (FAILED(hr)) | 94 if (FAILED(hr)) |
(...skipping 18 matching lines...) Expand all Loading... |
112 if (!::ControlService(service, SERVICE_CONTROL_STOP, &status)) | 113 if (!::ControlService(service, SERVICE_CONTROL_STOP, &status)) |
113 return cloud_print::GetLastHResult(); | 114 return cloud_print::GetLastHResult(); |
114 while (::QueryServiceStatus(service, &status) && | 115 while (::QueryServiceStatus(service, &status) && |
115 status.dwCurrentState > SERVICE_STOPPED) { | 116 status.dwCurrentState > SERVICE_STOPPED) { |
116 Sleep(500); | 117 Sleep(500); |
117 ::ControlService(service, SERVICE_CONTROL_STOP, &status); | 118 ::ControlService(service, SERVICE_CONTROL_STOP, &status); |
118 } | 119 } |
119 return S_OK; | 120 return S_OK; |
120 } | 121 } |
121 | 122 |
| 123 base::FilePath ServiceController::GetBinary() const { |
| 124 base::FilePath service_path; |
| 125 CHECK(PathService::Get(base::FILE_EXE, &service_path)); |
| 126 return service_path.DirName().Append(base::FilePath(kServiceExeName)); |
| 127 } |
| 128 |
122 HRESULT ServiceController::InstallConnectorService( | 129 HRESULT ServiceController::InstallConnectorService( |
123 const string16& user, | 130 const string16& user, |
124 const string16& password, | 131 const string16& password, |
125 const base::FilePath& user_data_dir, | 132 const base::FilePath& user_data_dir, |
126 bool enable_logging) { | 133 bool enable_logging) { |
127 return InstallService(user, password, true, kServiceSwitch, user_data_dir, | 134 return InstallService(user, password, true, kServiceSwitch, user_data_dir, |
128 enable_logging); | 135 enable_logging); |
129 } | 136 } |
130 | 137 |
131 HRESULT ServiceController::InstallCheckService( | 138 HRESULT ServiceController::InstallCheckService( |
(...skipping 13 matching lines...) Expand all Loading... |
145 // TODO(vitalybuka): consider "lite" version if we don't want unregister | 152 // TODO(vitalybuka): consider "lite" version if we don't want unregister |
146 // printers here. | 153 // printers here. |
147 HRESULT hr = UninstallService(); | 154 HRESULT hr = UninstallService(); |
148 if (FAILED(hr)) | 155 if (FAILED(hr)) |
149 return hr; | 156 return hr; |
150 | 157 |
151 hr = UpdateRegistryAppId(true); | 158 hr = UpdateRegistryAppId(true); |
152 if (FAILED(hr)) | 159 if (FAILED(hr)) |
153 return hr; | 160 return hr; |
154 | 161 |
155 base::FilePath service_path; | 162 base::FilePath service_path = GetBinary(); |
156 CHECK(PathService::Get(base::FILE_EXE, &service_path)); | |
157 service_path = service_path.DirName().Append(base::FilePath(kServiceExeName)); | |
158 if (!file_util::PathExists(service_path)) | 163 if (!file_util::PathExists(service_path)) |
159 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); | 164 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
160 CommandLine command_line(service_path); | 165 CommandLine command_line(service_path); |
161 command_line.AppendSwitch(run_switch); | 166 command_line.AppendSwitch(run_switch); |
162 if (!user_data_dir.empty()) | 167 if (!user_data_dir.empty()) |
163 command_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir); | 168 command_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir); |
164 if (enable_logging) { | 169 if (enable_logging) { |
165 command_line.AppendSwitch(switches::kEnableLogging); | 170 command_line.AppendSwitch(switches::kEnableLogging); |
166 command_line.AppendSwitchASCII(switches::kV, "1"); | 171 command_line.AppendSwitchASCII(switches::kV, "1"); |
167 } | 172 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 if (service) { | 216 if (service) { |
212 if (!::DeleteService(service)) { | 217 if (!::DeleteService(service)) { |
213 LOG(ERROR) << "Failed to uninstall service"; | 218 LOG(ERROR) << "Failed to uninstall service"; |
214 hr = cloud_print::GetLastHResult(); | 219 hr = cloud_print::GetLastHResult(); |
215 } | 220 } |
216 } | 221 } |
217 UpdateRegistryAppId(false); | 222 UpdateRegistryAppId(false); |
218 return hr; | 223 return hr; |
219 } | 224 } |
220 | 225 |
| 226 HRESULT ServiceController::UpdateBinaryPath() { |
| 227 UpdateState(); |
| 228 ServiceController::State origina_state = state(); |
| 229 if (origina_state < ServiceController::STATE_STOPPED) |
| 230 return S_FALSE; |
| 231 |
| 232 ServiceHandle service; |
| 233 HRESULT hr = OpenService(name_, SERVICE_CHANGE_CONFIG, &service); |
| 234 if (FAILED(hr)) |
| 235 return hr; |
| 236 |
| 237 base::FilePath service_path = GetBinary(); |
| 238 if (!file_util::PathExists(service_path)) |
| 239 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
| 240 |
| 241 command_line_.SetProgram(service_path); |
| 242 if (!::ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, |
| 243 SERVICE_NO_CHANGE, |
| 244 command_line_.GetCommandLineString().c_str(), NULL, |
| 245 NULL, NULL, NULL, NULL, NULL)) { |
| 246 return cloud_print::GetLastHResult(); |
| 247 } |
| 248 |
| 249 if (origina_state != ServiceController::STATE_RUNNING) |
| 250 return S_OK; |
| 251 |
| 252 hr = StopService(); |
| 253 if (FAILED(hr)) |
| 254 return hr; |
| 255 |
| 256 hr = StartService(); |
| 257 if (FAILED(hr)) |
| 258 return hr; |
| 259 |
| 260 return S_OK; |
| 261 } |
| 262 |
221 void ServiceController::UpdateState() { | 263 void ServiceController::UpdateState() { |
222 ServiceHandle service; | |
223 state_ = STATE_NOT_FOUND; | 264 state_ = STATE_NOT_FOUND; |
224 user_.clear(); | 265 user_.clear(); |
225 is_logging_enabled_ = false; | 266 is_logging_enabled_ = false; |
226 | 267 |
| 268 ServiceHandle service; |
227 HRESULT hr = OpenService(name_, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, | 269 HRESULT hr = OpenService(name_, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, |
228 &service); | 270 &service); |
229 if (FAILED(hr)) | 271 if (FAILED(hr)) |
230 return; | 272 return; |
231 | 273 |
232 state_ = STATE_STOPPED; | 274 state_ = STATE_STOPPED; |
233 SERVICE_STATUS status = {0}; | 275 SERVICE_STATUS status = {0}; |
234 if (::QueryServiceStatus(service, &status) && | 276 if (::QueryServiceStatus(service, &status) && |
235 status.dwCurrentState == SERVICE_RUNNING) { | 277 status.dwCurrentState == SERVICE_RUNNING) { |
236 state_ = STATE_RUNNING; | 278 state_ = STATE_RUNNING; |
237 } | 279 } |
238 | 280 |
239 DWORD config_size = 0; | 281 DWORD config_size = 0; |
240 ::QueryServiceConfig(service, NULL, 0, &config_size); | 282 ::QueryServiceConfig(service, NULL, 0, &config_size); |
241 if (!config_size) | 283 if (!config_size) |
242 return; | 284 return; |
243 | 285 |
244 std::vector<uint8> buffer(config_size, 0); | 286 std::vector<uint8> buffer(config_size, 0); |
245 QUERY_SERVICE_CONFIG* config = | 287 QUERY_SERVICE_CONFIG* config = |
246 reinterpret_cast<QUERY_SERVICE_CONFIG*>(&buffer[0]); | 288 reinterpret_cast<QUERY_SERVICE_CONFIG*>(&buffer[0]); |
247 if (!::QueryServiceConfig(service, config, buffer.size(), &config_size) || | 289 if (!::QueryServiceConfig(service, config, buffer.size(), &config_size) || |
248 config_size != buffer.size()) { | 290 config_size != buffer.size()) { |
249 return; | 291 return; |
250 } | 292 } |
251 | 293 |
252 CommandLine command_line(CommandLine::FromString(config->lpBinaryPathName)); | 294 command_line_ = CommandLine::FromString(config->lpBinaryPathName); |
253 if (!command_line.HasSwitch(kServiceSwitch)) { | 295 if (!command_line_.HasSwitch(kServiceSwitch)) { |
254 state_ = STATE_NOT_FOUND; | 296 state_ = STATE_NOT_FOUND; |
255 return; | 297 return; |
256 } | 298 } |
257 is_logging_enabled_ = command_line.HasSwitch(switches::kEnableLogging); | 299 is_logging_enabled_ = command_line_.HasSwitch(switches::kEnableLogging); |
258 user_ = config->lpServiceStartName; | 300 user_ = config->lpServiceStartName; |
259 } | 301 } |
| 302 |
| 303 bool ServiceController::is_logging_enabled() const { |
| 304 return command_line_.HasSwitch(switches::kEnableLogging); |
| 305 } |
OLD | NEW |