diff --git a/Utilities/File.cpp b/Utilities/File.cpp index ce0e0096c1..cfbc615dbf 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -27,9 +27,15 @@ static std::unique_ptr to_wchar(const std::string& source) const int size = narrow(buf_size, "to_wchar" HERE); // Buffer for max possible output length - std::unique_ptr buffer(new wchar_t[buf_size]); + std::unique_ptr buffer(new wchar_t[buf_size + 4 + 32768]); - verify("to_wchar" HERE), MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get(), size); + // Prepend wide path prefix (4 characters) + std::memcpy(buffer.get() + 32768, L"\\\\\?\\", 4 * sizeof(wchar_t)); + + verify("to_wchar" HERE), MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get() + 32768 + 4, size); + + // Canonicalize wide path (replace '/', ".", "..", \\ repetitions, etc) + verify("to_wchar" HERE), GetFullPathNameW(buffer.get() + 32768, 32768, buffer.get(), nullptr) - 1 < 32768 - 1; return buffer; } @@ -486,7 +492,11 @@ bool fs::statfs(const std::string& path, fs::device_stat& info) ULARGE_INTEGER total_size; ULARGE_INTEGER total_free; - if (!GetDiskFreeSpaceExW(to_wchar(path).get(), &avail_free, &total_size, &total_free)) + // Get disk letter from path (TODO) + std::wstring disk(L"C:"); + disk[0] = path[0]; + + if (!GetDiskFreeSpaceExW(disk.c_str(), &avail_free, &total_size, &total_free)) { g_tls_error = to_error(GetLastError()); return false;