[PATCH 05/12] [Server]: now allow a screen buffer to be attached to a given fd (for bare consoles)

Eric Pouech eric.pouech at orange.fr
Sat Aug 28 06:15:07 CDT 2010




A+
---

 dlls/kernel32/console.c            |    1 +
 include/wine/server_protocol.h     |    2 +-
 programs/wineconsole/wineconsole.c |    1 +
 server/console.c                   |   44 +++++++++++++++++++++++++++++++-----
 server/protocol.def                |    1 +
 server/request.h                   |    1 +
 server/trace.c                     |    1 +
 7 files changed, 44 insertions(+), 7 deletions(-)


diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index f682ca1..d760b65 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -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 ));
     }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index c35aab3..5d117de 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1640,7 +1640,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
 {
diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c
index 3842303..52edfb3 100644
--- a/programs/wineconsole/wineconsole.c
+++ b/programs/wineconsole/wineconsole.c
@@ -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 );
     }
diff --git a/server/console.c b/server/console.c
index 44078c5..3f75cff 100644
--- a/server/console.c
+++ b/server/console.c
@@ -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 input 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 */
@@ -381,7 +383,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;
@@ -402,6 +404,14 @@ 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
+    {
+        screen_buffer->fd = create_anonymous_fd( &console_fd_ops, fd, &screen_buffer->obj,
+                                                 FILE_SYNCHRONOUS_IO_NONALERT );
+        allow_fd_caching(screen_buffer->fd);
+    }
 
     list_add_head( &screen_buffer_list, &screen_buffer->entry );
 
@@ -1122,9 +1132,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,
@@ -1454,8 +1472,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 )))
@@ -1561,10 +1579,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
diff --git a/server/protocol.def b/server/protocol.def
index 2ebca95..fc85393 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1288,6 +1288,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
diff --git a/server/request.h b/server/request.h
index ca406e1..e5b854a 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1006,6 +1006,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 );
diff --git a/server/trace.c b/server/trace.c
index 443321a..ffec55f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1698,6 +1698,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 )






More information about the wine-patches mailing list