/*
 * Server-side console management
 *
 * Copyright (C) 1998 Alexandre Julliard
 *               2001 Eric Pouech
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#include "handle.h"
#include "process.h"
#include "request.h"
#include "unicode.h"
#include "console.h"

static void console_input_dump( struct object *obj, int verbose );
static void console_input_destroy( struct object *obj );

static const struct object_ops console_input_ops =
{
    sizeof(struct console_input),     /* size */
    console_input_dump,               /* dump */
    no_add_queue,                     /* add_queue */
    NULL,                             /* remove_queue */
    NULL,                             /* signaled */
    no_satisfied,                     /* satisfied */
    no_get_fd,                        /* get_fd */
    console_input_destroy             /* destroy */
};

static void console_input_events_dump( struct object *obj, int verbose );
static void console_input_events_destroy( struct object *obj );
static int  console_input_events_signaled( struct object *obj, struct thread *thread );

struct console_input_events
{
    struct object         obj;         /* object header */
    int			  num_alloc;   /* number of allocated events */
    int 		  num_used;    /* number of actually used events */
    struct console_renderer_event*	events;
};

static const struct object_ops console_input_events_ops =
{
    sizeof(struct console_input_events), /* size */
    console_input_events_dump,        /* dump */
    add_queue,                        /* add_queue */
    remove_queue,                     /* remove_queue */
    console_input_events_signaled,    /* signaled */
    no_satisfied,                     /* satisfied */
    no_get_fd,                        /* get_fd */
    console_input_events_destroy      /* destroy */
};

struct screen_buffer
{
    struct object         obj;           /* object header */
    struct screen_buffer *next;          /* linked list of all screen buffers */
    struct screen_buffer *prev;
    struct console_input *input;         /* associated console input */
    int                   mode;          /* output mode */
    int                   cursor_size;   /* size of cursor (percentage filled) */
    int                   cursor_visible;/* cursor visibility flag */
    int                   cursor_x;      /* position of cursor */
    int                   cursor_y;      /* position of cursor */
    int                   width;         /* size (w-h) of the screen buffer */
    int                   height;
    int                   max_width;     /* size (w-h) of the window given font size */
    int                   max_height;
    char_info_t          *data;          /* the data for each cell - a width x height matrix */
    unsigned short        attr;          /* default attribute for screen buffer */
    rectangle_t           win;           /* current visible window on the screen buffer *
					  * as seen in wineconsole */
};

static void screen_buffer_dump( struct object *obj, int verbose );
static void screen_buffer_destroy( struct object *obj );

static const struct object_ops screen_buffer_ops =
{
    sizeof(struct screen_buffer),     /* size */
    screen_buffer_dump,               /* dump */
    no_add_queue,                     /* add_queue */
    NULL,                             /* remove_queue */
    NULL,                             /* signaled */
    NULL,                             /* satisfied */
    no_get_fd,                        /* get_fd */
    screen_buffer_destroy             /* destroy */
};

static struct screen_buffer *screen_buffer_list;

static const char_info_t empty_char_info = { ' ', 0x000f };  /* white on black space */

/* dumps the renderer events of a console */
static void console_input_events_dump( struct object *obj, int verbose )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    fprintf( stderr, "Console input events: %d/%d events\n",
	     evts->num_used, evts->num_alloc );
}

/* destroys the renderer events of a console */
static void console_input_events_destroy( struct object *obj )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    free( evts->events );
}

/* the renderer events list is signaled when it's not empty */
static int console_input_events_signaled( struct object *obj, struct thread *thread )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    return (evts->num_used != 0);
}

/* add an event to the console's renderer events list */
static void console_input_events_append( struct console_input_events* evts,
					 struct console_renderer_event* evt)
{
    int collapsed = FALSE;

    /* to be done even when evt has been generated by the rendere ? */

    /* try to collapse evt into current queue's events */
    if (evts->num_used)
    {
        struct console_renderer_event* last = &evts->events[evts->num_used - 1];

        if (last->event == CONSOLE_RENDERER_UPDATE_EVENT &&
            evt->event == CONSOLE_RENDERER_UPDATE_EVENT)
        {
            /* if two update events overlap, collapse them into a single one */
            if (last->u.update.bottom + 1 >= evt->u.update.top &&
                evt->u.update.bottom + 1 >= last->u.update.top)
            {
                last->u.update.top = min(last->u.update.top, evt->u.update.top);
                last->u.update.bottom = max(last->u.update.bottom, evt->u.update.bottom);
                collapsed = TRUE;
            }
        }
    }
    if (!collapsed)
    {
        if (evts->num_used == evts->num_alloc)
        {
            evts->num_alloc += 16;
            evts->events = realloc( evts->events, evts->num_alloc * sizeof(*evt) );
            assert(evts->events);
        }
        evts->events[evts->num_used++] = *evt;
    }
    wake_up( &evts->obj, 0 );
}

/* retrieves events from the console's renderer events list */
static void console_input_events_get( struct console_input_events* evts )
{
    size_t num = get_reply_max_size() / sizeof(evts->events[0]);

    if (num > evts->num_used) num = evts->num_used;
    set_reply_data( evts->events, num * sizeof(evts->events[0]) );
    if (num < evts->num_used)
    {
        memmove( &evts->events[0], &evts->events[num],
                 (evts->num_used - num) * sizeof(evts->events[0]) );
    }
    evts->num_used -= num;
}

static struct console_input_events *create_console_input_events(void)
{
    struct console_input_events*	evt;

    if (!(evt = alloc_object( &console_input_events_ops ))) return NULL;
    evt->num_alloc = evt->num_used = 0;
    evt->events = NULL;
    return evt;
}

static struct object *create_console_input( struct thread* renderer )
{
    struct console_input *console_input;

    if (!(console_input = alloc_object( &console_input_ops ))) return NULL;
    console_input->renderer      = renderer;
    console_input->mode          = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
	                           ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
    console_input->num_proc      = 0;
    console_input->active        = NULL;
    console_input->recnum        = 0;
    console_input->records       = NULL;
    console_input->evt           = create_console_input_events();
    console_input->title         = NULL;
    console_input->history_size  = 50;
    console_input->history       = calloc( console_input->history_size, sizeof(WCHAR*) );
    console_input->history_index = 0;
    console_input->history_mode  = 0;
    console_input->edition_mode  = 0;
    console_input->event         = create_event( NULL, 0, 1, 0 );

    if (!console_input->history || !console_input->evt)
    {
	release_object( console_input );
	return NULL;
    }
    return &console_input->obj;
}

static struct screen_buffer *create_console_output( struct console_input *console_input )
{
    struct screen_buffer *screen_buffer;
    struct console_renderer_event evt;
    int	i;

    if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) return NULL;
    screen_buffer->mode           = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
    screen_buffer->input          = console_input;
    screen_buffer->cursor_size    = 100;
    screen_buffer->cursor_visible = 1;
    screen_buffer->width          = 80;
    screen_buffer->height         = 150;
    screen_buffer->max_width      = 80;
    screen_buffer->max_height     = 25;
    screen_buffer->cursor_x       = 0;
    screen_buffer->cursor_y       = 0;
    screen_buffer->attr           = 0x0F;
    screen_buffer->win.left       = 0;
    screen_buffer->win.right      = screen_buffer->max_width - 1;
    screen_buffer->win.top        = 0;
    screen_buffer->win.bottom     = screen_buffer->max_height - 1;

    if ((screen_buffer->next = screen_buffer_list)) screen_buffer->next->prev = screen_buffer;
    screen_buffer->prev = NULL;
    screen_buffer_list = screen_buffer;

    if (!(screen_buffer->data = malloc( screen_buffer->width * screen_buffer->height *
                                        sizeof(*screen_buffer->data) )))
    {
        release_object( screen_buffer );
        return NULL;
    }
    /* clear the first row */
    for (i = 0; i < screen_buffer->width; i++) screen_buffer->data[i] = empty_char_info;
    /* and copy it to all other rows */
    for (i = 1; i < screen_buffer->height; i++)
        memcpy( &screen_buffer->data[i * screen_buffer->width], screen_buffer->data,
                screen_buffer->width * sizeof(char_info_t) );

    if (!console_input->active)
    {
	console_input->active = (struct screen_buffer*)grab_object( screen_buffer );

	/* generate the initial events */
	evt.event = CONSOLE_RENDERER_ACTIVE_SB_EVENT;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT;
	evt.u.resize.width  = screen_buffer->width;
	evt.u.resize.height = screen_buffer->height;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_DISPLAY_EVENT;
	evt.u.display.left   = screen_buffer->win.left;
	evt.u.display.top    = screen_buffer->win.top;
	evt.u.display.width  = screen_buffer->win.right - screen_buffer->win.left + 1;
	evt.u.display.height = screen_buffer->win.bottom - screen_buffer->win.top + 1;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
	evt.u.update.top    = 0;
	evt.u.update.bottom = screen_buffer->height - 1;
	console_input_events_append( console_input->evt, &evt );

 	evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT;
 	evt.u.cursor_geom.size    = screen_buffer->cursor_size;
 	evt.u.cursor_geom.visible = screen_buffer->cursor_visible;
 	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
	evt.u.cursor_pos.x = screen_buffer->cursor_x;
	evt.u.cursor_pos.y = screen_buffer->cursor_y;
	console_input_events_append( console_input->evt, &evt );
    }
    return screen_buffer;
}

/* free the console for this process */
int free_console( struct process *process )
{
    struct console_input* console = process->console;

    if (!console || !console->renderer) return 0;

    process->console = NULL;
    if (--console->num_proc == 0)
    {
	/* all processes have terminated... tell the renderer to terminate too */
	struct console_renderer_event evt;
	evt.event = CONSOLE_RENDERER_EXIT_EVENT;
	console_input_events_append( console->evt, &evt );
    }
    release_object( console );

    return 1;
}

/* let process inherit the console from parent... this handle two cases :
 *	1/ generic console inheritance
 *	2/ parent is a renderer which launches process, and process should attach to the console
 *	   renderered by parent
 */
void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin)
{
    int done = 0;
    struct process* parent = parent_thread->process;

    /* if parent is a renderer, then attach current process to its console
     * a bit hacky....
     */
    if (hconin)
    {
	struct console_input* console;

        /* FIXME: should we check some access rights ? */
        if ((console = (struct console_input*)get_handle_obj( parent, hconin,
                                                              0, &console_input_ops )))
	{
            if (console->renderer == parent_thread)
	    {
		process->console = (struct console_input*)grab_object( console );
		process->console->num_proc++;
		done = 1;
	    }
	    release_object( console );
	}
    }
    /* otherwise, if parent has a console, attach child to this console */
    if (!done && parent->console)
    {
	assert(parent->console->renderer);
	process->console = (struct console_input*)grab_object( parent->console );
	process->console->num_proc++;
    }
}

static struct console_input* console_input_get( obj_handle_t handle, unsigned access )
{
    struct console_input*	console = 0;

    if (handle)
	console = (struct console_input *)get_handle_obj( current->process, handle,
							  access, &console_input_ops );
    else if (current->process->console)
    {
	assert( current->process->console->renderer );
	console = (struct console_input *)grab_object( current->process->console );
    }

    if (!console && !get_error()) set_error(STATUS_INVALID_PARAMETER);
    return console;
}

struct console_signal_info
{
    struct console_input        *console;
    process_id_t                 group;
    int                          signal;
};

static int propagate_console_signal_cb(struct process *process, void *user)
{
    struct console_signal_info* csi = (struct console_signal_info*)user;

    if (process->console == csi->console && process->running_threads &&
        (!csi->group || process->group_id == csi->group))
    {
        /* find a suitable thread to signal */
        struct thread *thread;
        for (thread = process->thread_list; thread; thread = thread->proc_next)
        {
            if (send_thread_signal( thread, csi->signal )) break;
        }
    }
    return FALSE;
}

static void propagate_console_signal( struct console_input *console,
                                      int sig, process_id_t group_id )
{
    struct console_signal_info csi;

    if (!console)
    {
        set_error( STATUS_INVALID_PARAMETER );
        return;
    }
    /* FIXME: should support the other events (like CTRL_BREAK) */
    if (sig != CTRL_C_EVENT)
    {
        set_error( STATUS_NOT_IMPLEMENTED );
        return;
    }
    csi.console = console;
    csi.signal  = SIGINT;
    csi.group   = group_id;

    enum_processes(propagate_console_signal_cb, &csi);
}

static int get_console_mode( obj_handle_t handle )
{
    struct object *obj;
    int ret = 0;

    if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
    {
        if (obj->ops == &console_input_ops)
            ret = ((struct console_input *)obj)->mode;
        else if (obj->ops == &screen_buffer_ops)
            ret = ((struct screen_buffer *)obj)->mode;
        else
            set_error( STATUS_OBJECT_TYPE_MISMATCH );
        release_object( obj );
    }
    return ret;
}

/* changes the mode of either a console input or a screen buffer */
static int set_console_mode( obj_handle_t handle, int mode )
{
    struct object *obj;
    int ret = 0;

    if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL )))
        return 0;
    if (obj->ops == &console_input_ops)
    {
	/* FIXME: if we remove the edit mode bits, we need (???) to clean up the history */
        ((struct console_input *)obj)->mode = mode;
        ret = 1;
    }
    else if (obj->ops == &screen_buffer_ops)
    {
        ((struct screen_buffer *)obj)->mode = mode;
        ret = 1;
    }
    else set_error( STATUS_OBJECT_TYPE_MISMATCH );
    release_object( obj );
    return ret;
}

/* add input events to a console input queue */
static int write_console_input( struct console_input* console, int count,
                                const INPUT_RECORD *records )
{
    INPUT_RECORD *new_rec;

    if (!count) return 0;
    if (!(new_rec = realloc( console->records,
                             (console->recnum + count) * sizeof(INPUT_RECORD) )))
    {
        set_error( STATUS_NO_MEMORY );
        release_object( console );
        return -1;
    }
    console->records = new_rec;
    memcpy( new_rec + console->recnum, records, count * sizeof(INPUT_RECORD) );

    if (console->mode & ENABLE_PROCESSED_INPUT)
    {
        int i = 0;
        while (i < count)
        {
            if (records[i].EventType == KEY_EVENT &&
		records[i].Event.KeyEvent.uChar.UnicodeChar == 'C' - 64 &&
		!(records[i].Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
            {
                if (i != count - 1)
                    memcpy( &console->records[console->recnum + i],
                            &console->records[console->recnum + i + 1],
                            (count - i - 1) * sizeof(INPUT_RECORD) );
                count--;
                if (records[i].Event.KeyEvent.bKeyDown)
                {
                    /* send SIGINT to all processes attached to this console */
                    propagate_console_signal( console, CTRL_C_EVENT, 0 );
                }
            }
            else i++;
        }
    }
    if (!console->recnum && count) set_event( console->event );
    console->recnum += count;
    return count;
}

/* retrieve a pointer to the console input records */
static int read_console_input( obj_handle_t handle, int count, int flush )
{
    struct console_input *console;

    if (!(console = (struct console_input *)get_handle_obj( current->process, handle,
                                                            GENERIC_READ, &console_input_ops )))
        return -1;

    if (!count)
    {
        /* special case: do not retrieve anything, but return
         * the total number of records available */
        count = console->recnum;
    }
    else
    {
        if (count > console->recnum) count = console->recnum;
        set_reply_data( console->records, count * sizeof(INPUT_RECORD) );
    }
    if (flush)
    {
        int i;
        for (i = count; i < console->recnum; i++)
            console->records[i-count] = console->records[i];
        if ((console->recnum -= count) > 0)
        {
            INPUT_RECORD *new_rec = realloc( console->records,
                                             console->recnum * sizeof(INPUT_RECORD) );
            if (new_rec) console->records = new_rec;
        }
        else
        {
            free( console->records );
            console->records = NULL;
            reset_event( console->event );
        }
    }
    release_object( console );
    return count;
}

/* set misc console input information */
static int set_console_input_info( const struct set_console_input_info_request *req,
				   const WCHAR *title, size_t len )
{
    struct console_input *console;
    struct console_renderer_event evt;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) goto error;

    if (req->mask & SET_CONSOLE_INPUT_INFO_ACTIVE_SB)
    {
	struct screen_buffer *screen_buffer;

	screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, req->active_sb,
								GENERIC_READ, &screen_buffer_ops );
	if (!screen_buffer || screen_buffer->input != console)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    if (screen_buffer) release_object( screen_buffer );
	    goto error;
	}

	if (screen_buffer != console->active)
	{
	    if (console->active) release_object( console->active );
	    console->active = screen_buffer;
	    evt.event = CONSOLE_RENDERER_ACTIVE_SB_EVENT;
	    console_input_events_append( console->evt, &evt );
	}
	else
	    release_object( screen_buffer );
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_TITLE)
    {
        WCHAR *new_title = mem_alloc( len + sizeof(WCHAR) );
        if (new_title)
        {
            memcpy( new_title, title, len );
            new_title[len / sizeof(WCHAR)] = 0;
            if (console->title) free( console->title );
            console->title = new_title;
	    evt.event = CONSOLE_RENDERER_TITLE_EVENT;
	    console_input_events_append( console->evt, &evt );
        }
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_HISTORY_MODE)
    {
	console->history_mode = req->history_mode;
    }
    if ((req->mask & SET_CONSOLE_INPUT_INFO_HISTORY_SIZE) &&
	console->history_size != req->history_size)
    {
	WCHAR**	mem = NULL;
	int	i;
	int	delta;

	if (req->history_size)
	{
	    mem = mem_alloc( req->history_size * sizeof(WCHAR*) );
	    if (!mem) goto error;
	    memset( mem, 0, req->history_size * sizeof(WCHAR*) );
	}

	delta = (console->history_index > req->history_size) ?
	    (console->history_index - req->history_size) : 0;

	for (i = delta; i < console->history_index; i++)
	{
	    mem[i - delta] = console->history[i];
	    console->history[i] = NULL;
	}
	console->history_index -= delta;

	for (i = 0; i < console->history_size; i++)
	    if (console->history[i]) free( console->history[i] );
	free( console->history );
	console->history = mem;
	console->history_size = req->history_size;
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_EDITION_MODE)
    {
        console->edition_mode = req->edition_mode;
    }
    release_object( console );
    return 1;
 error:
    if (console) release_object( console );
    return 0;
}

/* resize a screen buffer */
static int change_screen_buffer_size( struct screen_buffer *screen_buffer,
                                      int new_width, int new_height )
{
    int i, old_width, old_height, copy_width, copy_height;
    char_info_t *new_data;

    if (!(new_data = malloc( new_width * new_height * sizeof(*new_data) )))
    {
        set_error( STATUS_NO_MEMORY );
        return 0;
    }
    old_width = screen_buffer->width;
    old_height = screen_buffer->height;
    copy_width = min( old_width, new_width );
    copy_height = min( old_height, new_height );

    /* copy all the rows */
    for (i = 0; i < copy_height; i++)
    {
        memcpy( &new_data[i * new_width], &screen_buffer->data[i * old_width],
                copy_width * sizeof(char_info_t) );
    }

    /* clear the end of each row */
    if (new_width > old_width)
    {
        /* fill first row */
        for (i = old_width; i < new_width; i++) new_data[i] = empty_char_info;
        /* and blast it to the other rows */
        for (i = 1; i < copy_height; i++)
            memcpy( &new_data[i * new_width + old_width], &new_data[old_width],
                    (new_width - old_width) * sizeof(char_info_t) );
    }

    /* clear remaining rows */
    if (new_height > old_height)
    {
        /* fill first row */
        for (i = 0; i < new_width; i++) new_data[old_height * new_width + i] = empty_char_info;
        /* and blast it to the other rows */
        for (i = old_height+1; i < new_height; i++)
            memcpy( &new_data[i * new_width], &new_data[old_height * new_width],
                    new_width * sizeof(char_info_t) );
    }
    free( screen_buffer->data );
    screen_buffer->data = new_data;
    screen_buffer->width = new_width;
    screen_buffer->height = new_height;
    return 1;
}

/* set misc screen buffer information */
static int set_console_output_info( struct screen_buffer *screen_buffer,
                                    const struct set_console_output_info_request *req )
{
    struct console_renderer_event evt;

    if (req->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM)
    {
	if (req->cursor_size < 1 || req->cursor_size > 100)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
        if (screen_buffer->cursor_size != req->cursor_size ||
	    screen_buffer->cursor_visible != req->cursor_visible)
	{
	    screen_buffer->cursor_size    = req->cursor_size;
	    screen_buffer->cursor_visible = req->cursor_visible;
	    evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT;
	    evt.u.cursor_geom.size    = req->cursor_size;
	    evt.u.cursor_geom.visible = req->cursor_visible;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_POS)
    {
	if (req->cursor_x < 0 || req->cursor_x >= screen_buffer->width ||
	    req->cursor_y < 0 || req->cursor_y >= screen_buffer->height)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
	if (screen_buffer->cursor_x != req->cursor_x || screen_buffer->cursor_y != req->cursor_y)
	{
	    screen_buffer->cursor_x       = req->cursor_x;
	    screen_buffer->cursor_y       = req->cursor_y;
	    evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
	    evt.u.cursor_pos.x = req->cursor_x;
	    evt.u.cursor_pos.y = req->cursor_y;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_SIZE)
    {
        unsigned cc;

        /* new screen-buffer cannot be smaller than actual window */
	if (req->width < screen_buffer->win.right - screen_buffer->win.left + 1 ||
            req->height < screen_buffer->win.bottom - screen_buffer->win.top + 1)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
        /* FIXME: there are also some basic minimum and max size to deal with */
        if (!change_screen_buffer_size( screen_buffer, req->width, req->height )) return 0;

	evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT;
	evt.u.resize.width  = req->width;
	evt.u.resize.height = req->height;
	console_input_events_append( screen_buffer->input->evt, &evt );

	evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
	evt.u.update.top    = 0;
	evt.u.update.bottom = screen_buffer->height - 1;
	console_input_events_append( screen_buffer->input->evt, &evt );

        /* scroll window to display sb */
        if (screen_buffer->win.right >= req->width)
        {       
            screen_buffer->win.right -= screen_buffer->win.left;
            screen_buffer->win.left = 0;
        }
        if (screen_buffer->win.bottom >= req->height)
        {       
            screen_buffer->win.bottom -= screen_buffer->win.top;
            screen_buffer->win.top = 0;
        }
        /* reset cursor if needed (normally, if cursor was outside of new sb, the
         * window has been shifted so that the new position of the cursor will be 
         * visible */
        cc = 0;
        if (screen_buffer->cursor_x >= req->width)
        {
            screen_buffer->cursor_x = req->width - 1;
            cc++;
        }
        if (screen_buffer->cursor_y >= req->height)
        {
            screen_buffer->cursor_y = req->height - 1;
            cc++;
        }
        if (cc)
        {
            evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
            evt.u.cursor_pos.x = req->cursor_x;
            evt.u.cursor_pos.y = req->cursor_y;
            console_input_events_append( screen_buffer->input->evt, &evt );
        }

	if (screen_buffer == screen_buffer->input->active &&
	    screen_buffer->input->mode & ENABLE_WINDOW_INPUT)
	{
	    INPUT_RECORD	ir;
	    ir.EventType = WINDOW_BUFFER_SIZE_EVENT;
	    ir.Event.WindowBufferSizeEvent.dwSize.X = req->width;
	    ir.Event.WindowBufferSizeEvent.dwSize.Y = req->height;
	    write_console_input( screen_buffer->input, 1, &ir );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_ATTR)
    {
	screen_buffer->attr = req->attr;
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW)
    {
	if (req->win_left < 0 || req->win_left > req->win_right ||
	    req->win_right >= screen_buffer->width ||
	    req->win_top < 0  || req->win_top > req->win_bottom ||
	    req->win_bottom >= screen_buffer->height)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
	if (screen_buffer->win.left != req->win_left || screen_buffer->win.top != req->win_top ||
	    screen_buffer->win.right != req->win_right || screen_buffer->win.bottom != req->win_bottom)
	{
	    screen_buffer->win.left   = req->win_left;
	    screen_buffer->win.top    = req->win_top;
	    screen_buffer->win.right  = req->win_right;
	    screen_buffer->win.bottom = req->win_bottom;
	    evt.event = CONSOLE_RENDERER_DISPLAY_EVENT;
	    evt.u.display.left   = req->win_left;
	    evt.u.display.top    = req->win_top;
	    evt.u.display.width  = req->win_right - req->win_left + 1;
	    evt.u.display.height = req->win_bottom - req->win_top + 1;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_MAX_SIZE)
    {
	/* can only be done by renderer */
	if (current->process->console != screen_buffer->input)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}

	screen_buffer->max_width  = req->max_width;
	screen_buffer->max_height = req->max_height;
    }

    return 1;
}

/* appends a new line to history (history is a fixed size array) */
static void console_input_append_hist( struct console_input* console, const WCHAR* buf, size_t len )
{
    WCHAR*	ptr = mem_alloc( (len + 1) * sizeof(WCHAR) );

    if (!ptr)
    {
	set_error( STATUS_NO_MEMORY );
	return;
    }
    if (!console || !console->history_size)
    {
	set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
	return;
    }

    memcpy( ptr, buf, len * sizeof(WCHAR) );
    ptr[len] = 0;

    if (console->history_mode && console->history_index &&
	strncmpW( console->history[console->history_index - 1], ptr, len * sizeof(WCHAR) ) == 0)
    {
	/* ok, mode ask us to not use twice the same string...
	 * so just free mem and returns
	 */
	set_error( STATUS_ALIAS_EXISTS );
	free(ptr);
	return;
    }

    if (console->history_index < console->history_size)
    {
	console->history[console->history_index++] = ptr;
    }
    else
    {
	free( console->history[0]) ;
	memmove( &console->history[0], &console->history[1],
		 (console->history_size - 1) * sizeof(WCHAR*) );
	console->history[console->history_size - 1] = ptr;
    }
}

/* returns a line from the cache */
static size_t console_input_get_hist( struct console_input *console, int index )
{
    size_t ret = 0;

    if (index >= console->history_index) set_error( STATUS_INVALID_PARAMETER );
    else
    {
        ret = strlenW( console->history[index] ) * sizeof(WCHAR);
        set_reply_data( console->history[index], min( ret, get_reply_max_size() ));
    }
    return ret;
}

/* dumb dump */
static void console_input_dump( struct object *obj, int verbose )
{
    struct console_input *console = (struct console_input *)obj;
    assert( obj->ops == &console_input_ops );
    fprintf( stderr, "Console input active=%p evt=%p\n",
	     console->active, console->evt );
}

static void console_input_destroy( struct object *obj )
{
    struct console_input*	console_in = (struct console_input *)obj;
    struct screen_buffer*	curr;
    int				i;

    assert( obj->ops == &console_input_ops );
    if (console_in->title) free( console_in->title );
    if (console_in->records) free( console_in->records );

    if (console_in->active)	release_object( console_in->active );
    console_in->active = NULL;

    for (curr = screen_buffer_list; curr; curr = curr->next)
    {
	if (curr->input == console_in) curr->input = NULL;
    }

    release_object( console_in->evt );
    console_in->evt = NULL;
    release_object( console_in->event );

    for (i = 0; i < console_in->history_size; i++)
	if (console_in->history[i]) free( console_in->history[i] );
    if (console_in->history) free( console_in->history );
}

static void screen_buffer_dump( struct object *obj, int verbose )
{
    struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
    assert( obj->ops == &screen_buffer_ops );

    fprintf(stderr, "Console screen buffer input=%p\n", screen_buffer->input );
}

static void screen_buffer_destroy( struct object *obj )
{
    struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;

    assert( obj->ops == &screen_buffer_ops );

    if (screen_buffer->next) screen_buffer->next->prev = screen_buffer->prev;
    if (screen_buffer->prev) screen_buffer->prev->next = screen_buffer->next;
    else screen_buffer_list = screen_buffer->next;

    if (screen_buffer->input && screen_buffer->input->active == screen_buffer)
    {
	struct screen_buffer*	sb;
	for (sb = screen_buffer_list; sb && sb->input != screen_buffer->input; sb = sb->next);
	screen_buffer->input->active = sb;
    }
    if (screen_buffer->data) free( screen_buffer->data );
}

/* write data into a screen buffer */
static int write_console_output( struct screen_buffer *screen_buffer, size_t size,
                                 const void* data, enum char_info_mode mode,
                                 int x, int y, int wrap )
{
    int i;
    char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return 0;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        {
            const WCHAR *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->ch = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_ATTR:
        {
            const unsigned short *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->attr = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        {
            const char_info_t *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) *dest = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_TEXTSTDATTR:
        {
            const WCHAR *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++)
            {
                dest->ch   = ptr[i];
                dest->attr = screen_buffer->attr;
            }
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        return 0;
    }

    if (i && screen_buffer == screen_buffer->input->active)
    {
        struct console_renderer_event evt;
        evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
        evt.u.update.top    = y + x / screen_buffer->width;
        evt.u.update.bottom = y + (x + i - 1) / screen_buffer->width;
        console_input_events_append( screen_buffer->input->evt, &evt );
    }
    return i;
}

/* fill a screen buffer with uniform data */
static int fill_console_output( struct screen_buffer *screen_buffer, char_info_t data,
                                enum char_info_mode mode, int x, int y, int count, int wrap )
{
    int i;
    char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return 0;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    if (count > end - dest) count = end - dest;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        for (i = 0; i < count; i++) dest[i].ch = data.ch;
        break;
    case CHAR_INFO_MODE_ATTR:
        for (i = 0; i < count; i++) dest[i].attr = data.attr;
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        for (i = 0; i < count; i++) dest[i] = data;
        break;
    case CHAR_INFO_MODE_TEXTSTDATTR:
        for (i = 0; i < count; i++)
        {
            dest[i].ch   = data.ch;
            dest[i].attr = screen_buffer->attr;
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        return 0;
    }

    if (count && screen_buffer == screen_buffer->input->active)
    {
        struct console_renderer_event evt;
        evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
        evt.u.update.top    = y;
        evt.u.update.bottom = (y * screen_buffer->width + x + count - 1) / screen_buffer->width;
        console_input_events_append( screen_buffer->input->evt, &evt );
    }
    return i;
}

/* read data from a screen buffer */
static void read_console_output( struct screen_buffer *screen_buffer, int x, int y,
                                 enum char_info_mode mode, int wrap )
{
    int i;
    char_info_t *end, *src = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        {
            WCHAR *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i].ch;
            }
        }
        break;
    case CHAR_INFO_MODE_ATTR:
        {
            unsigned short *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i].attr;
            }
        }
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        {
            char_info_t *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i];
            }
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        break;
    }
}

/* scroll parts of a screen buffer */
static void scroll_console_output( obj_handle_t handle, int xsrc, int ysrc, int xdst, int ydst,
                                   int w, int h )
{
    struct screen_buffer *screen_buffer;
    int				j;
    char_info_t *psrc, *pdst;
    struct console_renderer_event evt;

    if (!(screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, handle,
								  GENERIC_READ, &screen_buffer_ops )))
	return;
    if (xsrc < 0 || ysrc < 0 || xdst < 0 || ydst < 0 ||
	xsrc + w > screen_buffer->width  ||
	xdst + w > screen_buffer->width  ||
	ysrc + h > screen_buffer->height ||
	ydst + h > screen_buffer->height ||
	w == 0 || h == 0)
    {
	set_error( STATUS_INVALID_PARAMETER );
	release_object( screen_buffer );
	return;
    }

    if (ysrc < ydst)
    {
	psrc = &screen_buffer->data[(ysrc + h - 1) * screen_buffer->width + xsrc];
	pdst = &screen_buffer->data[(ydst + h - 1) * screen_buffer->width + xdst];

	for (j = h; j > 0; j--)
	{
	    memcpy(pdst, psrc, w * sizeof(*pdst) );
	    pdst -= screen_buffer->width;
	    psrc -= screen_buffer->width;
	}
    }
    else
    {
	psrc = &screen_buffer->data[ysrc * screen_buffer->width + xsrc];
	pdst = &screen_buffer->data[ydst * screen_buffer->width + xdst];

	for (j = 0; j < h; j++)
	{
	    /* we use memmove here because when psrc and pdst are the same,
	     * copies are done on the same row, so the dst and src blocks
	     * can overlap */
	    memmove( pdst, psrc, w * sizeof(*pdst) );
	    pdst += screen_buffer->width;
	    psrc += screen_buffer->width;
	}
    }

    /* FIXME: this could be enhanced, by signalling scroll */
    evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
    evt.u.update.top    = min(ysrc, ydst);
    evt.u.update.bottom = max(ysrc, ydst) + h - 1;
    console_input_events_append( screen_buffer->input->evt, &evt );

    release_object( screen_buffer );
}

/* allocate a console for the renderer */
DECL_HANDLER(alloc_console)
{
    obj_handle_t in = 0;
    obj_handle_t evt = 0;
    struct process *process;
    struct process *renderer = current->process;
    struct console_input *console;

    process = (req->pid) ? get_process_from_id( req->pid ) :
              (struct process *)grab_object( renderer->parent );

    reply->handle_in = 0;
    reply->event = 0;
    if (!process) return;
    if (process != renderer && process->console)
    {
        set_error( STATUS_ACCESS_DENIED );
        goto the_end;
    }
    if ((console = (struct console_input*)create_console_input( current )))
    {
        if ((in = alloc_handle( renderer, console, req->access, req->inherit )))
        {
            if ((evt = alloc_handle( renderer, console->evt,
                                     SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, FALSE )))
            {
                if (process != renderer)
                {
                    process->console = (struct console_input*)grab_object( console );
                    console->num_proc++;
                }
                reply->handle_in = in;
                reply->event = evt;
                release_object( console );
                goto the_end;
            }
            close_handle( renderer, in, NULL );
        }
        free_console( process );
    }
 the_end:
    release_object( process );
}

/* free the console of the current process */
DECL_HANDLER(free_console)
{
    free_console( current->process );
}

/* let the renderer peek the events it's waiting on */
DECL_HANDLER(get_console_renderer_events)
{
    struct console_input_events *evt;

    evt = (struct console_input_events *)get_handle_obj( current->process, req->handle,
                                                         GENERIC_WRITE, &console_input_events_ops );
    if (!evt) return;
    console_input_events_get( evt );
    release_object( evt );
}

/* open a handle to the process console */
DECL_HANDLER(open_console)
{
    struct object      *obj = NULL;

    reply->handle = 0;
    switch (req->from)
    {
    case 0:
        if (current->process->console && current->process->console->renderer)
            obj = grab_object( (struct object*)current->process->console );
        break;
    case 1:
         if (current->process->console && current->process->console->renderer &&
             current->process->console->active)
             obj = grab_object( (struct object*)current->process->console->active );
        break;
    default:
        if ((obj = get_handle_obj( current->process, (obj_handle_t)req->from,
                                   GENERIC_READ|GENERIC_WRITE, &console_input_ops )))
        {
            struct console_input* console = (struct console_input*)obj;
            obj = (console->active) ? grab_object( console->active ) : NULL;
            release_object( console );
        }
        break;
    }

    /* FIXME: req->share is not used (as in screen buffer creation)  */
    if (obj)
    {
        reply->handle = alloc_handle( current->process, obj, req->access, req->inherit );
        release_object( obj );
    }
    else if (!get_error()) set_error( STATUS_ACCESS_DENIED );
}

/* set info about a console input */
DECL_HANDLER(set_console_input_info)
{
    set_console_input_info( req, get_req_data(), get_req_data_size() );
}

/* get info about a console (output only) */
DECL_HANDLER(get_console_input_info)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_READ ))) return;
    if (console->title)
    {
        size_t len = strlenW( console->title ) * sizeof(WCHAR);
        if (len > get_reply_max_size()) len = get_reply_max_size();
        set_reply_data( console->title, len );
    }
    reply->history_mode  = console->history_mode;
    reply->history_size  = console->history_size;
    reply->history_index = console->history_index;
    reply->edition_mode  = console->edition_mode;

    release_object( console );
}

/* get a console mode (input or output) */
DECL_HANDLER(get_console_mode)
{
    reply->mode = get_console_mode( req->handle );
}

/* set a console mode (input or output) */
DECL_HANDLER(set_console_mode)
{
    set_console_mode( req->handle, req->mode );
}

/* add input records to a console input queue */
DECL_HANDLER(write_console_input)
{
    struct console_input *console;

    reply->written = 0;
    if (!(console = (struct console_input *)get_handle_obj( current->process, req->handle,
                                                            GENERIC_WRITE, &console_input_ops )))
        return;
    reply->written = write_console_input( console, get_req_data_size() / sizeof(INPUT_RECORD),
                                          get_req_data() );
    release_object( console );
}

/* fetch input records from a console input queue */
DECL_HANDLER(read_console_input)
{
    int count = get_reply_max_size() / sizeof(INPUT_RECORD);
    reply->read = read_console_input( req->handle, count, req->flush );
}

/* appends a string to console's history */
DECL_HANDLER(append_console_input_history)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return;
    console_input_append_hist( console, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
    release_object( console );
}

/* appends a string to console's history */
DECL_HANDLER(get_console_input_history)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return;
    reply->total = console_input_get_hist( console, req->index );
    release_object( console );
}

/* creates a screen buffer */
DECL_HANDLER(create_console_output)
{
    struct console_input*	console;
    struct screen_buffer*	screen_buffer;

    if (!(console = console_input_get( req->handle_in, GENERIC_WRITE))) return;

    screen_buffer = create_console_output( console );
    if (screen_buffer)
    {
        /* FIXME: should store sharing and test it when opening the CONOUT$ device
         * see file.c on how this could be done */
        reply->handle_out = alloc_handle( current->process, screen_buffer,
                                          req->access, req->inherit );
        release_object( screen_buffer );
    }
    release_object( console );
}

/* set info about a console screen buffer */
DECL_HANDLER(set_console_output_info)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        set_console_output_info( screen_buffer, req );
        release_object( screen_buffer );
    }
}

/* get info about a console screen buffer */
DECL_HANDLER(get_console_output_info)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, req->handle,
                                                                 GENERIC_READ, &screen_buffer_ops)))
    {
        reply->cursor_size    = screen_buffer->cursor_size;
        reply->cursor_visible = screen_buffer->cursor_visible;
        reply->cursor_x       = screen_buffer->cursor_x;
        reply->cursor_y       = screen_buffer->cursor_y;
        reply->width          = screen_buffer->width;
        reply->height         = screen_buffer->height;
        reply->attr           = screen_buffer->attr;
        reply->win_left       = screen_buffer->win.left;
        reply->win_top        = screen_buffer->win.top;
        reply->win_right      = screen_buffer->win.right;
        reply->win_bottom     = screen_buffer->win.bottom;
        reply->max_width      = screen_buffer->max_width;
        reply->max_height     = screen_buffer->max_height;
        release_object( screen_buffer );
    }
}

/* read data (chars & attrs) from a screen buffer */
DECL_HANDLER(read_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_READ, &screen_buffer_ops )))
    {
        read_console_output( screen_buffer, req->x, req->y, req->mode, req->wrap );
        reply->width  = screen_buffer->width;
        reply->height = screen_buffer->height;
        release_object( screen_buffer );
    }
}

/* write data (char and/or attrs) to a screen buffer */
DECL_HANDLER(write_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        reply->written = write_console_output( screen_buffer, get_req_data_size(), get_req_data(),
                                               req->mode, req->x, req->y, req->wrap );
        reply->width  = screen_buffer->width;
        reply->height = screen_buffer->height;
        release_object( screen_buffer );
    }
}

/* fill a screen buffer with constant data (chars and/or attributes) */
DECL_HANDLER(fill_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        reply->written = fill_console_output( screen_buffer, req->data, req->mode,
                                              req->x, req->y, req->count, req->wrap );
        release_object( screen_buffer );
    }
}

/* move a rect of data in a screen buffer */
DECL_HANDLER(move_console_output)
{
    scroll_console_output( req->handle, req->x_src, req->y_src, req->x_dst, req->y_dst,
			   req->w, req->h );
}

/* sends a signal to a console (process, group...) */
DECL_HANDLER(send_console_signal)
{
    process_id_t group;

    group = req->group_id ? req->group_id : current->process->group_id;

    if (!group)
        set_error( STATUS_INVALID_PARAMETER );
    else
        propagate_console_signal( current->process->console, req->signal, group );
}

/* get console which renderer is 'current' */
static int cgwe_enum( struct process* process, void* user)
{
    if (process->console && process->console->renderer == current)
    {
        *(struct console_input**)user = process->console;
        return 1;
    }
    return 0;
}

DECL_HANDLER(get_console_wait_event)
{
    struct console_input* console = NULL;

    if (current->process->console && current->process->console->renderer)
        console = (struct console_input*)grab_object( (struct object*)current->process->console );
    else enum_processes(cgwe_enum, &console);

    if (console)
    {
        reply->handle = alloc_handle( current->process, console->event, 
                                      EVENT_ALL_ACCESS, FALSE);
        release_object( console );
    }
    else set_error( STATUS_INVALID_PARAMETER );
}
