Disable crashing tests, my previous checkin to mark them flaky did not help.
[chromium-blink-merge.git] / base / platform_file_win.cc
blob0cb3e53831b26bf32431e7c7800d760871b8a3bd
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/platform_file.h"
7 #include "base/file_path.h"
8 #include "base/logging.h"
9 #include "base/threading/thread_restrictions.h"
11 namespace base {
13 PlatformFile CreatePlatformFile(const FilePath& name,
14 int flags,
15 bool* created,
16 PlatformFileError* error_code) {
17 base::ThreadRestrictions::AssertIOAllowed();
19 DWORD disposition = 0;
21 if (flags & PLATFORM_FILE_OPEN)
22 disposition = OPEN_EXISTING;
24 if (flags & PLATFORM_FILE_CREATE) {
25 DCHECK(!disposition);
26 disposition = CREATE_NEW;
29 if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
30 DCHECK(!disposition);
31 disposition = OPEN_ALWAYS;
34 if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
35 DCHECK(!disposition);
36 disposition = CREATE_ALWAYS;
39 if (flags & PLATFORM_FILE_TRUNCATE) {
40 DCHECK(!disposition);
41 DCHECK(flags & PLATFORM_FILE_WRITE);
42 disposition = TRUNCATE_EXISTING;
45 if (!disposition) {
46 NOTREACHED();
47 return NULL;
50 DWORD access = (flags & PLATFORM_FILE_READ) ? GENERIC_READ : 0;
51 if (flags & PLATFORM_FILE_WRITE)
52 access |= GENERIC_WRITE;
53 if (flags & PLATFORM_FILE_WRITE_ATTRIBUTES)
54 access |= FILE_WRITE_ATTRIBUTES;
56 DWORD sharing = (flags & PLATFORM_FILE_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ;
57 if (!(flags & PLATFORM_FILE_EXCLUSIVE_WRITE))
58 sharing |= FILE_SHARE_WRITE;
60 DWORD create_flags = 0;
61 if (flags & PLATFORM_FILE_ASYNC)
62 create_flags |= FILE_FLAG_OVERLAPPED;
63 if (flags & PLATFORM_FILE_TEMPORARY)
64 create_flags |= FILE_ATTRIBUTE_TEMPORARY;
65 if (flags & PLATFORM_FILE_HIDDEN)
66 create_flags |= FILE_ATTRIBUTE_HIDDEN;
67 if (flags & PLATFORM_FILE_DELETE_ON_CLOSE)
68 create_flags |= FILE_FLAG_DELETE_ON_CLOSE;
70 HANDLE file = CreateFile(name.value().c_str(), access, sharing, NULL,
71 disposition, create_flags, NULL);
73 if (created && (INVALID_HANDLE_VALUE != file)) {
74 if (flags & (PLATFORM_FILE_OPEN_ALWAYS))
75 *created = (ERROR_ALREADY_EXISTS != GetLastError());
76 else if (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE))
77 *created = true;
80 if (error_code) {
81 if (file != kInvalidPlatformFileValue)
82 *error_code = PLATFORM_FILE_OK;
83 else {
84 DWORD last_error = GetLastError();
85 switch (last_error) {
86 case ERROR_SHARING_VIOLATION:
87 *error_code = PLATFORM_FILE_ERROR_IN_USE;
88 break;
89 case ERROR_FILE_EXISTS:
90 *error_code = PLATFORM_FILE_ERROR_EXISTS;
91 break;
92 case ERROR_FILE_NOT_FOUND:
93 *error_code = PLATFORM_FILE_ERROR_NOT_FOUND;
94 break;
95 case ERROR_ACCESS_DENIED:
96 *error_code = PLATFORM_FILE_ERROR_ACCESS_DENIED;
97 break;
98 default:
99 *error_code = PLATFORM_FILE_ERROR_FAILED;
104 return file;
107 bool ClosePlatformFile(PlatformFile file) {
108 base::ThreadRestrictions::AssertIOAllowed();
109 return (CloseHandle(file) != 0);
112 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
113 base::ThreadRestrictions::AssertIOAllowed();
114 if (file == kInvalidPlatformFileValue)
115 return -1;
117 LARGE_INTEGER offset_li;
118 offset_li.QuadPart = offset;
120 OVERLAPPED overlapped = {0};
121 overlapped.Offset = offset_li.LowPart;
122 overlapped.OffsetHigh = offset_li.HighPart;
124 DWORD bytes_read;
125 if (::ReadFile(file, data, size, &bytes_read, &overlapped) != 0)
126 return bytes_read;
127 else if (ERROR_HANDLE_EOF == GetLastError())
128 return 0;
130 return -1;
133 int WritePlatformFile(PlatformFile file, int64 offset,
134 const char* data, int size) {
135 base::ThreadRestrictions::AssertIOAllowed();
136 if (file == kInvalidPlatformFileValue)
137 return -1;
139 LARGE_INTEGER offset_li;
140 offset_li.QuadPart = offset;
142 OVERLAPPED overlapped = {0};
143 overlapped.Offset = offset_li.LowPart;
144 overlapped.OffsetHigh = offset_li.HighPart;
146 DWORD bytes_written;
147 if (::WriteFile(file, data, size, &bytes_written, &overlapped) != 0)
148 return bytes_written;
150 return -1;
153 bool TruncatePlatformFile(PlatformFile file, int64 length) {
154 base::ThreadRestrictions::AssertIOAllowed();
155 if (file == kInvalidPlatformFileValue)
156 return false;
158 // Get the current file pointer.
159 LARGE_INTEGER file_pointer;
160 LARGE_INTEGER zero;
161 zero.QuadPart = 0;
162 if (::SetFilePointerEx(file, zero, &file_pointer, FILE_CURRENT) == 0)
163 return false;
165 LARGE_INTEGER length_li;
166 length_li.QuadPart = length;
167 // If length > file size, SetFilePointerEx() should extend the file
168 // with zeroes on all Windows standard file systems (NTFS, FATxx).
169 if (!::SetFilePointerEx(file, length_li, NULL, FILE_BEGIN))
170 return false;
172 // Set the new file length and move the file pointer to its old position.
173 // This is consistent with ftruncate()'s behavior, even when the file
174 // pointer points to a location beyond the end of the file.
175 return ((::SetEndOfFile(file) != 0) &&
176 (::SetFilePointerEx(file, file_pointer, NULL, FILE_BEGIN) != 0));
179 bool FlushPlatformFile(PlatformFile file) {
180 base::ThreadRestrictions::AssertIOAllowed();
181 return ((file != kInvalidPlatformFileValue) && ::FlushFileBuffers(file));
184 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
185 const base::Time& last_modified_time) {
186 base::ThreadRestrictions::AssertIOAllowed();
187 if (file == kInvalidPlatformFileValue)
188 return false;
190 FILETIME last_access_filetime = last_access_time.ToFileTime();
191 FILETIME last_modified_filetime = last_modified_time.ToFileTime();
192 return (::SetFileTime(file, NULL, &last_access_filetime,
193 &last_modified_filetime) != 0);
196 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
197 base::ThreadRestrictions::AssertIOAllowed();
198 if (!info)
199 return false;
201 BY_HANDLE_FILE_INFORMATION file_info;
202 if (GetFileInformationByHandle(file, &file_info) == 0)
203 return false;
205 LARGE_INTEGER size;
206 size.HighPart = file_info.nFileSizeHigh;
207 size.LowPart = file_info.nFileSizeLow;
208 info->size = size.QuadPart;
209 info->is_directory =
210 file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
211 info->is_symbolic_link = false; // Windows doesn't have symbolic links.
212 info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime);
213 info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime);
214 info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime);
215 return true;
218 } // namespace disk_cache