13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/file.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/lazy_instance.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 10d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen#include "net/base/net_errors.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Structure used for asynchronous operations. 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct MyOverlapped { 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MyOverlapped(disk_cache::File* file, size_t offset, 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::FileIOCallback* callback); 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~MyOverlapped() {} 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OVERLAPPED* overlapped() { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return &context_.overlapped; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::IOContext context_; 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<disk_cache::File> file_; 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::FileIOCallback* callback_; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(!offsetof(MyOverlapped, context_), starts_with_overlapped); 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Helper class to handle the IO completion notifications from the message loop. 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass CompletionHandler : public MessageLoopForIO::IOHandler { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual_bytes, DWORD error); 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic base::LazyInstance<CompletionHandler> g_completion_handler( 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::LINKER_INITIALIZED); 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CompletionHandler::OnIOCompleted(MessageLoopForIO::IOContext* context, 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual_bytes, DWORD error) { 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MyOverlapped* data = reinterpret_cast<MyOverlapped*>(context); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (error) { 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!actual_bytes); 46d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen actual_bytes = static_cast<DWORD>(net::ERR_CACHE_READ_FAILURE); 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->callback_) 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->callback_->OnFileIOComplete(static_cast<int>(actual_bytes)); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete data; 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset, 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::FileIOCallback* callback) { 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(this, 0, sizeof(*this)); 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen context_.handler = g_completion_handler.Pointer(); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott context_.overlapped.Offset = static_cast<DWORD>(offset); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_ = file; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott callback_ = callback; 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFile::File(base::PlatformFile file) 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : init_(true), mixed_(true), platform_file_(INVALID_HANDLE_VALUE), 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sync_platform_file_(file) { 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::Init(const FilePath& name) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!init_); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (init_) 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD access = GENERIC_READ | GENERIC_WRITE | DELETE; 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick platform_file_ = CreateFile(name.value().c_str(), access, sharing, NULL, 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_HANDLE_VALUE == platform_file_) 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::current()->RegisterIOHandler( 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen platform_file_, g_completion_handler.Pointer()); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_ = true; 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_platform_file_ = CreateFile(name.value().c_str(), access, sharing, NULL, 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OPEN_EXISTING, 0, NULL); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_HANDLE_VALUE == sync_platform_file_) 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFile::~File() { 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!init_) 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_HANDLE_VALUE != platform_file_) 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandle(platform_file_); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_HANDLE_VALUE != sync_platform_file_) 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandle(sync_platform_file_); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbase::PlatformFile File::platform_file() const { 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (INVALID_HANDLE_VALUE == platform_file_) ? sync_platform_file_ : 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott platform_file_; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::IsValid() const { 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!init_) 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (INVALID_HANDLE_VALUE != platform_file_ || 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott INVALID_HANDLE_VALUE != sync_platform_file_); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::Read(void* buffer, size_t buffer_len, size_t offset) { 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer_len > ULONG_MAX || offset > LONG_MAX) 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD ret = SetFilePointer(sync_platform_file_, static_cast<LONG>(offset), 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, FILE_BEGIN); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_SET_FILE_POINTER == ret) 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = static_cast<DWORD>(buffer_len); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReadFile(sync_platform_file_, buffer, size, &actual, NULL)) 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return actual == size; 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::Write(const void* buffer, size_t buffer_len, size_t offset) { 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer_len > ULONG_MAX || offset > ULONG_MAX) 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD ret = SetFilePointer(sync_platform_file_, static_cast<LONG>(offset), 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, FILE_BEGIN); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_SET_FILE_POINTER == ret) 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = static_cast<DWORD>(buffer_len); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!WriteFile(sync_platform_file_, buffer, size, &actual, NULL)) 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return actual == size; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We have to increase the ref counter of the file before performing the IO to 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// prevent the completion to happen with an invalid handle (if the file is 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// closed while the IO is in flight). 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::Read(void* buffer, size_t buffer_len, size_t offset, 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileIOCallback* callback, bool* completed) { 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!callback) { 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (completed) 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = true; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Read(buffer, buffer_len, offset); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer_len > ULONG_MAX || offset > ULONG_MAX) 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MyOverlapped* data = new MyOverlapped(this, offset, callback); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = static_cast<DWORD>(buffer_len); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReadFile(platform_file_, buffer, size, &actual, data->overlapped())) { 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = false; 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetLastError() == ERROR_IO_PENDING) 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete data; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The operation completed already. We'll be called back anyway. 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = (actual == size); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(actual == size); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->callback_ = NULL; 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->file_ = NULL; // There is no reason to hold on to this anymore. 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *completed; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::Write(const void* buffer, size_t buffer_len, size_t offset, 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileIOCallback* callback, bool* completed) { 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!callback) { 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (completed) 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = true; 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Write(buffer, buffer_len, offset); 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return AsyncWrite(buffer, buffer_len, offset, callback, completed); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FileIOCallback* callback, bool* completed) { 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(callback); 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(completed); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer_len > ULONG_MAX || offset > ULONG_MAX) 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MyOverlapped* data = new MyOverlapped(this, offset, callback); 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = static_cast<DWORD>(buffer_len); 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD actual; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!WriteFile(platform_file_, buffer, size, &actual, data->overlapped())) { 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = false; 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (GetLastError() == ERROR_IO_PENDING) 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete data; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The operation completed already. We'll be called back anyway. 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *completed = (actual == size); 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(actual == size); 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->callback_ = NULL; 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->file_ = NULL; // There is no reason to hold on to this anymore. 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *completed; 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool File::SetLength(size_t length) { 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (length > ULONG_MAX) 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = static_cast<DWORD>(length); 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE file = platform_file(); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (INVALID_SET_FILE_POINTER == SetFilePointer(file, size, NULL, FILE_BEGIN)) 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE == SetEndOfFile(file); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottsize_t File::GetLength() { 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_); 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LARGE_INTEGER size; 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE file = platform_file(); 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetFileSizeEx(file, &size)) 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (size.HighPart) 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ULONG_MAX; 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<size_t>(size.LowPart); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Static. 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid File::WaitForPendingIO(int* num_pending_io) { 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (*num_pending_io) { 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Asynchronous IO operations may be in flight and the completion may end 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // up calling us back so let's wait for them. 26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen MessageLoopForIO::IOHandler* handler = g_completion_handler.Pointer(); 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::current()->WaitForIOCompletion(100, handler); 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace disk_cache 268