[PATCH 0/2] MR4520: Don't let GUI's app write to console.
From: Eric Pouech <epouech(a)codeweavers.com> Regular GUI programs don't use console nor std I/O. Signed-off-by: Eric Pouech <epouech(a)codeweavers.com> --- programs/winecfg/appdefaults.c | 28 +++++++++++++++++++++++----- programs/winecfg/audio.c | 1 - programs/winecfg/drive.c | 1 - programs/winecfg/driveui.c | 2 -- programs/winecfg/libraries.c | 1 - programs/winecfg/main.c | 14 +++++++------- programs/winecfg/theme.c | 1 - programs/winecfg/winecfg.c | 1 - programs/winecfg/x11drvdlg.c | 1 - 9 files changed, 30 insertions(+), 20 deletions(-) diff --git a/programs/winecfg/appdefaults.c b/programs/winecfg/appdefaults.c index 4900c1e14fd..0e61183e684 100644 --- a/programs/winecfg/appdefaults.c +++ b/programs/winecfg/appdefaults.c @@ -25,7 +25,6 @@ #include <windows.h> #include <commdlg.h> #include <wine/debug.h> -#include <stdio.h> #include <stdlib.h> #include <assert.h> #include "winecfg.h" @@ -510,29 +509,48 @@ BOOL set_winver_from_string(const WCHAR *version) return FALSE; } +static char *dupWtoA(const WCHAR *wstr) +{ + DWORD len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + char *str = malloc(len); + if (str) + WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); + return str; +} + void print_windows_versions(void) { int i; for (i = 0; i < ARRAY_SIZE(win_versions); i++) { - wprintf(L" %10s %s\n", win_versions[i].szVersion, win_versions[i].szDescription); + char *vers = dupWtoA(win_versions[i].szVersion); + char *desc = dupWtoA(win_versions[i].szDescription); + + if (vers && desc) + MESSAGE(" %10s %s\n", vers, desc); + free(vers); + free(desc); } } void print_current_winver(void) { WCHAR *winver = get_reg_key(config_key, keypath(L""), L"Version", L""); + const WCHAR *strW; + char *str; if (!winver || !winver[0]) { int ver = get_registry_version(); - wprintf(L"%s\n", ver == -1 ? DEFAULT_WIN_VERSION : win_versions[ver].szVersion); + strW = (ver == -1) ? DEFAULT_WIN_VERSION : win_versions[ver].szVersion; } else - wprintf(L"%s\n", winver); - + strW = winver; + if ((str = dupWtoA(strW))) + MESSAGE("%s\n", str); free(winver); + free(str); } static void on_winver_change(HWND dialog) diff --git a/programs/winecfg/audio.c b/programs/winecfg/audio.c index a5065ee5c21..b98efbc2ec6 100644 --- a/programs/winecfg/audio.c +++ b/programs/winecfg/audio.c @@ -23,7 +23,6 @@ #include <assert.h> #include <stdlib.h> -#include <stdio.h> #include <string.h> #define COBJMACROS diff --git a/programs/winecfg/drive.c b/programs/winecfg/drive.c index f002482f510..b113b71b199 100644 --- a/programs/winecfg/drive.c +++ b/programs/winecfg/drive.c @@ -23,7 +23,6 @@ #include <assert.h> #include <stdarg.h> -#include <stdio.h> #include <string.h> #include <ntstatus.h> diff --git a/programs/winecfg/driveui.c b/programs/winecfg/driveui.c index e21c99a6697..611c467b082 100644 --- a/programs/winecfg/driveui.c +++ b/programs/winecfg/driveui.c @@ -21,8 +21,6 @@ * */ -#include <stdio.h> - #define WIN32_LEAN_AND_MEAN #define COBJMACROS diff --git a/programs/winecfg/libraries.c b/programs/winecfg/libraries.c index 43cfe81a104..09fd397ab63 100644 --- a/programs/winecfg/libraries.c +++ b/programs/winecfg/libraries.c @@ -23,7 +23,6 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <commdlg.h> -#include <stdio.h> #include <assert.h> #include <stdlib.h> diff --git a/programs/winecfg/main.c b/programs/winecfg/main.c index d218d79770c..de460673913 100644 --- a/programs/winecfg/main.c +++ b/programs/winecfg/main.c @@ -197,13 +197,13 @@ ProcessCmdLine(LPWSTR lpCmdLine) if (lpCmdLine[1] == '?') { - printf("Usage: winecfg [options]\n\n"); - printf("Options:\n"); - printf(" [no option] Launch the graphical version of this program.\n"); - printf(" /v Display the current global Windows version.\n"); - printf(" /v version Set global Windows version to 'version'.\n"); - printf(" /? Display this information and exit.\n\n"); - printf("Valid versions for 'version':\n\n"); + MESSAGE("Usage: winecfg [options]\n\n"); + MESSAGE("Options:\n"); + MESSAGE(" [no option] Launch the graphical version of this program.\n"); + MESSAGE(" /v Display the current global Windows version.\n"); + MESSAGE(" /v version Set global Windows version to 'version'.\n"); + MESSAGE(" /? Display this information and exit.\n\n"); + MESSAGE("Valid versions for 'version':\n\n"); print_windows_versions(); return 0; diff --git a/programs/winecfg/theme.c b/programs/winecfg/theme.c index d52c127db0b..cc1a3c66820 100644 --- a/programs/winecfg/theme.c +++ b/programs/winecfg/theme.c @@ -25,7 +25,6 @@ #include <assert.h> #include <stdarg.h> #include <stdlib.h> -#include <stdio.h> #define COBJMACROS diff --git a/programs/winecfg/winecfg.c b/programs/winecfg/winecfg.c index c5c78c12b96..0433db0a728 100644 --- a/programs/winecfg/winecfg.c +++ b/programs/winecfg/winecfg.c @@ -30,7 +30,6 @@ #define WIN32_LEAN_AND_MEAN #include <assert.h> -#include <stdio.h> #include <limits.h> #include <windows.h> #include <winreg.h> diff --git a/programs/winecfg/x11drvdlg.c b/programs/winecfg/x11drvdlg.c index 215cd6534a2..aea52717a78 100644 --- a/programs/winecfg/x11drvdlg.c +++ b/programs/winecfg/x11drvdlg.c @@ -25,7 +25,6 @@ #include <stdarg.h> #include <stdlib.h> -#include <stdio.h> #include <windows.h> #include <wine/debug.h> -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4520
From: Eric Pouech <epouech(a)codeweavers.com> Regular GUI apps don't. Signed-off-by: Eric Pouech <epouech(a)codeweavers.com> --- programs/uninstaller/main.c | 111 ++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/programs/uninstaller/main.c b/programs/uninstaller/main.c index 52e8a0debe9..a3d907228e7 100644 --- a/programs/uninstaller/main.c +++ b/programs/uninstaller/main.c @@ -44,70 +44,57 @@ static uninst_entry *entries = NULL; static unsigned int numentries = 0; static int oldsel = -1; static WCHAR *sFilter; +static BOOL silent; static int FetchUninstallInformation(void); static void UninstallProgram(void); static const WCHAR PathUninstallW[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; -static void output_writeconsole(const WCHAR *str, DWORD len) -{ - DWORD written, lenA; - char *strA; - - if (WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, len, &written, NULL)) - return; - - /* WriteConsole fails if its output is redirected to a file. - * If this occurs, we should use an OEM codepage and call WriteFile. - */ - lenA = WideCharToMultiByte(GetOEMCP(), 0, str, len, NULL, 0, NULL, NULL); - strA = malloc(lenA); - if (strA) - { - WideCharToMultiByte(GetOEMCP(), 0, str, len, strA, lenA, NULL, NULL); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, lenA, &written, FALSE); - free(strA); - } -} -static void output_formatstring(const WCHAR *fmt, va_list va_args) +static void WINAPIV output_message(BOOL with_usage, unsigned int id, ...) { - WCHAR *str; - DWORD len; - - len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, - fmt, 0, 0, (LPWSTR)&str, 0, &va_args); - if (len == 0 && GetLastError() != ERROR_NO_WORK_DONE) - { - WINE_FIXME("Could not format string: le=%lu, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt)); - return; - } - output_writeconsole(str, len); - LocalFree(str); -} + WCHAR fmt[2048]; + LCID current_lcid; -static void WINAPIV output_message(unsigned int id, ...) -{ - WCHAR fmt[1024]; - va_list va_args; + current_lcid = GetThreadLocale(); + if (silent) /* force en-US not to have localized strings */ + SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); - if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, ARRAY_SIZE(fmt))) + if (LoadStringW(GetModuleHandleW(NULL), id, fmt, ARRAY_SIZE(fmt)) && + (!with_usage || LoadStringW(GetModuleHandleW(NULL), STRING_USAGE, fmt + wcslen(fmt), ARRAY_SIZE(fmt) - wcslen(fmt)))) { - WINE_FIXME("LoadString failed with %ld\n", GetLastError()); - return; + va_list va_args; + WCHAR *str; + DWORD len; + + va_start(va_args, id); + len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, + fmt, 0, 0, (LPWSTR)&str, 0, &va_args); + if (len > 0 || GetLastError() == ERROR_NO_WORK_DONE) + { + if (silent) + MESSAGE("%ls", str); + else + MessageBoxW(NULL, str, L"", MB_OK | MB_ICONSTOP); + LocalFree(str); + } + else + WINE_FIXME("Could not format string: le=%lu, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt)); + va_end(va_args); } - va_start(va_args, id); - output_formatstring(fmt, va_args); - va_end(va_args); + else + WINE_FIXME("LoadString failed with %ld\n", GetLastError()); + + SetThreadLocale(current_lcid); } -static void WINAPIV output_array(const WCHAR *fmt, ...) +static char *dupWtoA(const WCHAR *wstr) { - va_list va_args; - - va_start(va_args, fmt); - output_formatstring(fmt, va_args); - va_end(va_args); + DWORD len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + char *str = malloc(len); + if (str) + WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); + return str; } /** @@ -120,7 +107,14 @@ static void ListUninstallPrograms(void) FetchUninstallInformation(); for (i=0; i < numentries; i++) - output_array(L"%1|||%2\n", entries[i].key, entries[i].descr); + { + char *key = dupWtoA(entries[i].key); + char *descr = dupWtoA(entries[i].descr); + if (key && descr) + MESSAGE("%s|||%s\n", key, descr); + free(key); + free(descr); + } } @@ -142,7 +136,7 @@ static void RemoveSpecificProgram(WCHAR *nameW) if (i < numentries) UninstallProgram(); else - output_message(STRING_NO_APP_MATCH, nameW); + output_message(FALSE, STRING_NO_APP_MATCH, nameW); } @@ -185,10 +179,13 @@ int __cdecl wmain(int argc, WCHAR *argv[]) if( !lstrcmpW( token, L"--help" ) ) { - output_message(STRING_HEADER); - output_message(STRING_USAGE); + output_message(TRUE, STRING_HEADER); return 0; } + else if( !lstrcmpW( token, L"--silent" ) ) + { + silent = TRUE; + } else if( !lstrcmpW( token, L"--list" ) ) { ListUninstallPrograms(); @@ -198,16 +195,16 @@ int __cdecl wmain(int argc, WCHAR *argv[]) { if( i >= argc ) { - output_message(STRING_PARAMETER_REQUIRED); + output_message(FALSE, STRING_PARAMETER_REQUIRED); return 1; } RemoveSpecificProgram( argv[i++] ); return 0; } - else + else { - output_message(STRING_INVALID_OPTION, token); + output_message(FALSE, STRING_INVALID_OPTION, token); return 1; } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4520
Alexandre Julliard (@julliard) commented about programs/uninstaller/main.c:
- WINE_FIXME("LoadString failed with %ld\n", GetLastError()); - return; + va_list va_args; + WCHAR *str; + DWORD len; + + va_start(va_args, id); + len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, + fmt, 0, 0, (LPWSTR)&str, 0, &va_args); + if (len > 0 || GetLastError() == ERROR_NO_WORK_DONE) + { + if (silent) + MESSAGE("%ls", str); + else + MessageBoxW(NULL, str, L"", MB_OK | MB_ICONSTOP); + LocalFree(str); You should use IDS_APPNAME instead of an empty title for the message box.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/4520#note_53991
Alexandre Julliard (@julliard) commented about programs/uninstaller/main.c:
FetchUninstallInformation();
for (i=0; i < numentries; i++) - output_array(L"%1|||%2\n", entries[i].key, entries[i].descr); + { + char *key = dupWtoA(entries[i].key); + char *descr = dupWtoA(entries[i].descr); + if (key && descr) + MESSAGE("%s|||%s\n", key, descr); + free(key); + free(descr);
Why are you using %ls above and not here? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4520#note_53992
On Tue Nov 28 07:59:24 2023 +0000, Alexandre Julliard wrote:
You should use IDS_APPNAME instead of an empty title for the message box. added in V2
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/4520#note_54064
in this case, IMO there's no guarantee that description and key are translatable without loss in ANSI codepage, and using %ls will use the app default locale, which may end with a codepage that we don't want here (above all the strings are loaded with the app locale set to en-US which should give output in ANSI codepage) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4520#note_54065
We'd need to make sure that the C runtime locale is initialized, but apart from that I don't see how doing W->A by hand is better. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4520#note_54068
participants (3)
-
Alexandre Julliard (@julliard) -
Eric Pouech -
eric pouech (@epo)