| 217 | #ifdef _WIN32 |
| 218 | |
| 219 | bool FileSystem::GetWin32Path(std::wstring* dest, std::string_view str) |
| 220 | { |
| 221 | // Just convert to wide if it's a relative path, MAX_PATH still applies. |
| 222 | if (!Path::IsAbsolute(str)) |
| 223 | return StringUtil::UTF8StringToWideString(*dest, str); |
| 224 | |
| 225 | // PathCchCanonicalizeEx() thankfully takes care of everything. |
| 226 | // But need to widen the string first, avoid the stack allocation. |
| 227 | int wlen = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.length()), nullptr, 0); |
| 228 | if (wlen <= 0) [[unlikely]] |
| 229 | return false; |
| 230 | |
| 231 | // So copy it to a temp wide buffer first. |
| 232 | wchar_t* wstr_buf = static_cast<wchar_t*>(_malloca(sizeof(wchar_t) * (static_cast<size_t>(wlen) + 1))); |
| 233 | wlen = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.length()), wstr_buf, wlen); |
| 234 | if (wlen <= 0) [[unlikely]] |
| 235 | { |
| 236 | _freea(wstr_buf); |
| 237 | return false; |
| 238 | } |
| 239 | |
| 240 | // And use PathCchCanonicalizeEx() to fix up any non-direct elements. |
| 241 | wstr_buf[wlen] = '\0'; |
| 242 | dest->resize(std::max<size_t>(static_cast<size_t>(wlen) + (IsUNCPath(str) ? 9 : 5), 16)); |
| 243 | for (;;) |
| 244 | { |
| 245 | const HRESULT hr = |
| 246 | PathCchCanonicalizeEx(dest->data(), dest->size(), wstr_buf, PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH); |
| 247 | if (SUCCEEDED(hr)) |
| 248 | { |
| 249 | dest->resize(std::wcslen(dest->data())); |
| 250 | _freea(wstr_buf); |
| 251 | return true; |
| 252 | } |
| 253 | else if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) |
| 254 | { |
| 255 | dest->resize(dest->size() * 2); |
| 256 | continue; |
| 257 | } |
| 258 | else [[unlikely]] |
| 259 | { |
| 260 | Console.ErrorFmt("PathCchCanonicalizeEx() returned {:08X}", static_cast<unsigned>(hr)); |
| 261 | _freea(wstr_buf); |
| 262 | return false; |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | std::wstring FileSystem::GetWin32Path(std::string_view str) |
| 268 | { |