/*
 * Server-side directory object management
 *
 * Copyright (C) 2005 Vitaliy Margolen
 *
 * 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 <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "ddk/wdm.h"

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

#define HASH_SIZE 7  /* default hash size */

struct directory
{
    struct object     obj;        /* object header */
    struct namespace *entries;    /* directory's name space */
};

static void directory_dump( struct object *obj, int verbose );
static unsigned int directory_map_access( struct object *obj, unsigned int access );
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
                                             unsigned int attr );
static void directory_destroy( struct object *obj );

static const struct object_ops directory_ops =
{
    sizeof(struct directory),     /* size */
    directory_dump,               /* dump */
    no_add_queue,                 /* add_queue */
    NULL,                         /* remove_queue */
    NULL,                         /* signaled */
    NULL,                         /* satisfied */
    no_signal,                    /* signal */
    no_get_fd,                    /* get_fd */
    directory_map_access,         /* map_access */
    directory_lookup_name,        /* lookup_name */
    no_close_handle,              /* close_handle */
    directory_destroy             /* destroy */
};

static struct directory *root_directory;


static void directory_dump( struct object *obj, int verbose )
{
    assert( obj->ops == &directory_ops );

    fputs( "Directory ", stderr );
    dump_object_name( obj );
    fputc( '\n', stderr );
}

static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
                                             unsigned int attr )
{
    struct directory *dir = (struct directory *)obj;
    struct object *found;
    struct unicode_str tmp;
    const WCHAR *p;

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

    if (!(p = memchrW( name->str, '\\', name->len / sizeof(WCHAR) )))
        /* Last element in the path name */
        tmp.len = name->len;
    else
        tmp.len = (p - name->str) * sizeof(WCHAR);

    tmp.str = name->str;
    if ((found = find_object( dir->entries, &tmp, attr )))
    {
        /* Skip trailing \\ */
        if (p)
        {
            p++;
            tmp.len += sizeof(WCHAR);
        }
        /* Move to the next element*/
        name->str = p;
        name->len -= tmp.len;
        return found;
    }

    if (name->str)
    {
        if (tmp.len == 0) /* Double backslash */
            set_error( STATUS_OBJECT_NAME_INVALID );
        else if (p)  /* Path still has backslashes */
            set_error( STATUS_OBJECT_PATH_NOT_FOUND );
    }
    return NULL;
}

static unsigned int directory_map_access( struct object *obj, unsigned int access )
{
    if (access & GENERIC_READ)    access |= FILE_GENERIC_READ;
    if (access & GENERIC_WRITE)   access |= FILE_GENERIC_WRITE;
    if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
    if (access & GENERIC_ALL)     access |= FILE_ALL_ACCESS;
    return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
}

static void directory_destroy( struct object *obj )
{
    struct directory *dir = (struct directory *)obj;
    assert( obj->ops == &directory_ops );
    free( dir->entries );
}

static struct directory *create_directory( struct directory *root, const struct unicode_str *name,
                                           unsigned int attr, unsigned int hash_size )
{
    struct directory *dir;

    if ((dir = create_named_object_dir( root, name, attr, &directory_ops )) &&
        get_error() != STATUS_OBJECT_NAME_EXISTS)
    {
        if (!(dir->entries = create_namespace( hash_size )))
        {
            release_object( dir );
            dir = NULL;
        }
    }
    return dir;
}

struct directory *get_directory_obj( struct process *process, obj_handle_t handle, unsigned int access )
{
    return (struct directory *)get_handle_obj( process, handle, access, &directory_ops );
}

/******************************************************************************
 * Find an object by its name in a given root object
 *
 * PARAMS
 *  root      [I] directory to start search from or NULL to start from \\
 *  name      [I] object name to search for
 *  attr      [I] OBJECT_ATTRIBUTES.Attributes
 *  name_left [O] [optional] leftover name if object is not found
 *
 * RETURNS
 *  NULL:      If params are invalid
 *  Found:     If object with exact name is found returns that object
 *             (name_left->len == 0). Object's refcount is incremented
 *  Not found: The last matched parent. (name_left->len > 0)
 *             Parent's refcount is incremented.
 */
struct object *find_object_dir( struct directory *root, const struct unicode_str *name,
                                unsigned int attr, struct unicode_str *name_left )
{
    struct object *obj, *parent;
    struct unicode_str name_tmp;

    if (name) name_tmp = *name;
    else name_tmp.len = 0;

    /* Arguments check:
     * - Either rootdir or name have to be specified
     * - If root is specified path shouldn't start with backslash */
    if (root)
    {
        if (name_tmp.len && name_tmp.str[0] == '\\')
        {
            set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
            return NULL;
        }
        parent = grab_object( root );
    }
    else
    {
        if (!name_tmp.len || name_tmp.str[0] != '\\')
        {
            set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
            return NULL;
        }
        parent = grab_object( &root_directory->obj );
        /* skip leading backslash */
        name_tmp.str++;
        name_tmp.len -= sizeof(WCHAR);
    }

    /* Special case for opening RootDirectory */
    if (!name_tmp.len) goto done;

    while ((obj = parent->ops->lookup_name( parent, &name_tmp, attr )))
    {
        /* move to the next element */
        release_object ( parent );
        parent = obj;
    }
    if (get_error())
    {
        release_object( parent );
        return NULL;
    }

    done:
    if (name_left) *name_left = name_tmp;
    return parent;
}

/* create a named (if name is present) or unnamed object. */
void *create_named_object_dir( struct directory *root, const struct unicode_str *name,
                               unsigned int attributes, const struct object_ops *ops )
{
    struct object *obj, *new_obj = NULL;
    struct unicode_str new_name;

    if (!name || !name->len) return alloc_object( ops );

    if (!(obj = find_object_dir( root, name, attributes, &new_name ))) return NULL;
    if (!new_name.len)
    {
        if (attributes & OBJ_OPENIF && obj->ops == ops)
            set_error( STATUS_OBJECT_NAME_EXISTS );
        else
        {
            release_object( obj );
            obj = NULL;
            if (attributes & OBJ_OPENIF)
                set_error( STATUS_OBJECT_TYPE_MISMATCH );
            else
                set_error( STATUS_OBJECT_NAME_COLLISION );
        }
        return obj;
    }

    /* ATM we can't insert objects into anything else but directories */
    if (obj->ops != &directory_ops)
        set_error( STATUS_OBJECT_TYPE_MISMATCH );
    else
    {
        struct directory *dir = (struct directory *)obj;
        if ((new_obj = create_object( dir->entries, ops, &new_name, &dir->obj )))
            clear_error();
    }

    release_object( obj );
    return new_obj;
}

/* open a new handle to an existing object */
void *open_object_dir( struct directory *root, const struct unicode_str *name,
                       unsigned int attr, const struct object_ops *ops )
{
    struct unicode_str name_left;
    struct object *obj;

    if ((obj = find_object_dir( root, name, attr, &name_left )))
    {
        if (name_left.len) /* not fully parsed */
            set_error( STATUS_OBJECT_NAME_NOT_FOUND );
        else if (ops && obj->ops != ops)
            set_error( STATUS_OBJECT_TYPE_MISMATCH );
        else
            return obj;

        release_object( obj );
    }
    return NULL;
}


/* Global initialization */

static struct directory *dir_driver, *dir_device;
static struct symlink *link_dosdev, *link_global1, *link_global2, *link_local;
static struct named_pipe_device *dev_named_pipe;
static struct mailslot_device *dev_mailslot;

void init_directories(void)
{
    /* Directories */
    static const WCHAR dir_globalW[] = {'\\','?','?'};
    static const WCHAR dir_driverW[] = {'D','r','i','v','e','r'};
    static const WCHAR dir_deviceW[] = {'D','e','v','i','c','e'};
    static const WCHAR dir_basenamedW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'};
    static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)};
    static const struct unicode_str dir_driver_str = {dir_driverW, sizeof(dir_driverW)};
    static const struct unicode_str dir_device_str = {dir_deviceW, sizeof(dir_deviceW)};
    static const struct unicode_str dir_basenamed_str = {dir_basenamedW, sizeof(dir_basenamedW)};

    /* symlinks */
    static const WCHAR link_dosdevW[] = {'D','o','s','D','e','v','i','c','e','s'};
    static const WCHAR link_globalW[] = {'G','l','o','b','a','l'};
    static const WCHAR link_localW[]  = {'L','o','c','a','l'};
    static const struct unicode_str link_dosdev_str = {link_dosdevW, sizeof(link_dosdevW)};
    static const struct unicode_str link_global_str = {link_globalW, sizeof(link_globalW)};
    static const struct unicode_str link_local_str  = {link_localW, sizeof(link_localW)};

    /* devices */
    static const WCHAR pipeW[] = {'P','I','P','E'};
    static const WCHAR mailslotW[] = {'M','A','I','L','S','L','O','T'};
    static const struct unicode_str pipe_str = {pipeW, sizeof(pipeW)};
    static const struct unicode_str mailslot_str = {mailslotW, sizeof(mailslotW)};

    struct directory *dir_global, *dir_basenamed;

    root_directory = create_directory( NULL, NULL, 0, HASH_SIZE );
    dir_driver     = create_directory( root_directory, &dir_driver_str, 0, HASH_SIZE );
    dir_device     = create_directory( root_directory, &dir_device_str, 0, HASH_SIZE );

    dir_global     = create_directory( NULL, &dir_global_str, 0, HASH_SIZE );
    /* use a larger hash table for this one since it can contain a lot of objects */
    dir_basenamed  = create_directory( NULL, &dir_basenamed_str, 0, 37 );

    /* symlinks */
    link_dosdev    = create_symlink( root_directory, &link_dosdev_str, 0, &dir_global_str );
    link_global1   = create_symlink( dir_global, &link_global_str, 0, &dir_global_str );
    link_global2   = create_symlink( dir_basenamed, &link_global_str, 0, &dir_basenamed_str );
    link_local     = create_symlink( dir_basenamed, &link_local_str, 0, &dir_basenamed_str );

    /* devices */
    dev_named_pipe = create_named_pipe_device( dir_global, &pipe_str );
    dev_mailslot   = create_mailslot_device( dir_global, &mailslot_str );

    /* the symlinks or devices hold references so we can release these */
    release_object( dir_global );
    release_object( dir_basenamed );
}

void close_directories(void)
{
    release_object( dev_named_pipe );
    release_object( dev_mailslot );

    release_object( link_dosdev );
    release_object( link_global1 );
    release_object( link_global2 );
    release_object( link_local );

    release_object( dir_device );
    release_object( dir_driver );
    release_object( root_directory );
}


/* create a directory object */
DECL_HANDLER(create_directory)
{
    struct unicode_str name;
    struct directory *dir, *root = NULL;

    reply->handle = 0;
    get_req_unicode_str( &name );
    if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
        return;

    if ((dir = create_directory( root, &name, req->attributes, HASH_SIZE )))
    {
        reply->handle = alloc_handle( current->process, dir, req->access, req->attributes );
        release_object( dir );
    }

    if (root) release_object( root );
}

/* open a directory object */
DECL_HANDLER(open_directory)
{
    struct unicode_str name;
    struct directory *dir, *root = NULL;

    get_req_unicode_str( &name );
    if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
        return;

    if ((dir = open_object_dir( root, &name, req->attributes, &directory_ops )))
    {
        reply->handle = alloc_handle( current->process, &dir->obj, req->access, req->attributes );
        release_object( dir );
    }

    if (root) release_object( root );
}
