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