From a6a4bcc8fcd7cb928d4863d2887ab7e8d728f24c Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Fri, 1 May 2026 10:45:37 -0500 Subject: shell::Rename: report both rename + copy errors on fallback Cherry-picked the two surviving improvements from stale branch claude/fix-reported-issues-Iyt4s (issue #54). Rest of the branch's content (Starfield data dir, My Games spam fix) was already absorbed in main from a separate pass. - Rename copy fallback: previously dropped the original rename errno and returned generic ERROR_ACCESS_DENIED with no context. Now bubbles "Rename failed: %1. Copy fallback failed: %2" with both QFile::errorString() values so the log line actually identifies what went wrong. - formatSystemMessage: added an explicit comment block on why the codebase's Windows error macros (5=ACCESS_DENIED) must not be passed through strerror (5=EIO) on Linux. Co-Authored-By: Claude Opus 4.7 (1M context) --- libs/uibase/src/utility.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'libs') diff --git a/libs/uibase/src/utility.cpp b/libs/uibase/src/utility.cpp index 4304561..ddd96e2 100644 --- a/libs/uibase/src/utility.cpp +++ b/libs/uibase/src/utility.cpp @@ -563,17 +563,24 @@ namespace shell } #endif + const QString renameError = QString::fromStdString(ec.message()); + if (copyAllowed) { - if (QFile::copy(srcPath, destPath)) { + QFile copyFile(srcPath); + if (copyFile.copy(destPath)) { QFile::remove(srcPath); return Result::makeSuccess(); } + return Result::makeFailure( + ERROR_ACCESS_DENIED, + QObject::tr("Rename failed: %1. Copy fallback failed: %2") + .arg(renameError, copyFile.errorString())); } // Propagate the real errno text rather than a generic Windows code so the // log line actually reflects what failed. const int err = ec.value(); - QString msg = QString::fromStdString(ec.message()); + QString msg = renameError; if (msg.isEmpty()) { msg = QString("rename failed: errno=%1").arg(err); } @@ -1083,8 +1090,13 @@ std::wstring formatSystemMessage(DWORD id) std::wstring getMessage(DWORD id, HMODULE mod); return formatMessage(id, getMessage(id, 0)); #else - // On Linux, map common error codes to strings or use strerror for errno values - if (id == 0) { + // The codebase uses Windows error macros (ERROR_ACCESS_DENIED, etc.) as + // internal error representation. On Linux, strerror(id) would interpret + // these as POSIX errno values — which overlap numerically but mean + // completely different things (e.g. Windows error 5 = ACCESS_DENIED, + // Linux errno 5 = EIO). Map known Windows codes explicitly instead. + switch (id) { + case 0: // ERROR_SUCCESS return L"Success"; } -- cgit v1.3.1