From: Eric Pouech epouech@codeweavers.com
This program is in GUI subsystem, but expects I/O with Unix console. This is a Wine specific behavior. So explicitely use unix fd instead of the inherited standard handles.
Wine-Bugs: https://bugs.winehq.org/show_bug.cgi?id=55723
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/regsvr32/regsvr32.c | 47 ++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/programs/regsvr32/regsvr32.c b/programs/regsvr32/regsvr32.c index 81caeb2c820..a432fa12551 100644 --- a/programs/regsvr32/regsvr32.c +++ b/programs/regsvr32/regsvr32.c @@ -27,6 +27,7 @@ #include <ole2.h> #include "regsvr32.h" #include "wine/debug.h" +#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(regsvr32);
@@ -36,12 +37,38 @@ typedef HRESULT (WINAPI *DLLINSTALL) (BOOL,LPCWSTR);
static BOOL Silent = FALSE;
+/* This program is actually defined in GUI subsystem, but still wants + * to print to Unix console if available. + */ +static void wine_console_write(const WCHAR* str) +{ + static HANDLE output_handle; + static UINT output_codepage = (UINT)-1; + + if (output_codepage == (UINT)-1) + { + wine_server_fd_to_handle(1, GENERIC_WRITE | SYNCHRONIZE, OBJ_INHERIT, &output_handle); + output_codepage = (GetFileType(output_handle) == FILE_TYPE_CHAR) ? CP_UNIXCP : CP_OEMCP; + } + if (output_handle) + { + DWORD lenA = WideCharToMultiByte(output_codepage, 0, str, -1, NULL, 0, NULL, NULL); + char *strA = malloc(lenA); + if (strA) + { + WideCharToMultiByte(output_codepage, 0, str, -1, strA, lenA, NULL, NULL); + WriteFile(output_handle, strA, lenA, NULL, FALSE); + free(strA); + } + } +} + static void WINAPIV output_write(UINT id, ...) { WCHAR fmt[1024]; va_list va_args; WCHAR *str; - DWORD len, nOut; + DWORD len;
if (Silent) return;
@@ -61,23 +88,7 @@ static void WINAPIV output_write(UINT id, ...) return; }
- /* WriteConsole fails if its output is redirected to a file. - * If this occurs, we should use an OEM codepage and call WriteFile. - */ - if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, len, &nOut, NULL)) - { - DWORD lenA; - char *strA; - - lenA = WideCharToMultiByte(GetOEMCP(), 0, str, len, NULL, 0, NULL, NULL); - strA = HeapAlloc(GetProcessHeap(), 0, lenA); - if (strA) - { - WideCharToMultiByte(GetOEMCP(), 0, str, len, strA, lenA, NULL, NULL); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, lenA, &nOut, FALSE); - HeapFree(GetProcessHeap(), 0, strA); - } - } + wine_console_write(str); LocalFree(str); }