/*
 * Server-side request handling
 *
 * Copyright (C) 1998 Alexandre Julliard
 */

#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

#include "winerror.h"
#include "winnt.h"
#include "winbase.h"
#include "wincon.h"
#define WANT_REQUEST_HANDLERS
#include "server.h"
#include "server/request.h"
#include "server/process.h"
#include "server/thread.h"

/* check that the string is NULL-terminated and that the len is correct */
#define CHECK_STRING(func,str,len) \
  do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
         fatal_protocol_error( "%s: invalid string '%.*s'\n", (func), (len), (str) ); \
     } while(0)
 
struct thread *current = NULL;  /* thread handling the current request */

/* complain about a protocol error and terminate the client connection */
static void fatal_protocol_error( const char *err, ... )
{
    va_list args;

    va_start( args, err );
    fprintf( stderr, "Protocol error:%p: ", current );
    vfprintf( stderr, err, args );
    va_end( args );
    remove_client( current->client_fd, -2 );
}

/* call a request handler */
void call_req_handler( struct thread *thread, enum request req,
                       void *data, int len, int fd )
{
    const struct handler *handler = &req_handlers[req];
    char *ptr;

    current = thread;
    if ((req < 0) || (req >= REQ_NB_REQUESTS))
    {
        fatal_protocol_error( "unknown request %d\n", req );
        return;
    }

    if (len < handler->min_size)
    {
        fatal_protocol_error( "req %d bad length %d < %d)\n", req, len, handler->min_size );
        return;
    }

    /* now call the handler */
    if (current)
    {
        CLEAR_ERROR();
        if (debug_level) trace_request( req, data, len, fd );
    }
    len -= handler->min_size;
    ptr = (char *)data + handler->min_size;
    handler->handler( data, ptr, len, fd );
    current = NULL;
}

/* handle a client timeout (unused for now) */
void call_timeout_handler( struct thread *thread )
{
    current = thread;
    if (debug_level) trace_timeout();
    CLEAR_ERROR();
    thread_timeout();
    current = NULL;
}

/* a thread has been killed */
void call_kill_handler( struct thread *thread, int exit_code )
{
    /* must be reentrant WRT call_req_handler */
    struct thread *old_current = current;
    current = thread;
    if (current)
    {
        if (debug_level) trace_kill( exit_code );
        thread_killed( current, exit_code );
    }
    current = (old_current != thread) ? old_current : NULL;
}


/* create a new process */
DECL_HANDLER(new_process)
{
    struct new_process_reply reply;
    struct process *process;

    if ((process = create_process( req )))
    {
        reply.pid    = process;
        reply.handle = alloc_handle( current->process, process,
                                     PROCESS_ALL_ACCESS, req->inherit );
        release_object( process );
    }
    else
    {
        reply.handle = -1;
        reply.pid    = NULL;
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* create a new thread */
DECL_HANDLER(new_thread)
{
    struct new_thread_reply reply;
    int new_fd;

    if ((new_fd = dup(fd)) != -1)
    {
        reply.tid = create_thread( new_fd, req->pid, req->suspend,
                                   req->inherit, &reply.handle );
        if (!reply.tid) close( new_fd );
    }
    else
        SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );

    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* initialize a new process */
DECL_HANDLER(init_process)
{
    struct init_process_reply reply;
    if (current->state != RUNNING)
    {
        fatal_protocol_error( "init_process: init_thread not called yet\n" );
        return;
    }
    if (!get_process_init_info( current->process, &reply ))
    {
        fatal_protocol_error( "init_process: called twice\n" );
        return;
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* initialize a new thread */
DECL_HANDLER(init_thread)
{
    struct init_thread_reply reply;

    if (current->state != STARTING)
    {
        fatal_protocol_error( "init_thread: already running\n" );
        return;
    }
    current->state    = RUNNING;
    current->unix_pid = req->unix_pid;
    if (current->suspend > 0)
        kill( current->unix_pid, SIGSTOP );
    reply.pid = current->process;
    reply.tid = current;
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* set the debug level */
DECL_HANDLER(set_debug)
{
    debug_level = req->level;
    /* Make sure last_req is initialized */
    current->last_req = REQ_SET_DEBUG;
    CLEAR_ERROR();
    send_reply( current, -1, 0 );
}

/* terminate a process */
DECL_HANDLER(terminate_process)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
    {
        kill_process( process, req->exit_code );
        release_object( process );
    }
    if (current) send_reply( current, -1, 0 );
}

/* terminate a thread */
DECL_HANDLER(terminate_thread)
{
    struct thread *thread;

    if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
    {
        kill_thread( thread, req->exit_code );
        release_object( thread );
    }
    if (current) send_reply( current, -1, 0 );
}

/* close a handle */
DECL_HANDLER(close_handle)
{
    close_handle( current->process, req->handle );
    send_reply( current, -1, 0 );
}

/* get information about a handle */
DECL_HANDLER(get_handle_info)
{
    struct get_handle_info_reply reply;
    reply.flags = set_handle_info( current->process, req->handle, 0, 0 );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* set a handle information */
DECL_HANDLER(set_handle_info)
{
    set_handle_info( current->process, req->handle, req->mask, req->flags );
    send_reply( current, -1, 0 );
}

/* duplicate a handle */
DECL_HANDLER(dup_handle)
{
    struct dup_handle_reply reply = { -1 };
    struct process *src, *dst;

    if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
    {
        if (req->options & DUP_HANDLE_MAKE_GLOBAL)
        {
            reply.handle = duplicate_handle( src, req->src_handle, NULL,
                                             req->access, req->inherit, req->options );
        }
        else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
        {
            reply.handle = duplicate_handle( src, req->src_handle, dst,
                                             req->access, req->inherit, req->options );
            release_object( dst );
        }
        /* close the handle no matter what happened */
        if (req->options & DUP_HANDLE_CLOSE_SOURCE)
            close_handle( src, req->src_handle );
        release_object( src );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* fetch information about a process */
DECL_HANDLER(get_process_info)
{
    struct process *process;
    struct get_process_info_reply reply = { 0, 0, 0 };

    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
    {
        get_process_info( process, &reply );
        release_object( process );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* set information about a process */
DECL_HANDLER(set_process_info)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
    {
        set_process_info( process, req );
        release_object( process );
    }
    send_reply( current, -1, 0 );
}

/* fetch information about a thread */
DECL_HANDLER(get_thread_info)
{
    struct thread *thread;
    struct get_thread_info_reply reply = { 0, 0 };

    if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
    {
        get_thread_info( thread, &reply );
        release_object( thread );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* set information about a thread */
DECL_HANDLER(set_thread_info)
{
    struct thread *thread;

    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
    {
        set_thread_info( thread, req );
        release_object( thread );
    }
    send_reply( current, -1, 0 );
}

/* debugger support operations */
DECL_HANDLER(debugger)
{
    switch ( req->op )
    {
    case DEBUGGER_FREEZE_ALL:
        suspend_all_threads();
        break;

    case DEBUGGER_UNFREEZE_ALL:
        resume_all_threads();
        break;
    }

    send_reply( current, -1, 0 );
}

/* suspend a thread */
DECL_HANDLER(suspend_thread)
{
    struct thread *thread;
    struct suspend_thread_reply reply = { -1 };
    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
    {
        reply.count = suspend_thread( thread );
        release_object( thread );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
    
}

/* resume a thread */
DECL_HANDLER(resume_thread)
{
    struct thread *thread;
    struct resume_thread_reply reply = { -1 };
    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
    {
        reply.count = resume_thread( thread );
        release_object( thread );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
    
}

/* queue an APC for a thread */
DECL_HANDLER(queue_apc)
{
    struct thread *thread;
    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
    {
        thread_queue_apc( thread, req->func, req->param );
        release_object( thread );
    }
    send_reply( current, -1, 0 );
}

/* open a handle to a process */
DECL_HANDLER(open_process)
{
    struct open_process_reply reply = { -1 };
    struct process *process = get_process_from_id( req->pid );
    if (process)
    {
        reply.handle = alloc_handle( current->process, process,
                                     req->access, req->inherit );
        release_object( process );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* select on a handle list */
DECL_HANDLER(select)
{
    if (len != req->count * sizeof(int))
        fatal_protocol_error( "select: bad length %d for %d handles\n",
                              len, req->count );
    sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
}

/* create an event */
DECL_HANDLER(create_event)
{
    struct create_event_reply reply = { -1 };
    struct object *obj;
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "create_event", name, len );

    obj = create_event( name, req->manual_reset, req->initial_state );
    if (obj)
    {
        reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* do an event operation */
DECL_HANDLER(event_op)
{
    switch(req->op)
    {
    case PULSE_EVENT:
        pulse_event( req->handle );
        break;
    case SET_EVENT:
        set_event( req->handle );
        break;
    case RESET_EVENT:
        reset_event( req->handle );
        break;
    default:
        fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
    }
    send_reply( current, -1, 0 );
}

/* create a mutex */
DECL_HANDLER(create_mutex)
{
    struct create_mutex_reply reply = { -1 };
    struct object *obj;
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "create_mutex", name, len );

    obj = create_mutex( name, req->owned );
    if (obj)
    {
        reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* release a mutex */
DECL_HANDLER(release_mutex)
{
    if (release_mutex( req->handle )) CLEAR_ERROR();
    send_reply( current, -1, 0 );
}

/* create a semaphore */
DECL_HANDLER(create_semaphore)
{
    struct create_semaphore_reply reply = { -1 };
    struct object *obj;
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "create_semaphore", name, len );

    obj = create_semaphore( name, req->initial, req->max );
    if (obj)
    {
        reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* release a semaphore */
DECL_HANDLER(release_semaphore)
{
    struct release_semaphore_reply reply;
    if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* open a handle to a named object (event, mutex, semaphore) */
DECL_HANDLER(open_named_obj)
{
    struct open_named_obj_reply reply;
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "open_named_obj", name, len );

    switch(req->type)
    {
    case OPEN_EVENT:
        reply.handle = open_event( req->access, req->inherit, name );
        break;
    case OPEN_MUTEX:
        reply.handle = open_mutex( req->access, req->inherit, name );
        break;
    case OPEN_SEMAPHORE:
        reply.handle = open_semaphore( req->access, req->inherit, name );
        break;
    case OPEN_MAPPING:
        reply.handle = open_mapping( req->access, req->inherit, name );
        break;
    default:
        fatal_protocol_error( "open_named_obj: invalid type %d\n", req->type );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* create a file */
DECL_HANDLER(create_file)
{
    struct create_file_reply reply = { -1 };
    struct object *obj;
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "create_file", name, len );

    if ((obj = create_file( fd, name, req->access,
                            req->sharing, req->create, req->attrs )) != NULL)
    {
        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* get a Unix fd to read from a file */
DECL_HANDLER(get_read_fd)
{
    struct object *obj;
    int read_fd;

    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
    {
        read_fd = obj->ops->get_read_fd( obj );
        release_object( obj );
    }
    else read_fd = -1;
    send_reply( current, read_fd, 0 );
}

/* get a Unix fd to write to a file */
DECL_HANDLER(get_write_fd)
{
    struct object *obj;
    int write_fd;

    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
    {
        write_fd = obj->ops->get_write_fd( obj );
        release_object( obj );
    }
    else write_fd = -1;
    send_reply( current, write_fd, 0 );
}

/* set a file current position */
DECL_HANDLER(set_file_pointer)
{
    struct set_file_pointer_reply reply;
    reply.low = req->low;
    reply.high = req->high;
    set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* truncate (or extend) a file */
DECL_HANDLER(truncate_file)
{
    truncate_file( req->handle );
    send_reply( current, -1, 0 );
}

/* flush a file buffers */
DECL_HANDLER(flush_file)
{
    struct object *obj;

    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
    {
        obj->ops->flush( obj );
        release_object( obj );
    }
    send_reply( current, -1, 0 );
}

/* set a file access and modification times */
DECL_HANDLER(set_file_time)
{
    set_file_time( req->handle, req->access_time, req->write_time );
    send_reply( current, -1, 0 );
}

/* get a file information */
DECL_HANDLER(get_file_info)
{
    struct object *obj;
    struct get_file_info_reply reply;

    if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
    {
        obj->ops->get_file_info( obj, &reply );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* lock a region of a file */
DECL_HANDLER(lock_file)
{
    struct file *file;

    if ((file = get_file_obj( current->process, req->handle, 0 )))
    {
        file_lock( file, req->offset_high, req->offset_low,
                   req->count_high, req->count_low );
        release_object( file );
    }
    send_reply( current, -1, 0 );
}


/* unlock a region of a file */
DECL_HANDLER(unlock_file)
{
    struct file *file;

    if ((file = get_file_obj( current->process, req->handle, 0 )))
    {
        file_unlock( file, req->offset_high, req->offset_low,
                     req->count_high, req->count_low );
        release_object( file );
    }
    send_reply( current, -1, 0 );
}


/* create an anonymous pipe */
DECL_HANDLER(create_pipe)
{
    struct create_pipe_reply reply = { -1, -1 };
    struct object *obj[2];
    if (create_pipe( obj ))
    {
        reply.handle_read = alloc_handle( current->process, obj[0],
                                          STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
                                          req->inherit );
        if (reply.handle_read != -1)
        {
            reply.handle_write = alloc_handle( current->process, obj[1],
                                               STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
                                               req->inherit );
            if (reply.handle_write == -1)
                close_handle( current->process, reply.handle_read );
        }
        release_object( obj[0] );
        release_object( obj[1] );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* allocate a console for the current process */
DECL_HANDLER(alloc_console)
{
    alloc_console( current->process );
    send_reply( current, -1, 0 );
}

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

/* open a handle to the process console */
DECL_HANDLER(open_console)
{
    struct object *obj;
    struct open_console_reply reply = { -1 };
    if ((obj = get_console( current->process, req->output )))
    {
        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* set info about a console (output only) */
DECL_HANDLER(set_console_info)
{
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "set_console_info", name, len );
    set_console_info( req->handle, req, name );
    send_reply( current, -1, 0 );
}

/* get info about a console (output only) */
DECL_HANDLER(get_console_info)
{
    struct get_console_info_reply reply;
    const char *title;
    get_console_info( req->handle, &reply, &title );
    send_reply( current, -1, 2, &reply, sizeof(reply),
                title, title ? strlen(title)+1 : 0 );
}

/* set a console fd */
DECL_HANDLER(set_console_fd)
{
    set_console_fd( req->handle, fd, req->pid );
    send_reply( current, -1, 0 );
}

/* get a console mode (input or output) */
DECL_HANDLER(get_console_mode)
{
    struct get_console_mode_reply reply;
    get_console_mode( req->handle, &reply.mode );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

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

/* add input records to a console input queue */
DECL_HANDLER(write_console_input)
{
    struct write_console_input_reply reply;
    INPUT_RECORD *records = (INPUT_RECORD *)data;

    if (len != req->count * sizeof(INPUT_RECORD))
        fatal_protocol_error( "write_console_input: bad length %d for %d records\n",
                              len, req->count );
    reply.written = write_console_input( req->handle, req->count, records );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* fetch input records from a console input queue */
DECL_HANDLER(read_console_input)
{
    read_console_input( req->handle, req->count, req->flush );
}

/* create a change notification */
DECL_HANDLER(create_change_notification)
{
    struct object *obj;
    struct create_change_notification_reply reply = { -1 };

    if ((obj = create_change_notification( req->subtree, req->filter )))
    {
        reply.handle = alloc_handle( current->process, obj,
                                     STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* create a file mapping */
DECL_HANDLER(create_mapping)
{
    struct object *obj;
    struct create_mapping_reply reply = { -1 };
    char *name = (char *)data;
    if (!len) name = NULL;
    else CHECK_STRING( "create_mapping", name, len );

    if ((obj = create_mapping( req->size_high, req->size_low,
                               req->protect, req->handle, name )))
    {
        int access = FILE_MAP_ALL_ACCESS;
        if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE;
        reply.handle = alloc_handle( current->process, obj, access, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* get a mapping information */
DECL_HANDLER(get_mapping_info)
{
    struct get_mapping_info_reply reply;
    int map_fd = get_mapping_info( req->handle, &reply );
    send_reply( current, map_fd, 1, &reply, sizeof(reply) );
}

/* create a device */
DECL_HANDLER(create_device)
{
    struct object *obj;
    struct create_device_reply reply = { -1 };

    if ((obj = create_device( req->id )))
    {
        reply.handle = alloc_handle( current->process, obj,
                                     req->access, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* create a snapshot */
DECL_HANDLER(create_snapshot)
{
    struct object *obj;
    struct create_snapshot_reply reply = { -1 };

    if ((obj = create_snapshot( req->flags )))
    {
        reply.handle = alloc_handle( current->process, obj, 0, req->inherit );
        release_object( obj );
    }
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* get the next process from a snapshot */
DECL_HANDLER(next_process)
{
    struct next_process_reply reply;
    snapshot_next_process( req->handle, req->reset, &reply );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

