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 "cloud_print/service/win/cloud_print_service.h" | 5 #include "cloud_print/service/win/cloud_print_service.h" |
6 | 6 |
7 #include <iomanip> | 7 #include <iomanip> |
8 #include <iostream> | 8 #include <iostream> |
9 | 9 |
10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
13 #include "base/file_util.h" | |
14 #include "base/path_service.h" | 13 #include "base/path_service.h" |
15 #include "base/string_util.h" | |
16 #include "base/win/scoped_handle.h" | 14 #include "base/win/scoped_handle.h" |
17 #include "cloud_print/service/win/resource.h" | 15 #include "cloud_print/service/win/resource.h" |
18 #include "cloud_print/service/win/service_state.h" | |
19 | 16 |
20 namespace { | 17 namespace { |
21 | 18 |
22 const char kInstallSwitch[] = "install"; | 19 const char kInstallSwitch[] = "install"; |
23 const char kUninstallSwitch[] = "uninstall"; | 20 const char kUninstallSwitch[] = "uninstall"; |
24 const char kStartSwitch[] = "start"; | 21 const char kStartSwitch[] = "start"; |
25 const char kStopSwitch[] = "stop"; | 22 const char kStopSwitch[] = "stop"; |
26 | 23 |
27 const char kServiceSwitch[] = "service"; | 24 const char kServiceSwitch[] = "service"; |
28 | 25 |
29 const char kUserDataDirSwitch[] = "user-data-dir"; | 26 const char kUserDataDirSwitch[] = "user-data-dir"; |
30 const char kQuietSwitch[] = "quiet"; | 27 const char kQuietSwitch[] = "quiet"; |
31 | 28 |
32 const wchar_t kServiceStateFileName[] = L"Service State"; | |
33 | |
34 // The traits class for Windows Service. | 29 // The traits class for Windows Service. |
35 class ServiceHandleTraits { | 30 class ServiceHandleTraits { |
36 public: | 31 public: |
37 typedef SC_HANDLE Handle; | 32 typedef SC_HANDLE Handle; |
38 | 33 |
39 // Closes the handle. | 34 // Closes the handle. |
40 static bool CloseHandle(Handle handle) { | 35 static bool CloseHandle(Handle handle) { |
41 return ::CloseServiceHandle(handle) != FALSE; | 36 return ::CloseServiceHandle(handle) != FALSE; |
42 } | 37 } |
43 | 38 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 }; | 91 }; |
97 | 92 |
98 for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) { | 93 for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) { |
99 std::cout << std::setiosflags(std::ios::left); | 94 std::cout << std::setiosflags(std::ios::left); |
100 std::cout << " -" << std::setw(15) << kSwitchHelp[i].name; | 95 std::cout << " -" << std::setw(15) << kSwitchHelp[i].name; |
101 std::cout << kSwitchHelp[i].description << "\n"; | 96 std::cout << kSwitchHelp[i].description << "\n"; |
102 } | 97 } |
103 std::cout << "\n"; | 98 std::cout << "\n"; |
104 } | 99 } |
105 | 100 |
106 std::string GetOption(const std::string& name, const std::string& default, | |
107 bool secure) { | |
108 std::cout << "Input \'" << name << "\'"; | |
109 if (!default.empty()) { | |
110 std::cout << ", press [ENTER] to keep '"; | |
111 std::cout << default; | |
112 std::cout << "'"; | |
113 } | |
114 std::cout << ":"; | |
115 std::string tmp; | |
116 | |
117 if (secure) { | |
118 DWORD saved_mode = 0; | |
119 // Don't close. | |
120 HANDLE stdin_handle = ::GetStdHandle(STD_INPUT_HANDLE); | |
121 ::GetConsoleMode(stdin_handle, &saved_mode); | |
122 ::SetConsoleMode(stdin_handle, saved_mode & ~ENABLE_ECHO_INPUT); | |
123 std::getline(std::cin, tmp); | |
124 ::SetConsoleMode(stdin_handle, saved_mode); | |
125 std::cout << "\n"; | |
126 } else { | |
127 std::getline(std::cin, tmp); | |
128 } | |
129 if (tmp.empty()) | |
130 return default; | |
131 return tmp; | |
132 } | |
133 | |
134 } // namespace | 101 } // namespace |
135 | 102 |
136 class CloudPrintServiceModule | 103 class CloudPrintServiceModule |
137 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { | 104 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { |
138 public: | 105 public: |
139 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, | 106 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, |
140 IDS_SERVICENAME> Base; | 107 IDS_SERVICENAME> Base; |
141 | 108 |
142 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, | 109 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, |
143 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") | 110 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 if (command_line.HasSwitch(kUninstallSwitch)) | 189 if (command_line.HasSwitch(kUninstallSwitch)) |
223 return Uninstall() ? S_OK : E_FAIL; | 190 return Uninstall() ? S_OK : E_FAIL; |
224 | 191 |
225 if (command_line.HasSwitch(kInstallSwitch)) { | 192 if (command_line.HasSwitch(kInstallSwitch)) { |
226 if (!command_line.HasSwitch(kUserDataDirSwitch)) { | 193 if (!command_line.HasSwitch(kUserDataDirSwitch)) { |
227 InvalidUsage(); | 194 InvalidUsage(); |
228 return S_FALSE; | 195 return S_FALSE; |
229 } | 196 } |
230 | 197 |
231 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 198 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
232 HRESULT hr = ProcessServiceState(data_dir, | 199 HRESULT hr = Install(data_dir); |
233 command_line.HasSwitch(kQuietSwitch)); | |
234 if (FAILED(hr)) | |
235 return hr; | |
236 hr = Install(data_dir); | |
237 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) | 200 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) |
238 return StartService(); | 201 return StartService(); |
239 | 202 |
240 return hr; | 203 return hr; |
241 } | 204 } |
242 | 205 |
243 if (command_line.HasSwitch(kStartSwitch)) | 206 if (command_line.HasSwitch(kStartSwitch)) |
244 return StartService(); | 207 return StartService(); |
245 | 208 |
246 if (command_line.HasSwitch(kServiceSwitch)) { | 209 if (command_line.HasSwitch(kServiceSwitch)) { |
247 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 210 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
248 *is_service = true; | 211 *is_service = true; |
249 return S_OK; | 212 return S_OK; |
250 } | 213 } |
251 | 214 |
252 InvalidUsage(); | 215 InvalidUsage(); |
253 return S_FALSE; | 216 return S_FALSE; |
254 } | 217 } |
255 | 218 |
256 HRESULT ProcessServiceState(const FilePath& user_data_dir, bool quiet) { | |
257 FilePath file = user_data_dir.Append(kServiceStateFileName); | |
258 | |
259 for (;;) { | |
260 std::string contents; | |
261 ServiceState service_state; | |
262 | |
263 bool is_valid = file_util::ReadFileToString(file, &contents) && | |
264 service_state.FromString(contents); | |
265 | |
266 if (!quiet) { | |
267 std::cout << file.value() << ":\n"; | |
268 std::cout << contents << "\n"; | |
269 } | |
270 | |
271 if (!is_valid) | |
272 LOG(ERROR) << "Invalid file: " << file.value(); | |
273 | |
274 if (quiet) | |
275 return is_valid ? S_OK : HRESULT_FROM_WIN32(ERROR_FILE_INVALID); | |
276 | |
277 std::cout << "Do you want to use this file [y/n]:"; | |
278 for (;;) { | |
279 std::string input; | |
280 std::getline(std::cin, input); | |
281 StringToLowerASCII(&input); | |
282 if (input == "y") { | |
283 return S_OK; | |
284 } else if (input == "n") { | |
285 is_valid = false; | |
286 break; | |
287 } | |
288 } | |
289 | |
290 while (!is_valid) { | |
291 std::string email = GetOption("email", service_state.email(), false); | |
292 std::string password = GetOption("password", "", true); | |
293 std::string proxy_id = GetOption("connector_id", | |
294 service_state.proxy_id(), false); | |
295 is_valid = service_state.Configure(email, password, proxy_id); | |
296 if (is_valid) { | |
297 std::string new_contents = service_state.ToString(); | |
298 if (new_contents != contents) { | |
299 if (file_util::WriteFile(file, new_contents.c_str(), | |
300 new_contents.size()) <= 0) { | |
301 return HResultFromLastError(); | |
302 } | |
303 } | |
304 } | |
305 } | |
306 } | |
307 | |
308 return S_OK; | |
309 } | |
310 | |
311 HRESULT OpenServiceManager(ServiceHandle* service_manager) { | 219 HRESULT OpenServiceManager(ServiceHandle* service_manager) { |
312 if (!service_manager) | 220 if (!service_manager) |
313 return E_POINTER; | 221 return E_POINTER; |
314 | 222 |
315 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); | 223 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); |
316 if (!service_manager->IsValid()) | 224 if (!service_manager->IsValid()) |
317 return HResultFromLastError(); | 225 return HResultFromLastError(); |
318 | 226 |
319 return S_OK; | 227 return S_OK; |
320 } | 228 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 | 274 |
367 FilePath user_data_dir_; | 275 FilePath user_data_dir_; |
368 }; | 276 }; |
369 | 277 |
370 CloudPrintServiceModule _AtlModule; | 278 CloudPrintServiceModule _AtlModule; |
371 | 279 |
372 int main() { | 280 int main() { |
373 base::AtExitManager at_exit; | 281 base::AtExitManager at_exit; |
374 return _AtlModule.WinMain(0); | 282 return _AtlModule.WinMain(0); |
375 } | 283 } |
OLD | NEW |