Piotr Caban : msvcrt: Use correct code page in _write when outputing to console.

Alexandre Julliard julliard at winehq.org
Wed Aug 5 16:05:00 CDT 2020


Module: wine
Branch: master
Commit: 081d25d4b989c732d301b786311c034132c8d7a3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=081d25d4b989c732d301b786311c034132c8d7a3

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Aug  5 15:08:06 2020 +0200

msvcrt: Use correct code page in _write when outputing to console.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/file.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 5 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index b6655e6886..a37aa87b5d 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -40,6 +40,7 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "wincon.h"
 #include "winternl.h"
 #include "winnls.h"
 #include "msvcrt.h"
@@ -3446,6 +3447,7 @@ int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
     ioinfo *info = get_ioinfo(fd);
     HANDLE hand = info->handle;
     DWORD num_written, i;
+    BOOL console;
 
     if (hand == INVALID_HANDLE_VALUE || fd == MSVCRT_NO_CONSOLE_FD)
     {
@@ -3480,13 +3482,65 @@ int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
         return num_written;
     }
 
+    console = MSVCRT__isatty(fd);
     for (i = 0; i < count;)
     {
         const char *s = buf;
         char lfbuf[2048];
-        DWORD j;
+        DWORD j = 0;
 
-        if (!(info->exflag & (EF_UTF8|EF_UTF16)))
+        if (!(info->exflag & (EF_UTF8|EF_UTF16)) && console)
+        {
+            char conv[sizeof(lfbuf)];
+            MSVCRT_size_t len = 0;
+
+#if _MSVCR_VER >= 90
+            if (info->dbcsBufferUsed)
+            {
+                conv[j++] = info->dbcsBuffer;
+                info->dbcsBufferUsed = FALSE;
+                conv[j++] = s[i++];
+                len++;
+            }
+#endif
+
+            for (;  i < count && j < sizeof(conv)-1; i++, j++, len++)
+            {
+                if (MSVCRT_isleadbyte((unsigned char)s[i]))
+                {
+                    conv[j++] = s[i++];
+
+                    if (i == count)
+                    {
+#if _MSVCR_VER >= 90
+                        info->dbcsBuffer = conv[j-1];
+                        info->dbcsBufferUsed = TRUE;
+                        break;
+#else
+                        *MSVCRT__errno() = MSVCRT_EINVAL;
+                        release_ioinfo(info);
+                        return -1;
+#endif
+                    }
+                }
+                else if (s[i] == '\n')
+                {
+                    conv[j++] = '\r';
+                    len++;
+                }
+                conv[j] = s[i];
+            }
+
+            len = MSVCRT_mbstowcs((WCHAR*)lfbuf, conv, len);
+            if (len == -1)
+            {
+                msvcrt_set_errno(GetLastError());
+                release_ioinfo(info);
+                return -1;
+            }
+            j = len * 2;
+        }
+        else if (!(info->exflag & (EF_UTF8|EF_UTF16)))
         {
             for (j = 0; i < count && j < sizeof(lfbuf)-1; i++, j++)
             {
@@ -3495,7 +3549,7 @@ int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
                 lfbuf[j] = s[i];
             }
         }
-        else if (info->exflag & EF_UTF16)
+        else if (info->exflag & EF_UTF16 || console)
         {
             for (j = 0; i < count && j < sizeof(lfbuf)-3; i++, j++)
             {
@@ -3532,9 +3586,20 @@ int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
             }
         }
 
-        if (!WriteFile(hand, lfbuf, j, &num_written, NULL) || num_written != j)
+        if (console)
         {
-            TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd,
+            j = j/2;
+            if (!WriteConsoleW(hand, lfbuf, j, &num_written, NULL))
+                num_written = -1;
+        }
+        else if (!WriteFile(hand, lfbuf, j, &num_written, NULL))
+        {
+            num_written = -1;
+        }
+
+        if (num_written != j)
+        {
+            TRACE("WriteFile/WriteConsoleW (fd %d, hand %p) failed-last error (%d)\n", fd,
                     hand, GetLastError());
             msvcrt_set_errno(GetLastError());
             release_ioinfo(info);




More information about the wine-cvs mailing list