OLD | NEW |
| (Empty) |
1 // Copyright 2008-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/common/command_line_builder.h" | |
17 #include <shellapi.h> | |
18 #include "omaha/base/debug.h" | |
19 #include "omaha/base/error.h" | |
20 #include "omaha/base/logging.h" | |
21 #include "omaha/base/path.h" | |
22 #include "omaha/base/safe_format.h" | |
23 #include "omaha/common/command_line.h" | |
24 #include "omaha/common/const_cmd_line.h" | |
25 #include "omaha/common/const_goopdate.h" | |
26 | |
27 namespace omaha { | |
28 | |
29 CommandLineBuilder::CommandLineBuilder(CommandLineMode mode) | |
30 : mode_(mode), | |
31 is_interactive_set_(false), | |
32 is_machine_set_(false), | |
33 is_silent_set_(false), | |
34 is_eula_required_set_(false) { | |
35 } | |
36 | |
37 CommandLineBuilder::~CommandLineBuilder() { | |
38 } | |
39 | |
40 void CommandLineBuilder::set_is_interactive_set(bool is_interactive_set) { | |
41 ASSERT1(mode_ == COMMANDLINE_MODE_REPORTCRASH); | |
42 is_interactive_set_ = is_interactive_set; | |
43 } | |
44 | |
45 void CommandLineBuilder::set_is_machine_set(bool is_machine_set) { | |
46 ASSERT1(mode_ == COMMANDLINE_MODE_REPORTCRASH); | |
47 is_machine_set_ = is_machine_set; | |
48 } | |
49 | |
50 void CommandLineBuilder::set_is_silent_set(bool is_silent_set) { | |
51 ASSERT1(mode_ == COMMANDLINE_MODE_INSTALL || | |
52 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL); | |
53 is_silent_set_ = is_silent_set; | |
54 } | |
55 | |
56 void CommandLineBuilder::set_is_eula_required_set(bool is_eula_required_set) { | |
57 ASSERT1(mode_ == COMMANDLINE_MODE_INSTALL || | |
58 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL); | |
59 is_eula_required_set_ = is_eula_required_set; | |
60 } | |
61 | |
62 void CommandLineBuilder::set_extra_args(const CString& extra_args) { | |
63 ASSERT1(mode_ == COMMANDLINE_MODE_INSTALL || | |
64 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL || | |
65 mode_ == COMMANDLINE_MODE_REGISTER_PRODUCT || | |
66 mode_ == COMMANDLINE_MODE_UNREGISTER_PRODUCT); | |
67 extra_args_ = extra_args; | |
68 } | |
69 | |
70 void CommandLineBuilder::set_app_args(const CString& app_args) { | |
71 ASSERT1(mode_ == COMMANDLINE_MODE_INSTALL || | |
72 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL); | |
73 app_args_ = app_args; | |
74 } | |
75 | |
76 void CommandLineBuilder::set_install_source(const CString& install_source) { | |
77 ASSERT1(mode_ == COMMANDLINE_MODE_WEBPLUGIN || | |
78 mode_ == COMMANDLINE_MODE_INSTALL || | |
79 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL || | |
80 mode_ == COMMANDLINE_MODE_UA); | |
81 install_source_ = install_source; | |
82 } | |
83 | |
84 void CommandLineBuilder::set_session_id(const CString& session_id) { | |
85 ASSERT1(mode_ == COMMANDLINE_MODE_INSTALL || | |
86 mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL || | |
87 mode_ == COMMANDLINE_MODE_UPDATE); | |
88 session_id_ = session_id; | |
89 } | |
90 | |
91 void CommandLineBuilder::set_crash_filename(const CString& crash_filename) { | |
92 ASSERT1(mode_ == COMMANDLINE_MODE_REPORTCRASH); | |
93 crash_filename_ = crash_filename; | |
94 } | |
95 | |
96 void CommandLineBuilder::set_custom_info_filename( | |
97 const CString& custom_info_filename) { | |
98 ASSERT1(mode_ == COMMANDLINE_MODE_REPORTCRASH); | |
99 custom_info_filename_ = custom_info_filename; | |
100 } | |
101 | |
102 void CommandLineBuilder::set_webplugin_url_domain( | |
103 const CString& webplugin_url_domain) { | |
104 ASSERT1(mode_ == COMMANDLINE_MODE_WEBPLUGIN); | |
105 webplugin_url_domain_ = webplugin_url_domain; | |
106 } | |
107 | |
108 void CommandLineBuilder::set_webplugin_args(const CString& webplugin_args) { | |
109 ASSERT1(mode_ == COMMANDLINE_MODE_WEBPLUGIN); | |
110 webplugin_args_ = webplugin_args; | |
111 } | |
112 | |
113 void CommandLineBuilder::set_code_red_metainstaller_path( | |
114 const CString& code_red_metainstaller_path) { | |
115 ASSERT1(mode_ == COMMANDLINE_MODE_RECOVER); | |
116 code_red_metainstaller_path_ = code_red_metainstaller_path; | |
117 } | |
118 | |
119 void CommandLineBuilder::set_ping_string(const CString& ping_string) { | |
120 ASSERT1(mode_ == COMMANDLINE_MODE_PING); | |
121 ping_string_ = ping_string; | |
122 } | |
123 | |
124 void CommandLineBuilder::SetOfflineDir(const CString& offline_dir) { | |
125 ASSERT1(mode_ == COMMANDLINE_MODE_HANDOFF_INSTALL); | |
126 offline_dir_ = offline_dir; | |
127 ::PathRemoveBackslash(CStrBuf(offline_dir_, MAX_PATH)); | |
128 } | |
129 | |
130 CString CommandLineBuilder::GetCommandLineArgs() const { | |
131 CString cmd_line_args; | |
132 | |
133 switch (mode_) { | |
134 case COMMANDLINE_MODE_NOARGS: | |
135 cmd_line_args.Empty(); | |
136 break; | |
137 case COMMANDLINE_MODE_CORE: | |
138 cmd_line_args = GetCore(); | |
139 break; | |
140 case COMMANDLINE_MODE_SERVICE: | |
141 cmd_line_args = GetService(); | |
142 break; | |
143 case COMMANDLINE_MODE_REGSERVER: | |
144 cmd_line_args = GetRegServer(); | |
145 break; | |
146 case COMMANDLINE_MODE_UNREGSERVER: | |
147 cmd_line_args = GetUnregServer(); | |
148 break; | |
149 case COMMANDLINE_MODE_NETDIAGS: | |
150 cmd_line_args = GetNetDiags(); | |
151 break; | |
152 case COMMANDLINE_MODE_CRASH: | |
153 cmd_line_args = GetCrash(); | |
154 break; | |
155 case COMMANDLINE_MODE_REPORTCRASH: | |
156 cmd_line_args = GetReportCrash(); | |
157 break; | |
158 case COMMANDLINE_MODE_INSTALL: | |
159 cmd_line_args = GetInstall(); | |
160 break; | |
161 case COMMANDLINE_MODE_UPDATE: | |
162 cmd_line_args = GetUpdate(); | |
163 break; | |
164 case COMMANDLINE_MODE_HANDOFF_INSTALL: | |
165 cmd_line_args = GetHandoffInstall(); | |
166 break; | |
167 case COMMANDLINE_MODE_UA: | |
168 cmd_line_args = GetUA(); | |
169 break; | |
170 case COMMANDLINE_MODE_RECOVER: | |
171 cmd_line_args = GetRecover(); | |
172 break; | |
173 case COMMANDLINE_MODE_WEBPLUGIN: | |
174 cmd_line_args = GetWebPlugin(); | |
175 break; | |
176 case COMMANDLINE_MODE_CODE_RED_CHECK: | |
177 cmd_line_args = GetCodeRedCheck(); | |
178 break; | |
179 case COMMANDLINE_MODE_COMSERVER: | |
180 cmd_line_args = GetComServer(); | |
181 break; | |
182 case COMMANDLINE_MODE_REGISTER_PRODUCT: | |
183 cmd_line_args = GetRegisterProduct(); | |
184 break; | |
185 case COMMANDLINE_MODE_UNREGISTER_PRODUCT: | |
186 cmd_line_args = GetUnregisterProduct(); | |
187 break; | |
188 case COMMANDLINE_MODE_SERVICE_REGISTER: | |
189 cmd_line_args = GetServiceRegister(); | |
190 break; | |
191 case COMMANDLINE_MODE_SERVICE_UNREGISTER: | |
192 cmd_line_args = GetServiceUnregister(); | |
193 break; | |
194 case COMMANDLINE_MODE_CRASH_HANDLER: | |
195 cmd_line_args = GetCrashHandler(); | |
196 break; | |
197 case COMMANDLINE_MODE_COMBROKER: | |
198 cmd_line_args = GetComBroker(); | |
199 break; | |
200 case COMMANDLINE_MODE_ONDEMAND: | |
201 cmd_line_args = GetOnDemand(); | |
202 break; | |
203 case COMMANDLINE_MODE_MEDIUM_SERVICE: | |
204 cmd_line_args = GetMediumService(); | |
205 break; | |
206 case COMMANDLINE_MODE_UNINSTALL: | |
207 cmd_line_args = GetUninstall(); | |
208 break; | |
209 case COMMANDLINE_MODE_PING: | |
210 cmd_line_args = GetPing(); | |
211 break; | |
212 case COMMANDLINE_MODE_UNKNOWN: | |
213 default: | |
214 ASSERT1(false); | |
215 break; | |
216 } | |
217 | |
218 #ifdef _DEBUG | |
219 CString full_command_line; | |
220 SafeCStringFormat(&full_command_line, _T("gu.exe %s"), cmd_line_args); | |
221 CommandLineArgs args; | |
222 ASSERT1(SUCCEEDED(ParseCommandLine(full_command_line, &args))); | |
223 #endif | |
224 | |
225 return cmd_line_args; | |
226 } | |
227 | |
228 CString CommandLineBuilder::GetCommandLine(const CString& program_name) const { | |
229 // Do not pass the results of the the /update builder to GoogleUpdate.exe. | |
230 // The command line for /update is intended to be passed to a metainstaller. | |
231 // See GetUpdate() for more information. | |
232 ASSERT1(COMMANDLINE_MODE_UPDATE != mode_ || | |
233 -1 == program_name.Find(kOmahaShellFileName)); | |
234 | |
235 // Always enclose the program name in double quotes. | |
236 CString enclosed_program_name(program_name); | |
237 EnclosePath(&enclosed_program_name); | |
238 CString cmd_line; | |
239 SafeCStringFormat(&cmd_line, _T("%s %s"), | |
240 enclosed_program_name, | |
241 GetCommandLineArgs()); | |
242 return cmd_line; | |
243 } | |
244 | |
245 CString CommandLineBuilder::GetSingleSwitch(const CString& switch_name) const { | |
246 CString cmd_line; | |
247 cmd_line.Format(_T("/%s"), switch_name); | |
248 return cmd_line; | |
249 } | |
250 | |
251 CString CommandLineBuilder::GetCore() const { | |
252 return GetSingleSwitch(kCmdLineCore); | |
253 } | |
254 | |
255 CString CommandLineBuilder::GetCrashHandler() const { | |
256 return GetSingleSwitch(kCmdLineCrashHandler); | |
257 } | |
258 | |
259 CString CommandLineBuilder::GetService() const { | |
260 return GetSingleSwitch(kCmdLineService); | |
261 } | |
262 | |
263 CString CommandLineBuilder::GetServiceRegister() const { | |
264 return GetSingleSwitch(kCmdLineRegisterService); | |
265 } | |
266 | |
267 CString CommandLineBuilder::GetServiceUnregister() const { | |
268 return GetSingleSwitch(kCmdLineUnregisterService); | |
269 } | |
270 | |
271 CString CommandLineBuilder::GetRegServer() const { | |
272 return GetSingleSwitch(kCmdRegServer); | |
273 } | |
274 | |
275 CString CommandLineBuilder::GetUnregServer() const { | |
276 return GetSingleSwitch(kCmdUnregServer); | |
277 } | |
278 | |
279 CString CommandLineBuilder::GetNetDiags() const { | |
280 return GetSingleSwitch(kCmdLineNetDiags); | |
281 } | |
282 | |
283 CString CommandLineBuilder::GetCrash() const { | |
284 CString cmd_line = GetSingleSwitch(kCmdLineCrash); | |
285 return cmd_line; | |
286 } | |
287 | |
288 CString CommandLineBuilder::GetReportCrash() const { | |
289 ASSERT1(!crash_filename_.IsEmpty()); | |
290 if (crash_filename_.IsEmpty()) { | |
291 return CString(); | |
292 } | |
293 CString cmd_line = GetSingleSwitch(kCmdLineReport); | |
294 if (is_interactive_set_) { | |
295 SafeCStringAppendFormat(&cmd_line, _T(" /%s"), kCmdLineInteractive); | |
296 } | |
297 CString enclosed_crash_filename_(crash_filename_); | |
298 EnclosePath(&enclosed_crash_filename_); | |
299 SafeCStringAppendFormat(&cmd_line, _T(" %s"), enclosed_crash_filename_); | |
300 if (is_machine_set()) { | |
301 SafeCStringAppendFormat(&cmd_line, _T(" /%s"), kCmdLineMachine); | |
302 } | |
303 | |
304 if (!custom_info_filename_.IsEmpty()) { | |
305 CString enclosed_custom_info_filename_(custom_info_filename_); | |
306 EnclosePath(&enclosed_custom_info_filename_); | |
307 SafeCStringAppendFormat(&cmd_line, _T(" /%s %s"), | |
308 kCmdLineCustomInfoFileName, | |
309 enclosed_custom_info_filename_); | |
310 } | |
311 | |
312 return cmd_line; | |
313 } | |
314 | |
315 CString CommandLineBuilder::GetExtraAndAppArgs( | |
316 const TCHAR* extra_switch_name) const { | |
317 ASSERT1(extra_switch_name && *extra_switch_name); | |
318 ASSERT1(!extra_args_.IsEmpty()); | |
319 if (extra_args_.IsEmpty()) { | |
320 return CString(); | |
321 } | |
322 | |
323 CString cmd_line; | |
324 CString enclosed_extra_args_(extra_args_); | |
325 EnclosePath(&enclosed_extra_args_); | |
326 SafeCStringFormat(&cmd_line, _T("/%s %s"), | |
327 extra_switch_name, | |
328 enclosed_extra_args_); | |
329 | |
330 if (!app_args_.IsEmpty()) { | |
331 CString enclosed_app_args = app_args_; | |
332 EnclosePath(&enclosed_app_args); | |
333 SafeCStringAppendFormat(&cmd_line, _T(" /%s %s"), | |
334 kCmdLineAppArgs, | |
335 enclosed_app_args); | |
336 } | |
337 | |
338 return cmd_line; | |
339 } | |
340 | |
341 // Does not support /oem or /eularequired because we would never build that | |
342 // internally. | |
343 CString CommandLineBuilder::GetInstall() const { | |
344 CString cmd_line(GetExtraAndAppArgs(kCmdLineInstall)); | |
345 if (cmd_line.IsEmpty()) { | |
346 return CString(); | |
347 } | |
348 | |
349 if (!install_source_.IsEmpty()) { | |
350 SafeCStringAppendFormat(&cmd_line, _T(" /%s %s"), | |
351 kCmdLineInstallSource, | |
352 install_source_); | |
353 } | |
354 if (!session_id_.IsEmpty()) { | |
355 SafeCStringAppendFormat(&cmd_line, _T(" /%s \"%s\""), | |
356 kCmdLineSessionId, | |
357 session_id_); | |
358 } | |
359 if (is_silent_set_) { | |
360 SafeCStringAppendFormat(&cmd_line, _T(" /%s"), kCmdLineSilent); | |
361 } | |
362 return cmd_line; | |
363 } | |
364 | |
365 CString CommandLineBuilder::GetUpdate() const { | |
366 CString cmd_line; | |
367 cmd_line.Format(_T("/%s"), kCmdLineUpdate); | |
368 if (!session_id_.IsEmpty()) { | |
369 SafeCStringAppendFormat(&cmd_line, _T(" /%s \"%s\""), | |
370 kCmdLineSessionId, | |
371 session_id_); | |
372 } | |
373 return cmd_line; | |
374 } | |
375 | |
376 CString CommandLineBuilder::GetHandoffInstall() const { | |
377 CString cmd_line(GetExtraAndAppArgs(kCmdLineAppHandoffInstall)); | |
378 if (cmd_line.IsEmpty()) { | |
379 return CString(); | |
380 } | |
381 | |
382 if (!install_source_.IsEmpty()) { | |
383 SafeCStringAppendFormat(&cmd_line, _T(" /%s %s"), | |
384 kCmdLineInstallSource, | |
385 install_source_); | |
386 } | |
387 if (!session_id_.IsEmpty()) { | |
388 SafeCStringAppendFormat(&cmd_line, _T(" /%s \"%s\""), | |
389 kCmdLineSessionId, | |
390 session_id_); | |
391 } | |
392 if (is_silent_set_) { | |
393 SafeCStringAppendFormat(&cmd_line, _T(" /%s"), kCmdLineSilent); | |
394 } | |
395 if (is_eula_required_set_) { | |
396 SafeCStringAppendFormat(&cmd_line, _T(" /%s"), kCmdLineEulaRequired); | |
397 } | |
398 if (!offline_dir_.IsEmpty()) { | |
399 SafeCStringAppendFormat(&cmd_line, _T(" /%s \"%s\""), | |
400 kCmdLineOfflineDir, | |
401 offline_dir_); | |
402 } | |
403 return cmd_line; | |
404 } | |
405 | |
406 CString CommandLineBuilder::GetUA() const { | |
407 ASSERT1(!install_source_.IsEmpty()); | |
408 if (install_source_.IsEmpty()) { | |
409 return CString(); | |
410 } | |
411 | |
412 CString cmd_line(GetSingleSwitch(kCmdLineUpdateApps)); | |
413 SafeCStringAppendFormat(&cmd_line, _T(" /%s %s"), | |
414 kCmdLineInstallSource, | |
415 install_source_); | |
416 | |
417 return cmd_line; | |
418 } | |
419 | |
420 CString CommandLineBuilder::GetRecover() const { | |
421 ASSERT1(!code_red_metainstaller_path_.IsEmpty()); | |
422 if (code_red_metainstaller_path_.IsEmpty()) { | |
423 return CString(); | |
424 } | |
425 CString cmd_line; | |
426 SafeCStringFormat(&cmd_line, _T("/%s %s"), | |
427 kCmdLineRecover, | |
428 code_red_metainstaller_path_); | |
429 return cmd_line; | |
430 } | |
431 | |
432 CString CommandLineBuilder::GetWebPlugin() const { | |
433 ASSERT1(!webplugin_url_domain_.IsEmpty()); | |
434 ASSERT1(!webplugin_args_.IsEmpty()); | |
435 ASSERT1(!install_source_.IsEmpty()); | |
436 if (webplugin_url_domain_.IsEmpty() || | |
437 webplugin_args_.IsEmpty() || | |
438 install_source_.IsEmpty()) { | |
439 return CString(); | |
440 } | |
441 CString cmd_line; | |
442 CString enclosed_webplugin_url_domain_(webplugin_url_domain_); | |
443 CString enclosed_webplugin_args_(webplugin_args_); | |
444 EnclosePath(&enclosed_webplugin_url_domain_); | |
445 EnclosePath(&enclosed_webplugin_args_); | |
446 // TODO(omaha): Do we want this to handle the urlencoding for us? | |
447 SafeCStringFormat(&cmd_line, _T("/%s %s %s /%s %s"), | |
448 kCmdLineWebPlugin, | |
449 enclosed_webplugin_url_domain_, | |
450 enclosed_webplugin_args_, | |
451 kCmdLineInstallSource, | |
452 install_source_); | |
453 return cmd_line; | |
454 } | |
455 | |
456 CString CommandLineBuilder::GetCodeRedCheck() const { | |
457 return GetSingleSwitch(kCmdLineCodeRedCheck); | |
458 } | |
459 | |
460 CString CommandLineBuilder::GetComServer() const { | |
461 return kCmdLineComServerDash; | |
462 } | |
463 | |
464 CString CommandLineBuilder::GetComBroker() const { | |
465 return kCmdLineComBroker; | |
466 } | |
467 | |
468 CString CommandLineBuilder::GetOnDemand() const { | |
469 return kCmdLineOnDemand; | |
470 } | |
471 | |
472 CString CommandLineBuilder::GetMediumService() const { | |
473 return GetSingleSwitch(kCmdLineMediumService); | |
474 } | |
475 | |
476 CString CommandLineBuilder::GetUninstall() const { | |
477 return GetSingleSwitch(kCmdLineUninstall); | |
478 } | |
479 | |
480 CString CommandLineBuilder::GetRegisterProduct() const { | |
481 ASSERT1(app_args_.IsEmpty()); | |
482 return GetExtraAndAppArgs(kCmdLineRegisterProduct); | |
483 } | |
484 | |
485 CString CommandLineBuilder::GetUnregisterProduct() const { | |
486 ASSERT1(app_args_.IsEmpty()); | |
487 return GetExtraAndAppArgs(kCmdLineUnregisterProduct); | |
488 } | |
489 | |
490 CString CommandLineBuilder::GetPing() const { | |
491 CString cmd_line; | |
492 SafeCStringFormat(&cmd_line, _T("/%s %s"), kCmdLinePing, ping_string_); | |
493 return cmd_line; | |
494 } | |
495 | |
496 } // namespace omaha | |
OLD | NEW |