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/webplugin_utils.h" | |
17 | |
18 #include "omaha/base/app_util.h" | |
19 #include "omaha/base/debug.h" | |
20 #include "omaha/base/error.h" | |
21 #include "omaha/base/file.h" | |
22 #include "omaha/base/logging.h" | |
23 #include "omaha/base/path.h" | |
24 #include "omaha/base/safe_format.h" | |
25 #include "omaha/base/string.h" | |
26 #include "omaha/base/system.h" | |
27 #include "omaha/base/utils.h" | |
28 #include "omaha/base/xml_utils.h" | |
29 #include "omaha/common/command_line_builder.h" | |
30 #include "omaha/common/const_goopdate.h" | |
31 #include "omaha/common/goopdate_utils.h" | |
32 #include "omaha/common/lang.h" | |
33 #include "omaha/net/browser_request.h" | |
34 #include "omaha/net/cup_request.h" | |
35 #include "omaha/net/network_request.h" | |
36 #include "omaha/net/simple_request.h" | |
37 | |
38 namespace omaha { | |
39 | |
40 namespace webplugin_utils { | |
41 | |
42 HRESULT BuildOneClickRequestString(const CommandLineArgs& args, | |
43 CString* request_str) { | |
44 if (NULL == request_str) { | |
45 return E_INVALIDARG; | |
46 } | |
47 | |
48 // If we're not /webplugin or the urldomain is empty, something's wrong. | |
49 if (args.mode != COMMANDLINE_MODE_WEBPLUGIN || | |
50 args.webplugin_urldomain.IsEmpty()) { | |
51 return E_UNEXPECTED; | |
52 } | |
53 | |
54 const TCHAR* request_string_template = _T("?du=%s&args=%s"); | |
55 CString request; | |
56 | |
57 CString urldomain_escaped; | |
58 CString pluginargs_escaped; | |
59 | |
60 StringEscape(args.webplugin_urldomain, false, &urldomain_escaped); | |
61 StringEscape(args.webplugin_args, false, &pluginargs_escaped); | |
62 | |
63 SafeCStringFormat(&request, request_string_template, | |
64 urldomain_escaped, | |
65 pluginargs_escaped); | |
66 | |
67 *request_str = request; | |
68 return S_OK; | |
69 } | |
70 | |
71 HRESULT IsLanguageSupported(const CString& webplugin_args) { | |
72 CString cmd_line; | |
73 SafeCStringFormat(&cmd_line, _T("gu.exe %s"), webplugin_args); | |
74 CommandLineArgs parsed_args; | |
75 HRESULT hr = ParseCommandLine(cmd_line, &parsed_args); | |
76 if (FAILED(hr)) { | |
77 CORE_LOG(LE, (_T("[ParseCommandLine failed][0x%08x]"), hr)); | |
78 return hr; | |
79 } | |
80 | |
81 | |
82 if (!lang::IsLanguageSupported(parsed_args.extra.language)) { | |
83 CORE_LOG(LE, (_T("Language not supported][%s]"), | |
84 parsed_args.extra.language)); | |
85 return GOOPDATE_E_ONECLICK_LANGUAGE_NOT_SUPPORTED; | |
86 } | |
87 | |
88 return S_OK; | |
89 } | |
90 | |
91 HRESULT BuildOneClickWorkerArgs(const CommandLineArgs& args, | |
92 CString* oneclick_args) { | |
93 ASSERT1(oneclick_args); | |
94 | |
95 // Since this is being called via WebPlugin only, we can rebuild the | |
96 // command line arguments from the valid params we can send on. | |
97 // For example, the web plugin will not send crash_cmd or debug_cmd | |
98 // or reg_server or unreg_server so we don't have to worry about those here. | |
99 CString cmd_line_args; | |
100 CommandLineArgs webplugin_cmdline_args; | |
101 | |
102 // ParseCommandLine assumes the first argument is the program being run. | |
103 // Don't want to enforce that constraint on our callers, so we prepend with a | |
104 // fake exe name. | |
105 CString args_to_parse; | |
106 SafeCStringFormat(&args_to_parse, _T("%s %s"), | |
107 kOmahaShellFileName, | |
108 args.webplugin_args); | |
109 | |
110 // Parse the arguments we received as the second parameter to /webplugin. | |
111 HRESULT hr = ParseCommandLine(args_to_parse, &webplugin_cmdline_args); | |
112 if (FAILED(hr)) { | |
113 return hr; | |
114 } | |
115 | |
116 // Silent and other non-standard installs could be malicious. Prevent them. | |
117 if (webplugin_cmdline_args.mode != COMMANDLINE_MODE_INSTALL) { | |
118 return E_INVALIDARG; | |
119 } | |
120 if (webplugin_cmdline_args.is_silent_set || | |
121 webplugin_cmdline_args.is_eula_required_set) { | |
122 return E_INVALIDARG; | |
123 } | |
124 | |
125 CommandLineBuilder builder(COMMANDLINE_MODE_INSTALL); | |
126 builder.set_extra_args(webplugin_cmdline_args.extra_args_str); | |
127 | |
128 // We expect this value from the plugin. | |
129 ASSERT1(!args.install_source.IsEmpty()); | |
130 if (args.install_source.IsEmpty()) { | |
131 return E_INVALIDARG; | |
132 } | |
133 | |
134 builder.set_install_source(args.install_source); | |
135 | |
136 *oneclick_args = builder.GetCommandLineArgs(); | |
137 | |
138 return S_OK; | |
139 } | |
140 | |
141 // It is important that current_goopdate_path be the version path and not the | |
142 // Update\ path. | |
143 HRESULT CopyGoopdateToTempDir(const CPath& current_goopdate_path, | |
144 CPath* goopdate_temp_path) { | |
145 ASSERT1(goopdate_temp_path); | |
146 | |
147 // Create a unique directory in the user's temp directory. | |
148 TCHAR pathbuf[MAX_PATH] = {0}; | |
149 DWORD ret = ::GetTempPath(arraysize(pathbuf), pathbuf); | |
150 if (0 == ret) { | |
151 return HRESULTFromLastError(); | |
152 } | |
153 if (ret >= arraysize(pathbuf)) { | |
154 return E_FAIL; | |
155 } | |
156 | |
157 GUID guid = GUID_NULL; | |
158 HRESULT hr = ::CoCreateGuid(&guid); | |
159 if (FAILED(hr)) { | |
160 return hr; | |
161 } | |
162 | |
163 CString guid_str = GuidToString(guid); | |
164 CPath temp_path = pathbuf; | |
165 temp_path.Append(guid_str); | |
166 temp_path.Canonicalize(); | |
167 | |
168 hr = CreateDir(temp_path, NULL); | |
169 if (FAILED(hr)) { | |
170 return hr; | |
171 } | |
172 | |
173 hr = File::CopyTree(current_goopdate_path, temp_path, true); | |
174 if (FAILED(hr)) { | |
175 return hr; | |
176 } | |
177 | |
178 CORE_LOG(L2, (_T("[CopyGoopdateToTempDir][temp_path = %s]"), temp_path)); | |
179 *goopdate_temp_path = temp_path; | |
180 return S_OK; | |
181 } | |
182 | |
183 HRESULT DoOneClickInstall(const CommandLineArgs& args) { | |
184 CString cmd_line_args; | |
185 HRESULT hr = BuildOneClickWorkerArgs(args, &cmd_line_args); | |
186 if (FAILED(hr)) { | |
187 CORE_LOG(LE, (_T("[BuildOneClickWorkerArgs failed][0x%08x]"), hr)); | |
188 return hr; | |
189 } | |
190 | |
191 CORE_LOG(L2, (_T("[DoOneClickInstall][cmd_line_args: %s]"), cmd_line_args)); | |
192 | |
193 // Check if we're running from the machine dir. | |
194 // If we're not, we must be running from user directory since OneClick only | |
195 // works against installed versions of Omaha. | |
196 CPath current_goopdate_path(app_util::GetCurrentModuleDirectory()); | |
197 CPath goopdate_temp_path; | |
198 hr = CopyGoopdateToTempDir(current_goopdate_path, &goopdate_temp_path); | |
199 if (FAILED(hr)) { | |
200 CORE_LOG(LE, (_T("[CopyGoopdateToTempDir failed][0x%08x]"), hr)); | |
201 return hr; | |
202 } | |
203 | |
204 CPath goopdate_temp_exe_path = goopdate_temp_path; | |
205 goopdate_temp_exe_path.Append(kOmahaShellFileName); | |
206 | |
207 // Launch goopdate again with the updated command line arguments. | |
208 hr = System::ShellExecuteProcess(goopdate_temp_exe_path, | |
209 cmd_line_args, | |
210 NULL, | |
211 NULL); | |
212 if (FAILED(hr)) { | |
213 CORE_LOG(LE, (_T("[ShellExecuteProcess failed][%s][0x%08x]"), | |
214 goopdate_temp_exe_path, hr)); | |
215 return hr; | |
216 } | |
217 | |
218 return S_OK; | |
219 } | |
220 | |
221 } // namespace webplugin_utils | |
222 | |
223 } // namespace omaha | |
224 | |
OLD | NEW |