/*
 * Server-side handle management
 *
 * Copyright (C) 1998 Alexandre Julliard
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

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

#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"

#include "handle.h"
#include "process.h"
#include "thread.h"
#include "security.h"
#include "request.h"

struct handle_entry
{
    struct object *ptr;       /* object */
    unsigned int   access;    /* access rights */
};

struct handle_table
{
    struct object        obj;         /* object header */
    struct process      *process;     /* process owning this table */
    int                  count;       /* number of allocated entries */
    int                  last;        /* last used entry */
    int                  free;        /* first entry that may be free */
    struct handle_entry *entries;     /* handle entries */
};

static struct handle_table *global_table;

/* reserved handle access rights */
#define RESERVED_SHIFT         26
#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)

#define MIN_HANDLE_ENTRIES  32
#define MAX_HANDLE_ENTRIES  0x00ffffff


/* handle to table index conversion */

/* handles are a multiple of 4 under NT; handle 0 is not used */
static inline obj_handle_t index_to_handle( int index )
{
    return (obj_handle_t)((index + 1) << 2);
}
static inline int handle_to_index( obj_handle_t handle )
{
    return (handle >> 2) - 1;
}

/* global handle conversion */

#define HANDLE_OBFUSCATOR 0x544a4def

static inline int handle_is_global( obj_handle_t handle)
{
    return (handle ^ HANDLE_OBFUSCATOR) <= (MAX_HANDLE_ENTRIES << 2);
}
static inline obj_handle_t handle_local_to_global( obj_handle_t handle )
{
    if (!handle) return 0;
    return handle ^ HANDLE_OBFUSCATOR;
}
static inline obj_handle_t handle_global_to_local( obj_handle_t handle )
{
    return handle ^ HANDLE_OBFUSCATOR;
}

/* grab an object and increment its handle count */
static struct object *grab_object_for_handle( struct object *obj )
{
    obj->handle_count++;
    return grab_object( obj );
}

/* release an object and decrement its handle count */
static void release_object_from_handle( struct object *obj )
{
    assert( obj->handle_count );
    obj->handle_count--;
    release_object( obj );
}

static void handle_table_dump( struct object *obj, int verbose );
static void handle_table_destroy( struct object *obj );

static const struct object_ops handle_table_ops =
{
    sizeof(struct handle_table),     /* size */
    handle_table_dump,               /* dump */
    no_get_type,                     /* get_type */
    no_add_queue,                    /* add_queue */
    NULL,                            /* remove_queue */
    NULL,                            /* signaled */
    NULL,                            /* satisfied */
    no_signal,                       /* signal */
    no_get_fd,                       /* get_fd */
    no_map_access,                   /* map_access */
    default_get_sd,                  /* get_sd */
    default_set_sd,                  /* set_sd */
    no_lookup_name,                  /* lookup_name */
    no_link_name,                    /* link_name */
    NULL,                            /* unlink_name */
    no_open_file,                    /* open_file */
    no_close_handle,                 /* close_handle */
    handle_table_destroy             /* destroy */
};

/* dump a handle table */
static void handle_table_dump( struct object *obj, int verbose )
{
    int i;
    struct handle_table *table = (struct handle_table *)obj;
    struct handle_entry *entry;

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

    fprintf( stderr, "Handle table last=%d count=%d process=%p\n",
             table->last, table->count, table->process );
    if (!verbose) return;
    entry = table->entries;
    for (i = 0; i <= table->last; i++, entry++)
    {
        if (!entry->ptr) continue;
        fprintf( stderr, "    %04x: %p %08x ",
                 index_to_handle(i), entry->ptr, entry->access );
        dump_object_name( entry->ptr );
        entry->ptr->ops->dump( entry->ptr, 0 );
    }
}

/* destroy a handle table */
static void handle_table_destroy( struct object *obj )
{
    int i;
    struct handle_table *table = (struct handle_table *)obj;
    struct handle_entry *entry;

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

    /* first notify all objects that handles are being closed */
    if (table->process)
    {
        for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
        {
            struct object *obj = entry->ptr;
            if (obj) obj->ops->close_handle( obj, table->process, index_to_handle(i) );
        }
    }

    for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
    {
        struct object *obj = entry->ptr;
        entry->ptr = NULL;
        if (obj) release_object_from_handle( obj );
    }
    free( table->entries );
}

/* close all the process handles and free the handle table */
void close_process_handles( struct process *process )
{
    struct handle_table *table = process->handles;

    process->handles = NULL;
    if (table) release_object( table );
}

/* allocate a new handle table */
struct handle_table *alloc_handle_table( struct process *process, int count )
{
    struct handle_table *table;

    if (count < MIN_HANDLE_ENTRIES) count = MIN_HANDLE_ENTRIES;
    if (!(table = alloc_object( &handle_table_ops )))
        return NULL;
    table->process = process;
    table->count   = count;
    table->last    = -1;
    table->free    = 0;
    if ((table->entries = mem_alloc( count * sizeof(*table->entries) ))) return table;
    release_object( table );
    return NULL;
}

/* grow a handle table */
static int grow_handle_table( struct handle_table *table )
{
    struct handle_entry *new_entries;
    int count = min( table->count * 2, MAX_HANDLE_ENTRIES );

    if (count == table->count ||
        !(new_entries = realloc( table->entries, count * sizeof(struct handle_entry) )))
    {
        set_error( STATUS_INSUFFICIENT_RESOURCES );
        return 0;
    }
    table->entries = new_entries;
    table->count   = count;
    return 1;
}

/* allocate the first free entry in the handle table */
static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned int access )
{
    struct handle_entry *entry = table->entries + table->free;
    int i;

    for (i = table->free; i <= table->last; i++, entry++) if (!entry->ptr) goto found;
    if (i >= table->count)
    {
        if (!grow_handle_table( table )) return 0;
        entry = table->entries + i;  /* the entries may have moved */
    }
    table->last = i;
 found:
    table->free = i + 1;
    entry->ptr    = grab_object_for_handle( obj );
    entry->access = access;
    return index_to_handle(i);
}

/* allocate a handle for an object, incrementing its refcount */
static obj_handle_t alloc_handle_entry( struct process *process, void *ptr,
                                        unsigned int access, unsigned int attr )
{
    struct object *obj = ptr;

    assert( !(access & RESERVED_ALL) );
    if (attr & OBJ_INHERIT) access |= RESERVED_INHERIT;
    if (!process->handles)
    {
        set_error( STATUS_PROCESS_IS_TERMINATING );
        return 0;
    }
    return alloc_entry( process->handles, obj, access );
}

/* allocate a handle for an object, incrementing its refcount */
/* return the handle, or 0 on error */
obj_handle_t alloc_handle_no_access_check( struct process *process, void *ptr, unsigned int access, unsigned int attr )
{
    struct object *obj = ptr;
    if (access & MAXIMUM_ALLOWED) access = GENERIC_ALL;
    access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL;
    return alloc_handle_entry( process, ptr, access, attr );
}

/* allocate a handle for an object, checking the dacl allows the process to */
/* access it and incrementing its refcount */
/* return the handle, or 0 on error */
obj_handle_t alloc_handle( struct process *process, void *ptr, unsigned int access, unsigned int attr )
{
    struct object *obj = ptr;
    access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL;
    if (access && !check_object_access( obj, &access )) return 0;
    return alloc_handle_entry( process, ptr, access, attr );
}

/* allocate a global handle for an object, incrementing its refcount */
/* return the handle, or 0 on error */
static obj_handle_t alloc_global_handle_no_access_check( void *obj, unsigned int access )
{
    if (!global_table)
    {
        if (!(global_table = alloc_handle_table( NULL, 0 )))
            return 0;
        make_object_static( &global_table->obj );
    }
    return handle_local_to_global( alloc_entry( global_table, obj, access ));
}

/* allocate a global handle for an object, checking the dacl allows the */
/* process to access it and incrementing its refcount and incrementing its refcount */
/* return the handle, or 0 on error */
static obj_handle_t alloc_global_handle( void *obj, unsigned int access )
{
    if (access && !check_object_access( obj, &access )) return 0;
    return alloc_global_handle_no_access_check( obj, access );
}

/* return a handle entry, or NULL if the handle is invalid */
static struct handle_entry *get_handle( struct process *process, obj_handle_t handle )
{
    struct handle_table *table = process->handles;
    struct handle_entry *entry;
    int index;

    if (handle_is_global(handle))
    {
        handle = handle_global_to_local(handle);
        table = global_table;
    }
    if (!table) return NULL;
    index = handle_to_index( handle );
    if (index < 0) return NULL;
    if (index > table->last) return NULL;
    entry = table->entries + index;
    if (!entry->ptr) return NULL;
    return entry;
}

/* attempt to shrink a table */
static void shrink_handle_table( struct handle_table *table )
{
    struct handle_entry *entry = table->entries + table->last;
    struct handle_entry *new_entries;
    int count = table->count;

    while (table->last >= 0)
    {
        if (entry->ptr) break;
        table->last--;
        entry--;
    }
    if (table->last >= count / 4) return;  /* no need to shrink */
    if (count < MIN_HANDLE_ENTRIES * 2) return;  /* too small to shrink */
    count /= 2;
    if (!(new_entries = realloc( table->entries, count * sizeof(*new_entries) ))) return;
    table->count   = count;
    table->entries = new_entries;
}

/* copy the handle table of the parent process */
/* return 1 if OK, 0 on error */
struct handle_table *copy_handle_table( struct process *process, struct process *parent )
{
    struct handle_table *parent_table = parent->handles;
    struct handle_table *table;
    int i;

    assert( parent_table );
    assert( parent_table->obj.ops == &handle_table_ops );

    if (!(table = alloc_handle_table( process, parent_table->count )))
        return NULL;

    if ((table->last = parent_table->last) >= 0)
    {
        struct handle_entry *ptr = table->entries;
        memcpy( ptr, parent_table->entries, (table->last + 1) * sizeof(struct handle_entry) );
        for (i = 0; i <= table->last; i++, ptr++)
        {
            if (!ptr->ptr) continue;
            if (ptr->access & RESERVED_INHERIT) grab_object_for_handle( ptr->ptr );
            else ptr->ptr = NULL; /* don't inherit this entry */
        }
    }
    /* attempt to shrink the table */
    shrink_handle_table( table );
    return table;
}

/* close a handle and decrement the refcount of the associated object */
unsigned int close_handle( struct process *process, obj_handle_t handle )
{
    struct handle_table *table;
    struct handle_entry *entry;
    struct object *obj;

    if (!(entry = get_handle( process, handle ))) return STATUS_INVALID_HANDLE;
    if (entry->access & RESERVED_CLOSE_PROTECT) return STATUS_HANDLE_NOT_CLOSABLE;
    obj = entry->ptr;
    if (!obj->ops->close_handle( obj, process, handle )) return STATUS_HANDLE_NOT_CLOSABLE;
    entry->ptr = NULL;
    table = handle_is_global(handle) ? global_table : process->handles;
    if (entry < table->entries + table->free) table->free = entry - table->entries;
    if (entry == table->entries + table->last) shrink_handle_table( table );
    release_object_from_handle( obj );
    return STATUS_SUCCESS;
}

/* retrieve the object corresponding to one of the magic pseudo-handles */
static inline struct object *get_magic_handle( obj_handle_t handle )
{
    switch(handle)
    {
        case 0xfffffffa:  /* current thread impersonation token pseudo-handle */
            return (struct object *)thread_get_impersonation_token( current );
        case 0xfffffffb:  /* current thread token pseudo-handle */
            return (struct object *)current->token;
        case 0xfffffffc:  /* current process token pseudo-handle */
            return (struct object *)current->process->token;
        case 0xfffffffe:  /* current thread pseudo-handle */
            return &current->obj;
        case 0x7fffffff:  /* current process pseudo-handle */
        case 0xffffffff:  /* current process pseudo-handle */
            return (struct object *)current->process;
        default:
            return NULL;
    }
}

/* retrieve the object corresponding to a handle, incrementing its refcount */
struct object *get_handle_obj( struct process *process, obj_handle_t handle,
                               unsigned int access, const struct object_ops *ops )
{
    struct handle_entry *entry;
    struct object *obj;

    if (!(obj = get_magic_handle( handle )))
    {
        if (!(entry = get_handle( process, handle )))
        {
            set_error( STATUS_INVALID_HANDLE );
            return NULL;
        }
        obj = entry->ptr;
        if (ops && (obj->ops != ops))
        {
            set_error( STATUS_OBJECT_TYPE_MISMATCH );  /* not the right type */
            return NULL;
        }
        if ((entry->access & access) != access)
        {
            set_error( STATUS_ACCESS_DENIED );
            return NULL;
        }
    }
    else if (ops && (obj->ops != ops))
    {
        set_error( STATUS_OBJECT_TYPE_MISMATCH );  /* not the right type */
        return NULL;
    }
    return grab_object( obj );
}

/* retrieve the access rights of a given handle */
unsigned int get_handle_access( struct process *process, obj_handle_t handle )
{
    struct handle_entry *entry;

    if (get_magic_handle( handle )) return ~RESERVED_ALL;  /* magic handles have all access rights */
    if (!(entry = get_handle( process, handle ))) return 0;
    return entry->access & ~RESERVED_ALL;
}

/* find the first inherited handle of the given type */
/* this is needed for window stations and desktops (don't ask...) */
obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops )
{
    struct handle_table *table = process->handles;
    struct handle_entry *ptr;
    int i;

    if (!table) return 0;

    for (i = 0, ptr = table->entries; i <= table->last; i++, ptr++)
    {
        if (!ptr->ptr) continue;
        if (ptr->ptr->ops != ops) continue;
        if (ptr->access & RESERVED_INHERIT) return index_to_handle(i);
    }
    return 0;
}

/* enumerate handles of a given type */
/* this is needed for window stations and desktops */
obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops,
                                unsigned int *index )
{
    struct handle_table *table = process->handles;
    unsigned int i;
    struct handle_entry *entry;

    if (!table) return 0;

    for (i = *index, entry = &table->entries[i]; i <= table->last; i++, entry++)
    {
        if (!entry->ptr) continue;
        if (entry->ptr->ops != ops) continue;
        *index = i + 1;
        return index_to_handle(i);
    }
    return 0;
}

/* get/set the handle reserved flags */
/* return the old flags (or -1 on error) */
static int set_handle_flags( struct process *process, obj_handle_t handle, int mask, int flags )
{
    struct handle_entry *entry;
    unsigned int old_access;

    if (get_magic_handle( handle ))
    {
        /* we can retrieve but not set info for magic handles */
        if (mask) set_error( STATUS_ACCESS_DENIED );
        return 0;
    }
    if (!(entry = get_handle( process, handle )))
    {
        set_error( STATUS_INVALID_HANDLE );
        return -1;
    }
    old_access = entry->access;
    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
    flags = (flags << RESERVED_SHIFT) & mask;
    entry->access = (entry->access & ~mask) | flags;
    return (old_access & RESERVED_ALL) >> RESERVED_SHIFT;
}

/* duplicate a handle */
obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
                               unsigned int access, unsigned int attr, unsigned int options )
{
    obj_handle_t res;
    struct handle_entry *entry;
    unsigned int src_access;
    struct object *obj = get_handle_obj( src, src_handle, 0, NULL );

    if (!obj) return 0;
    if ((entry = get_handle( src, src_handle )))
        src_access = entry->access;
    else  /* pseudo-handle, give it full access */
        src_access = obj->ops->map_access( obj, GENERIC_ALL );
    src_access &= ~RESERVED_ALL;

    if (options & DUP_HANDLE_SAME_ACCESS)
        access = src_access;
    else
        access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL;

    /* asking for the more access rights than src_access? */
    if (access & ~src_access)
    {
        if (options & DUP_HANDLE_MAKE_GLOBAL)
            res = alloc_global_handle( obj, access );
        else
            res = alloc_handle( dst, obj, access, attr );
    }
    else
    {
        if (options & DUP_HANDLE_MAKE_GLOBAL)
            res = alloc_global_handle_no_access_check( obj, access );
        else if ((options & DUP_HANDLE_CLOSE_SOURCE) && src == dst &&
                 entry && !(entry->access & RESERVED_CLOSE_PROTECT))
        {
            if (attr & OBJ_INHERIT) access |= RESERVED_INHERIT;
            entry->access = access;
            res = src_handle;
        }
        else
            res = alloc_handle_entry( dst, obj, access, attr );
    }

    release_object( obj );
    return res;
}

/* open a new handle to an existing object */
obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned int access,
                          const struct object_ops *ops, const struct unicode_str *name,
                          unsigned int attributes )
{
    obj_handle_t handle = 0;
    struct object *obj, *root = NULL;

    if (name->len >= 65534)
    {
        set_error( STATUS_OBJECT_NAME_INVALID );
        return 0;
    }

    if (parent)
    {
        if (name->len)
            root = get_directory_obj( process, parent );
        else  /* opening the object itself can work for non-directories too */
            root = get_handle_obj( process, parent, 0, NULL );
        if (!root) return 0;
    }

    if ((obj = open_named_object( root, ops, name, attributes )))
    {
        handle = alloc_handle( process, obj, access, attributes );
        release_object( obj );
    }
    if (root) release_object( root );
    return handle;
}

/* return the size of the handle table of a given process */
unsigned int get_handle_table_count( struct process *process )
{
    if (!process->handles) return 0;
    return process->handles->count;
}

/* close a handle */
DECL_HANDLER(close_handle)
{
    unsigned int err = close_handle( current->process, req->handle );
    set_error( err );
}

/* set a handle information */
DECL_HANDLER(set_handle_info)
{
    reply->old_flags = set_handle_flags( current->process, req->handle, req->mask, req->flags );
}

/* duplicate a handle */
DECL_HANDLER(dup_handle)
{
    struct process *src, *dst = NULL;

    reply->handle = 0;
    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->attributes, 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->attributes, req->options );
            release_object( dst );
        }
        /* close the handle no matter what happened */
        if ((req->options & DUP_HANDLE_CLOSE_SOURCE) && (src != dst || req->src_handle != reply->handle))
            reply->closed = !close_handle( src, req->src_handle );
        reply->self = (src == current->process);
        release_object( src );
    }
}

DECL_HANDLER(get_object_info)
{
    struct object *obj;
    WCHAR *name;

    if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;

    reply->access = get_handle_access( current->process, req->handle );
    reply->ref_count = obj->refcount;
    reply->handle_count = obj->handle_count;
    if ((name = get_object_full_name( obj, &reply->total )))
        set_reply_data_ptr( name, min( reply->total, get_reply_max_size() ));
    release_object( obj );
}

DECL_HANDLER(set_security_object)
{
    data_size_t sd_size = get_req_data_size();
    const struct security_descriptor *sd = get_req_data();
    struct object *obj;
    unsigned int access = 0;

    if (!sd_is_valid( sd, sd_size ))
    {
        set_error( STATUS_ACCESS_VIOLATION );
        return;
    }

    if (req->security_info & OWNER_SECURITY_INFORMATION ||
        req->security_info & GROUP_SECURITY_INFORMATION ||
        req->security_info & LABEL_SECURITY_INFORMATION)
        access |= WRITE_OWNER;
    if (req->security_info & SACL_SECURITY_INFORMATION)
        access |= ACCESS_SYSTEM_SECURITY;
    if (req->security_info & DACL_SECURITY_INFORMATION)
        access |= WRITE_DAC;

    if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;

    obj->ops->set_sd( obj, sd, req->security_info );
    release_object( obj );
}

DECL_HANDLER(get_security_object)
{
    const struct security_descriptor *sd;
    struct object *obj;
    unsigned int access = READ_CONTROL;
    struct security_descriptor req_sd;
    int present;
    const SID *owner, *group;
    const ACL *sacl, *dacl;
    ACL *label_acl = NULL;

    if (req->security_info & SACL_SECURITY_INFORMATION)
        access |= ACCESS_SYSTEM_SECURITY;

    if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;

    sd = obj->ops->get_sd( obj );
    if (sd)
    {
        req_sd.control = sd->control & ~SE_SELF_RELATIVE;

        owner = sd_get_owner( sd );
        if (req->security_info & OWNER_SECURITY_INFORMATION)
            req_sd.owner_len = sd->owner_len;
        else
            req_sd.owner_len = 0;

        group = sd_get_group( sd );
        if (req->security_info & GROUP_SECURITY_INFORMATION)
            req_sd.group_len = sd->group_len;
        else
            req_sd.group_len = 0;

        sacl = sd_get_sacl( sd, &present );
        if (req->security_info & SACL_SECURITY_INFORMATION && present)
            req_sd.sacl_len = sd->sacl_len;
        else if (req->security_info & LABEL_SECURITY_INFORMATION && present && sacl)
        {
            if (!(label_acl = extract_security_labels( sacl ))) goto done;
            req_sd.sacl_len = label_acl->AclSize;
            sacl = label_acl;
        }
        else
            req_sd.sacl_len = 0;

        dacl = sd_get_dacl( sd, &present );
        if (req->security_info & DACL_SECURITY_INFORMATION && present)
            req_sd.dacl_len = sd->dacl_len;
        else
            req_sd.dacl_len = 0;

        reply->sd_len = sizeof(req_sd) + req_sd.owner_len + req_sd.group_len +
            req_sd.sacl_len + req_sd.dacl_len;
        if (reply->sd_len <= get_reply_max_size())
        {
            char *ptr = set_reply_data_size(reply->sd_len);

            memcpy( ptr, &req_sd, sizeof(req_sd) );
            ptr += sizeof(req_sd);
            memcpy( ptr, owner, req_sd.owner_len );
            ptr += req_sd.owner_len;
            memcpy( ptr, group, req_sd.group_len );
            ptr += req_sd.group_len;
            memcpy( ptr, sacl, req_sd.sacl_len );
            ptr += req_sd.sacl_len;
            memcpy( ptr, dacl, req_sd.dacl_len );
        }
        else
            set_error(STATUS_BUFFER_TOO_SMALL);
    }

done:
    release_object( obj );
    free( label_acl );
}

struct enum_handle_info
{
    unsigned int count;
    struct handle_info *handle;
};

static int enum_handles( struct process *process, void *user )
{
    struct enum_handle_info *info = user;
    struct handle_table *table = process->handles;
    struct handle_entry *entry;
    struct handle_info *handle;
    unsigned int i;

    if (!table)
        return 0;

    for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
    {
        if (!entry->ptr) continue;
        if (!info->handle)
        {
            info->count++;
            continue;
        }
        assert( info->count );
        handle = info->handle++;
        handle->owner  = process->id;
        handle->handle = index_to_handle(i);
        handle->access = entry->access & ~RESERVED_ALL;
        info->count--;
    }

    return 0;
}

DECL_HANDLER(get_system_handles)
{
    struct enum_handle_info info;
    struct handle_info *handle;
    data_size_t max_handles = get_reply_max_size() / sizeof(*handle);

    info.handle = NULL;
    info.count  = 0;
    enum_processes( enum_handles, &info );
    reply->count = info.count;

    if (max_handles < info.count)
        set_error( STATUS_BUFFER_TOO_SMALL );
    else if ((handle = set_reply_data_size( info.count * sizeof(*handle) )))
    {
        info.handle = handle;
        enum_processes( enum_handles, &info );
    }
}
