diff options
Diffstat (limited to 'chromium/base/files/file_win.cc')
-rw-r--r-- | chromium/base/files/file_win.cc | 268 |
1 files changed, 160 insertions, 108 deletions
diff --git a/chromium/base/files/file_win.cc b/chromium/base/files/file_win.cc index 727b5ce1dbb..97928522f10 100644 --- a/chromium/base/files/file_win.cc +++ b/chromium/base/files/file_win.cc @@ -6,7 +6,6 @@ #include <io.h> -#include "base/files/file_path.h" #include "base/logging.h" #include "base/metrics/sparse_histogram.h" #include "base/threading/thread_restrictions.h" @@ -18,90 +17,6 @@ COMPILE_ASSERT(File::FROM_BEGIN == FILE_BEGIN && File::FROM_CURRENT == FILE_CURRENT && File::FROM_END == FILE_END, whence_matches_system); -void File::InitializeUnsafe(const FilePath& name, uint32 flags) { - base::ThreadRestrictions::AssertIOAllowed(); - DCHECK(!IsValid()); - - DWORD disposition = 0; - - if (flags & FLAG_OPEN) - disposition = OPEN_EXISTING; - - if (flags & FLAG_CREATE) { - DCHECK(!disposition); - disposition = CREATE_NEW; - } - - if (flags & FLAG_OPEN_ALWAYS) { - DCHECK(!disposition); - disposition = OPEN_ALWAYS; - } - - if (flags & FLAG_CREATE_ALWAYS) { - DCHECK(!disposition); - DCHECK(flags & FLAG_WRITE); - disposition = CREATE_ALWAYS; - } - - if (flags & FLAG_OPEN_TRUNCATED) { - DCHECK(!disposition); - DCHECK(flags & FLAG_WRITE); - disposition = TRUNCATE_EXISTING; - } - - if (!disposition) { - NOTREACHED(); - return; - } - - DWORD access = 0; - if (flags & FLAG_WRITE) - access = GENERIC_WRITE; - if (flags & FLAG_APPEND) { - DCHECK(!access); - access = FILE_APPEND_DATA; - } - if (flags & FLAG_READ) - access |= GENERIC_READ; - if (flags & FLAG_WRITE_ATTRIBUTES) - access |= FILE_WRITE_ATTRIBUTES; - if (flags & FLAG_EXECUTE) - access |= GENERIC_EXECUTE; - - DWORD sharing = (flags & FLAG_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ; - if (!(flags & FLAG_EXCLUSIVE_WRITE)) - sharing |= FILE_SHARE_WRITE; - if (flags & FLAG_SHARE_DELETE) - sharing |= FILE_SHARE_DELETE; - - DWORD create_flags = 0; - if (flags & FLAG_ASYNC) - create_flags |= FILE_FLAG_OVERLAPPED; - if (flags & FLAG_TEMPORARY) - create_flags |= FILE_ATTRIBUTE_TEMPORARY; - if (flags & FLAG_HIDDEN) - create_flags |= FILE_ATTRIBUTE_HIDDEN; - if (flags & FLAG_DELETE_ON_CLOSE) - create_flags |= FILE_FLAG_DELETE_ON_CLOSE; - if (flags & FLAG_BACKUP_SEMANTICS) - create_flags |= FILE_FLAG_BACKUP_SEMANTICS; - - file_.Set(CreateFile(name.value().c_str(), access, sharing, NULL, - disposition, create_flags, NULL)); - - if (file_.IsValid()) { - error_details_ = FILE_OK; - async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); - - if (flags & (FLAG_OPEN_ALWAYS)) - created_ = (ERROR_ALREADY_EXISTS != GetLastError()); - else if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) - created_ = true; - } else { - error_details_ = OSErrorToFileError(GetLastError()); - } -} - bool File::IsValid() const { return file_.IsValid(); } @@ -115,16 +30,20 @@ PlatformFile File::TakePlatformFile() { } void File::Close() { - if (file_.IsValid()) { - base::ThreadRestrictions::AssertIOAllowed(); - file_.Close(); - } + if (!file_.IsValid()) + return; + + ThreadRestrictions::AssertIOAllowed(); + SCOPED_FILE_TRACE("Close"); + file_.Close(); } int64 File::Seek(Whence whence, int64 offset) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); + SCOPED_FILE_TRACE_WITH_SIZE("Seek", offset); + LARGE_INTEGER distance, res; distance.QuadPart = offset; DWORD move_method = static_cast<DWORD>(whence); @@ -134,12 +53,14 @@ int64 File::Seek(Whence whence, int64 offset) { } int File::Read(int64 offset, char* data, int size) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); DCHECK(!async_); if (size < 0) return -1; + SCOPED_FILE_TRACE_WITH_SIZE("Read", size); + LARGE_INTEGER offset_li; offset_li.QuadPart = offset; @@ -157,12 +78,14 @@ int File::Read(int64 offset, char* data, int size) { } int File::ReadAtCurrentPos(char* data, int size) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); DCHECK(!async_); if (size < 0) return -1; + SCOPED_FILE_TRACE_WITH_SIZE("ReadAtCurrentPos", size); + DWORD bytes_read; if (::ReadFile(file_.Get(), data, size, &bytes_read, NULL)) return bytes_read; @@ -173,18 +96,22 @@ int File::ReadAtCurrentPos(char* data, int size) { } int File::ReadNoBestEffort(int64 offset, char* data, int size) { + // TODO(dbeam): trace this separately? return Read(offset, data, size); } int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { + // TODO(dbeam): trace this separately? return ReadAtCurrentPos(data, size); } int File::Write(int64 offset, const char* data, int size) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); DCHECK(!async_); + SCOPED_FILE_TRACE_WITH_SIZE("Write", size); + LARGE_INTEGER offset_li; offset_li.QuadPart = offset; @@ -200,12 +127,14 @@ int File::Write(int64 offset, const char* data, int size) { } int File::WriteAtCurrentPos(const char* data, int size) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); DCHECK(!async_); if (size < 0) return -1; + SCOPED_FILE_TRACE_WITH_SIZE("WriteAtCurrentPos", size); + DWORD bytes_written; if (::WriteFile(file_.Get(), data, size, &bytes_written, NULL)) return bytes_written; @@ -218,8 +147,11 @@ int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { } int64 File::GetLength() { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); + + SCOPED_FILE_TRACE("GetLength"); + LARGE_INTEGER size; if (!::GetFileSizeEx(file_.Get(), &size)) return -1; @@ -228,9 +160,11 @@ int64 File::GetLength() { } bool File::SetLength(int64 length) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); + SCOPED_FILE_TRACE_WITH_SIZE("SetLength", length); + // Get the current file pointer. LARGE_INTEGER file_pointer; LARGE_INTEGER zero; @@ -256,16 +190,12 @@ bool File::SetLength(int64 length) { FALSE)); } -bool File::Flush() { - base::ThreadRestrictions::AssertIOAllowed(); - DCHECK(IsValid()); - return ::FlushFileBuffers(file_.Get()) != FALSE; -} - bool File::SetTimes(Time last_access_time, Time last_modified_time) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); + SCOPED_FILE_TRACE("SetTimes"); + FILETIME last_access_filetime = last_access_time.ToFileTime(); FILETIME last_modified_filetime = last_modified_time.ToFileTime(); return (::SetFileTime(file_.Get(), NULL, &last_access_filetime, @@ -273,9 +203,11 @@ bool File::SetTimes(Time last_access_time, Time last_modified_time) { } bool File::GetInfo(Info* info) { - base::ThreadRestrictions::AssertIOAllowed(); + ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); + SCOPED_FILE_TRACE("GetInfo"); + BY_HANDLE_FILE_INFORMATION file_info; if (!GetFileInformationByHandle(file_.Get(), &file_info)) return false; @@ -287,14 +219,17 @@ bool File::GetInfo(Info* info) { info->is_directory = (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info->is_symbolic_link = false; // Windows doesn't have symbolic links. - info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime); - info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime); - info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime); + info->last_modified = Time::FromFileTime(file_info.ftLastWriteTime); + info->last_accessed = Time::FromFileTime(file_info.ftLastAccessTime); + info->creation_time = Time::FromFileTime(file_info.ftCreationTime); return true; } -File::Error base::File::Lock() { +File::Error File::Lock() { DCHECK(IsValid()); + + SCOPED_FILE_TRACE("Lock"); + BOOL result = LockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD); if (!result) return OSErrorToFileError(GetLastError()); @@ -303,12 +238,39 @@ File::Error base::File::Lock() { File::Error File::Unlock() { DCHECK(IsValid()); + + SCOPED_FILE_TRACE("Unlock"); + BOOL result = UnlockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD); if (!result) return OSErrorToFileError(GetLastError()); return FILE_OK; } +File File::Duplicate() { + if (!IsValid()) + return File(); + + SCOPED_FILE_TRACE("Duplicate"); + + HANDLE other_handle = nullptr; + + if (!::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle + GetPlatformFile(), + GetCurrentProcess(), // hTargetProcessHandle + &other_handle, + 0, // dwDesiredAccess ignored due to SAME_ACCESS + FALSE, // !bInheritHandle + DUPLICATE_SAME_ACCESS)) { + return File(OSErrorToFileError(GetLastError())); + } + + File other(other_handle); + if (async()) + other.async_ = true; + return other.Pass(); +} + // Static. File::Error File::OSErrorToFileError(DWORD last_error) { switch (last_error) { @@ -346,6 +308,96 @@ File::Error File::OSErrorToFileError(DWORD last_error) { } } +void File::DoInitialize(uint32 flags) { + ThreadRestrictions::AssertIOAllowed(); + DCHECK(!IsValid()); + + DWORD disposition = 0; + + if (flags & FLAG_OPEN) + disposition = OPEN_EXISTING; + + if (flags & FLAG_CREATE) { + DCHECK(!disposition); + disposition = CREATE_NEW; + } + + if (flags & FLAG_OPEN_ALWAYS) { + DCHECK(!disposition); + disposition = OPEN_ALWAYS; + } + + if (flags & FLAG_CREATE_ALWAYS) { + DCHECK(!disposition); + DCHECK(flags & FLAG_WRITE); + disposition = CREATE_ALWAYS; + } + + if (flags & FLAG_OPEN_TRUNCATED) { + DCHECK(!disposition); + DCHECK(flags & FLAG_WRITE); + disposition = TRUNCATE_EXISTING; + } + + if (!disposition) { + NOTREACHED(); + return; + } + + DWORD access = 0; + if (flags & FLAG_WRITE) + access = GENERIC_WRITE; + if (flags & FLAG_APPEND) { + DCHECK(!access); + access = FILE_APPEND_DATA; + } + if (flags & FLAG_READ) + access |= GENERIC_READ; + if (flags & FLAG_WRITE_ATTRIBUTES) + access |= FILE_WRITE_ATTRIBUTES; + if (flags & FLAG_EXECUTE) + access |= GENERIC_EXECUTE; + + DWORD sharing = (flags & FLAG_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ; + if (!(flags & FLAG_EXCLUSIVE_WRITE)) + sharing |= FILE_SHARE_WRITE; + if (flags & FLAG_SHARE_DELETE) + sharing |= FILE_SHARE_DELETE; + + DWORD create_flags = 0; + if (flags & FLAG_ASYNC) + create_flags |= FILE_FLAG_OVERLAPPED; + if (flags & FLAG_TEMPORARY) + create_flags |= FILE_ATTRIBUTE_TEMPORARY; + if (flags & FLAG_HIDDEN) + create_flags |= FILE_ATTRIBUTE_HIDDEN; + if (flags & FLAG_DELETE_ON_CLOSE) + create_flags |= FILE_FLAG_DELETE_ON_CLOSE; + if (flags & FLAG_BACKUP_SEMANTICS) + create_flags |= FILE_FLAG_BACKUP_SEMANTICS; + + file_.Set(CreateFile(path_.value().c_str(), access, sharing, NULL, + disposition, create_flags, NULL)); + + if (file_.IsValid()) { + error_details_ = FILE_OK; + async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); + + if (flags & (FLAG_OPEN_ALWAYS)) + created_ = (ERROR_ALREADY_EXISTS != GetLastError()); + else if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) + created_ = true; + } else { + error_details_ = OSErrorToFileError(GetLastError()); + } +} + +bool File::DoFlush() { + ThreadRestrictions::AssertIOAllowed(); + DCHECK(IsValid()); + return ::FlushFileBuffers(file_.Get()) != FALSE; +} + void File::SetPlatformFile(PlatformFile file) { file_.Set(file); } |