OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/browser/download/quarantine.h" | 5 #include "content/browser/download/quarantine.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <cguid.h> | 9 #include <cguid.h> |
10 #include <objbase.h> | 10 #include <objbase.h> |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 // Typical |save_result| values: | 148 // Typical |save_result| values: |
149 // S_OK : The file was okay. If any viruses were found, they were cleaned. | 149 // S_OK : The file was okay. If any viruses were found, they were cleaned. |
150 // E_FAIL : Virus infected. | 150 // E_FAIL : Virus infected. |
151 // INET_E_SECURITY_PROBLEM : The file was blocked due to security policy. | 151 // INET_E_SECURITY_PROBLEM : The file was blocked due to security policy. |
152 // | 152 // |
153 // Any other return value indicates an unexpected error during the scan. | 153 // Any other return value indicates an unexpected error during the scan. |
154 // | 154 // |
155 // |full_path| : is the path to the downloaded file. This should be the final | 155 // |full_path| : is the path to the downloaded file. This should be the final |
156 // path of the download. Must be present. | 156 // path of the download. Must be present. |
157 // |source_url|: the source URL for the download. If empty, the source will | 157 // |source_url|: the source URL for the download. If empty, the source will |
158 // not be set. | 158 // be set to 'about:internet'. |
| 159 // |referrer_url|: the referrer URL for the download. If empty, the referrer |
| 160 // will not be set. |
159 // |client_guid|: the GUID to be set in the IAttachmentExecute client slot. | 161 // |client_guid|: the GUID to be set in the IAttachmentExecute client slot. |
160 // Used to identify the app to the system AV function. | 162 // Used to identify the app to the system AV function. |
161 // If GUID_NULL is passed, no client GUID is set. | 163 // If GUID_NULL is passed, no client GUID is set. |
162 // |save_result|: Receives the result of invoking IAttachmentExecute::Save(). | 164 // |save_result|: Receives the result of invoking IAttachmentExecute::Save(). |
163 bool InvokeAttachmentServices(const base::FilePath& full_path, | 165 bool InvokeAttachmentServices(const base::FilePath& full_path, |
164 const std::string& source_url, | 166 const std::string& source_url, |
| 167 const std::string& referrer_url, |
165 const GUID& client_guid, | 168 const GUID& client_guid, |
166 HRESULT* save_result) { | 169 HRESULT* save_result) { |
167 base::win::ScopedComPtr<IAttachmentExecute> attachment_services; | 170 base::win::ScopedComPtr<IAttachmentExecute> attachment_services; |
168 HRESULT hr = attachment_services.CreateInstance(CLSID_AttachmentServices); | 171 HRESULT hr = attachment_services.CreateInstance(CLSID_AttachmentServices); |
169 *save_result = S_OK; | 172 *save_result = S_OK; |
170 | 173 |
171 if (FAILED(hr)) { | 174 if (FAILED(hr)) { |
172 // The thread must have COM initialized. | 175 // The thread must have COM initialized. |
173 DCHECK_NE(CO_E_NOTINITIALIZED, hr); | 176 DCHECK_NE(CO_E_NOTINITIALIZED, hr); |
174 RecordAttachmentServicesResult( | 177 RecordAttachmentServicesResult( |
175 AttachmentServicesResult::NO_ATTACHMENT_SERVICES); | 178 AttachmentServicesResult::NO_ATTACHMENT_SERVICES); |
176 return false; | 179 return false; |
177 } | 180 } |
178 | 181 |
179 hr = attachment_services->SetClientGuid(client_guid); | 182 hr = attachment_services->SetClientGuid(client_guid); |
180 if (FAILED(hr)) { | 183 if (FAILED(hr)) { |
181 RecordAttachmentServicesResult( | 184 RecordAttachmentServicesResult( |
182 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); | 185 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); |
183 return false; | 186 return false; |
184 } | 187 } |
185 | 188 |
186 hr = attachment_services->SetLocalPath(full_path.value().c_str()); | 189 hr = attachment_services->SetLocalPath(full_path.value().c_str()); |
187 if (FAILED(hr)) { | 190 if (FAILED(hr)) { |
188 RecordAttachmentServicesResult( | 191 RecordAttachmentServicesResult( |
189 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); | 192 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); |
190 return false; | 193 return false; |
191 } | 194 } |
192 | 195 |
193 // Note: SetSource looks like it needs to be called, even if empty. | 196 hr = attachment_services->SetSource( |
194 // Docs say it is optional, but it appears not calling it at all sets | 197 source_url.empty() ? L"about:internet" |
195 // a zone that is too restrictive. | 198 : base::UTF8ToWide(source_url).c_str()); |
196 hr = attachment_services->SetSource(base::UTF8ToWide(source_url).c_str()); | |
197 if (FAILED(hr)) { | 199 if (FAILED(hr)) { |
198 RecordAttachmentServicesResult( | 200 RecordAttachmentServicesResult( |
199 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); | 201 AttachmentServicesResult::FAILED_TO_SET_PARAMETER); |
200 return false; | 202 return false; |
201 } | 203 } |
202 | 204 |
| 205 // Only set referrer if one is present. Also, the source_url is authoritative |
| 206 // for determining the relative danger of |full_path|. So not going to |
| 207 // consider it fatal if setting the referrer fails. |
| 208 if (!referrer_url.empty()) |
| 209 attachment_services->SetReferrer(base::UTF8ToWide(referrer_url).c_str()); |
| 210 |
203 { | 211 { |
204 // This method has been known to take longer than 10 seconds in some | 212 // This method has been known to take longer than 10 seconds in some |
205 // instances. | 213 // instances. |
206 SCOPED_UMA_HISTOGRAM_LONG_TIMER("Download.AttachmentServices.Duration"); | 214 SCOPED_UMA_HISTOGRAM_LONG_TIMER("Download.AttachmentServices.Duration"); |
207 *save_result = attachment_services->Save(); | 215 *save_result = attachment_services->Save(); |
208 } | 216 } |
209 RecordAttachmentServicesSaveResult(full_path, *save_result); | 217 RecordAttachmentServicesSaveResult(full_path, *save_result); |
210 return true; | 218 return true; |
211 } | 219 } |
212 | 220 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 // | 287 // |
280 // If the file is still there, then the error could be due to Windows | 288 // If the file is still there, then the error could be due to Windows |
281 // Attachment Services not being available or some other error during the AES | 289 // Attachment Services not being available or some other error during the AES |
282 // invocation. In either case, we don't surface the error to the user. | 290 // invocation. In either case, we don't surface the error to the user. |
283 if (!base::PathExists(file)) | 291 if (!base::PathExists(file)) |
284 return FailedSaveResultToQuarantineResult(save_result); | 292 return FailedSaveResultToQuarantineResult(save_result); |
285 return QuarantineFileResult::OK; | 293 return QuarantineFileResult::OK; |
286 } | 294 } |
287 | 295 |
288 } // namespace content | 296 } // namespace content |
OLD | NEW |