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/goopdate_command_line_validator.h" | |
17 #include "omaha/base/command_line_parser.h" | |
18 #include "omaha/base/command_line_validator.h" | |
19 #include "omaha/base/debug.h" | |
20 #include "omaha/base/error.h" | |
21 #include "omaha/base/logging.h" | |
22 #include "omaha/base/path.h" | |
23 #include "omaha/base/string.h" | |
24 #include "omaha/common/command_line.h" | |
25 #include "omaha/common/const_cmd_line.h" | |
26 #include "omaha/common/extra_args_parser.h" | |
27 | |
28 namespace omaha { | |
29 | |
30 GoopdateCommandLineValidator::GoopdateCommandLineValidator() { | |
31 } | |
32 | |
33 GoopdateCommandLineValidator::~GoopdateCommandLineValidator() { | |
34 } | |
35 | |
36 HRESULT GoopdateCommandLineValidator::Setup() { | |
37 validator_.reset(new CommandLineValidator); | |
38 | |
39 CString cmd_line; | |
40 | |
41 // gu.exe | |
42 cmd_line.Empty(); | |
43 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnNoArgs); | |
44 | |
45 // gu.exe /c [/nocrashserver | |
46 cmd_line.Format(_T("/%s [/%s"), kCmdLineCore, kCmdLineNoCrashHandler); | |
47 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnCore); | |
48 | |
49 // gu.exe /crashhandler | |
50 cmd_line.Format(_T("/%s"), kCmdLineCrashHandler); | |
51 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnCrashHandler); | |
52 | |
53 // gu.exe /svc | |
54 cmd_line.Format(_T("/%s"), kCmdLineService); | |
55 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnService); | |
56 | |
57 // gu.exe /medsvc | |
58 cmd_line.Format(_T("/%s"), kCmdLineMediumService); | |
59 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnMediumService); | |
60 | |
61 // gu.exe /regsvc | |
62 cmd_line.Format(_T("/%s"), kCmdLineRegisterService); | |
63 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnServiceRegister); | |
64 | |
65 // gu.exe /unregsvc | |
66 cmd_line.Format(_T("/%s"), kCmdLineUnregisterService); | |
67 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnServiceUnregister); | |
68 | |
69 // gu.exe /regserver | |
70 cmd_line.Format(_T("/%s"), kCmdRegServer); | |
71 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnRegServer); | |
72 | |
73 // gu.exe /unregserver | |
74 cmd_line.Format(_T("/%s"), kCmdUnregServer); | |
75 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnUnregServer); | |
76 | |
77 // gu.exe /netdiags | |
78 cmd_line.Format(_T("/%s"), kCmdLineNetDiags); | |
79 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnNetDiags); | |
80 | |
81 // gu.exe /crash | |
82 cmd_line.Format(_T("/%s"), kCmdLineCrash); | |
83 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnCrash); | |
84 | |
85 // gu.exe -Embedding. The -Embedding text is injected via COM. | |
86 CreateScenario(kCmdLineComServerDash, | |
87 &GoopdateCommandLineValidator::OnComServer); | |
88 | |
89 // COM server mode, but only for the broker. | |
90 CreateScenario(kCmdLineComBroker, &GoopdateCommandLineValidator::OnComBroker); | |
91 | |
92 // COM server mode, but only for the OnDemand. | |
93 CreateScenario(kCmdLineOnDemand, &GoopdateCommandLineValidator::OnDemand); | |
94 | |
95 // gu.exe /install <extraargs> [/appargs <appargs> [/installsource source | |
96 // [/silent [/eularequired [/oem [/installelevated [/sessionid <sid> | |
97 cmd_line.Format(_T("/%s extra [/%s appargs [/%s src [/%s [/%s [/%s [/%s ") | |
98 _T("[/%s sid"), | |
99 kCmdLineInstall, | |
100 kCmdLineAppArgs, | |
101 kCmdLineInstallSource, | |
102 kCmdLineSilent, | |
103 kCmdLineEulaRequired, | |
104 kCmdLineOem, | |
105 kCmdLineInstallElevated, | |
106 kCmdLineSessionId); | |
107 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnInstall); | |
108 | |
109 // gu.exe /update [/sessionid <sid> | |
110 cmd_line.Format(_T("/%s [/%s sid"), kCmdLineUpdate, kCmdLineSessionId); | |
111 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnUpdate); | |
112 | |
113 // gu.exe /handoff <extraargs> [/appargs <appargs> [/installsource source | |
114 // [/silent [/eularequired [/offlineinstall [/offlinedir <dir> | |
115 // [/sessionid <sid> | |
116 cmd_line.Format(_T("/%s extra [/%s appargs [/%s src [/%s [/%s [/%s [/%s dir ") | |
117 _T("[/%s sid"), | |
118 kCmdLineAppHandoffInstall, | |
119 kCmdLineAppArgs, | |
120 kCmdLineInstallSource, | |
121 kCmdLineSilent, | |
122 kCmdLineEulaRequired, | |
123 kCmdLineLegacyOfflineInstall, | |
124 kCmdLineOfflineDir, | |
125 kCmdLineSessionId); | |
126 CreateScenario(cmd_line, | |
127 &GoopdateCommandLineValidator::OnInstallHandoffWorker); | |
128 | |
129 // gu.exe /ua [/installsource source [/machine | |
130 cmd_line.Format(_T("/%s [/%s source [/%s"), | |
131 kCmdLineUpdateApps, kCmdLineInstallSource, kCmdLineMachine); | |
132 CreateScenario(cmd_line, | |
133 &GoopdateCommandLineValidator::OnUpdateApps); | |
134 | |
135 // gu.exe /report <crash_filename> [/machine | |
136 // [/custom_info <custom_info_filename> | |
137 cmd_line.Format(_T("/%s filename [/%s [/%s customfilename"), | |
138 kCmdLineReport, | |
139 kCmdLineMachine, | |
140 kCmdLineCustomInfoFileName); | |
141 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnReportCrash); | |
142 | |
143 // gu.exe /report /i <crash_filename> [/machine | |
144 cmd_line.Format(_T("/%s /%s filename [/%s"), | |
145 kCmdLineReport, | |
146 kCmdLineInteractive, | |
147 kCmdLineMachine); | |
148 CreateScenario(cmd_line, | |
149 &GoopdateCommandLineValidator::OnReportCrashInteractive); | |
150 | |
151 // gu.exe /pi <domainurl> <args> /installsource <oneclick|update3web> | |
152 cmd_line.Format(_T("/%s domainurl args /%s src"), | |
153 kCmdLineWebPlugin, | |
154 kCmdLineInstallSource); | |
155 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnWebPlugin); | |
156 | |
157 // gu.exe /cr | |
158 cmd_line.Format(_T("/%s"), kCmdLineCodeRedCheck); | |
159 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnCodeRed); | |
160 | |
161 // gu.exe /recover <repair_file> | |
162 cmd_line.Format(_T("/%s repairfile"), kCmdLineRecover); | |
163 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnRecover); | |
164 | |
165 // gu.exe /recover /machine <repair_file> | |
166 cmd_line.Format(_T("/%s /%s repairfile"), kCmdLineRecover, kCmdLineMachine); | |
167 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnRecoverMachine); | |
168 | |
169 // gu.exe /uninstall | |
170 cmd_line.Format(_T("/%s"), kCmdLineUninstall); | |
171 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnUninstall); | |
172 | |
173 // gu.exe /registerproduct "extraargs" [/installsource source | |
174 cmd_line.Format(_T("/%s extraargs [/%s source"), | |
175 kCmdLineRegisterProduct, | |
176 kCmdLineInstallSource); | |
177 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnRegisterProduct); | |
178 | |
179 // gu.exe /unregisterproduct "extraargs" | |
180 cmd_line.Format(_T("/%s extraargs"), kCmdLineUnregisterProduct); | |
181 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnUnregisterProduct); | |
182 | |
183 // gu.exe /ping pingstring | |
184 cmd_line.Format(_T("/%s pingstring"), kCmdLinePing); | |
185 CreateScenario(cmd_line, &GoopdateCommandLineValidator::OnPing); | |
186 | |
187 return S_OK; | |
188 } | |
189 | |
190 // TODO(Omaha): Add check that each scenario is unique and does not overlap an | |
191 // existing one in DBG builds. | |
192 HRESULT GoopdateCommandLineValidator::Validate(const CommandLineParser* parser, | |
193 CommandLineArgs* args) { | |
194 ASSERT1(parser); | |
195 ASSERT1(args); | |
196 | |
197 parser_ = parser; | |
198 args_ = args; | |
199 | |
200 CString scenario_name; | |
201 HRESULT hr = validator_->Validate(*parser_, &scenario_name); | |
202 if (FAILED(hr)) { | |
203 CORE_LOG(LE, (_T("[GoopdateCommandLineValidator::Validate Failed][0x%x]"), | |
204 hr)); | |
205 return hr; | |
206 } | |
207 | |
208 MapScenarioHandlersIter iter = scenario_handlers_.find(scenario_name); | |
209 if (iter == scenario_handlers_.end()) { | |
210 ASSERT1(false); | |
211 return GOOGLEUPDATE_COMMANDLINE_E_NO_SCENARIO_HANDLER; | |
212 } | |
213 | |
214 ScenarioHandler handler = (*iter).second; | |
215 return (this->*handler)(); | |
216 } | |
217 | |
218 void GoopdateCommandLineValidator::CreateScenario(const TCHAR* cmd_line, | |
219 ScenarioHandler handler) { | |
220 // Prepend the program name onto the cmd_line. | |
221 CString scenario_cmd_line; | |
222 scenario_cmd_line.Format(_T("prog.exe %s"), cmd_line); | |
223 | |
224 CString scenario_name; | |
225 validator_->CreateScenarioFromCmdLine(scenario_cmd_line, &scenario_name); | |
226 // TODO(omaha): Make sure it doesn't already exist. | |
227 scenario_handlers_[scenario_name] = handler; | |
228 } | |
229 | |
230 HRESULT GoopdateCommandLineValidator::GetExtraAndAppArgs(const CString& name) { | |
231 HRESULT hr = parser_->GetSwitchArgumentValue(name, | |
232 0, | |
233 &args_->extra_args_str); | |
234 if (FAILED(hr)) { | |
235 return hr; | |
236 } | |
237 | |
238 hr = parser_->GetSwitchArgumentValue(kCmdLineAppArgs, | |
239 0, | |
240 &args_->app_args_str); | |
241 if (FAILED(hr)) { | |
242 args_->app_args_str.Empty(); | |
243 } | |
244 | |
245 ExtraArgsParser extra_args_parser; | |
246 return extra_args_parser.Parse(args_->extra_args_str, | |
247 args_->app_args_str, | |
248 &args_->extra); | |
249 } | |
250 | |
251 HRESULT GoopdateCommandLineValidator::OnNoArgs() { | |
252 args_->mode = COMMANDLINE_MODE_NOARGS; | |
253 return S_OK; | |
254 } | |
255 | |
256 HRESULT GoopdateCommandLineValidator::OnCore() { | |
257 args_->mode = COMMANDLINE_MODE_CORE; | |
258 args_->is_crash_handler_disabled = parser_->HasSwitch(kCmdLineNoCrashHandler); | |
259 | |
260 return S_OK; | |
261 } | |
262 | |
263 HRESULT GoopdateCommandLineValidator::OnCrashHandler() { | |
264 args_->mode = COMMANDLINE_MODE_CRASH_HANDLER; | |
265 return S_OK; | |
266 } | |
267 | |
268 HRESULT GoopdateCommandLineValidator::OnService() { | |
269 args_->mode = COMMANDLINE_MODE_SERVICE; | |
270 return S_OK; | |
271 } | |
272 | |
273 HRESULT GoopdateCommandLineValidator::OnMediumService() { | |
274 args_->mode = COMMANDLINE_MODE_MEDIUM_SERVICE; | |
275 return S_OK; | |
276 } | |
277 | |
278 HRESULT GoopdateCommandLineValidator::OnServiceRegister() { | |
279 args_->mode = COMMANDLINE_MODE_SERVICE_REGISTER; | |
280 return S_OK; | |
281 } | |
282 | |
283 HRESULT GoopdateCommandLineValidator::OnServiceUnregister() { | |
284 args_->mode = COMMANDLINE_MODE_SERVICE_UNREGISTER; | |
285 return S_OK; | |
286 } | |
287 | |
288 HRESULT GoopdateCommandLineValidator::OnRegServer() { | |
289 args_->mode = COMMANDLINE_MODE_REGSERVER; | |
290 return S_OK; | |
291 } | |
292 | |
293 HRESULT GoopdateCommandLineValidator::OnUnregServer() { | |
294 args_->mode = COMMANDLINE_MODE_UNREGSERVER; | |
295 return S_OK; | |
296 } | |
297 | |
298 HRESULT GoopdateCommandLineValidator::OnNetDiags() { | |
299 args_->mode = COMMANDLINE_MODE_NETDIAGS; | |
300 return S_OK; | |
301 } | |
302 | |
303 HRESULT GoopdateCommandLineValidator::OnCrash() { | |
304 args_->mode = COMMANDLINE_MODE_CRASH; | |
305 return S_OK; | |
306 } | |
307 | |
308 HRESULT GoopdateCommandLineValidator::OnComServer() { | |
309 args_->mode = COMMANDLINE_MODE_COMSERVER; | |
310 return S_OK; | |
311 } | |
312 | |
313 HRESULT GoopdateCommandLineValidator::OnComBroker() { | |
314 args_->mode = COMMANDLINE_MODE_COMBROKER; | |
315 return S_OK; | |
316 } | |
317 | |
318 HRESULT GoopdateCommandLineValidator::OnDemand() { | |
319 args_->mode = COMMANDLINE_MODE_ONDEMAND; | |
320 return S_OK; | |
321 } | |
322 | |
323 HRESULT GoopdateCommandLineValidator::OnInstall() { | |
324 args_->mode = COMMANDLINE_MODE_INSTALL; | |
325 parser_->GetSwitchArgumentValue(kCmdLineInstallSource, | |
326 0, | |
327 &args_->install_source); | |
328 parser_->GetSwitchArgumentValue(kCmdLineSessionId, | |
329 0, | |
330 &args_->session_id); | |
331 args_->is_silent_set = parser_->HasSwitch(kCmdLineSilent); | |
332 args_->is_eula_required_set = parser_->HasSwitch(kCmdLineEulaRequired); | |
333 args_->is_oem_set = parser_->HasSwitch(kCmdLineOem); | |
334 args_->is_install_elevated = parser_->HasSwitch(kCmdLineInstallElevated); | |
335 return GetExtraAndAppArgs(kCmdLineInstall); | |
336 } | |
337 | |
338 HRESULT GoopdateCommandLineValidator::OnUpdate() { | |
339 args_->mode = COMMANDLINE_MODE_UPDATE; | |
340 parser_->GetSwitchArgumentValue(kCmdLineSessionId, | |
341 0, | |
342 &args_->session_id); | |
343 return S_OK; | |
344 } | |
345 | |
346 HRESULT GoopdateCommandLineValidator::OnInstallHandoffWorker() { | |
347 args_->mode = COMMANDLINE_MODE_HANDOFF_INSTALL; | |
348 parser_->GetSwitchArgumentValue(kCmdLineInstallSource, | |
349 0, | |
350 &args_->install_source); | |
351 parser_->GetSwitchArgumentValue(kCmdLineSessionId, | |
352 0, | |
353 &args_->session_id); | |
354 args_->is_silent_set = parser_->HasSwitch(kCmdLineSilent); | |
355 args_->is_eula_required_set = parser_->HasSwitch(kCmdLineEulaRequired); | |
356 args_->is_offline_set = parser_->HasSwitch(kCmdLineLegacyOfflineInstall) || | |
357 parser_->HasSwitch(kCmdLineOfflineDir); | |
358 | |
359 if (SUCCEEDED(parser_->GetSwitchArgumentValue(kCmdLineOfflineDir, | |
360 0, | |
361 &args_->offline_dir))) { | |
362 RemoveMismatchedEndQuoteInDirectoryPath(&args_->offline_dir); | |
363 ::PathRemoveBackslash(CStrBuf(args_->offline_dir, MAX_PATH)); | |
364 } | |
365 | |
366 return GetExtraAndAppArgs(kCmdLineAppHandoffInstall); | |
367 } | |
368 | |
369 HRESULT GoopdateCommandLineValidator::OnUpdateApps() { | |
370 args_->mode = COMMANDLINE_MODE_UA; | |
371 args_->is_machine_set = parser_->HasSwitch(kCmdLineMachine); | |
372 parser_->GetSwitchArgumentValue(kCmdLineInstallSource, | |
373 0, | |
374 &args_->install_source); | |
375 return S_OK; | |
376 } | |
377 | |
378 HRESULT GoopdateCommandLineValidator::OnReportCrash() { | |
379 args_->mode = COMMANDLINE_MODE_REPORTCRASH; | |
380 args_->is_machine_set = parser_->HasSwitch(kCmdLineMachine); | |
381 parser_->GetSwitchArgumentValue(kCmdLineCustomInfoFileName, | |
382 0, | |
383 &args_->custom_info_filename); | |
384 return parser_->GetSwitchArgumentValue(kCmdLineReport, | |
385 0, | |
386 &args_->crash_filename); | |
387 } | |
388 | |
389 HRESULT GoopdateCommandLineValidator::OnReportCrashInteractive() { | |
390 args_->mode = COMMANDLINE_MODE_REPORTCRASH; | |
391 args_->is_interactive_set = true; | |
392 args_->is_machine_set = parser_->HasSwitch(kCmdLineMachine); | |
393 return parser_->GetSwitchArgumentValue(kCmdLineInteractive, | |
394 0, | |
395 &args_->crash_filename); | |
396 } | |
397 | |
398 HRESULT GoopdateCommandLineValidator::OnWebPlugin() { | |
399 HRESULT hr = parser_->GetSwitchArgumentValue(kCmdLineInstallSource, | |
400 0, | |
401 &args_->install_source); | |
402 if (FAILED(hr)) { | |
403 return hr; | |
404 } | |
405 // Validate install_source value. | |
406 args_->install_source.MakeLower(); | |
407 if ((args_->install_source.Compare(kCmdLineInstallSource_OneClick) != 0) && | |
408 (args_->install_source.Compare(kCmdLineInstallSource_Update3Web) != 0)) { | |
409 args_->install_source.Empty(); | |
410 return E_INVALIDARG; | |
411 } | |
412 | |
413 args_->mode = COMMANDLINE_MODE_WEBPLUGIN; | |
414 | |
415 CString urldomain; | |
416 hr = parser_->GetSwitchArgumentValue(kCmdLineWebPlugin, | |
417 0, | |
418 &urldomain); | |
419 if (FAILED(hr)) { | |
420 return hr; | |
421 } | |
422 hr = StringUnescape(urldomain, &args_->webplugin_urldomain); | |
423 if (FAILED(hr)) { | |
424 return hr; | |
425 } | |
426 | |
427 CString webplugin_args; | |
428 hr = parser_->GetSwitchArgumentValue(kCmdLineWebPlugin, | |
429 1, | |
430 &webplugin_args); | |
431 if (FAILED(hr)) { | |
432 return hr; | |
433 } | |
434 return StringUnescape(webplugin_args, &args_->webplugin_args); | |
435 } | |
436 | |
437 HRESULT GoopdateCommandLineValidator::OnCodeRed() { | |
438 args_->mode = COMMANDLINE_MODE_CODE_RED_CHECK; | |
439 return S_OK; | |
440 } | |
441 | |
442 HRESULT GoopdateCommandLineValidator::OnRecover() { | |
443 args_->mode = COMMANDLINE_MODE_RECOVER; | |
444 return parser_->GetSwitchArgumentValue( | |
445 kCmdLineRecover, | |
446 0, | |
447 &args_->code_red_metainstaller_path); | |
448 } | |
449 | |
450 HRESULT GoopdateCommandLineValidator::OnRecoverMachine() { | |
451 args_->mode = COMMANDLINE_MODE_RECOVER; | |
452 args_->is_machine_set = true; | |
453 return parser_->GetSwitchArgumentValue( | |
454 kCmdLineMachine, | |
455 0, | |
456 &args_->code_red_metainstaller_path); | |
457 } | |
458 | |
459 HRESULT GoopdateCommandLineValidator::OnUninstall() { | |
460 args_->mode = COMMANDLINE_MODE_UNINSTALL; | |
461 return S_OK; | |
462 } | |
463 | |
464 HRESULT GoopdateCommandLineValidator::OnRegisterProduct() { | |
465 args_->mode = COMMANDLINE_MODE_REGISTER_PRODUCT; | |
466 parser_->GetSwitchArgumentValue(kCmdLineInstallSource, | |
467 0, | |
468 &args_->install_source); | |
469 return GetExtraAndAppArgs(kCmdLineRegisterProduct); | |
470 } | |
471 | |
472 HRESULT GoopdateCommandLineValidator::OnUnregisterProduct() { | |
473 args_->mode = COMMANDLINE_MODE_UNREGISTER_PRODUCT; | |
474 return GetExtraAndAppArgs(kCmdLineUnregisterProduct); | |
475 } | |
476 | |
477 HRESULT GoopdateCommandLineValidator::OnPing() { | |
478 args_->mode = COMMANDLINE_MODE_PING; | |
479 return parser_->GetSwitchArgumentValue(kCmdLinePing, | |
480 0, | |
481 &args_->ping_string); | |
482 } | |
483 | |
484 } // namespace omaha | |
485 | |
OLD | NEW |