15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/cache_dumper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/entry_impl.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_cache.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/url_to_filename_encoder.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CacheDumper::CacheDumper(disk_cache::Backend* cache) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : cache_(cache) { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CacheDumper::CreateEntry(const std::string& key, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disk_cache::Entry** entry, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cache_->CreateEntry(key, entry, callback); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CacheDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf, int buf_len, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry->WriteData(index, offset, buf, buf_len, callback, false); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CacheDumper::CloseEntry(disk_cache::Entry* entry, base::Time last_used, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time last_modified) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<disk_cache::EntryImpl*>(entry)->SetTimes(last_used, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_modified); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->Close(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A version of CreateDirectory which supports lengthy filenames. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true on success, false on failure. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SafeCreateDirectory(const base::FilePath& path) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32_LARGE_FILENAME_SUPPORT 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Due to large paths on windows, it can't simply do a 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateDirectory("a/b/c"). Instead, create each subdirectory manually. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool rv = false; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring::size_type pos(0); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring backslash(L"\\"); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the path starts with the long file header, skip over that 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring kLargeFilenamePrefix(L"\\\\?\\"); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring header(kLargeFilenamePrefix); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path.value().find(header) == 0) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = 4; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the subdirectories individually 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((pos = path.value().find(backslash, pos)) != std::wstring::npos) { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType subdir = path.value().substr(0, pos); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDirectoryW(subdir.c_str(), NULL); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we keep going even if directory creation failed. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos++; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now create the full path 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateDirectoryW(path.value().c_str(), NULL) == TRUE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::CreateDirectory(path); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DiskDumper::DiskDumper(const base::FilePath& path) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : path_(path), entry_(NULL) { 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::CreateDirectory(path); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DiskDumper::CreateEntry(const std::string& key, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disk_cache::Entry** entry, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URL may not start with a valid protocol; search for it. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int urlpos = key.find("http"); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = urlpos > 0 ? key.substr(urlpos) : key; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string base_path = path_.MaybeAsASCII(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_path = 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::UrlToFilenameEncoder::Encode(url, base_path, false); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry_path_ = base::FilePath::FromUTF8Unsafe(new_path); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32_LARGE_FILENAME_SUPPORT 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In order for long filenames to work, we'll need to prepend 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the windows magic token. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring kLongFilenamePrefix(L"\\\\?\\"); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no way to prepend to a filename. We simply *have* 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to convert to a wstring to do this. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring name = kLongFilenamePrefix; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.append(entry_path_.value()); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry_path_ = base::FilePath(name); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_url_ = key; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SafeCreateDirectory(entry_path_.DirName()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType file = entry_path_.value(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32_LARGE_FILENAME_SUPPORT 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = CreateFileW(file.c_str(), GENERIC_WRITE|GENERIC_READ, 0, 0, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_ == INVALID_HANDLE_VALUE) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wprintf(L"CreateFileW (%s) failed: %d\n", file.c_str(), GetLastError()); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (entry_ != INVALID_HANDLE_VALUE) ? net::OK : net::ERR_FAILED; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry_ = base::OpenFile(entry_path_, "w+"); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (entry_ != NULL) ? net::OK : net::ERR_FAILED; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility Function to create a normalized header string from a 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HttpResponseInfo. The output will be formatted exactly 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// like so: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/<version> <status_code> <status_text>\n 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [<header-name>: <header-values>\n]* 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// meaning, each line is \n-terminated, and there is no extra whitespace 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// beyond the single space separators shown (of course, values can contain 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whitespace within them). If a given header-name appears more than once 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the set of headers, they are combined into a single line like so: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <header-name>: <header-value1>, <header-value2>, ...<header-valueN>\n 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DANGER: For some headers (e.g., "Set-Cookie"), the normalized form can be 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a lossy format. This is due to the fact that some servers generate 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set-Cookie headers that contain unquoted commas (usually as part of the 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value of an "expires" attribute). So, use this function with caution. Do 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not expect to be able to re-parse Set-Cookie headers from this output. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: Do not make any assumptions about the encoding of this output 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string. It may be non-ASCII, and the encoding used by the server is not 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// necessarily known to us. Do not assume that this output is UTF-8! 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetNormalizedHeaders(const net::HttpResponseInfo& info, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start with the status line 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->assign(info.headers->GetStatusLine()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append("\r\n"); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enumerate the headers 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name, value; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append(name); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append(": "); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append(value); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append("\r\n"); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark the end of headers 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append("\r\n"); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf, int buf_len, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry_) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string headers; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *data; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == 0) { // Stream 0 is the headers. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpResponseInfo response_info; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool truncated; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!net::HttpCache::ParseResponseInfo(buf->data(), buf_len, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response_info, &truncated)) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip this entry if it was truncated (results in an empty file). 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (truncated) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buf_len; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the size headers. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info.headers->RemoveHeader("transfer-encoding"); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info.headers->RemoveHeader("content-length"); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info.headers->RemoveHeader("x-original-url"); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert the headers into a string ending with LF. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNormalizedHeaders(response_info, &headers); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append a header for the original URL. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = entry_url_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // strip off the "XXGET" which may be in the key. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::size_type pos(0); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((pos = url.find("http")) != 0) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos != std::string::npos) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = url.substr(pos); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string x_original_url = "X-Original-Url: " + url + "\r\n"; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we know that the last two bytes are CRLF. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers.replace(headers.length() - 2, 0, x_original_url); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = headers.c_str(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = headers.size(); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (index == 1) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = buf->data(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = buf_len; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32_LARGE_FILENAME_SUPPORT 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD bytes; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteFile(entry_, data, len, &bytes, 0)) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fwrite(data, 1, len, entry_); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DiskDumper::CloseEntry(disk_cache::Entry* entry, base::Time last_used, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time last_modified) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32_LARGE_FILENAME_SUPPORT 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(entry_); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::CloseFile(entry_); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 224