No, from this point of view the patch is correct.
+/*
=========================================================================
- Output a formatted unicode string. Ideally this will go to the console
- and hence required WriteConsoleW to output it, however if file i/o is
- redirected, it needs to be WriteFile'd using OEM (not ANSI) format
=========================================================================
*/
The described above behaviour should be implemented either inside of wprintf implementation in msvcrt,
Just little test:
#include <windows.h> #include <stdio.h>
int main(void) { WCHAR str_uni[]={0x044d, 0x0442, 0x043e, 0x0020, 0x0442, 0x0435, 0x0441, 0x0442, 0x0000}; char str_oem[]="~]Б╝ ЮЦАА╙╗╘ Б╔╙АБ in OEM";
wprintf(str_uni); printf(str_oem); return 0; }
It will write both strings in wine and only second in windows. wprintf should not write unicode strings to console.
or inside of the console driver of WriteConsoleW depending on the test results IMO.
And not here too. Application must check this itself. http://msdn2.microsoft.com/en-us/library/ms687401.aspx contains tips: [quote] Both WriteConsole and WriteFile can be used for console I/O. While WriteConsole supports writing Unicode characters to a console screen buffer, WriteFile does not. However, WriteConsole fails if it is used with a standard handle that is redirected to a file. If an application handles multilingual output that can be redirected, determine whether the output handle is a console handle (one method is to call the GetConsoleMode function and check whether it succeeds). If the handle is a console handle, call WriteConsole; otherwise, the output is redirected and you should call WideCharToMultiByte to convert the text to the current code page and WriteFile to perform the I/O. [/quote]
There are some my tests at: http://www.winehq.com/pipermail/wine-devel/2007-April/056102.html I could miss something, it would be great if you check it!
I've just found another bug in the patch:
/* Convert to OEM, then output */
convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0,
output_bufW,
len, output_bufA, MAX_WRITECONSOLE_SIZE,
"?", &usedDefaultChar);
The comment is correct, but code is wrong. Here should be CP_OEMCP instead of GetConsoleOutputCP().
I did not noticed it before, because there two bugs: one is here, and another is in WriteConsoleA (the same bug - should be CP_OEMCP not GetConsoleOutputCP()). And they are mutually annihilated ;-)
Test demostrating that WriteConsoleA is wrong: #include <windows.h> #include <stdio.h>
int main(void) { DWORD tmp; WCHAR str_uni[]={0x044d, 0x0442, 0x043e, 0x0020, 0x0442, 0x0435, 0x0441, 0x0442, 0x0000}; char str_oem[]="~]Б╝ ЮЦАА╙╗╘ Б╔╙АБ in OEM\n";
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str_uni, wcslen(str_uni), &tmp, NULL); WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), str_oem, strlen(str_oem), &tmp, NULL); SetConsoleCP(1251); SetConsoleOutputCP(1251); WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str_uni, wcslen(str_uni), &tmp, NULL); WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), str_oem, strlen(str_oem), &tmp, NULL); SetConsoleCP(866); SetConsoleOutputCP(866); return 0; }
=^_^= -- Kirill