Chromium Code Reviews| Index: runtime/bin/file_win.cc |
| diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc |
| index b23049dce5bfc7241347d89db5fae8060409d6d5..295835bfa5692067ff684374f8a5bb78423fb8ff 100644 |
| --- a/runtime/bin/file_win.cc |
| +++ b/runtime/bin/file_win.cc |
| @@ -279,6 +279,52 @@ off_t File::LengthFromPath(const char* name) { |
| } |
| +char* File::LinkTarget(const char* pathname) { |
| + const wchar_t* name = StringUtils::Utf8ToWide(pathname); |
| + HANDLE dir_handle = CreateFileW( |
| + name, |
| + GENERIC_READ, |
| + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| + NULL, |
| + OPEN_EXISTING, |
| + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| + NULL); |
| + free(const_cast<wchar_t*>(name)); |
| + if (dir_handle == INVALID_HANDLE_VALUE) { |
| + return NULL; |
| + } |
| + |
| + int reparse_data_buffer_size = |
| + sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR; |
| + REPARSE_DATA_BUFFER* reparse_data_buffer = |
| + static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1)); |
| + DWORD received_bytes; |
| + int result = DeviceIoControl( |
| + dir_handle, |
| + FSCTL_GET_REPARSE_POINT, |
| + NULL, |
| + 0, |
| + reparse_data_buffer, |
| + reparse_data_buffer_size, |
| + &received_bytes, |
| + NULL); |
| + if (CloseHandle(dir_handle) == 0) return NULL; |
| + if (result == 0) return NULL; |
| + if (reparse_data_buffer->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT) { |
| + return NULL; |
| + } |
| + wchar_t* target = reparse_data_buffer->MountPointReparseBuffer.PathBuffer + |
| + reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset; |
| + size_t target_length = |
| + reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength; |
| + if (wcsncmp(L"\\??\\", target, 4) != 0) return NULL; |
| + target += 4; |
|
Bill Hesse
2013/03/18 09:05:54
We really need to copy the data out here, because
|
| + char* target_string = StringUtils::WideToUtf8(target); |
| + free(reparse_data_buffer); |
| + return target_string; |
| +} |
| + |
| + |
| time_t File::LastModified(const char* name) { |
| struct _stat st; |
| const wchar_t* system_name = StringUtils::Utf8ToWide(name); |