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