kernel32: Fix writing to a pipe in WriteConsoleW().
Francois Gouget
fgouget at free.fr
Wed Aug 3 11:07:09 CDT 2011
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.
Now both cases work.
dlls/kernel32/console.c | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index d28c153..bab2322 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -45,6 +45,7 @@
# include <sys/poll.h>
#endif
+#define NONAMELESSUNION
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
@@ -2361,7 +2362,9 @@ BOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumber
{
char* ptr;
unsigned len;
- BOOL ret;
+ HANDLE hFile;
+ NTSTATUS status;
+ IO_STATUS_BLOCK iosb;
close(fd);
/* FIXME: mode ENABLED_OUTPUT is not processed (or actually we rely on underlying Unix/TTY fd
@@ -2372,17 +2375,28 @@ BOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumber
return FALSE;
WideCharToMultiByte(CP_UNIXCP, 0, lpBuffer, nNumberOfCharsToWrite, ptr, len, NULL, NULL);
- ret = WriteFile(wine_server_ptr_handle(console_handle_unmap(hConsoleOutput)),
- ptr, len, lpNumberOfCharsWritten, NULL);
- if (ret && lpNumberOfCharsWritten)
+ hFile = wine_server_ptr_handle(console_handle_unmap(hConsoleOutput));
+ status = NtWriteFile(hFile, NULL, NULL, NULL, &iosb, ptr, len, 0, NULL);
+ if (status == STATUS_PENDING)
{
- if (*lpNumberOfCharsWritten == len)
+ WaitForSingleObject(hFile, INFINITE);
+ status = iosb.u.Status;
+ }
+
+ if (status != STATUS_PENDING && lpNumberOfCharsWritten)
+ {
+ if (iosb.Information == len)
*lpNumberOfCharsWritten = nNumberOfCharsToWrite;
else
FIXME("Conversion not supported yet\n");
}
HeapFree(GetProcessHeap(), 0, ptr);
- return ret;
+ if (status != STATUS_SUCCESS)
+ {
+ SetLastError(RtlNtStatusToDosError(status));
+ return FALSE;
+ }
+ return TRUE;
}
if (!GetConsoleMode(hConsoleOutput, &mode) || !GetConsoleScreenBufferInfo(hConsoleOutput, &csbi))
--
1.7.5.4
More information about the wine-patches
mailing list