| 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 |