/*
 * Server-side device management
 *
 * Copyright (C) 1999 Alexandre Julliard
 */

/*
 * FIXME:
 * all this stuff is a simple hack to avoid breaking
 * client-side device support.
 */

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "winerror.h"
#include "winbase.h"

#include "handle.h"
#include "thread.h"

struct device
{
    struct object  obj;             /* object header */
    int            id;              /* client identifier */
};

static void device_dump( struct object *obj, int verbose );
static int device_get_info( struct object *obj, struct get_file_info_reply *reply );
static void device_destroy( struct object *obj );

static const struct object_ops device_ops =
{
    device_dump,
    no_add_queue,
    NULL,  /* should never get called */
    NULL,  /* should never get called */
    NULL,  /* should never get called */
    no_read_fd,
    no_write_fd,
    no_flush,
    device_get_info,
    device_destroy
};

static struct object *create_device( int id )
{
    struct device *dev;

    if (!(dev = mem_alloc(sizeof(*dev)))) return NULL;
    init_object( &dev->obj, &device_ops, NULL );
    dev->id = id;
    return &dev->obj;
}

static void device_dump( struct object *obj, int verbose )
{
    struct device *dev = (struct device *)obj;
    assert( obj->ops == &device_ops );
    fprintf( stderr, "Device id=%08x\n", dev->id );
}

static int device_get_info( struct object *obj, struct get_file_info_reply *reply )
{
    struct device *dev = (struct device *)obj;
    assert( obj->ops == &device_ops );
    memset( reply, 0, sizeof(*reply) );
    reply->type = FILE_TYPE_UNKNOWN;
    reply->attr = dev->id;  /* hack! */
    return 1;
}

static void device_destroy( struct object *obj )
{
    struct device *dev = (struct device *)obj;
    assert( obj->ops == &device_ops );
    free( dev );
}

/* 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) );
}
