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" |
13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/string_util.h" |
14 #include "base/win/scoped_handle.h" | 16 #include "base/win/scoped_handle.h" |
15 #include "cloud_print/service/win/resource.h" | 17 #include "cloud_print/service/win/resource.h" |
| 18 #include "cloud_print/service/win/service_state.h" |
16 | 19 |
17 namespace { | 20 namespace { |
18 | 21 |
19 const char kInstallSwitch[] = "install"; | 22 const char kInstallSwitch[] = "install"; |
20 const char kUninstallSwitch[] = "uninstall"; | 23 const char kUninstallSwitch[] = "uninstall"; |
21 const char kStartSwitch[] = "start"; | 24 const char kStartSwitch[] = "start"; |
22 const char kStopSwitch[] = "stop"; | 25 const char kStopSwitch[] = "stop"; |
23 | 26 |
24 const char kServiceSwitch[] = "service"; | 27 const char kServiceSwitch[] = "service"; |
25 | 28 |
26 const char kUserDataDirSwitch[] = "user-data-dir"; | 29 const char kUserDataDirSwitch[] = "user-data-dir"; |
27 const char kQuietSwitch[] = "quiet"; | 30 const char kQuietSwitch[] = "quiet"; |
28 | 31 |
| 32 const wchar_t kServiceStateFileName[] = L"Service State"; |
| 33 |
29 // The traits class for Windows Service. | 34 // The traits class for Windows Service. |
30 class ServiceHandleTraits { | 35 class ServiceHandleTraits { |
31 public: | 36 public: |
32 typedef SC_HANDLE Handle; | 37 typedef SC_HANDLE Handle; |
33 | 38 |
34 // Closes the handle. | 39 // Closes the handle. |
35 static bool CloseHandle(Handle handle) { | 40 static bool CloseHandle(Handle handle) { |
36 return ::CloseServiceHandle(handle) != FALSE; | 41 return ::CloseServiceHandle(handle) != FALSE; |
37 } | 42 } |
38 | 43 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 }; | 96 }; |
92 | 97 |
93 for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) { | 98 for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) { |
94 std::cout << std::setiosflags(std::ios::left); | 99 std::cout << std::setiosflags(std::ios::left); |
95 std::cout << " -" << std::setw(15) << kSwitchHelp[i].name; | 100 std::cout << " -" << std::setw(15) << kSwitchHelp[i].name; |
96 std::cout << kSwitchHelp[i].description << "\n"; | 101 std::cout << kSwitchHelp[i].description << "\n"; |
97 } | 102 } |
98 std::cout << "\n"; | 103 std::cout << "\n"; |
99 } | 104 } |
100 | 105 |
| 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 |
101 } // namespace | 134 } // namespace |
102 | 135 |
103 class CloudPrintServiceModule | 136 class CloudPrintServiceModule |
104 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { | 137 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { |
105 public: | 138 public: |
106 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, | 139 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, |
107 IDS_SERVICENAME> Base; | 140 IDS_SERVICENAME> Base; |
108 | 141 |
109 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, | 142 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, |
110 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") | 143 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 if (command_line.HasSwitch(kUninstallSwitch)) | 222 if (command_line.HasSwitch(kUninstallSwitch)) |
190 return Uninstall() ? S_OK : E_FAIL; | 223 return Uninstall() ? S_OK : E_FAIL; |
191 | 224 |
192 if (command_line.HasSwitch(kInstallSwitch)) { | 225 if (command_line.HasSwitch(kInstallSwitch)) { |
193 if (!command_line.HasSwitch(kUserDataDirSwitch)) { | 226 if (!command_line.HasSwitch(kUserDataDirSwitch)) { |
194 InvalidUsage(); | 227 InvalidUsage(); |
195 return S_FALSE; | 228 return S_FALSE; |
196 } | 229 } |
197 | 230 |
198 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 231 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
199 HRESULT hr = Install(data_dir); | 232 HRESULT hr = ProcessServiceState(data_dir, |
| 233 command_line.HasSwitch(kQuietSwitch)); |
| 234 if (FAILED(hr)) |
| 235 return hr; |
| 236 hr = Install(data_dir); |
200 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) | 237 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) |
201 return StartService(); | 238 return StartService(); |
202 | 239 |
203 return hr; | 240 return hr; |
204 } | 241 } |
205 | 242 |
206 if (command_line.HasSwitch(kStartSwitch)) | 243 if (command_line.HasSwitch(kStartSwitch)) |
207 return StartService(); | 244 return StartService(); |
208 | 245 |
209 if (command_line.HasSwitch(kServiceSwitch)) { | 246 if (command_line.HasSwitch(kServiceSwitch)) { |
210 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 247 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
211 *is_service = true; | 248 *is_service = true; |
212 return S_OK; | 249 return S_OK; |
213 } | 250 } |
214 | 251 |
215 InvalidUsage(); | 252 InvalidUsage(); |
216 return S_FALSE; | 253 return S_FALSE; |
217 } | 254 } |
218 | 255 |
| 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 |
219 HRESULT OpenServiceManager(ServiceHandle* service_manager) { | 311 HRESULT OpenServiceManager(ServiceHandle* service_manager) { |
220 if (!service_manager) | 312 if (!service_manager) |
221 return E_POINTER; | 313 return E_POINTER; |
222 | 314 |
223 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); | 315 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); |
224 if (!service_manager->IsValid()) | 316 if (!service_manager->IsValid()) |
225 return HResultFromLastError(); | 317 return HResultFromLastError(); |
226 | 318 |
227 return S_OK; | 319 return S_OK; |
228 } | 320 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 | 366 |
275 FilePath user_data_dir_; | 367 FilePath user_data_dir_; |
276 }; | 368 }; |
277 | 369 |
278 CloudPrintServiceModule _AtlModule; | 370 CloudPrintServiceModule _AtlModule; |
279 | 371 |
280 int main() { | 372 int main() { |
281 base::AtExitManager at_exit; | 373 base::AtExitManager at_exit; |
282 return _AtlModule.WinMain(0); | 374 return _AtlModule.WinMain(0); |
283 } | 375 } |
OLD | NEW |