| Index: runtime/bin/file_win.cc
|
| diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
|
| index 08417ea9ac03220bc7d83a648c42ef3a9b7f8260..e7cedb47b43804fa374db09df31a80e42b9e3319 100644
|
| --- a/runtime/bin/file_win.cc
|
| +++ b/runtime/bin/file_win.cc
|
| @@ -471,20 +471,50 @@ bool File::IsAbsolutePath(const char* pathname) {
|
| char* File::GetCanonicalPath(const char* pathname) {
|
| struct _stat st;
|
| const wchar_t* system_name = StringUtils::Utf8ToWide(pathname);
|
| - int stat_status = _wstat(system_name, &st);
|
| - if (stat_status != 0) {
|
| - SetLastError(ERROR_FILE_NOT_FOUND);
|
| + HANDLE file_handle = CreateFileW(
|
| + system_name,
|
| + 0,
|
| + FILE_SHARE_READ,
|
| + NULL,
|
| + OPEN_EXISTING,
|
| + FILE_FLAG_BACKUP_SEMANTICS,
|
| + NULL);
|
| + if (file_handle == INVALID_HANDLE_VALUE) {
|
| free(const_cast<wchar_t*>(system_name));
|
| return NULL;
|
| }
|
| - int required_size = GetFullPathNameW(system_name, 0, NULL, NULL);
|
| + wchar_t dummy_buffer[1];
|
| + int required_size = GetFinalPathNameByHandle(file_handle,
|
| + dummy_buffer,
|
| + 0,
|
| + VOLUME_NAME_DOS);
|
| + if (required_size == 0) {
|
| + free(const_cast<wchar_t*>(system_name));
|
| + DWORD error = GetLastError();
|
| + CloseHandle(file_handle);
|
| + SetLastError(error);
|
| + return NULL;
|
| + }
|
| wchar_t* path =
|
| static_cast<wchar_t*>(malloc(required_size * sizeof(wchar_t)));
|
| - int written = GetFullPathNameW(system_name, required_size, path, NULL);
|
| + int result_size = GetFinalPathNameByHandle(file_handle,
|
| + path,
|
| + required_size,
|
| + VOLUME_NAME_DOS);
|
| + ASSERT(result_size <= required_size - 1);
|
| + // Remove leading \\?\ if possible, unless input used it.
|
| + char* result;
|
| + if (result_size < MAX_PATH - 1 + 4 &&
|
| + result_size > 4 &&
|
| + wcsncmp(path, L"\\\\?\\", 4) == 0 &&
|
| + wcsncmp(system_name, L"\\\\?\\", 4) != 0) {
|
| + result = StringUtils::WideToUtf8(path + 4);
|
| + } else {
|
| + result = StringUtils::WideToUtf8(path);
|
| + }
|
| free(const_cast<wchar_t*>(system_name));
|
| - ASSERT(written <= (required_size - 1));
|
| - char* result = StringUtils::WideToUtf8(path);
|
| free(path);
|
| + CloseHandle(file_handle);
|
| return result;
|
| }
|
|
|
|
|