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

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: Fix memory leak. Improve OS error for Link.target of a non-link. 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 buffer_size =
299 sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR;
300 REPARSE_DATA_BUFFER* buffer =
301 static_cast<REPARSE_DATA_BUFFER*>(calloc(buffer_size, 1));
302 DWORD received_bytes; // Value is not used.
303 int result = DeviceIoControl(
304 dir_handle,
305 FSCTL_GET_REPARSE_POINT,
306 NULL,
307 0,
308 buffer,
309 buffer_size,
310 &received_bytes,
311 NULL);
312 if (result == 0) {
313 DWORD error = GetLastError();
314 CloseHandle(dir_handle);
315 free(buffer);
316 SetLastError(error);
317 return NULL;
318 }
319 if (CloseHandle(dir_handle) == 0) {
320 DWORD error = GetLastError();
Bill Hesse 2013/03/18 16:13:27 Trying to combine the two error cases here gets ug
321 free(buffer);
322 SetLastError(error);
323 return NULL;
324 }
325
326 wchar_t* target;
327 size_t target_offset;
328 size_t target_length;
329 if (buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
330 target = buffer->MountPointReparseBuffer.PathBuffer;
331 target_offset = buffer->MountPointReparseBuffer.SubstituteNameOffset;
332 target_length = buffer->MountPointReparseBuffer.SubstituteNameLength;
333 } else if (buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
334 target = buffer->SymbolicLinkReparseBuffer.PathBuffer;
335 target_offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset;
336 target_length = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
337 } else { // Not a junction or a symbolic link.
338 free(buffer);
339 SetLastError(ERROR_NOT_A_REPARSE_POINT);
340 return NULL;
341 }
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.
Søren Gjesse 2013/03/19 09:40:29 Don't you mean \\?\ here?
Bill Hesse 2013/03/19 10:34:03 No, I really mean \??\. This is what is used in j
347 if (target_length > 4 && wcsncmp(L"\\??\\", target, 4) == 0) {
Søren Gjesse 2013/03/19 09:40:29 L"\\\\?\\"
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(buffer);
370 free(utf8_target);
371 SetLastError(error);
372 return NULL;
373 }
374 utf8_target[utf8_length] = '\0';
375 free(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