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

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 copying of target string 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 272 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
273 int stat_status = _wstat(system_name, &st); 273 int stat_status = _wstat(system_name, &st);
274 free(const_cast<wchar_t*>(system_name)); 274 free(const_cast<wchar_t*>(system_name));
275 if (stat_status == 0) { 275 if (stat_status == 0) {
276 return st.st_size; 276 return st.st_size;
277 } 277 }
278 return -1; 278 return -1;
279 } 279 }
280 280
281 281
282 char* File::LinkTarget(const char* pathname) {
283 const wchar_t* name = StringUtils::Utf8ToWide(pathname);
284 HANDLE dir_handle = CreateFileW(
285 name,
286 GENERIC_READ,
287 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
288 NULL,
289 OPEN_EXISTING,
290 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
291 NULL);
292 free(const_cast<wchar_t*>(name));
293 if (dir_handle == INVALID_HANDLE_VALUE) {
294 return NULL;
295 }
296
297 int reparse_data_buffer_size =
298 sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR;
299 REPARSE_DATA_BUFFER* reparse_data_buffer =
300 static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
301 DWORD received_bytes;
302 int result = DeviceIoControl(
303 dir_handle,
304 FSCTL_GET_REPARSE_POINT,
305 NULL,
306 0,
307 reparse_data_buffer,
308 reparse_data_buffer_size,
309 &received_bytes,
310 NULL);
311 if (CloseHandle(dir_handle) == 0) return NULL;
Søren Gjesse 2013/03/18 12:28:03 Here it seems like we are clearing the last error
Bill Hesse 2013/03/18 16:13:27 Yes. Fixed.
312 if (result == 0) return NULL;
313 if (reparse_data_buffer->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT) {
Søren Gjesse 2013/03/18 12:28:03 Here GetLastError will return NOERROR, so we get a
Bill Hesse 2013/03/18 16:13:27 Now we are returning Not a Reparse Point.
314 return NULL;
315 }
316 wchar_t* target = reparse_data_buffer->MountPointReparseBuffer.PathBuffer +
317 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset;
318 size_t target_length =
319 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength;
320 // Remove "\??\" from beginning of target.
321 if (target_length <= 4 || wcsncmp(L"\\??\\", target, 4) != 0) return NULL;
Søren Gjesse 2013/03/18 12:28:03 Ditto.
Bill Hesse 2013/03/18 16:13:27 Changed. Now, we just skip removing \??\ if it is
322 int utf8_length = WideCharToMultiByte(CP_UTF8,
Søren Gjesse 2013/03/18 12:28:03 Indentation.
323 0,
324 target + 4,
325 target_length - 4,
326 NULL,
327 0,
328 NULL,
329 NULL);
Søren Gjesse 2013/03/18 12:28:03 Can this call fail?
Bill Hesse 2013/03/18 16:13:27 If it fails, it returns 0, and the next call to it
330 char* utf8_target = reinterpret_cast<char*>(malloc(utf8_length + 1));
331 if (0 == WideCharToMultiByte(CP_UTF8,
332 0,
333 target + 4,
334 target_length - 4,
335 utf8_target,
336 utf8_length,
337 NULL,
338 NULL)) {
339 free(reparse_data_buffer);
340 free(utf8_target);
Søren Gjesse 2013/03/18 12:28:03 Set an error code?
Bill Hesse 2013/03/18 16:13:27 Done.
341 return NULL;
342 }
343 utf8_target[utf8_length] = '\0';
344 free(reparse_data_buffer);
345 return utf8_target;
346 }
347
348
282 time_t File::LastModified(const char* name) { 349 time_t File::LastModified(const char* name) {
283 struct _stat st; 350 struct _stat st;
284 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 351 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
285 int stat_status = _wstat(system_name, &st); 352 int stat_status = _wstat(system_name, &st);
286 free(const_cast<wchar_t*>(system_name)); 353 free(const_cast<wchar_t*>(system_name));
287 if (stat_status == 0) { 354 if (stat_status == 0) {
288 return st.st_mtime; 355 return st.st_mtime;
289 } 356 }
290 return -1; 357 return -1;
291 } 358 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 477 }
411 } 478 }
412 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 479 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
413 return File::kIsDirectory; 480 return File::kIsDirectory;
414 } else { 481 } else {
415 return File::kIsFile; 482 return File::kIsFile;
416 } 483 }
417 } 484 }
418 485
419 #endif // defined(TARGET_OS_WINDOWS) 486 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698