Fix xcopy so output is either unicode (console) or oem (file)
Dmitry Timoshkov
dmitry at codeweavers.com
Mon Apr 23 02:49:14 CDT 2007
"Kirill K. Smirnov" <lich at math.spbu.ru> wrote:
> 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.
wprintf does write unicode strings to a console, the problem in your test
is that it doesn't change the locale from the default "C" to russian, and
the conversion from unicode to code page simply fails.
I'm attaching a modified version of your test, with some results/conclusions:
WriteConsole uses current console output code page to translate strings.
WriteConsole does produce an output when not redirecting output to a file.
WriteConsole does not produce an output when redirecting output to a file,
returns FALSE and sets last error to 6 (ERROR_INVALID_HANDLE).
wprintf translates unicode strings to current CRT multibyte locale before
printing them either to a console or to a file.
printf doesn't care about locale at all, it simply prints what it has.
So, the patch sent by Jason is OK, except using wchar_t instead of WCHAR.
--
Dmitry.
-------------- next part --------------
#include <windows.h>
#include <stdio.h>
#include <locale.h>
int main(void)
{
DWORD dummy;
BOOL ret;
WCHAR str_uni[]={0x044d, 0x0442, 0x043e,
0x0020, 0x0442, 0x0435,
0x0441, 0x0442, '\r', '\n', 0x0000};
char str_cp866[]="â® àãá᪨© ⥪áâ in cp866\n\0\0";
char str_cp1251[]="Ýòî ðóññêèé òåêñò in cp1251\n\0\0";
char *loc_str;
loc_str = setlocale(LC_ALL, NULL);
printf("current locale %s\n", loc_str);
loc_str = setlocale(LC_ALL, "Russian");
printf("current locale %s\n", loc_str);
SetConsoleOutputCP(866);
printf("WriteConsoleW: ");
SetLastError(-1);
ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str_uni, lstrlenW(str_uni), &dummy, NULL);
if (!ret) printf("error %d\n", GetLastError());
printf("WriteConsoleA: ");
SetLastError(-1);
ret = WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), str_cp866, lstrlenA(str_cp866), &dummy, NULL);
if (!ret) printf("error %d\n", GetLastError());
printf("wprintf(%%ws): ");
wprintf(L"%ws", L"unicode string ðóññêèé\n");
printf("printf: ");
printf("%s", str_cp866);
printf("printf: ");
printf("%s", str_cp1251);
SetConsoleOutputCP(1251);
printf("WriteConsoleW: ");
SetLastError(-1);
ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str_uni, lstrlenW(str_uni), &dummy, NULL);
if (!ret) printf("error %d\n", GetLastError());
printf("WriteConsoleA: ");
SetLastError(-1);
ret = WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), str_cp1251, lstrlenA(str_cp1251), &dummy, NULL);
if (!ret) printf("error %d\n", GetLastError());
printf("wprintf(%%ws): ");
wprintf(L"%ws", L"unicode string ðóññêèé\n");
printf("printf: ");
printf("%s", str_cp866);
printf("printf: ");
printf("%s", str_cp1251);
return 0;
}
More information about the wine-devel
mailing list