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

Side by Side Diff: content/browser/download/base_file.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: Created 8 years, 2 months 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS; 189 FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS;
190 190
191 int result = SHFileOperation(&move_info); 191 int result = SHFileOperation(&move_info);
192 192
193 if (result == 0) 193 if (result == 0)
194 return (move_info.fAnyOperationsAborted) ? net::ERR_ABORTED : net::OK; 194 return (move_info.fAnyOperationsAborted) ? net::ERR_ABORTED : net::OK;
195 195
196 return MapShFileOperationCodes(result); 196 return MapShFileOperationCodes(result);
197 } 197 }
198 198
199 // Maps a return code from ScanAndSaveDownloadedFile() to a net::Error. The
200 // return code is usually from the final IAttachmentExecute::Save() call.
201 net::Error MapScanAndSaveErrorCodeToNetError(HRESULT hresult) {
202 switch (hresult) {
203 case INET_E_SECURITY_PROBLEM: // 0x800c000e
204 // This is returned if the download was blocked due to security
205 // restrictions. E.g. if the source URL was in the Restricted Sites zone
206 // and downloads are blocked on that zone, then the download would be
207 // deleted and this error code is returned.
208 return net::ERR_BLOCKED_BY_CLIENT;
209
210 case __HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED): // 0x80070005
211 case __HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT): // 0x800700c1
212 // These are errors that we have observed in the wild
213 // (http://crbug.com/153212). We don't have a useful explanation as to why
214 // this happens.
Randy Smith (Not in Mondays) 2012/10/16 18:19:19 Part of me would like to find *some* different err
asanka 2012/10/25 23:51:27 Added a new interrupt reason. I named it 'SECURITY
215 case E_FAIL: // 0x80004005
216 // Returned if an anti-virus product reports an infection in the
217 // downloaded file during IAE::Save().
218 default:
219 // Any error that occurs during IAttachmentExecute::Save() other than
220 // INET_E_SECURITY_PROBLEM is interpreted as a virus infection. This
221 // follows the behavior in IE.
222 return net::ERR_FILE_VIRUS_INFECTED;
223 }
224 }
225
199 #endif 226 #endif
200 227
201 } // namespace 228 } // namespace
202 229
203 // This will initialize the entire array to zero. 230 // This will initialize the entire array to zero.
204 const unsigned char BaseFile::kEmptySha256Hash[] = { 0 }; 231 const unsigned char BaseFile::kEmptySha256Hash[] = { 0 };
205 232
206 BaseFile::BaseFile(const FilePath& full_path, 233 BaseFile::BaseFile(const FilePath& full_path,
207 const GURL& source_url, 234 const GURL& source_url,
208 const GURL& referrer_url, 235 const GURL& referrer_url,
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 PickleIterator data_iterator(hash_state); 484 PickleIterator data_iterator(hash_state);
458 485
459 return secure_hash_->Deserialize(&data_iterator); 486 return secure_hash_->Deserialize(&data_iterator);
460 } 487 }
461 488
462 bool BaseFile::IsEmptyHash(const std::string& hash) { 489 bool BaseFile::IsEmptyHash(const std::string& hash) {
463 return (hash.size() == kSha256HashLen && 490 return (hash.size() == kSha256HashLen &&
464 0 == memcmp(hash.data(), kEmptySha256Hash, sizeof(kSha256HashLen))); 491 0 == memcmp(hash.data(), kEmptySha256Hash, sizeof(kSha256HashLen)));
465 } 492 }
466 493
467 void BaseFile::AnnotateWithSourceInformation() { 494 net::Error BaseFile::AnnotateWithSourceInformation() {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
469 DCHECK(!detached_); 496 DCHECK(!detached_);
470 497
498 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED);
499 int os_error = 0; // Only used for logging.
500 net::Error net_error = net::OK;
471 #if defined(OS_WIN) 501 #if defined(OS_WIN)
472 // Sets the Zone to tell Windows that this file comes from the internet. 502 HRESULT hr = win_util::ScanAndSaveDownloadedFile(full_path_, source_url_);
473 // We ignore the return value because a failure is not fatal. 503 if (!file_util::PathExists(full_path_)) {
474 win_util::SetInternetZoneIdentifier(full_path_, 504 DCHECK(FAILED(hr));
475 UTF8ToWide(source_url_.spec())); 505 // If the ScanAndSaveDownloadedFile() call failed, but the downloaded file
506 // is still around, then log the error, but don't show it to the
507 // user. Attachment Execution Services deletes the submitted file if the
508 // downloaded file is blocked by policy or if it was found to be infected.
509 //
510 // If the file is still there, then the error could be due to AES not being
511 // available or some other error during the AES invocation. In either case,
512 // we don't surface the error to the user.
513 net_error = MapScanAndSaveErrorCodeToNetError(hr);
514 if (net_error == net::OK)
515 net_error = net::ERR_FAILED;
Randy Smith (Not in Mondays) 2012/10/16 18:19:19 Do we want some better way to call out the case in
asanka 2012/10/25 23:51:27 Add a UMA count for this case.
516 }
517 os_error = hr;
476 #elif defined(OS_MACOSX) 518 #elif defined(OS_MACOSX)
477 content::AddQuarantineMetadataToFile(full_path_, source_url_, referrer_url_); 519 content::AddQuarantineMetadataToFile(full_path_, source_url_, referrer_url_);
478 content::AddOriginMetadataToFile(full_path_, source_url_, referrer_url_); 520 content::AddOriginMetadataToFile(full_path_, source_url_, referrer_url_);
479 #elif defined(OS_LINUX) 521 #elif defined(OS_LINUX)
480 content::AddOriginMetadataToFile(full_path_, source_url_, referrer_url_); 522 content::AddOriginMetadataToFile(full_path_, source_url_, referrer_url_);
481 #endif 523 #endif
524 bound_net_log_.EndEvent(
525 net::NetLog::TYPE_DOWNLOAD_FILE_ANNOTATED,
526 base::Bind(&download_net_logs::AnnotateWithSourceCallback,
527 os_error, net_error));
528 return net_error;
482 } 529 }
483 530
484 void BaseFile::CreateFileStream() { 531 void BaseFile::CreateFileStream() {
485 file_stream_.reset(new net::FileStream(bound_net_log_.net_log())); 532 file_stream_.reset(new net::FileStream(bound_net_log_.net_log()));
486 file_stream_->SetBoundNetLogSource(bound_net_log_); 533 file_stream_->SetBoundNetLogSource(bound_net_log_);
487 } 534 }
488 535
489 net::Error BaseFile::Open() { 536 net::Error BaseFile::Open() {
490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
491 DCHECK(!detached_); 538 DCHECK(!detached_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 int64 BaseFile::CurrentSpeedAtTime(base::TimeTicks current_time) const { 603 int64 BaseFile::CurrentSpeedAtTime(base::TimeTicks current_time) const {
557 base::TimeDelta diff = current_time - start_tick_; 604 base::TimeDelta diff = current_time - start_tick_;
558 int64 diff_ms = diff.InMilliseconds(); 605 int64 diff_ms = diff.InMilliseconds();
559 return diff_ms == 0 ? 0 : bytes_so_far() * 1000 / diff_ms; 606 return diff_ms == 0 ? 0 : bytes_so_far() * 1000 / diff_ms;
560 } 607 }
561 608
562 int64 BaseFile::CurrentSpeed() const { 609 int64 BaseFile::CurrentSpeed() const {
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 610 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
564 return CurrentSpeedAtTime(base::TimeTicks::Now()); 611 return CurrentSpeedAtTime(base::TimeTicks::Now());
565 } 612 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698