[PATCH 08/11] kernelbase/console, programs/conhost: support CONSOLE_READCONSOLE_CONTROL in ReadConsoleW

Jacek Caban jacek at codeweavers.com
Sun Feb 20 07:03:20 CST 2022


Hi Eric,

On 2/9/22 16:44, Eric Pouech wrote:
> Signed-off-by: Eric Pouech<eric.pouech at gmail.com>
>
> ---
>   dlls/kernelbase/console.c  |   32 ++++++++++++++-
>   include/wine/condrv.h      |    1
>   programs/conhost/conhost.c |   93 +++++++++++++++++++++++++++++++++++---------
>   programs/conhost/conhost.h |    1
>   server/console.c           |    1
>   5 files changed, 107 insertions(+), 21 deletions(-)
>
> diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
> index a7eeb439232..52949ab7541 100644
> --- a/dlls/kernelbase/console.c
> +++ b/dlls/kernelbase/console.c
> @@ -1598,8 +1598,36 @@ BOOL WINAPI ReadConsoleW( HANDLE handle, void *buffer, DWORD length, DWORD *coun
>           return FALSE;
>       }
>   
> -    ret = console_ioctl( handle, IOCTL_CONDRV_READ_CONSOLE, NULL, 0, buffer,
> -                         length * sizeof(WCHAR), count );
> +    if (reserved)
> +    {
> +        CONSOLE_READCONSOLE_CONTROL* crc = reserved;
> +        char *tmp;
> +
> +        if (crc->nLength != sizeof(*crc) || crc->nInitialChars >= length)
> +        {
> +            SetLastError( ERROR_INVALID_PARAMETER );
> +            return FALSE;
> +        }
> +        if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR) )))
> +        {
> +            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
> +            return FALSE;
> +        }
> +
> +        memcpy( tmp, &crc->dwCtrlWakeupMask, sizeof(DWORD) );
> +        memcpy( tmp + sizeof(DWORD), buffer, crc->nInitialChars * sizeof(WCHAR) );
> +        ret = console_ioctl( handle, IOCTL_CONDRV_READ_COMPLETION,
> +                             tmp, sizeof(DWORD) + crc->nInitialChars * sizeof(WCHAR),
> +                             buffer, length * sizeof(WCHAR),
> +                             count );
> +        crc->dwConsoleKeyState = 0;
> +        HeapFree( GetProcessHeap(), 0, tmp );
> +    }
> +    else
> +    {
> +        ret = console_ioctl( handle, IOCTL_CONDRV_READ_CONSOLE, NULL, 0, buffer,
> +                             length * sizeof(WCHAR), count );
> +    }
>       if (ret) *count /= sizeof(WCHAR);
>       return ret;


Could we just use IOCTL_CONDRV_READ_CONSOLE in both cases and 
distinguish the actual mode by checking input size in conhost?


Also, it would be interesting to try to add a test for this, see 
conhost/tests/tty.c for an example of other ReadConsole() tests. A fair 
warning: it may prove to be tricky. When I wrote those tests, I observed 
some weird or inconsistent Windows behaviour. Pseudo consoles were not 
matured on Windows back then, hopefully things will be better now. There 
is a huge chance that it's not one of those cases and it will be 
straightforward. If things get ugly, I'm fine skipping tests, but it's 
worth to try.


Thanks,

Jacek




More information about the wine-devel mailing list