172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/base_file.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_util.h" 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/format_macros.h" 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h" 10201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/stringprintf.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/secure_hash.h" 12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "net/base/file_stream.h" 13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "net/base/net_errors.h" 14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/download_util.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN) 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/win_safe_util.h" 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#elif defined(OS_MACOSX) 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/cocoa/file_metadata.h" 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBaseFile::BaseFile(const FilePath& full_path, 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const GURL& source_url, 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const GURL& referrer_url, 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int64 received_bytes, 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const linked_ptr<net::FileStream>& file_stream) 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : full_path_(full_path), 29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen source_url_(source_url), 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen referrer_url_(referrer_url), 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_(file_stream), 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bytes_so_far_(received_bytes), 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen power_save_blocker_(true), 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen calculate_hash_(false), 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen detached_(false) { 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen memset(sha256_hash_, 0, sizeof(sha256_hash_)); 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBaseFile::~BaseFile() { 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (detached_) 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Close(); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Cancel(); // Will delete the file. 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BaseFile::Initialize(bool calculate_hash) { 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen calculate_hash_ = calculate_hash; 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (calculate_hash_) 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!full_path_.empty() || 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen download_util::CreateTemporaryFileForDownload(&full_path_)) 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return Open(); 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool BaseFile::AppendDataToFile(const char* data, size_t data_len) { 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!file_stream_.get()) 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // TODO(phajdan.jr): get rid of this check. 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (data_len == 0) 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bytes_so_far_ += data_len; 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(phajdan.jr): handle errors on file writes. http://crbug.com/58355 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen size_t written = file_stream_->Write(data, data_len, NULL); 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (written != data_len) 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (calculate_hash_) 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen secure_hash_->Update(data, data_len); 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool BaseFile::Rename(const FilePath& new_path) { 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Save the information whether the download is in progress because 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // it will be overwritten by closing the file. 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool saved_in_progress = in_progress(); 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If the new path is same as the old one, there is no need to perform the 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // following renaming logic. 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (new_path == full_path_) { 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Don't close the file if we're not done (finished or canceled). 98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!saved_in_progress) 99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Close(); 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Close(); 105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_util::CreateDirectory(new_path.DirName()); 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN) 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We cannot rename because rename will keep the same security descriptor 110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // on the destination file. We want to recreate the security descriptor 111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // with the security that makes sense in the new path. 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!file_util::RenameFileAndResetSecurityDescriptor(full_path_, new_path)) 113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#elif defined(OS_POSIX) 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen { 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Similarly, on Unix, we're moving a temp file created with permissions 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // 600 to |new_path|. Here, we try to fix up the destination file with 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // appropriate permissions. 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen struct stat st; 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // First check the file existence and create an empty file if it doesn't 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // exist. 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!file_util::PathExists(new_path)) 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_util::WriteFile(new_path, "", 0); 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool stat_succeeded = (stat(new_path.value().c_str(), &st) == 0); 125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // TODO(estade): Move() falls back to copying and deleting when a simple 127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // rename fails. Copying sucks for large downloads. crbug.com/8737 128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!file_util::Move(full_path_, new_path)) 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (stat_succeeded) 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen chmod(new_path.value().c_str(), st.st_mode); 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen full_path_ = new_path; 137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We don't need to re-open the file if we're done (finished or canceled). 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!saved_in_progress) 140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!Open()) 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BaseFile::Detach() { 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen detached_ = true; 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BaseFile::Cancel() { 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Close(); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!full_path_.empty()) 159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_util::Delete(full_path_, false); 160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BaseFile::Finish() { 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (calculate_hash_) 16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen secure_hash_->Finish(sha256_hash_, kSha256HashLen); 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Close(); 169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BaseFile::GetSha256Hash(std::string* hash) { 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!calculate_hash_ || in_progress()) 17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen hash->assign(reinterpret_cast<const char*>(sha256_hash_), 17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sizeof(sha256_hash_)); 17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BaseFile::AnnotateWithSourceInformation() { 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN) 185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Sets the Zone to tell Windows that this file comes from the internet. 186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We ignore the return value because a failure is not fatal. 187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen win_util::SetInternetZoneIdentifier(full_path_); 188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#elif defined(OS_MACOSX) 189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_metadata::AddQuarantineMetadataToFile(full_path_, source_url_, 190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen referrer_url_); 191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_metadata::AddOriginMetadataToFile(full_path_, source_url_, 192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen referrer_url_); 193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool BaseFile::Open() { 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!detached_); 199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(!full_path_.empty()); 200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Create a new file stream if it is not provided. 202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!file_stream_.get()) { 203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_.reset(new net::FileStream); 204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (file_stream_->Open(full_path_, 205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen base::PLATFORM_FILE_OPEN_ALWAYS | 206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen base::PLATFORM_FILE_WRITE) != net::OK) { 207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_.reset(); 208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We may be re-opening the file after rename. Always make sure we're 212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // writing at the end of the file. 213bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (file_stream_->Seek(net::FROM_END, 0) < 0) { 214bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_.reset(); 215bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 216bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 217bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 218bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 219bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN) 220bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AnnotateWithSourceInformation(); 221bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 223bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 225bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BaseFile::Close() { 226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (file_stream_.get()) { 228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_CHROMEOS) 229bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Currently we don't really care about the return value, since if it fails 230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // theres not much we can do. But we might in the future. 231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_->Flush(); 232bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 233bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_->Close(); 234bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen file_stream_.reset(); 235bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 236bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::string BaseFile::DebugString() const { 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return base::StringPrintf("{ source_url_ = \"%s\"" 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen " full_path_ = \"%" PRFilePath "\"" 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen " bytes_so_far_ = %" PRId64 " detached_ = %c }", 242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch source_url_.spec().c_str(), 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen full_path_.value().c_str(), 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bytes_so_far_, 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen detached_ ? 'T' : 'F'); 246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 247