kernel32: Fix writing to a pipe in WriteConsoleW().

Francois Gouget fgouget at free.fr
Wed Aug 24 11:10:15 CDT 2011


On Tue, 23 Aug 2011, Eric Pouech wrote:

> Le 03/08/2011 18:07, Francois Gouget a écrit :
> > WriteFile() checks if the handle corresponds to the console and if it
> > does invokes WriteConsoleA(). This barely escaped an infinite loop but
> > messed up the string encoding as CP_UNIXCP is usually different from
> > CP_ACP.
> > ---
> >
> > I noticed this issue while testing the net.exe tool. After making it
> > use WineConsole() I was getting the following outputs:
> >
> > $ wine net stop
> > Spécifie le service à arrêter.
> > $ ./wine net stop | cat
> > Sp├®cifie le service ├á arr├¬ter.
> >
> > It turns out that it's because we only get through the WineConsoleW() ->
> > WriteFile() ->  WriteConsoleA() loop in the second case.
> could you elaborate a bit more. in case of wine ... | cat, the standard 
> output should be a pipe not a console

* net.c is calling GetStdHandle(STD_OUTPUT_HANDLE).
* It then passes that to WriteConsoleW() and get_console_bare_fd() 
  does return an fd for it (no idea if that's right or wrong).
* So we end up in the WriteFile case and give it 
  wine_server_ptr_handle(console_handle_unmap(hConsoleOutput)).
  Frankly I don't know what that's supposed to do but when WriteFile() 
  calls is_console_handle() on it it gets TRUE.


> so writeconsoleW is supposed to fail

Yes. It does fail when output is a pipe on Windows.


> so it would make more sense to simply let WriteConsoleW  fail when 
> is_console_handle(hConsoleOutput) is FALSE ?
> (similar functions as WriteConsoleA, ReadConsoleA/W should be protected 
> the same way)

Currently only three APIs in console.c check is_console_handle(): 
VerifyConsoleIoHandle(), DuplicateConsoleHandle() and 
CloseConsoleHandle(). That could certainly be extended to others and 
things even seems to work if I add a simple 'if 
(!is_console_handle(hConsoleOutput)) return FALSE;' at the start of 
WriteConsoleW().

One could then rip out the code in the WriteFile() branch but I'm not 
sure what the consequences of all this would be or why the WriteFile() 
case was added in the first place. The author of that code would 
probably know better than me<g>.


-- 
Francois Gouget <fgouget at free.fr>              http://fgouget.free.fr/
  Any sufficiently advanced Operating System is indistinguishable from Linux


More information about the wine-devel mailing list