Jacek Caban : kernelbase: Use IOCTL_CONDRV_WRITE_OUTPUT in WriteConsoleOutputW.

Alexandre Julliard julliard at winehq.org
Thu Jul 23 16:36:57 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jul 23 17:31:28 2020 +0200

kernelbase: Use IOCTL_CONDRV_WRITE_OUTPUT in WriteConsoleOutputW.

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

---

 dlls/kernelbase/console.c | 54 ++++++++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 26 deletions(-)

diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
index 262db40003..a79644723a 100644
--- a/dlls/kernelbase/console.c
+++ b/dlls/kernelbase/console.c
@@ -1486,41 +1486,43 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputA( HANDLE handle, const CHAR_INF
 BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputW( HANDLE handle, const CHAR_INFO *buffer,
                                                    COORD size, COORD coord, SMALL_RECT *region )
 {
-    int width, height, y;
-    BOOL ret = TRUE;
+    struct condrv_write_output_params *params;
+    unsigned int width, height, y;
+    size_t params_size;
+    BOOL ret;
 
     TRACE( "(%p,%p,(%d,%d),(%d,%d),(%d,%dx%d,%d)\n",
            handle, buffer, size.X, size.Y, coord.X, coord.Y,
            region->Left, region->Top, region->Right, region->Bottom );
 
-    width = min( region->Right - region->Left + 1, size.X - coord.X );
+    if (region->Left > region->Right || region->Top > region->Bottom || size.X <= coord.X || size.Y <= coord.Y)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+
+    width  = min( region->Right - region->Left + 1, size.X - coord.X );
     height = min( region->Bottom - region->Top + 1, size.Y - coord.Y );
+    region->Right = region->Left + width - 1;
+    region->Bottom = region->Top + height - 1;
 
-    if (width > 0 && height > 0)
+    params_size = sizeof(*params) + width * height * sizeof(*buffer);
+    if (!(params = HeapAlloc( GetProcessHeap(), 0, params_size )))
     {
-        for (y = 0; y < height; y++)
-        {
-            SERVER_START_REQ( write_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_add_data( 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;
-        }
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+        return FALSE;
     }
-    region->Bottom = region->Top + height - 1;
-    region->Right = region->Left + width - 1;
+
+    params->mode  = CHAR_INFO_MODE_TEXTATTR;
+    params->x     = region->Left;
+    params->y     = region->Top;
+    params->width = width;
+
+    for (y = 0; y < height; y++)
+        memcpy( &((CHAR_INFO *)(params + 1))[y * width], &buffer[(y + coord.Y) * size.X + coord.X], width * sizeof(CHAR_INFO) );
+
+    ret = console_ioctl( handle, IOCTL_CONDRV_WRITE_OUTPUT, params, params_size, region, sizeof(*region), NULL );
+    HeapFree( GetProcessHeap(), 0, params );
     return ret;
 }
 




More information about the wine-cvs mailing list