start:start.c Display messages in the console encoding.

Kirill K. Smirnov lich at math.spbu.ru
Wed Oct 24 06:06:03 CDT 2007


> static void output(const char *message)
> {
>-	DWORD count;
>-	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), message, strlen(message), 
>&count, NULL);
>+	DWORD count = 0;
>+	WCHAR *mesW = NULL;
>+	char  *mes = NULL;
>+	int   wlen = 0;
>+	int   len = 0;
>+        
>+	wlen = MultiByteToWideChar( CP_ACP, 0, message, -1, NULL, 0 );
>+	mesW = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
>+	mes = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(char) );
>+
>+	MultiByteToWideChar( CP_ACP, 0, message, -1, mesW, wlen );
>+	len = WideCharToMultiByte( GetConsoleOutputCP(), 0, mesW, wlen, NULL, 0, 
>NULL, NULL );
>+	WideCharToMultiByte( GetConsoleOutputCP(), 0, mesW, wlen, mes, len, NULL, 
>NULL );
>+    
>+	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), mes, len, &count, NULL);
>+	if( !count && len )
>+      	    SetLastError( ERROR_FUNCTION_FAILED );
>+    
>+	HeapFree(GetProcessHeap(), 0, mesW);
>+	HeapFree(GetProcessHeap(), 0, mes);
> }


WriteFile does not output unicode characters to console screen buffer, so if 
ConsoleOutputCP is smth like 65001, this will fail.
The page http://msdn2.microsoft.com/en-us/library/ms687401.aspx contains 
remedy by Microsoft how to deal with problem:
1) If device handle is console, then output wide chars using WriteConsoleW
2) If device handle is not console, then convert wide chars to ConsoleOutputCP 
and output using WriteFileA.

This way is already implemented in cmd (See WCMD_output_asis_len function).

And it may be much better to convert start utility to unicode.

--
Kirill

P.S. all this manipulations is supposed to be done by msvcrt printf function 
family, but wine lacks this functionality :-(



More information about the wine-devel mailing list