[Bug 5541] WriteConsole can't write to stdout; affects e.g. wsh's cscript' s usage message

wine-bugs at winehq.org wine-bugs at winehq.org
Sat Jan 26 19:40:31 CST 2008


http://bugs.winehq.org/show_bug.cgi?id=5541





--- Comment #14 from Anastasius Focht <focht at gmx.net>  2008-01-26 19:40:29 ---
Created an attachment (id=10462)
 --> (http://bugs.winehq.org/attachment.cgi?id=10462)
patch which fixes cscript WriteConsoleA/W stdout problem

Hello again,

some re-thoughts ...
After digging in MSDN, I find this cscript behaviour similar to the "remarks"
section of WriteConsoleW() MSDN documention
(http://msdn2.microsoft.com/en-us/library/ms687401.aspx).

--- quote ---
..
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 ---

The problem is that cscript.exe doesn't call "GetConsoleMode" as suggested by
remarks section to determine output target.
As outlined earlier, it's using:

--- snip ---
if( GetFileType( GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_CHAR)
{
   /* console mode */
}
else
{
   /* redirected */
}
--- snip ---

If not redirected, wine GetFileType( GetStdHandle( std_handle )) will return
FILE_TYPE_CHAR for all 3 std handles because the underlying 
NtQueryVolumeInformationFile -> get_device_info() -> FILE_DEVICE_UNKNOWN is
mapped to FILE_TYPE_CHAR.
Cscript thinks it's in true console mode, calling WriteConsoleW() for output.
In all other cases (redirect/pipe), WriteFile() is used.

Because the std handles are not real wine-style console handles (registered
consoles in wine server), cscript WriteConsoleW calls will subsequently fail:

--- snip ---
BOOL WINAPI WriteConsoleW( .. )
{
 if (!GetConsoleMode(hConsoleOutput, &mode) ||
        !GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) 
     return FALSE;
--- snip ---

Cscript and the scripting engine inproc server don't use any other console API
functions.
That WriteConsoleW() is only used for line based output.

For the time being I made a small not-very-intrusive patch.
There might be better (general) solutions to attack this problem like
msvcrt-style process stdio handles (requires some work/rethoughts) but for now
it's sufficient.

It fixes the problem by using a WriteFile fallback in WriteConsoleA/W().
If WriteConsoleA/W() is used on redirected handles it fails on purpose (matches
MSDN).
Although MSDN says WriteFile() shouldn't use UNICODE on console/std handles
this seems not a problem in wine. In fact it works nicely (omitting double
conversion for ansi case).

Regards


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list