Jacek Caban : kernel32: Always use conhost for WriteConsoleW.

Alexandre Julliard julliard at winehq.org
Tue Oct 13 15:42:04 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct 13 16:27:11 2020 +0200

kernel32: Always use conhost for WriteConsoleW.

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

---

 dlls/kernel32/console.c | 207 +++---------------------------------------------
 1 file changed, 10 insertions(+), 197 deletions(-)

diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index e56a09516d..37e36730a9 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -357,116 +357,6 @@ BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons)
     return TRUE;
 }
 
-/******************************************************************
- *		CONSOLE_WriteChars
- *
- * WriteConsoleOutput helper: hides server call semantics
- * writes a string at a given pos with standard attribute
- */
-static int CONSOLE_WriteChars(HANDLE handle, const WCHAR *str, size_t length, COORD *coord)
-{
-    struct condrv_output_params *params;
-    DWORD written = 0, size;
-
-    if (!length) return 0;
-
-    size = sizeof(*params) + length * sizeof(WCHAR);
-    if (!(params = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
-    params->mode   = CHAR_INFO_MODE_TEXTSTDATTR;
-    params->x      = coord->X;
-    params->y      = coord->Y;
-    params->width  = 0;
-    memcpy( params + 1, str, length * sizeof(*str) );
-    if (DeviceIoControl( handle, IOCTL_CONDRV_WRITE_OUTPUT, params, size,
-                         &written, sizeof(written), NULL, NULL ))
-        coord->X += written;
-    HeapFree( GetProcessHeap(), 0, params );
-    return written;
-}
-
-/******************************************************************
- *		next_line
- *
- * WriteConsoleOutput helper: handles passing to next line (+scrolling if necessary)
- *
- */
-static BOOL next_line(HANDLE hCon, CONSOLE_SCREEN_BUFFER_INFO* csbi)
-{
-    SMALL_RECT	src;
-    CHAR_INFO	ci;
-    COORD	dst;
-
-    csbi->dwCursorPosition.X = 0;
-    csbi->dwCursorPosition.Y++;
-
-    if (csbi->dwCursorPosition.Y < csbi->dwSize.Y) return TRUE;
-
-    src.Top    = 1;
-    src.Bottom = csbi->dwSize.Y - 1;
-    src.Left   = 0;
-    src.Right  = csbi->dwSize.X - 1;
-
-    dst.X      = 0;
-    dst.Y      = 0;
-
-    ci.Attributes = csbi->wAttributes;
-    ci.Char.UnicodeChar = ' ';
-
-    csbi->dwCursorPosition.Y--;
-    if (!ScrollConsoleScreenBufferW(hCon, &src, NULL, dst, &ci))
-        return FALSE;
-    return TRUE;
-}
-
-/******************************************************************
- *		write_block
- *
- * WriteConsoleOutput helper: writes a block of non special characters
- * Block can spread on several lines, and wrapping, if needed, is
- * handled
- *
- */
-static BOOL write_block(HANDLE hCon, CONSOLE_SCREEN_BUFFER_INFO* csbi,
-                        DWORD mode, LPCWSTR ptr, int len)
-{
-    int	blk;	/* number of chars to write on current line */
-    int done;   /* number of chars already written */
-
-    if (len <= 0) return TRUE;
-
-    if (mode & ENABLE_WRAP_AT_EOL_OUTPUT) /* writes remaining on next line */
-    {
-        for (done = 0; done < len; done += blk)
-        {
-            blk = min(len - done, csbi->dwSize.X - csbi->dwCursorPosition.X);
-
-            if (CONSOLE_WriteChars(hCon, ptr + done, blk, &csbi->dwCursorPosition) != blk)
-                return FALSE;
-            if (csbi->dwCursorPosition.X == csbi->dwSize.X && !next_line(hCon, csbi))
-                return FALSE;
-        }
-    }
-    else
-    {
-        int     pos = csbi->dwCursorPosition.X;
-        /* FIXME: we could reduce the number of loops
-         * but, in most cases we wouldn't gain lots of time (it would only
-         * happen if we're asked to overwrite more than twice the part of the line,
-         * which is unlikely
-         */
-        for (done = 0; done < len; done += blk)
-        {
-            blk = min(len - done, csbi->dwSize.X - csbi->dwCursorPosition.X);
-
-            csbi->dwCursorPosition.X = pos;
-            if (CONSOLE_WriteChars(hCon, ptr + done, blk, &csbi->dwCursorPosition) != blk)
-                return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
 
 /***********************************************************************
  *            WriteConsoleA   (KERNEL32.@)
@@ -492,95 +382,18 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA( HANDLE handle, LPCVOID buffer, DWOR
 /***********************************************************************
  *            WriteConsoleW   (KERNEL32.@)
  */
-BOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumberOfCharsToWrite,
-			  LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
-{
-    DWORD			mode;
-    DWORD			nw = 0;
-    const WCHAR*		psz = lpBuffer;
-    CONSOLE_SCREEN_BUFFER_INFO	csbi;
-    int				k, first = 0;
-    IO_STATUS_BLOCK io;
-
-    TRACE("%p %s %d %p %p\n",
-	  hConsoleOutput, debugstr_wn(lpBuffer, nNumberOfCharsToWrite),
-	  nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved);
-
-    if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = 0;
-
-    if (!NtDeviceIoControlFile(hConsoleOutput, NULL, NULL, NULL, &io, IOCTL_CONDRV_WRITE_CONSOLE, (void *)lpBuffer,
-                               nNumberOfCharsToWrite * sizeof(WCHAR), NULL, 0))
-    {
-        if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
-        return TRUE;
-    }
-
-    if (!GetConsoleMode(hConsoleOutput, &mode) || !GetConsoleScreenBufferInfo(hConsoleOutput, &csbi))
-	return FALSE;
-
-    if (!nNumberOfCharsToWrite) return TRUE;
-
-    if (mode & ENABLE_PROCESSED_OUTPUT)
-    {
-	unsigned int	i;
-
-	for (i = 0; i < nNumberOfCharsToWrite; i++)
-	{
-	    switch (psz[i])
-	    {
-	    case '\b': case '\t': case '\n': case '\a': case '\r':
-		/* don't handle here the i-th char... done below */
-		if ((k = i - first) > 0)
-		{
-		    if (!write_block(hConsoleOutput, &csbi, mode, &psz[first], k))
-			goto the_end;
-		    nw += k;
-		}
-		first = i + 1;
-		nw++;
-	    }
-	    switch (psz[i])
-	    {
-	    case '\b':
-		if (csbi.dwCursorPosition.X > 0) csbi.dwCursorPosition.X--;
-		break;
-	    case '\t':
-	        {
-		    static const WCHAR tmp[] = {' ',' ',' ',' ',' ',' ',' ',' '};
-		    if (!write_block(hConsoleOutput, &csbi, mode, tmp,
-				     ((csbi.dwCursorPosition.X + 8) & ~7) - csbi.dwCursorPosition.X))
-			goto the_end;
-		}
-		break;
-	    case '\n':
-		next_line(hConsoleOutput, &csbi);
-		break;
- 	    case '\a':
-		Beep(400, 300);
- 		break;
-	    case '\r':
-		csbi.dwCursorPosition.X = 0;
-		break;
-	    default:
-		break;
-	    }
-	}
-    }
+BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW( HANDLE handle, const void *buffer, DWORD length,
+                                             DWORD *written, void *reserved )
+{
+    BOOL ret;
 
-    /* write the remaining block (if any) if processed output is enabled, or the
-     * entire buffer otherwise
-     */
-    if ((k = nNumberOfCharsToWrite - first) > 0)
-    {
-	if (!write_block(hConsoleOutput, &csbi, mode, &psz[first], k))
-	    goto the_end;
-	nw += k;
-    }
+    TRACE( "(%p,%s,%d,%p,%p)\n", handle, debugstr_wn(buffer, length), length, written, reserved );
 
- the_end:
-    SetConsoleCursorPosition(hConsoleOutput, csbi.dwCursorPosition);
-    if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = nw;
-    return nw != 0;
+    ret = DeviceIoControl( handle, IOCTL_CONDRV_WRITE_CONSOLE, (void *)buffer,
+                           length * sizeof(WCHAR), NULL, 0, NULL, NULL );
+    if (written) *written = ret ? length : 0;
+    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
+    return ret;
 }
 
 




More information about the wine-cvs mailing list