Module: wine Branch: master Commit: f8fa6fd68608b53def2c34a489b5af2416f47cd7 URL: https://source.winehq.org/git/wine.git/?a=commit;h=f8fa6fd68608b53def2c34a48...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Jul 28 17:10:56 2020 +0200
kernelbase: Use IOCTL_CONDRV_READ_OUTPUT in ReadConsoleOutputW.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/console.c | 59 ++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 24 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index a4b9b8c491..b97cf140d6 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -894,37 +894,48 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputA( HANDLE handle, CHAR_INFO *buff BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputW( HANDLE handle, CHAR_INFO *buffer, COORD size, COORD coord, SMALL_RECT *region ) { - int width, height, y; - BOOL ret = TRUE; + struct condrv_output_params params; + unsigned int width, height, y; + SMALL_RECT *result; + DWORD count; + BOOL ret;
+ if (region->Left > region->Right || region->Top > region->Bottom) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + if (size.X <= coord.X || size.Y <= coord.Y) + { + region->Right = region->Left - 1; + region->Bottom = region->Top - 1; + SetLastError( ERROR_INVALID_FUNCTION ); + return FALSE; + } width = min( region->Right - region->Left + 1, size.X - coord.X ); height = min( region->Bottom - region->Top + 1, size.Y - coord.Y );
- if (width > 0 && height > 0) + count = sizeof(*result) + width * height * sizeof(*buffer); + if (!(result = HeapAlloc( GetProcessHeap(), 0, count ))) { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + + params.mode = CHAR_INFO_MODE_TEXTATTR; + params.x = region->Left; + params.y = region->Top; + params.width = width; + if ((ret = console_ioctl( handle, IOCTL_CONDRV_READ_OUTPUT, ¶ms, sizeof(params), result, count, &count )) && count) + { + CHAR_INFO *char_info = (CHAR_INFO *)(result + 1); + *region = *result; + width = region->Right - region->Left + 1; + height = region->Bottom - region->Top + 1; for (y = 0; y < height; y++) - { - SERVER_START_REQ( read_console_output ) - { - req->handle = console_handle_unmap( handle ); - req->x = region->Left; - req->y = region->Top + y; - req->mode = CHAR_INFO_MODE_TEXTATTR; - req->wrap = FALSE; - wine_server_set_reply( req, &buffer[(y+coord.Y) * size.X + coord.X], - width * sizeof(CHAR_INFO) ); - if ((ret = !wine_server_call_err( req ))) - { - width = min( width, reply->width - region->Left ); - height = min( height, reply->height - region->Top ); - } - } - SERVER_END_REQ; - if (!ret) break; - } + memcpy( &buffer[(y + coord.Y) * size.X + coord.X], &char_info[y * width], width * sizeof(*buffer) ); } - region->Bottom = region->Top + height - 1; - region->Right = region->Left + width - 1; + HeapFree( GetProcessHeap(), 0, result ); return ret; }