Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: content/browser/download/base_file_win.cc

Issue 11150027: Handle the case where IAttachmentExecute::Save() deletes a downloaded file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Android Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/base_file.h" 5 #include "content/browser/download/base_file.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include "base/file_util.h"
10 #include "base/threading/thread_restrictions.h" 11 #include "base/threading/thread_restrictions.h"
11 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
12 #include "content/browser/download/download_interrupt_reasons_impl.h" 13 #include "content/browser/download/download_interrupt_reasons_impl.h"
14 #include "content/browser/download/download_stats.h"
13 #include "content/browser/safe_util_win.h" 15 #include "content/browser/safe_util_win.h"
14 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
15 17
16 namespace { 18 namespace {
17 19
18 // Maps the result of a call to |SHFileOperation()| onto a 20 // Maps the result of a call to |SHFileOperation()| onto a
19 // |content::DownloadInterruptReason|. 21 // |content::DownloadInterruptReason|.
20 // 22 //
21 // These return codes are *old* (as in, DOS era), and specific to 23 // These return codes are *old* (as in, DOS era), and specific to
22 // |SHFileOperation()|. 24 // |SHFileOperation()|.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // Destination is a root directory and cannot be renamed. 136 // Destination is a root directory and cannot be renamed.
135 // DE_ROOTDIR | ERRORONDEST == 0x10074 137 // DE_ROOTDIR | ERRORONDEST == 0x10074
136 case 0x10074: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; 138 case 0x10074: return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
137 } 139 }
138 140
139 // If not one of the above codes, it should be a standard Windows error code. 141 // If not one of the above codes, it should be a standard Windows error code.
140 return content::ConvertNetErrorToInterruptReason( 142 return content::ConvertNetErrorToInterruptReason(
141 net::MapSystemError(code), content::DOWNLOAD_INTERRUPT_FROM_DISK); 143 net::MapSystemError(code), content::DOWNLOAD_INTERRUPT_FROM_DISK);
142 } 144 }
143 145
146 // Maps a return code from ScanAndSaveDownloadedFile() to a
147 // DownloadInterruptReason. The return code in |result| is usually from the
148 // final IAttachmentExecute::Save() call.
149 content::DownloadInterruptReason MapScanAndSaveErrorCodeToInterruptReason(
150 HRESULT result) {
151 if (SUCCEEDED(result))
152 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
153
154 switch (result) {
155 case INET_E_SECURITY_PROBLEM: // 0x800c000e
156 // This is returned if the download was blocked due to security
157 // restrictions. E.g. if the source URL was in the Restricted Sites zone
158 // and downloads are blocked on that zone, then the download would be
159 // deleted and this error code is returned.
160 return content::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED;
161
162 case E_FAIL: // 0x80004005
163 // Returned if an anti-virus product reports an infection in the
164 // downloaded file during IAE::Save().
165 return content::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED;
166
167 default:
168 // Any other error that occurs during IAttachmentExecute::Save() likely
169 // indicates a problem with the security check, but not necessarily the
170 // download. See http://crbug.com/153212.
171 return content::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED;
172 }
173 }
174
144 } // namespace 175 } // namespace
145 176
146 // Renames a file using the SHFileOperation API to ensure that the target file 177 // Renames a file using the SHFileOperation API to ensure that the target file
147 // gets the correct default security descriptor in the new path. 178 // gets the correct default security descriptor in the new path.
148 // Returns a network error, or net::OK for success. 179 // Returns a network error, or net::OK for success.
149 content::DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions( 180 content::DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions(
150 const FilePath& new_path) { 181 const FilePath& new_path) {
151 base::ThreadRestrictions::AssertIOAllowed(); 182 base::ThreadRestrictions::AssertIOAllowed();
152 183
153 // The parameters to SHFileOperation must be terminated with 2 NULL chars. 184 // The parameters to SHFileOperation must be terminated with 2 NULL chars.
(...skipping 17 matching lines...) Expand all
171 if (result == 0 && move_info.fAnyOperationsAborted) 202 if (result == 0 && move_info.fAnyOperationsAborted)
172 interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; 203 interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
173 else if (result != 0) 204 else if (result != 0)
174 interrupt_reason = MapShFileOperationCodes(result); 205 interrupt_reason = MapShFileOperationCodes(result);
175 206
176 if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) 207 if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE)
177 return LogInterruptReason("SHFileOperation", result, interrupt_reason); 208 return LogInterruptReason("SHFileOperation", result, interrupt_reason);
178 return interrupt_reason; 209 return interrupt_reason;
179 } 210 }
180 211
181 void BaseFile::AnnotateWithSourceInformation() { 212 content::DownloadInterruptReason BaseFile::AnnotateWithSourceInformation() {
182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 213 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
183 DCHECK(!detached_); 214 DCHECK(!detached_);
184 215
185 // Sets the Zone to tell Windows that this file comes from the internet. 216 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED);
186 // We ignore the return value because a failure is not fatal. 217 content::DownloadInterruptReason result =
187 win_util::SetInternetZoneIdentifier(full_path_, 218 content::DOWNLOAD_INTERRUPT_REASON_NONE;
188 UTF8ToWide(source_url_.spec())); 219 HRESULT hr = win_util::ScanAndSaveDownloadedFile(full_path_, source_url_);
220
221 // If the download file is missing after the call, then treat this as an
222 // interrupted download.
223 //
224 // If the ScanAndSaveDownloadedFile() call failed, but the downloaded file is
225 // still around, then don't interrupt the download. Attachment Execution
226 // Services deletes the submitted file if the downloaded file is blocked by
227 // policy or if it was found to be infected.
228 //
229 // If the file is still there, then the error could be due to AES not being
230 // available or some other error during the AES invocation. In either case,
231 // we don't surface the error to the user.
232 if (!file_util::PathExists(full_path_)) {
233 DCHECK(FAILED(hr));
234 result = MapScanAndSaveErrorCodeToInterruptReason(hr);
235 if (result == content::DOWNLOAD_INTERRUPT_REASON_NONE) {
236 download_stats::RecordDownloadCount(
237 download_stats::FILE_MISSING_AFTER_SUCCESSFUL_SCAN_COUNT);
238 result = content::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED;
239 }
240 LogInterruptReason("ScanAndSaveDownloadedFile", hr, result);
241 }
242 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED);
243 return result;
189 } 244 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698