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

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

Issue 12812010: dart:io | Add Link.targetSync on all platforms. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Improve error handling on Windows. 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
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 ULONG ReparseTag; 160 ULONG ReparseTag;
161 USHORT ReparseDataLength; 161 USHORT ReparseDataLength;
162 USHORT Reserved; 162 USHORT Reserved;
163 163
164 union { 164 union {
165 struct { 165 struct {
166 USHORT SubstituteNameOffset; 166 USHORT SubstituteNameOffset;
167 USHORT SubstituteNameLength; 167 USHORT SubstituteNameLength;
168 USHORT PrintNameOffset; 168 USHORT PrintNameOffset;
169 USHORT PrintNameLength; 169 USHORT PrintNameLength;
170 ULONG Flags;
170 WCHAR PathBuffer[1]; 171 WCHAR PathBuffer[1];
171 } SymbolicLinkReparseBuffer; 172 } SymbolicLinkReparseBuffer;
172 173
173 struct { 174 struct {
174 USHORT SubstituteNameOffset; 175 USHORT SubstituteNameOffset;
175 USHORT SubstituteNameLength; 176 USHORT SubstituteNameLength;
176 USHORT PrintNameOffset; 177 USHORT PrintNameOffset;
177 USHORT PrintNameLength; 178 USHORT PrintNameLength;
178 WCHAR PathBuffer[1]; 179 WCHAR PathBuffer[1];
179 } MountPointReparseBuffer; 180 } MountPointReparseBuffer;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 273 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
273 int stat_status = _wstat(system_name, &st); 274 int stat_status = _wstat(system_name, &st);
274 free(const_cast<wchar_t*>(system_name)); 275 free(const_cast<wchar_t*>(system_name));
275 if (stat_status == 0) { 276 if (stat_status == 0) {
276 return st.st_size; 277 return st.st_size;
277 } 278 }
278 return -1; 279 return -1;
279 } 280 }
280 281
281 282
283 char* File::LinkTarget(const char* pathname) {
284 const wchar_t* name = StringUtils::Utf8ToWide(pathname);
285 HANDLE dir_handle = CreateFileW(
286 name,
287 GENERIC_READ,
288 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
289 NULL,
290 OPEN_EXISTING,
291 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
292 NULL);
293 free(const_cast<wchar_t*>(name));
294 if (dir_handle == INVALID_HANDLE_VALUE) {
295 return NULL;
296 }
297
298 int reparse_data_buffer_size =
299 sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR;
300 REPARSE_DATA_BUFFER* reparse_data_buffer =
301 static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
302 DWORD received_bytes;
303 int result = DeviceIoControl(
304 dir_handle,
305 FSCTL_GET_REPARSE_POINT,
306 NULL,
307 0,
308 reparse_data_buffer,
309 reparse_data_buffer_size,
310 &received_bytes,
311 NULL);
312 if (result == 0) {
313 DWORD error = GetLastError();
Bill Hesse 2013/03/18 16:13:27 This code occurs, slightly differently, 4 times, b
314 CloseHandle(dir_handle); // Might reset the error.
315 SetLastError(error);
316 return NULL;
317 }
318 if (CloseHandle(dir_handle) == 0) return NULL;
319 bool junction =
320 reparse_data_buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT;
321 bool symlink = reparse_data_buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK;
322 if (!junction && !symlink) {
323 SetLastError(ERROR_NOT_A_REPARSE_POINT);
324 return NULL;
325 }
326 wchar_t* target;
327 size_t target_offset;
328 size_t target_length;
329 if (junction) {
330 target = reparse_data_buffer->MountPointReparseBuffer.PathBuffer;
331 target_offset =
332 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset;
333 target_length =
334 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength;
335 }
336 if (symlink) {
337 target = reparse_data_buffer->SymbolicLinkReparseBuffer.PathBuffer;
338 target_offset =
339 reparse_data_buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset;
340 target_length =
341 reparse_data_buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
342 }
343 target_offset /= sizeof(wchar_t); // Offset and length are in bytes.
344 target_length /= sizeof(wchar_t);
345 target += target_offset;
346 // Remove "\??\" from beginning of target.
347 if (target_length > 4 && wcsncmp(L"\\??\\", target, 4) == 0) {
348 target += 4;
349 target_length -=4;
350 }
351 int utf8_length = WideCharToMultiByte(CP_UTF8,
352 0,
353 target,
354 target_length,
355 NULL,
356 0,
357 NULL,
358 NULL);
359 char* utf8_target = reinterpret_cast<char*>(malloc(utf8_length + 1));
360 if (0 == WideCharToMultiByte(CP_UTF8,
361 0,
362 target,
363 target_length,
364 utf8_target,
365 utf8_length,
366 NULL,
367 NULL)) {
368 DWORD error = GetLastError();
369 free(reparse_data_buffer);
370 free(utf8_target);
371 SetLastError(error);
372 return NULL;
373 }
374 utf8_target[utf8_length] = '\0';
375 free(reparse_data_buffer);
376 return utf8_target;
377 }
378
379
282 time_t File::LastModified(const char* name) { 380 time_t File::LastModified(const char* name) {
283 struct _stat st; 381 struct _stat st;
284 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 382 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
285 int stat_status = _wstat(system_name, &st); 383 int stat_status = _wstat(system_name, &st);
286 free(const_cast<wchar_t*>(system_name)); 384 free(const_cast<wchar_t*>(system_name));
287 if (stat_status == 0) { 385 if (stat_status == 0) {
288 return st.st_mtime; 386 return st.st_mtime;
289 } 387 }
290 return -1; 388 return -1;
291 } 389 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 508 }
411 } 509 }
412 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 510 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
413 return File::kIsDirectory; 511 return File::kIsDirectory;
414 } else { 512 } else {
415 return File::kIsFile; 513 return File::kIsFile;
416 } 514 }
417 } 515 }
418 516
419 #endif // defined(TARGET_OS_WINDOWS) 517 #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