server: Introduce IOCTL_CONDRV_SETUP_INPUT ioctl.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-09-21 17:06:26 +02:00 committed by Alexandre Julliard
parent 158471d676
commit 52f6a56a1a
3 changed files with 64 additions and 1 deletions

View File

@ -50,7 +50,10 @@
#define IOCTL_CONDRV_SCROLL CTL_CODE(FILE_DEVICE_CONSOLE, 37, METHOD_BUFFERED, FILE_WRITE_ACCESS)
/* console connection ioctls */
#define IOCTL_CONDRV_BIND_PID CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_READ_PROPERTIES)
#define IOCTL_CONDRV_BIND_PID CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* console server ioctls */
#define IOCTL_CONDRV_SETUP_INPUT CTL_CODE(FILE_DEVICE_CONSOLE, 60, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* console renderer ioctls */
#define IOCTL_CONDRV_GET_RENDERER_EVENTS CTL_CODE(FILE_DEVICE_CONSOLE, 70, METHOD_BUFFERED, FILE_READ_ACCESS)

View File

@ -28,6 +28,8 @@
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <termios.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@ -198,6 +200,8 @@ struct console_server
struct list queue; /* ioctl queue */
struct list read_queue; /* blocking read queue */
int busy; /* flag if server processing an ioctl */
int term_fd; /* UNIX terminal fd */
struct termios termios; /* original termios */
};
static void console_server_dump( struct object *obj, int verbose );
@ -665,6 +669,13 @@ static void disconnect_console_server( struct console_server *server )
console_host_ioctl_terminate( call, STATUS_CANCELLED );
}
if (server->term_fd != -1)
{
tcsetattr( server->term_fd, TCSANOW, &server->termios );
close( server->term_fd );
server->term_fd = -1;
}
if (server->console)
{
assert( server->console->server == server );
@ -1772,6 +1783,7 @@ static struct object *create_console_server( void )
if (!(server = alloc_object( &console_server_ops ))) return NULL;
server->console = NULL;
server->busy = 0;
server->term_fd = -1;
list_init( &server->queue );
list_init( &server->read_queue );
server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
@ -2337,6 +2349,53 @@ static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async
return !get_error();
}
case IOCTL_CONDRV_SETUP_INPUT:
{
struct termios term;
obj_handle_t handle;
struct file *file;
int unix_fd;
if (get_req_data_size() != sizeof(unsigned int) || get_reply_max_size())
{
set_error( STATUS_INVALID_PARAMETER );
return 0;
}
if (server->term_fd != -1)
{
tcsetattr( server->term_fd, TCSANOW, &server->termios );
close( server->term_fd );
server->term_fd = -1;
}
handle = *(unsigned int *)get_req_data();
if (!handle) return 1;
if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA )))
{
return 0;
}
unix_fd = get_file_unix_fd( file );
release_object( file );
if (tcgetattr( unix_fd, &server->termios ))
{
file_set_error();
return 0;
}
term = server->termios;
term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
term.c_cflag &= ~(CSIZE | PARENB);
term.c_cflag |= CS8;
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (tcsetattr( unix_fd, TCSANOW, &term ) || (server->term_fd = dup( unix_fd )) == -1)
{
file_set_error();
return 0;
}
return 1;
}
default:
set_error( STATUS_INVALID_HANDLE );
return 0;

View File

@ -129,6 +129,7 @@ static void dump_ioctl_code( const char *prefix, const ioctl_code_t *code )
CASE(IOCTL_CONDRV_READ_OUTPUT);
CASE(IOCTL_CONDRV_SET_MODE);
CASE(IOCTL_CONDRV_SET_OUTPUT_INFO);
CASE(IOCTL_CONDRV_SETUP_INPUT);
CASE(IOCTL_CONDRV_WRITE_CONSOLE);
CASE(IOCTL_CONDRV_WRITE_INPUT);
CASE(IOCTL_CONDRV_WRITE_OUTPUT);