Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: base/files/file_win.cc

Issue 1446363003: Deleted OS_WIN and all Windows specific files from base. (Closed) Base URL: https://github.com/domokit/mojo.git@base_tests
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/files/file_util_win.cc ('k') | base/files/memory_mapped_file.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "base/files/file.h"
6
7 #include <io.h>
8
9 #include "base/logging.h"
10 #include "base/metrics/sparse_histogram.h"
11 #include "base/threading/thread_restrictions.h"
12
13 namespace base {
14
15 // Make sure our Whence mappings match the system headers.
16 COMPILE_ASSERT(File::FROM_BEGIN == FILE_BEGIN &&
17 File::FROM_CURRENT == FILE_CURRENT &&
18 File::FROM_END == FILE_END, whence_matches_system);
19
20 bool File::IsValid() const {
21 return file_.IsValid();
22 }
23
24 PlatformFile File::GetPlatformFile() const {
25 return file_.Get();
26 }
27
28 PlatformFile File::TakePlatformFile() {
29 return file_.Take();
30 }
31
32 void File::Close() {
33 if (!file_.IsValid())
34 return;
35
36 ThreadRestrictions::AssertIOAllowed();
37 SCOPED_FILE_TRACE("Close");
38 file_.Close();
39 }
40
41 int64 File::Seek(Whence whence, int64 offset) {
42 ThreadRestrictions::AssertIOAllowed();
43 DCHECK(IsValid());
44
45 SCOPED_FILE_TRACE_WITH_SIZE("Seek", offset);
46
47 LARGE_INTEGER distance, res;
48 distance.QuadPart = offset;
49 DWORD move_method = static_cast<DWORD>(whence);
50 if (!SetFilePointerEx(file_.Get(), distance, &res, move_method))
51 return -1;
52 return res.QuadPart;
53 }
54
55 int File::Read(int64 offset, char* data, int size) {
56 ThreadRestrictions::AssertIOAllowed();
57 DCHECK(IsValid());
58 DCHECK(!async_);
59 if (size < 0)
60 return -1;
61
62 SCOPED_FILE_TRACE_WITH_SIZE("Read", size);
63
64 LARGE_INTEGER offset_li;
65 offset_li.QuadPart = offset;
66
67 OVERLAPPED overlapped = {0};
68 overlapped.Offset = offset_li.LowPart;
69 overlapped.OffsetHigh = offset_li.HighPart;
70
71 DWORD bytes_read;
72 if (::ReadFile(file_.Get(), data, size, &bytes_read, &overlapped))
73 return bytes_read;
74 if (ERROR_HANDLE_EOF == GetLastError())
75 return 0;
76
77 return -1;
78 }
79
80 int File::ReadAtCurrentPos(char* data, int size) {
81 ThreadRestrictions::AssertIOAllowed();
82 DCHECK(IsValid());
83 DCHECK(!async_);
84 if (size < 0)
85 return -1;
86
87 SCOPED_FILE_TRACE_WITH_SIZE("ReadAtCurrentPos", size);
88
89 DWORD bytes_read;
90 if (::ReadFile(file_.Get(), data, size, &bytes_read, NULL))
91 return bytes_read;
92 if (ERROR_HANDLE_EOF == GetLastError())
93 return 0;
94
95 return -1;
96 }
97
98 int File::ReadNoBestEffort(int64 offset, char* data, int size) {
99 // TODO(dbeam): trace this separately?
100 return Read(offset, data, size);
101 }
102
103 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) {
104 // TODO(dbeam): trace this separately?
105 return ReadAtCurrentPos(data, size);
106 }
107
108 int File::Write(int64 offset, const char* data, int size) {
109 ThreadRestrictions::AssertIOAllowed();
110 DCHECK(IsValid());
111 DCHECK(!async_);
112
113 SCOPED_FILE_TRACE_WITH_SIZE("Write", size);
114
115 LARGE_INTEGER offset_li;
116 offset_li.QuadPart = offset;
117
118 OVERLAPPED overlapped = {0};
119 overlapped.Offset = offset_li.LowPart;
120 overlapped.OffsetHigh = offset_li.HighPart;
121
122 DWORD bytes_written;
123 if (::WriteFile(file_.Get(), data, size, &bytes_written, &overlapped))
124 return bytes_written;
125
126 return -1;
127 }
128
129 int File::WriteAtCurrentPos(const char* data, int size) {
130 ThreadRestrictions::AssertIOAllowed();
131 DCHECK(IsValid());
132 DCHECK(!async_);
133 if (size < 0)
134 return -1;
135
136 SCOPED_FILE_TRACE_WITH_SIZE("WriteAtCurrentPos", size);
137
138 DWORD bytes_written;
139 if (::WriteFile(file_.Get(), data, size, &bytes_written, NULL))
140 return bytes_written;
141
142 return -1;
143 }
144
145 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) {
146 return WriteAtCurrentPos(data, size);
147 }
148
149 int64 File::GetLength() {
150 ThreadRestrictions::AssertIOAllowed();
151 DCHECK(IsValid());
152
153 SCOPED_FILE_TRACE("GetLength");
154
155 LARGE_INTEGER size;
156 if (!::GetFileSizeEx(file_.Get(), &size))
157 return -1;
158
159 return static_cast<int64>(size.QuadPart);
160 }
161
162 bool File::SetLength(int64 length) {
163 ThreadRestrictions::AssertIOAllowed();
164 DCHECK(IsValid());
165
166 SCOPED_FILE_TRACE_WITH_SIZE("SetLength", length);
167
168 // Get the current file pointer.
169 LARGE_INTEGER file_pointer;
170 LARGE_INTEGER zero;
171 zero.QuadPart = 0;
172 if (!::SetFilePointerEx(file_.Get(), zero, &file_pointer, FILE_CURRENT))
173 return false;
174
175 LARGE_INTEGER length_li;
176 length_li.QuadPart = length;
177 // If length > file size, SetFilePointerEx() should extend the file
178 // with zeroes on all Windows standard file systems (NTFS, FATxx).
179 if (!::SetFilePointerEx(file_.Get(), length_li, NULL, FILE_BEGIN))
180 return false;
181
182 // Set the new file length and move the file pointer to its old position.
183 // This is consistent with ftruncate()'s behavior, even when the file
184 // pointer points to a location beyond the end of the file.
185 // TODO(rvargas): Emulating ftruncate details seem suspicious and it is not
186 // promised by the interface (nor was promised by PlatformFile). See if this
187 // implementation detail can be removed.
188 return ((::SetEndOfFile(file_.Get()) != FALSE) &&
189 (::SetFilePointerEx(file_.Get(), file_pointer, NULL, FILE_BEGIN) !=
190 FALSE));
191 }
192
193 bool File::SetTimes(Time last_access_time, Time last_modified_time) {
194 ThreadRestrictions::AssertIOAllowed();
195 DCHECK(IsValid());
196
197 SCOPED_FILE_TRACE("SetTimes");
198
199 FILETIME last_access_filetime = last_access_time.ToFileTime();
200 FILETIME last_modified_filetime = last_modified_time.ToFileTime();
201 return (::SetFileTime(file_.Get(), NULL, &last_access_filetime,
202 &last_modified_filetime) != FALSE);
203 }
204
205 bool File::GetInfo(Info* info) {
206 ThreadRestrictions::AssertIOAllowed();
207 DCHECK(IsValid());
208
209 SCOPED_FILE_TRACE("GetInfo");
210
211 BY_HANDLE_FILE_INFORMATION file_info;
212 if (!GetFileInformationByHandle(file_.Get(), &file_info))
213 return false;
214
215 LARGE_INTEGER size;
216 size.HighPart = file_info.nFileSizeHigh;
217 size.LowPart = file_info.nFileSizeLow;
218 info->size = size.QuadPart;
219 info->is_directory =
220 (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
221 info->is_symbolic_link = false; // Windows doesn't have symbolic links.
222 info->last_modified = Time::FromFileTime(file_info.ftLastWriteTime);
223 info->last_accessed = Time::FromFileTime(file_info.ftLastAccessTime);
224 info->creation_time = Time::FromFileTime(file_info.ftCreationTime);
225 return true;
226 }
227
228 File::Error File::Lock() {
229 DCHECK(IsValid());
230
231 SCOPED_FILE_TRACE("Lock");
232
233 BOOL result = LockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD);
234 if (!result)
235 return OSErrorToFileError(GetLastError());
236 return FILE_OK;
237 }
238
239 File::Error File::Unlock() {
240 DCHECK(IsValid());
241
242 SCOPED_FILE_TRACE("Unlock");
243
244 BOOL result = UnlockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD);
245 if (!result)
246 return OSErrorToFileError(GetLastError());
247 return FILE_OK;
248 }
249
250 File File::Duplicate() {
251 if (!IsValid())
252 return File();
253
254 SCOPED_FILE_TRACE("Duplicate");
255
256 HANDLE other_handle = nullptr;
257
258 if (!::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle
259 GetPlatformFile(),
260 GetCurrentProcess(), // hTargetProcessHandle
261 &other_handle,
262 0, // dwDesiredAccess ignored due to SAME_ACCESS
263 FALSE, // !bInheritHandle
264 DUPLICATE_SAME_ACCESS)) {
265 return File(OSErrorToFileError(GetLastError()));
266 }
267
268 File other(other_handle);
269 if (async())
270 other.async_ = true;
271 return other.Pass();
272 }
273
274 // Static.
275 File::Error File::OSErrorToFileError(DWORD last_error) {
276 switch (last_error) {
277 case ERROR_SHARING_VIOLATION:
278 return FILE_ERROR_IN_USE;
279 case ERROR_FILE_EXISTS:
280 return FILE_ERROR_EXISTS;
281 case ERROR_FILE_NOT_FOUND:
282 case ERROR_PATH_NOT_FOUND:
283 return FILE_ERROR_NOT_FOUND;
284 case ERROR_ACCESS_DENIED:
285 return FILE_ERROR_ACCESS_DENIED;
286 case ERROR_TOO_MANY_OPEN_FILES:
287 return FILE_ERROR_TOO_MANY_OPENED;
288 case ERROR_OUTOFMEMORY:
289 case ERROR_NOT_ENOUGH_MEMORY:
290 return FILE_ERROR_NO_MEMORY;
291 case ERROR_HANDLE_DISK_FULL:
292 case ERROR_DISK_FULL:
293 case ERROR_DISK_RESOURCES_EXHAUSTED:
294 return FILE_ERROR_NO_SPACE;
295 case ERROR_USER_MAPPED_FILE:
296 return FILE_ERROR_INVALID_OPERATION;
297 case ERROR_NOT_READY:
298 case ERROR_SECTOR_NOT_FOUND:
299 case ERROR_DEV_NOT_EXIST:
300 case ERROR_IO_DEVICE:
301 case ERROR_FILE_CORRUPT:
302 case ERROR_DISK_CORRUPT:
303 return FILE_ERROR_IO;
304 default:
305 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Windows",
306 last_error);
307 return FILE_ERROR_FAILED;
308 }
309 }
310
311 void File::DoInitialize(uint32 flags) {
312 ThreadRestrictions::AssertIOAllowed();
313 DCHECK(!IsValid());
314
315 DWORD disposition = 0;
316
317 if (flags & FLAG_OPEN)
318 disposition = OPEN_EXISTING;
319
320 if (flags & FLAG_CREATE) {
321 DCHECK(!disposition);
322 disposition = CREATE_NEW;
323 }
324
325 if (flags & FLAG_OPEN_ALWAYS) {
326 DCHECK(!disposition);
327 disposition = OPEN_ALWAYS;
328 }
329
330 if (flags & FLAG_CREATE_ALWAYS) {
331 DCHECK(!disposition);
332 DCHECK(flags & FLAG_WRITE);
333 disposition = CREATE_ALWAYS;
334 }
335
336 if (flags & FLAG_OPEN_TRUNCATED) {
337 DCHECK(!disposition);
338 DCHECK(flags & FLAG_WRITE);
339 disposition = TRUNCATE_EXISTING;
340 }
341
342 if (!disposition) {
343 NOTREACHED();
344 return;
345 }
346
347 DWORD access = 0;
348 if (flags & FLAG_WRITE)
349 access = GENERIC_WRITE;
350 if (flags & FLAG_APPEND) {
351 DCHECK(!access);
352 access = FILE_APPEND_DATA;
353 }
354 if (flags & FLAG_READ)
355 access |= GENERIC_READ;
356 if (flags & FLAG_WRITE_ATTRIBUTES)
357 access |= FILE_WRITE_ATTRIBUTES;
358 if (flags & FLAG_EXECUTE)
359 access |= GENERIC_EXECUTE;
360
361 DWORD sharing = (flags & FLAG_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ;
362 if (!(flags & FLAG_EXCLUSIVE_WRITE))
363 sharing |= FILE_SHARE_WRITE;
364 if (flags & FLAG_SHARE_DELETE)
365 sharing |= FILE_SHARE_DELETE;
366
367 DWORD create_flags = 0;
368 if (flags & FLAG_ASYNC)
369 create_flags |= FILE_FLAG_OVERLAPPED;
370 if (flags & FLAG_TEMPORARY)
371 create_flags |= FILE_ATTRIBUTE_TEMPORARY;
372 if (flags & FLAG_HIDDEN)
373 create_flags |= FILE_ATTRIBUTE_HIDDEN;
374 if (flags & FLAG_DELETE_ON_CLOSE)
375 create_flags |= FILE_FLAG_DELETE_ON_CLOSE;
376 if (flags & FLAG_BACKUP_SEMANTICS)
377 create_flags |= FILE_FLAG_BACKUP_SEMANTICS;
378
379 file_.Set(CreateFile(path_.value().c_str(), access, sharing, NULL,
380 disposition, create_flags, NULL));
381
382 if (file_.IsValid()) {
383 error_details_ = FILE_OK;
384 async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
385
386 if (flags & (FLAG_OPEN_ALWAYS))
387 created_ = (ERROR_ALREADY_EXISTS != GetLastError());
388 else if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE))
389 created_ = true;
390 } else {
391 error_details_ = OSErrorToFileError(GetLastError());
392 }
393 }
394
395 bool File::DoFlush() {
396 ThreadRestrictions::AssertIOAllowed();
397 DCHECK(IsValid());
398 return ::FlushFileBuffers(file_.Get()) != FALSE;
399 }
400
401 void File::SetPlatformFile(PlatformFile file) {
402 file_.Set(file);
403 }
404
405 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_util_win.cc ('k') | base/files/memory_mapped_file.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698