server: Allow a screen buffer to be attached to a given fd (for bare consoles).

This commit is contained in:
Eric Pouech 2010-08-30 22:18:52 +02:00 committed by Alexandre Julliard
parent b39a8d9ea2
commit 6f32644aa0
7 changed files with 49 additions and 8 deletions

View File

@ -1809,6 +1809,7 @@ HANDLE WINAPI CreateConsoleScreenBuffer(DWORD dwDesiredAccess, DWORD dwShareMode
req->access = dwDesiredAccess;
req->attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0;
req->share = dwShareMode;
req->fd = -1;
if (!wine_server_call_err( req ))
ret = console_handle_map( wine_server_ptr_handle( reply->handle_out ));
}

View File

@ -1654,7 +1654,7 @@ struct create_console_output_request
unsigned int access;
unsigned int attributes;
unsigned int share;
char __pad_28[4];
int fd;
};
struct create_console_output_reply
{
@ -5506,6 +5506,6 @@ union generic_reply
struct set_cursor_reply set_cursor_reply;
};
#define SERVER_PROTOCOL_VERSION 405
#define SERVER_PROTOCOL_VERSION 406
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -612,6 +612,7 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, DWORD pid, LPCWSTR appna
req->access = GENERIC_WRITE|GENERIC_READ;
req->attributes = 0;
req->share = FILE_SHARE_READ|FILE_SHARE_WRITE;
req->fd = -1;
ret = !wine_server_call_err( req );
data->hConOut = wine_server_ptr_handle( reply->handle_out );
}

View File

@ -143,10 +143,12 @@ struct screen_buffer
unsigned short attr; /* default attribute for screen buffer */
rectangle_t win; /* current visible window on the screen buffer *
* as seen in wineconsole */
struct fd *fd; /* for bare console, attached output fd */
};
static void screen_buffer_dump( struct object *obj, int verbose );
static void screen_buffer_destroy( struct object *obj );
static struct fd *screen_buffer_get_fd( struct object *obj );
static const struct object_ops screen_buffer_ops =
{
@ -158,7 +160,7 @@ static const struct object_ops screen_buffer_ops =
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
screen_buffer_get_fd, /* get_fd */
default_fd_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@ -395,7 +397,7 @@ static void generate_sb_initial_events( struct console_input *console_input )
console_input_events_append( console_input->evt, &evt );
}
static struct screen_buffer *create_console_output( struct console_input *console_input )
static struct screen_buffer *create_console_output( struct console_input *console_input, int fd )
{
struct screen_buffer *screen_buffer;
int i;
@ -416,6 +418,18 @@ static struct screen_buffer *create_console_output( struct console_input *consol
screen_buffer->win.right = screen_buffer->max_width - 1;
screen_buffer->win.top = 0;
screen_buffer->win.bottom = screen_buffer->max_height - 1;
if (fd == -1)
screen_buffer->fd = NULL;
else
{
if (!(screen_buffer->fd = create_anonymous_fd( &console_fd_ops, fd, &screen_buffer->obj,
FILE_SYNCHRONOUS_IO_NONALERT )))
{
release_object( screen_buffer );
return NULL;
}
allow_fd_caching(screen_buffer->fd);
}
list_add_head( &screen_buffer_list, &screen_buffer->entry );
@ -1136,9 +1150,17 @@ static void screen_buffer_destroy( struct object *obj )
}
}
}
if (screen_buffer->fd) release_object( screen_buffer->fd );
free( screen_buffer->data );
}
static struct fd *screen_buffer_get_fd( struct object *obj )
{
struct screen_buffer *screen_buffer = (struct screen_buffer*)obj;
assert( obj->ops == &screen_buffer_ops );
return screen_buffer->fd ? (struct fd*)grab_object( screen_buffer->fd ) : NULL;
}
/* write data into a screen buffer */
static int write_console_output( struct screen_buffer *screen_buffer, data_size_t size,
const void* data, enum char_info_mode mode,
@ -1468,8 +1490,8 @@ DECL_HANDLER(open_console)
}
else if (req->from == (obj_handle_t)1)
{
if (current->process->console && current->process->console->active)
obj = grab_object( (struct object*)current->process->console->active );
if (current->process->console && current->process->console->active)
obj = grab_object( (struct object*)current->process->console->active );
}
else if ((obj = get_handle_obj( current->process, req->from,
FILE_READ_PROPERTIES|FILE_WRITE_PROPERTIES, &console_input_ops )))
@ -1575,10 +1597,24 @@ DECL_HANDLER(create_console_output)
{
struct console_input* console;
struct screen_buffer* screen_buffer;
int fd;
if (!(console = console_input_get( req->handle_in, FILE_WRITE_PROPERTIES ))) return;
if (req->fd != -1)
{
if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
{
set_error( STATUS_INVALID_HANDLE ); /* FIXME */
return;
}
}
else fd = -1;
if (!(console = console_input_get( req->handle_in, FILE_WRITE_PROPERTIES )))
{
close(fd);
return;
}
screen_buffer = create_console_output( console );
screen_buffer = create_console_output( console, fd );
if (screen_buffer)
{
/* FIXME: should store sharing and test it when opening the CONOUT$ device

View File

@ -1295,6 +1295,7 @@ struct console_renderer_event
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
unsigned int share; /* sharing credentials */
int fd; /* for bare consoles, fd the screen-buffer is attached to */
@REPLY
obj_handle_t handle_out; /* handle to the screen buffer */
@END

View File

@ -1011,6 +1011,7 @@ C_ASSERT( FIELD_OFFSET(struct create_console_output_request, handle_in) == 12 );
C_ASSERT( FIELD_OFFSET(struct create_console_output_request, access) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_console_output_request, attributes) == 20 );
C_ASSERT( FIELD_OFFSET(struct create_console_output_request, share) == 24 );
C_ASSERT( FIELD_OFFSET(struct create_console_output_request, fd) == 28 );
C_ASSERT( sizeof(struct create_console_output_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct create_console_output_reply, handle_out) == 8 );
C_ASSERT( sizeof(struct create_console_output_reply) == 16 );

View File

@ -1704,6 +1704,7 @@ static void dump_create_console_output_request( const struct create_console_outp
fprintf( stderr, ", access=%08x", req->access );
fprintf( stderr, ", attributes=%08x", req->attributes );
fprintf( stderr, ", share=%08x", req->share );
fprintf( stderr, ", fd=%d", req->fd );
}
static void dump_create_console_output_reply( const struct create_console_output_reply *req )