summaryrefslogtreecommitdiffstats
path: root/chromium/base/files/file_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/files/file_win.cc')
-rw-r--r--chromium/base/files/file_win.cc268
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);
}