Eric Pouech : kernelbase: Return key state in ReadConsoleW with control.

Alexandre Julliard julliard at winehq.org
Tue Mar 1 15:45:34 CST 2022


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

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Tue Mar  1 09:26:02 2022 +0100

kernelbase: Return key state in ReadConsoleW with control.

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernelbase/console.c  | 12 ++++++++----
 programs/conhost/conhost.c | 10 ++++++++--
 programs/conhost/conhost.h |  1 +
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
index 1f23292d467..b2bb6c53fd9 100644
--- a/dlls/kernelbase/console.c
+++ b/dlls/kernelbase/console.c
@@ -2031,7 +2031,7 @@ BOOL WINAPI ReadConsoleW( HANDLE handle, void *buffer, DWORD length, DWORD *coun
             SetLastError( ERROR_INVALID_PARAMETER );
             return FALSE;
         }
-        if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR) )))
+        if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD) + length * sizeof(WCHAR) )))
         {
             SetLastError( ERROR_NOT_ENOUGH_MEMORY );
             return FALSE;
@@ -2041,9 +2041,13 @@ BOOL WINAPI ReadConsoleW( HANDLE handle, void *buffer, DWORD length, DWORD *coun
         memcpy( tmp + sizeof(DWORD), buffer, crc->nInitialChars * sizeof(WCHAR) );
         ret = console_ioctl( handle, IOCTL_CONDRV_READ_CONSOLE_CONTROL,
                              tmp, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR),
-                             buffer, length * sizeof(WCHAR),
-                             count );
-        crc->dwConsoleKeyState = 0;
+                             tmp, sizeof(DWORD) + length * sizeof(WCHAR), count );
+        if (ret)
+        {
+            memcpy( &crc->dwConsoleKeyState, tmp, sizeof(DWORD) );
+            *count -= sizeof(DWORD);
+            memcpy( buffer, tmp + sizeof(DWORD), *count );
+        }
         HeapFree( GetProcessHeap(), 0, tmp );
     }
     else
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index b08d26c2641..11e97993fd8 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -457,6 +457,8 @@ static NTSTATUS read_complete( struct console *console, NTSTATUS status, const v
         req->signal = signal;
         req->read   = 1;
         req->status = status;
+        if (console->read_ioctl == IOCTL_CONDRV_READ_CONSOLE_CONTROL)
+            wine_server_add_data( req, &console->key_state, sizeof(console->key_state) );
         wine_server_add_data( req, buf, size );
         status = wine_server_call( req );
     }
@@ -1250,6 +1252,7 @@ static NTSTATUS process_console_input( struct console *console )
     struct edit_line *ctx = &console->edit_line;
     unsigned int i;
     WCHAR ctrl_value = FIRST_NON_CONTROL_CHAR;
+    unsigned int ctrl_keyvalue = 0;
 
     switch (console->read_ioctl)
     {
@@ -1297,6 +1300,7 @@ static NTSTATUS process_console_input( struct console *console )
                 if (ctx->ctrl_mask & (1u << ir.Event.KeyEvent.uChar.UnicodeChar))
                 {
                     ctrl_value = ir.Event.KeyEvent.uChar.UnicodeChar;
+                    ctrl_keyvalue = ir.Event.KeyEvent.dwControlKeyState;
                     ctx->status = STATUS_SUCCESS;
                     TRACE("Found ctrl char in mask: ^%lc %x\n", ir.Event.KeyEvent.uChar.UnicodeChar + '@', ctx->ctrl_mask);
                     continue;
@@ -1363,6 +1367,7 @@ static NTSTATUS process_console_input( struct console *console )
         if (ctrl_value < FIRST_NON_CONTROL_CHAR)
         {
             edit_line_insert( console, &ctrl_value, 1 );
+            console->key_state = ctrl_keyvalue;
         }
         else
         {
@@ -1404,6 +1409,7 @@ static NTSTATUS read_console( struct console *console, unsigned int ioctl, size_
     }
 
     console->read_ioctl = ioctl;
+    console->key_state = 0;
     if (!out_size || console->read_buffer_count)
     {
         read_from_buffer( console, out_size );
@@ -2562,10 +2568,10 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
 
     case IOCTL_CONDRV_READ_CONSOLE_CONTROL:
         if ((in_size < sizeof(DWORD)) || ((in_size - sizeof(DWORD)) % sizeof(WCHAR)) ||
-            (*out_size % sizeof(WCHAR)))
+            (*out_size < sizeof(DWORD)) || ((*out_size - sizeof(DWORD)) % sizeof(WCHAR)))
             return STATUS_INVALID_PARAMETER;
         ensure_tty_input_thread( console );
-        status = read_console( console, code, *out_size,
+        status = read_console( console, code, *out_size - sizeof(DWORD),
                                (const WCHAR*)((const char*)in_data + sizeof(DWORD)),
                                (in_size - sizeof(DWORD)) / sizeof(WCHAR),
                                *(DWORD*)in_data );
diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h
index e5f70aa3ca4..35876689419 100644
--- a/programs/conhost/conhost.h
+++ b/programs/conhost/conhost.h
@@ -88,6 +88,7 @@ struct console
     unsigned int           read_ioctl;          /* current read ioctl */
     size_t                 pending_read;        /* size of pending read buffer */
     struct edit_line       edit_line;           /* edit line context */
+    unsigned int           key_state;
     struct console_window *window;
     WCHAR                 *title;               /* console title */
     struct history_line  **history;             /* lines history */




More information about the wine-cvs mailing list