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 class ServiceStateDelegate : public ServiceState::OptionsDelegate { | |
107 public: | |
108 virtual std::string GetOption(const std::string& name, | |
109 const std::string& default, | |
110 bool secure) { | |
111 std::cout << "Input \'" << name << "\'"; | |
112 if (!default.empty()) { | |
113 std::cout << ", press [ENTER] to keep '"; | |
114 std::cout << default; | |
115 std::cout << "'"; | |
116 } | |
117 std::cout << ":"; | |
118 std::string tmp; | |
119 | |
120 if (secure) { | |
121 DWORD saved_mode = 0; | |
122 // Don't close. | |
123 HANDLE stdin_handle = ::GetStdHandle(STD_INPUT_HANDLE); | |
124 ::GetConsoleMode(stdin_handle, &saved_mode); | |
125 ::SetConsoleMode(stdin_handle, saved_mode & ~ENABLE_ECHO_INPUT); | |
126 std::getline(std::cin, tmp); | |
127 ::SetConsoleMode(stdin_handle, saved_mode); | |
128 std::cout << "\n"; | |
129 } else { | |
130 std::getline(std::cin, tmp); | |
131 } | |
132 if (tmp.empty()) | |
133 return default; | |
134 return tmp; | |
135 } | |
136 }; | |
137 | |
101 } // namespace | 138 } // namespace |
102 | 139 |
103 class CloudPrintServiceModule | 140 class CloudPrintServiceModule |
104 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { | 141 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { |
105 public: | 142 public: |
106 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, | 143 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, |
107 IDS_SERVICENAME> Base; | 144 IDS_SERVICENAME> Base; |
108 | 145 |
109 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, | 146 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, |
110 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") | 147 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 if (command_line.HasSwitch(kUninstallSwitch)) | 226 if (command_line.HasSwitch(kUninstallSwitch)) |
190 return Uninstall() ? S_OK : E_FAIL; | 227 return Uninstall() ? S_OK : E_FAIL; |
191 | 228 |
192 if (command_line.HasSwitch(kInstallSwitch)) { | 229 if (command_line.HasSwitch(kInstallSwitch)) { |
193 if (!command_line.HasSwitch(kUserDataDirSwitch)) { | 230 if (!command_line.HasSwitch(kUserDataDirSwitch)) { |
194 InvalidUsage(); | 231 InvalidUsage(); |
195 return S_FALSE; | 232 return S_FALSE; |
196 } | 233 } |
197 | 234 |
198 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 235 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
199 HRESULT hr = Install(data_dir); | 236 HRESULT hr = ProcessServiceState(data_dir, |
237 command_line.HasSwitch(kQuietSwitch)); | |
238 if (FAILED(hr)) | |
239 return hr; | |
240 hr = Install(data_dir); | |
200 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) | 241 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) |
201 return StartService(); | 242 return StartService(); |
202 | 243 |
203 return hr; | 244 return hr; |
204 } | 245 } |
205 | 246 |
206 if (command_line.HasSwitch(kStartSwitch)) | 247 if (command_line.HasSwitch(kStartSwitch)) |
207 return StartService(); | 248 return StartService(); |
208 | 249 |
209 if (command_line.HasSwitch(kServiceSwitch)) { | 250 if (command_line.HasSwitch(kServiceSwitch)) { |
210 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); | 251 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); |
211 *is_service = true; | 252 *is_service = true; |
212 return S_OK; | 253 return S_OK; |
213 } | 254 } |
214 | 255 |
215 InvalidUsage(); | 256 InvalidUsage(); |
216 return S_FALSE; | 257 return S_FALSE; |
217 } | 258 } |
218 | 259 |
260 HRESULT ProcessServiceState(const FilePath& user_data_dir, bool quiet) { | |
261 FilePath file = user_data_dir.Append(kServiceStateFileName); | |
262 | |
263 for (;;) { | |
264 std::string contents; | |
265 ServiceState service_state; | |
266 | |
267 bool is_valid = file_util::ReadFileToString(file, &contents) && | |
268 service_state.FromString(contents); | |
269 | |
270 std::cout << file.value() << ":\n"; | |
gene
2012/05/21 23:08:06
if (!quiet) - ???
Vitaly Buka (NO REVIEWS)
2012/05/22 05:47:20
Done.
| |
271 std::cout << contents << "\n"; | |
272 | |
273 if (!is_valid) | |
274 LOG(ERROR) << "Invalid file: " << file.value(); | |
275 | |
276 if (quiet) | |
277 return is_valid ? S_OK : HRESULT_FROM_WIN32(ERROR_FILE_INVALID); | |
278 | |
279 if (is_valid) { | |
280 std::cout << "Do you want to use this file [y/n]:"; | |
gene
2012/05/21 23:08:06
If file is not valid, shall we ask user before ove
Vitaly Buka (NO REVIEWS)
2012/05/22 05:47:20
Done.
| |
281 for (;;) { | |
282 std::string input; | |
283 std::getline(std::cin, input); | |
284 StringToLowerASCII(&input); | |
285 if (input == "y") { | |
286 return S_OK; | |
287 } else if (input == "n") { | |
288 is_valid = false; | |
289 break; | |
290 } | |
291 } | |
292 } | |
293 | |
294 while (!is_valid) { | |
295 ServiceStateDelegate delegate; | |
296 is_valid = service_state.Configure(&delegate); | |
gene
2012/05/21 23:08:06
Can we call GetOption() here, and then Configure(e
Vitaly Buka (NO REVIEWS)
2012/05/22 05:47:20
Done.
| |
297 if (is_valid) { | |
298 std::string new_contents = service_state.ToString(); | |
299 if (new_contents != contents) { | |
300 if (file_util::WriteFile(file, new_contents.c_str(), | |
301 new_contents.size()) <= 0) { | |
302 return HResultFromLastError(); | |
303 } | |
304 } | |
305 } | |
306 } | |
307 } | |
308 | |
309 return S_OK; | |
310 } | |
311 | |
219 HRESULT OpenServiceManager(ServiceHandle* service_manager) { | 312 HRESULT OpenServiceManager(ServiceHandle* service_manager) { |
220 if (!service_manager) | 313 if (!service_manager) |
221 return E_POINTER; | 314 return E_POINTER; |
222 | 315 |
223 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); | 316 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); |
224 if (!service_manager->IsValid()) | 317 if (!service_manager->IsValid()) |
225 return HResultFromLastError(); | 318 return HResultFromLastError(); |
226 | 319 |
227 return S_OK; | 320 return S_OK; |
228 } | 321 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 | 367 |
275 FilePath user_data_dir_; | 368 FilePath user_data_dir_; |
276 }; | 369 }; |
277 | 370 |
278 CloudPrintServiceModule _AtlModule; | 371 CloudPrintServiceModule _AtlModule; |
279 | 372 |
280 int main() { | 373 int main() { |
281 base::AtExitManager at_exit; | 374 base::AtExitManager at_exit; |
282 return _AtlModule.WinMain(0); | 375 return _AtlModule.WinMain(0); |
283 } | 376 } |
OLD | NEW |