blob: 13983977de48453e2ee8f0ac41c910053b1404d7 [file] [log] [blame]
[email protected]21da6eb2008-11-03 17:18:141// 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.
4
5#include "base/platform_file.h"
6
[email protected]f294da72009-10-12 21:39:377#include "base/file_path.h"
[email protected]21da6eb2008-11-03 17:18:148#include "base/logging.h"
[email protected]45446a52010-11-04 17:41:009#include "base/thread_restrictions.h"
[email protected]21da6eb2008-11-03 17:18:1410
11namespace base {
12
[email protected]f294da72009-10-12 21:39:3713PlatformFile CreatePlatformFile(const FilePath& name,
[email protected]21da6eb2008-11-03 17:18:1414 int flags,
[email protected]ed65fec2010-08-31 19:30:2715 bool* created,
16 PlatformFileError* error_code) {
[email protected]45446a52010-11-04 17:41:0017 base::ThreadRestrictions::AssertIOAllowed();
18
[email protected]21da6eb2008-11-03 17:18:1419 DWORD disposition = 0;
20
21 if (flags & PLATFORM_FILE_OPEN)
22 disposition = OPEN_EXISTING;
23
24 if (flags & PLATFORM_FILE_CREATE) {
25 DCHECK(!disposition);
26 disposition = CREATE_NEW;
27 }
28
29 if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
30 DCHECK(!disposition);
31 disposition = OPEN_ALWAYS;
32 }
33
34 if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
35 DCHECK(!disposition);
36 disposition = CREATE_ALWAYS;
37 }
38
[email protected]ed65fec2010-08-31 19:30:2739 if (flags & PLATFORM_FILE_TRUNCATE) {
40 DCHECK(!disposition);
41 DCHECK(flags & PLATFORM_FILE_WRITE);
42 disposition = TRUNCATE_EXISTING;
43 }
44
[email protected]21da6eb2008-11-03 17:18:1445 if (!disposition) {
46 NOTREACHED();
47 return NULL;
48 }
49
50 DWORD access = (flags & PLATFORM_FILE_READ) ? GENERIC_READ : 0;
51 if (flags & PLATFORM_FILE_WRITE)
52 access |= GENERIC_WRITE;
[email protected]507fb9a2010-09-23 23:28:2253 if (flags & PLATFORM_FILE_WRITE_ATTRIBUTES)
54 access |= FILE_WRITE_ATTRIBUTES;
[email protected]21da6eb2008-11-03 17:18:1455
56 DWORD sharing = (flags & PLATFORM_FILE_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ;
57 if (!(flags & PLATFORM_FILE_EXCLUSIVE_WRITE))
58 sharing |= FILE_SHARE_WRITE;
59
60 DWORD create_flags = 0;
61 if (flags & PLATFORM_FILE_ASYNC)
62 create_flags |= FILE_FLAG_OVERLAPPED;
[email protected]017022b2009-07-27 23:06:3463 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;
[email protected]21da6eb2008-11-03 17:18:1469
[email protected]f294da72009-10-12 21:39:3770 HANDLE file = CreateFile(name.value().c_str(), access, sharing, NULL,
71 disposition, create_flags, NULL);
[email protected]21da6eb2008-11-03 17:18:1472
[email protected]3fb43ed12010-09-10 03:01:1473 if (created && (INVALID_HANDLE_VALUE != file)) {
[email protected]fd55c282010-10-15 00:37:3474 if (flags & (PLATFORM_FILE_OPEN_ALWAYS))
[email protected]3fb43ed12010-09-10 03:01:1475 *created = (ERROR_ALREADY_EXISTS != GetLastError());
[email protected]fd55c282010-10-15 00:37:3476 else if (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE))
[email protected]3fb43ed12010-09-10 03:01:1477 *created = true;
[email protected]21da6eb2008-11-03 17:18:1478 }
79
[email protected]3fb43ed12010-09-10 03:01:1480 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;
100 }
[email protected]ed65fec2010-08-31 19:30:27101 }
102 }
103
[email protected]21da6eb2008-11-03 17:18:14104 return file;
105}
106
[email protected]f294da72009-10-12 21:39:37107PlatformFile CreatePlatformFile(const std::wstring& name, int flags,
108 bool* created) {
[email protected]ed65fec2010-08-31 19:30:27109 return CreatePlatformFile(FilePath::FromWStringHack(name), flags,
110 created, NULL);
[email protected]f294da72009-10-12 21:39:37111}
112
[email protected]ee8d4c82009-08-28 21:58:28113bool ClosePlatformFile(PlatformFile file) {
[email protected]45446a52010-11-04 17:41:00114 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14115 return (CloseHandle(file) != 0);
116}
117
118int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
[email protected]45446a52010-11-04 17:41:00119 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14120 if (file == kInvalidPlatformFileValue)
121 return -1;
122
123 LARGE_INTEGER offset_li;
124 offset_li.QuadPart = offset;
125
126 OVERLAPPED overlapped = {0};
127 overlapped.Offset = offset_li.LowPart;
128 overlapped.OffsetHigh = offset_li.HighPart;
129
130 DWORD bytes_read;
131 if (::ReadFile(file, data, size, &bytes_read, &overlapped) != 0)
132 return bytes_read;
133 else if (ERROR_HANDLE_EOF == GetLastError())
134 return 0;
135
136 return -1;
137}
138
139int WritePlatformFile(PlatformFile file, int64 offset,
140 const char* data, int size) {
[email protected]45446a52010-11-04 17:41:00141 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14142 if (file == kInvalidPlatformFileValue)
143 return -1;
144
145 LARGE_INTEGER offset_li;
146 offset_li.QuadPart = offset;
147
148 OVERLAPPED overlapped = {0};
149 overlapped.Offset = offset_li.LowPart;
150 overlapped.OffsetHigh = offset_li.HighPart;
151
152 DWORD bytes_written;
153 if (::WriteFile(file, data, size, &bytes_written, &overlapped) != 0)
154 return bytes_written;
155
156 return -1;
157}
158
159bool TruncatePlatformFile(PlatformFile file, int64 length) {
[email protected]45446a52010-11-04 17:41:00160 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14161 if (file == kInvalidPlatformFileValue)
162 return false;
163
164 // Get the current file pointer.
165 LARGE_INTEGER file_pointer;
166 LARGE_INTEGER zero;
167 zero.QuadPart = 0;
168 if (::SetFilePointerEx(file, zero, &file_pointer, FILE_CURRENT) == 0)
169 return false;
170
171 LARGE_INTEGER length_li;
172 length_li.QuadPart = length;
173 // If length > file size, SetFilePointerEx() should extend the file
174 // with zeroes on all Windows standard file systems (NTFS, FATxx).
175 if (!::SetFilePointerEx(file, length_li, NULL, FILE_BEGIN))
176 return false;
177
178 // Set the new file length and move the file pointer to its old position.
179 // This is consistent with ftruncate()'s behavior, even when the file
180 // pointer points to a location beyond the end of the file.
181 return ((::SetEndOfFile(file) != 0) &&
182 (::SetFilePointerEx(file, file_pointer, NULL, FILE_BEGIN) != 0));
183}
184
185bool FlushPlatformFile(PlatformFile file) {
[email protected]45446a52010-11-04 17:41:00186 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14187 return ((file != kInvalidPlatformFileValue) && ::FlushFileBuffers(file));
188}
189
190bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
191 const base::Time& last_modified_time) {
[email protected]45446a52010-11-04 17:41:00192 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14193 if (file == kInvalidPlatformFileValue)
194 return false;
195
196 FILETIME last_access_filetime = last_access_time.ToFileTime();
197 FILETIME last_modified_filetime = last_modified_time.ToFileTime();
198 return (::SetFileTime(file, NULL, &last_access_filetime,
199 &last_modified_filetime) != 0);
200}
201
202bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
[email protected]45446a52010-11-04 17:41:00203 base::ThreadRestrictions::AssertIOAllowed();
[email protected]3fb43ed12010-09-10 03:01:14204 if (!info)
205 return false;
206
207 BY_HANDLE_FILE_INFORMATION file_info;
208 if (GetFileInformationByHandle(file, &file_info) == 0)
209 return false;
210
211 LARGE_INTEGER size;
212 size.HighPart = file_info.nFileSizeHigh;
213 size.LowPart = file_info.nFileSizeLow;
214 info->size = size.QuadPart;
215 info->is_directory =
216 file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
[email protected]2e733d102010-11-30 00:43:37217 info->is_symbolic_link = false; // Windows doesn't have symbolic links.
[email protected]3fb43ed12010-09-10 03:01:14218 info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime);
219 info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime);
220 info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime);
221 return true;
[email protected]ee8d4c82009-08-28 21:58:28222}
223
[email protected]21da6eb2008-11-03 17:18:14224} // namespace disk_cache