diff --git a/src/Dialogs.c b/src/Dialogs.c index 4af3205d2..4e2ea81be 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -475,12 +475,13 @@ LONG InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...) msgBox.uType = uType; msgBox.lpstrMessage = AllocMem((COUNTOF(wchMessage)+1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); - const PUINT_PTR argp = (PUINT_PTR)& uidMsg + 1; - if (argp && *argp) { - StringCchVPrintfW(msgBox.lpstrMessage, COUNTOF(wchMessage), wchMessage, (LPVOID)argp); - } else { - StringCchCopy(msgBox.lpstrMessage, COUNTOF(wchMessage), wchMessage); - } + // Use va_list (not the &uidMsg+1 stack-walk hack): on Windows ARM64 the first 8 + // varargs are in registers X0–X7, not at &uidMsg+1, so the old code read garbage and + // typically fell through to the no-args branch — leaving literal "%s" in the message. + va_list args; + va_start(args, uidMsg); + StringCchVPrintfW(msgBox.lpstrMessage, COUNTOF(wchMessage), wchMessage, args); + va_end(args); bool bLastError = false; switch (uidMsg) { diff --git a/src/MuiLanguage.c b/src/MuiLanguage.c index a93a13c2c..8d2b5529c 100644 --- a/src/MuiLanguage.c +++ b/src/MuiLanguage.c @@ -644,7 +644,12 @@ int FormatLngStringW(LPWSTR lpOutput, int nOutput, UINT uIdFormat, ...) WCHAR* const pBuffer = AllocMem(sizeof(WCHAR) * nOutput, HEAP_ZERO_MEMORY); if (pBuffer) { if (LoadLngStringW(uIdFormat, pBuffer, nOutput)) { - StringCchVPrintfW(lpOutput, nOutput, pBuffer, (LPVOID)((PUINT_PTR)& uIdFormat + 1)); + // va_list, not &uIdFormat+1 — the latter walks the stack and breaks on ARM64 + // where the first 8 varargs are in X0–X7 registers. + va_list args; + va_start(args, uIdFormat); + StringCchVPrintfW(lpOutput, nOutput, pBuffer, args); + va_end(args); } FreeMem(pBuffer); return (int)StringCchLen(lpOutput, nOutput); @@ -661,7 +666,10 @@ int FormatLngStringA(LPSTR lpOutput, int nOutput, UINT uIdFormat, ...) CHAR* const pBuffer = AllocMem(sizeof(CHAR) * nOutput, HEAP_ZERO_MEMORY); if (pBuffer) { if (LoadLngStringA(uIdFormat, pBuffer, nOutput)) { - StringCchVPrintfA(lpOutput, nOutput, pBuffer, (LPVOID)((PUINT_PTR)& uIdFormat + 1)); + va_list args; + va_start(args, uIdFormat); + StringCchVPrintfA(lpOutput, nOutput, pBuffer, args); + va_end(args); } FreeMem(pBuffer); return (int)StringCchLenA(lpOutput, nOutput);