From: Hugh McMaster Subject: [PATCH] reg.exe: Modernise print functions Message-Id: Date: Mon, 10 Nov 2014 22:00:59 +1100 This patch modernises reg.exe so its printf-type functions conform to the other Wine programs. It will also mean other developers do not have to add this functionality in various places, e.g. printing error messages. From 0e85f8651420d09e3a55c2afc513b9615fea2075 Mon Sep 17 00:00:00 2001 From: Hugh McMaster Date: Mon, 10 Nov 2014 19:43:21 +1100 Subject: [PATCH] reg: Modernise print functions --- programs/reg/reg.c | 88 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index d299cbf..7fdf9f9 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -18,53 +18,77 @@ #include #include +#include #include "reg.h" -static int reg_printfW(const WCHAR *msg, ...) +WINE_DEFAULT_DEBUG_CHANNEL(reg); + +static void output_write(const WCHAR *str, int wlen) { - va_list va_args; - int wlen; DWORD count, ret; - WCHAR msg_buffer[8192]; - va_start(va_args, msg); - vsnprintfW(msg_buffer, 8192, msg, va_args); - va_end(va_args); - - wlen = lstrlenW(msg_buffer); - ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL); + ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL); if (!ret) { DWORD len; - char *msgA; - - /* On Windows WriteConsoleW() fails if the output is redirected. So fall - * back to WriteFile(), assuming the console encoding is still the right - * one in that case. - */ - len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, - NULL, 0, NULL, NULL); - msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); - if (!msgA) - return 0; + char *strA; + + /* WriteConsole() fails on Windows if its output is redirected to a file. + * If this occurs, we should call WriteFile() and use an OEM codepage. */ + len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL); + strA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); + if (!strA) + return; + + WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, strA, len, NULL, NULL); + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, len, &count, FALSE); + HeapFree(GetProcessHeap(), 0, strA); + } +} + +static void output_vprintf(const WCHAR* fmt, __ms_va_list va_args) +{ + WCHAR *str; + int len; + + SetLastError(NO_ERROR); + len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, + fmt, 0, 0, (LPWSTR)&str, 0, &va_args); + if (len == 0 && GetLastError() != NO_ERROR) + { + WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt)); + return; + } + output_write(str, len); + LocalFree(str); +} + +static void __cdecl reg_message(int msg_id, ...) +{ + WCHAR fmt[1024]; + __ms_va_list va_args; - WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len, - NULL, NULL); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE); - HeapFree(GetProcessHeap(), 0, msgA); + if (!LoadStringW(GetModuleHandleW(NULL), msg_id, fmt, sizeof(fmt)/sizeof(fmt[0]))) + { + WINE_FIXME("LoadString failed with %d\n", GetLastError()); + return; } - return count; + va_start(va_args, msg_id); + output_vprintf(fmt, va_args); + va_end(va_args); } -static int reg_message(int msg) +static void __cdecl reg_printfW(const WCHAR* msg, ...) { - static const WCHAR formatW[] = {'%','s',0}; - WCHAR msg_buffer[8192]; + __ms_va_list va_args; + WCHAR msg_buffer[1024]; + + va_start(va_args, msg); + vsnprintfW(msg_buffer, sizeof(msg_buffer)/sizeof(WCHAR), msg, va_args); + va_end(va_args); - LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, - sizeof(msg_buffer)/sizeof(WCHAR)); - return reg_printfW(formatW, msg_buffer); + output_write(msg_buffer, lstrlenW(msg_buffer)); } static HKEY get_rootkey(LPWSTR key) -- 1.9.1