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

Side by Side Diff: runtime/bin/file_win.cc

Issue 12691002: dart:io | Add Link class, as sibling to File and Directory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix Windows errors Created 7 years, 9 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_WINDOWS) 6 #if defined(TARGET_OS_WINDOWS)
7 7
8 #include "bin/file.h" 8 #include "bin/file.h"
9 9
10 #include <fcntl.h> // NOLINT 10 #include <fcntl.h> // NOLINT
11 #include <io.h> // NOLINT 11 #include <io.h> // NOLINT
12 #include <stdio.h> // NOLINT 12 #include <stdio.h> // NOLINT
13 #include <string.h> // NOLINT 13 #include <string.h> // NOLINT
14 #include <sys/stat.h> // NOLINT 14 #include <sys/stat.h> // NOLINT
15 #include <WinIoCtl.h> // NOLINT
15 16
16 #include "bin/builtin.h" 17 #include "bin/builtin.h"
17 #include "bin/log.h" 18 #include "bin/log.h"
18 19
19 class FileHandle { 20 class FileHandle {
20 public: 21 public:
21 explicit FileHandle(int fd) : fd_(fd) { } 22 explicit FileHandle(int fd) : fd_(fd) { }
22 ~FileHandle() { } 23 ~FileHandle() { }
23 int fd() const { return fd_; } 24 int fd() const { return fd_; }
24 void set_fd(int fd) { fd_ = fd; } 25 void set_fd(int fd) { fd_ = fd; }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 148 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
148 int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666); 149 int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666);
149 free(const_cast<wchar_t*>(system_name)); 150 free(const_cast<wchar_t*>(system_name));
150 if (fd < 0) { 151 if (fd < 0) {
151 return false; 152 return false;
152 } 153 }
153 return (close(fd) == 0); 154 return (close(fd) == 0);
154 } 155 }
155 156
156 157
158 // This structure is needed for creating and reading Junctions.
159 typedef struct _REPARSE_DATA_BUFFER {
160 ULONG ReparseTag;
161 USHORT ReparseDataLength;
162 USHORT Reserved;
163
164 union {
165 struct {
166 USHORT SubstituteNameOffset;
167 USHORT SubstituteNameLength;
168 USHORT PrintNameOffset;
169 USHORT PrintNameLength;
170 WCHAR PathBuffer[1];
171 } SymbolicLinkReparseBuffer;
172
173 struct {
174 USHORT SubstituteNameOffset;
175 USHORT SubstituteNameLength;
176 USHORT PrintNameOffset;
177 USHORT PrintNameLength;
178 WCHAR PathBuffer[1];
179 } MountPointReparseBuffer;
180
181 struct {
182 UCHAR DataBuffer[1];
183 } GenericReparseBuffer;
184 };
185 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
186
187
188 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT;
189 static const int kMountPointHeaderSize = 4 * sizeof USHORT;
190
191
192 bool File::CreateLink(const char* utf8_name, const char* utf8_target) {
193 const wchar_t* name = StringUtils::Utf8ToWide(utf8_name);
194 int create_status = CreateDirectoryW(name, NULL);
195 // If the directory already existed, treat it as a success.
196 if (create_status == 0 &&
197 (GetLastError() != ERROR_ALREADY_EXISTS ||
198 (GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
199 free(const_cast<wchar_t*>(name));
200 return false;
201 }
202
203 HANDLE dir_handle = CreateFileW(
204 name,
205 GENERIC_READ | GENERIC_WRITE,
206 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
207 NULL,
208 OPEN_EXISTING,
209 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
210 NULL);
211 free(const_cast<wchar_t*>(name));
212 if (dir_handle == INVALID_HANDLE_VALUE) {
213 return false;
214 }
215
216 const wchar_t* target = StringUtils::Utf8ToWide(utf8_target);
217 int target_len = wcslen(target);
218 if (target_len > MAX_PATH - 1) {
219 free(const_cast<wchar_t*>(target));
220 CloseHandle(dir_handle);
221 return false;
222 }
223
224 int reparse_data_buffer_size =
225 sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
226 REPARSE_DATA_BUFFER* reparse_data_buffer =
227 static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
228 reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
229 wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target);
230 wcscpy(
231 reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1,
232 target);
233 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
234 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength =
235 target_len * sizeof WCHAR;
236 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset =
237 (target_len + 1) * sizeof WCHAR;
238 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength =
239 target_len * sizeof WCHAR;
240 reparse_data_buffer->ReparseDataLength =
241 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize;
242 DWORD dummy_received_bytes;
243 int result = DeviceIoControl(
244 dir_handle,
245 FSCTL_SET_REPARSE_POINT,
246 reparse_data_buffer,
247 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize,
248 NULL,
249 0,
250 &dummy_received_bytes,
251 NULL);
252 if (CloseHandle(dir_handle) == 0) return false;
253 free(const_cast<wchar_t*>(target));
254 free(reparse_data_buffer);
255 return (result != 0);
256 }
257
258
157 bool File::Delete(const char* name) { 259 bool File::Delete(const char* name) {
158 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 260 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
159 int status = _wremove(system_name); 261 int status = _wremove(system_name);
160 free(const_cast<wchar_t*>(system_name)); 262 free(const_cast<wchar_t*>(system_name));
161 if (status == -1) { 263 if (status == -1) {
162 return false; 264 return false;
163 } 265 }
164 return true; 266 return true;
165 } 267 }
166 268
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 374
273 375
274 File::Type File::GetType(const char* pathname, bool follow_links) { 376 File::Type File::GetType(const char* pathname, bool follow_links) {
275 const wchar_t* name = StringUtils::Utf8ToWide(pathname); 377 const wchar_t* name = StringUtils::Utf8ToWide(pathname);
276 WIN32_FIND_DATAW file_data; 378 WIN32_FIND_DATAW file_data;
277 HANDLE find_handle = FindFirstFileW(name, &file_data); 379 HANDLE find_handle = FindFirstFileW(name, &file_data);
278 if (find_handle == INVALID_HANDLE_VALUE) { 380 if (find_handle == INVALID_HANDLE_VALUE) {
279 // TODO(whesse): Distinguish other errors from does not exist. 381 // TODO(whesse): Distinguish other errors from does not exist.
280 return File::kDoesNotExist; 382 return File::kDoesNotExist;
281 } 383 }
384 FindClose(find_handle);
282 DWORD attributes = file_data.dwFileAttributes; 385 DWORD attributes = file_data.dwFileAttributes;
283 if (!follow_links && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { 386 if (!follow_links && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
284 DWORD reparse_tag = file_data.dwReserved0; 387 DWORD reparse_tag = file_data.dwReserved0;
285 if (reparse_tag == IO_REPARSE_TAG_SYMLINK || 388 if (reparse_tag == IO_REPARSE_TAG_SYMLINK ||
286 reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) { 389 reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) {
287 return File::kIsLink; 390 return File::kIsLink;
288 } else { 391 } else {
289 return File::kDoesNotExist; 392 return File::kDoesNotExist;
290 } 393 }
291 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 394 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
292 return File::kIsDirectory; 395 return File::kIsDirectory;
293 } else { 396 } else {
294 return File::kIsFile; 397 return File::kIsFile;
295 } 398 }
296 } 399 }
297 400
298 #endif // defined(TARGET_OS_WINDOWS) 401 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/file_patch.dart ('k') | sdk/lib/_internal/compiler/implementation/lib/io_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698