Fix xcopy so output is either unicode (console) or oem (file)
Kirill K. Smirnov
lich at math.spbu.ru
Sat Apr 21 04:14:11 CDT 2007
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
More information about the wine-devel
mailing list