/*
 *	Object management functions
 *
 * Copyright 1999, 2000 Juergen Schmied
 * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "wine/debug.h"
#include "windef.h"
#include "winternl.h"
#include "ntdll_misc.h"
#include "wine/server.h"

WINE_DEFAULT_DEBUG_CHANNEL(ntdll);


/*
 *	Generic object functions
 */

/******************************************************************************
 * NtQueryObject [NTDLL.@]
 * ZwQueryObject [NTDLL.@]
 */
NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
                              IN OBJECT_INFORMATION_CLASS info_class,
                              OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
{
    NTSTATUS status;

    TRACE("(%p,0x%08x,%p,0x%08x,%p): stub\n",
          handle, info_class, ptr, len, used_len);

    if (used_len) *used_len = 0;

    switch (info_class)
    {
    case ObjectBasicInformation:
        {
            POBJECT_BASIC_INFORMATION p = ptr;

            if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;

            SERVER_START_REQ( get_object_info )
            {
                req->handle = wine_server_obj_handle( handle );
                status = wine_server_call( req );
                if (status == STATUS_SUCCESS)
                {
                    memset( p, 0, sizeof(*p) );
                    p->GrantedAccess = reply->access;
                    p->PointerCount = reply->ref_count;
                    p->HandleCount = 1; /* at least one */
                    if (used_len) *used_len = sizeof(*p);
                }
            }
            SERVER_END_REQ;
        }
        break;
    case ObjectNameInformation:
        {
            OBJECT_NAME_INFORMATION* p = ptr;
            ANSI_STRING unix_name;

            /* first try as a file object */

            if (!(status = server_get_unix_name( handle, &unix_name )))
            {
                UNICODE_STRING nt_name;

                if (!(status = wine_unix_to_nt_file_name( &unix_name, &nt_name )))
                {
                    if (len < sizeof(*p))
                        status = STATUS_INFO_LENGTH_MISMATCH;
                    else if (len < sizeof(*p) + nt_name.MaximumLength)
                        status = STATUS_BUFFER_OVERFLOW;
                    else
                    {
                        p->Name.Buffer = (WCHAR *)(p + 1);
                        p->Name.Length = nt_name.Length;
                        p->Name.MaximumLength = nt_name.MaximumLength;
                        memcpy( p->Name.Buffer, nt_name.Buffer, nt_name.MaximumLength );
                    }
                    if (used_len) *used_len = sizeof(*p) + nt_name.MaximumLength;
                    RtlFreeUnicodeString( &nt_name );
                }
                RtlFreeAnsiString( &unix_name );
                break;
            }
            else if (status != STATUS_OBJECT_TYPE_MISMATCH) break;

            /* not a file, treat as a generic object */

            SERVER_START_REQ( get_object_info )
            {
                req->handle = wine_server_obj_handle( handle );
                if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
                status = wine_server_call( req );
                if (status == STATUS_SUCCESS)
                {
                    if (!reply->total)  /* no name */
                    {
                        if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
                        else memset( p, 0, sizeof(*p) );
                        if (used_len) *used_len = sizeof(*p);
                    }
                    else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
                    {
                        if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
                        status = STATUS_INFO_LENGTH_MISMATCH;
                    }
                    else
                    {
                        ULONG res = wine_server_reply_size( reply );
                        p->Name.Buffer = (WCHAR *)(p + 1);
                        p->Name.Length = res;
                        p->Name.MaximumLength = res + sizeof(WCHAR);
                        p->Name.Buffer[res / sizeof(WCHAR)] = 0;
                        if (used_len) *used_len = sizeof(*p) + p->Name.MaximumLength;
                    }
                }
            }
            SERVER_END_REQ;
        }
        break;
    case ObjectDataInformation:
        {
            OBJECT_DATA_INFORMATION* p = ptr;

            if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;

            SERVER_START_REQ( set_handle_info )
            {
                req->handle = wine_server_obj_handle( handle );
                req->flags  = 0;
                req->mask   = 0;
                status = wine_server_call( req );
                if (status == STATUS_SUCCESS)
                {
                    p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) != 0;
                    p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
                    if (used_len) *used_len = sizeof(*p);
                }
            }
            SERVER_END_REQ;
        }
        break;
    default:
        FIXME("Unsupported information class %u\n", info_class);
        status = STATUS_NOT_IMPLEMENTED;
        break;
    }
    return status;
}

/******************************************************************
 *		NtSetInformationObject [NTDLL.@]
 *		ZwSetInformationObject [NTDLL.@]
 *
 */
NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
                                       IN OBJECT_INFORMATION_CLASS info_class,
                                       IN PVOID ptr, IN ULONG len)
{
    NTSTATUS status;

    TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
          handle, info_class, ptr, len);

    switch (info_class)
    {
    case ObjectDataInformation:
        {
            OBJECT_DATA_INFORMATION* p = ptr;

            if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;

            SERVER_START_REQ( set_handle_info )
            {
                req->handle = wine_server_obj_handle( handle );
                req->flags  = 0;
                req->mask   = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
                if (p->InheritHandle)    req->flags |= HANDLE_FLAG_INHERIT;
                if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
                status = wine_server_call( req );
            }
            SERVER_END_REQ;
        }
        break;
    default:
        FIXME("Unsupported information class %u\n", info_class);
        status = STATUS_NOT_IMPLEMENTED;
        break;
    }
    return status;
}

/******************************************************************************
 *  NtQuerySecurityObject	[NTDLL.@]
 *
 * An ntdll analogue to GetKernelObjectSecurity().
 *
 */
NTSTATUS WINAPI
NtQuerySecurityObject(
	IN HANDLE Object,
	IN SECURITY_INFORMATION RequestedInformation,
	OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
	IN ULONG Length,
	OUT PULONG ResultLength)
{
    PISECURITY_DESCRIPTOR_RELATIVE psd = pSecurityDescriptor;
    NTSTATUS status;
    unsigned int buffer_size = 512;
    BOOLEAN need_more_memory;

    TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
	Object, RequestedInformation, pSecurityDescriptor, Length, ResultLength);

    do
    {
        char *buffer = RtlAllocateHeap(GetProcessHeap(), 0, buffer_size);
        if (!buffer)
            return STATUS_NO_MEMORY;

        need_more_memory = FALSE;

        SERVER_START_REQ( get_security_object )
        {
            req->handle = wine_server_obj_handle( Object );
            req->security_info = RequestedInformation;
            wine_server_set_reply( req, buffer, buffer_size );
            status = wine_server_call( req );
            if (status == STATUS_SUCCESS)
            {
                struct security_descriptor *sd = (struct security_descriptor *)buffer;
                if (reply->sd_len)
                {
                    *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
                        sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
                    if (Length >= *ResultLength)
                    {
                        psd->Revision = SECURITY_DESCRIPTOR_REVISION;
                        psd->Sbz1 = 0;
                        psd->Control = sd->control | SE_SELF_RELATIVE;
                        psd->Owner = sd->owner_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : 0;
                        psd->Group = sd->group_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len : 0;
                        psd->Sacl = sd->sacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len : 0;
                        psd->Dacl = sd->dacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len + sd->sacl_len : 0;
                        /* owner, group, sacl and dacl are the same type as in the server
                         * and in the same order so we copy the memory in one block */
                        memcpy((char *)pSecurityDescriptor + sizeof(SECURITY_DESCRIPTOR_RELATIVE),
                               buffer + sizeof(struct security_descriptor),
                               sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len);
                    }
                    else
                        status = STATUS_BUFFER_TOO_SMALL;
                }
                else
                {
                    *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
                    if (Length >= *ResultLength)
                    {
                        memset(psd, 0, sizeof(*psd));
                        psd->Revision = SECURITY_DESCRIPTOR_REVISION;
                        psd->Control = SE_SELF_RELATIVE;
                    }
                    else
                        status = STATUS_BUFFER_TOO_SMALL;
                }
            }
            else if (status == STATUS_BUFFER_TOO_SMALL)
            {
                buffer_size = reply->sd_len;
                need_more_memory = TRUE;
            }
        }
        SERVER_END_REQ;
        RtlFreeHeap(GetProcessHeap(), 0, buffer);
    } while (need_more_memory);

    return status;
}


/******************************************************************************
 *  NtDuplicateObject		[NTDLL.@]
 *  ZwDuplicateObject		[NTDLL.@]
 */
NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
                                   HANDLE dest_process, PHANDLE dest,
                                   ACCESS_MASK access, ULONG attributes, ULONG options )
{
    NTSTATUS ret;
    SERVER_START_REQ( dup_handle )
    {
        req->src_process = wine_server_obj_handle( source_process );
        req->src_handle  = wine_server_obj_handle( source );
        req->dst_process = wine_server_obj_handle( dest_process );
        req->access      = access;
        req->attributes  = attributes;
        req->options     = options;

        if (!(ret = wine_server_call( req )))
        {
            if (dest) *dest = wine_server_ptr_handle( reply->handle );
            if (reply->closed && reply->self)
            {
                int fd = server_remove_fd_from_cache( source );
                if (fd != -1) close( fd );
            }
        }
    }
    SERVER_END_REQ;
    return ret;
}

/* Everquest 2 / Pirates of the Burning Sea hooks NtClose, so we need a wrapper */
NTSTATUS close_handle( HANDLE handle )
{
    NTSTATUS ret;
    int fd = server_remove_fd_from_cache( handle );

    SERVER_START_REQ( close_handle )
    {
        req->handle = wine_server_obj_handle( handle );
        ret = wine_server_call( req );
    }
    SERVER_END_REQ;
    if (fd != -1) close( fd );
    return ret;
}

/**************************************************************************
 *                 NtClose				[NTDLL.@]
 *
 * Close a handle reference to an object.
 * 
 * PARAMS
 *  Handle [I] handle to close
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtClose( HANDLE Handle )
{
    return close_handle( Handle );
}

/*
 *	Directory functions
 */

/**************************************************************************
 * NtOpenDirectoryObject [NTDLL.@]
 * ZwOpenDirectoryObject [NTDLL.@]
 *
 * Open a namespace directory object.
 * 
 * PARAMS
 *  DirectoryHandle  [O] Destination for the new directory handle
 *  DesiredAccess    [I] Desired access to the directory
 *  ObjectAttributes [I] Structure describing the directory
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
                                      POBJECT_ATTRIBUTES ObjectAttributes)
{
    NTSTATUS ret;

    if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
    if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
    TRACE("(%p,0x%08x,%s)\n", DirectoryHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes));
    /* Have to test it here because server won't know difference between
     * ObjectName == NULL and ObjectName == "" */
    if (!ObjectAttributes->ObjectName)
    {
        if (ObjectAttributes->RootDirectory)
            return STATUS_OBJECT_NAME_INVALID;
        else
            return STATUS_OBJECT_PATH_SYNTAX_BAD;
    }

    SERVER_START_REQ(open_directory)
    {
        req->access = DesiredAccess;
        req->attributes = ObjectAttributes->Attributes;
        req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory );
        if (ObjectAttributes->ObjectName)
            wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
                                 ObjectAttributes->ObjectName->Length);
        ret = wine_server_call( req );
        *DirectoryHandle = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}

/******************************************************************************
 *  NtCreateDirectoryObject	[NTDLL.@]
 *  ZwCreateDirectoryObject	[NTDLL.@]
 *
 * Create a namespace directory object.
 * 
 * PARAMS
 *  DirectoryHandle  [O] Destination for the new directory handle
 *  DesiredAccess    [I] Desired access to the directory
 *  ObjectAttributes [I] Structure describing the directory
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
                                        POBJECT_ATTRIBUTES ObjectAttributes)
{
    NTSTATUS ret;

    if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
    TRACE("(%p,0x%08x,%s)\n", DirectoryHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes));

    SERVER_START_REQ(create_directory)
    {
        req->access = DesiredAccess;
        req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
        req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
        if (ObjectAttributes && ObjectAttributes->ObjectName)
            wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
                                 ObjectAttributes->ObjectName->Length);
        ret = wine_server_call( req );
        *DirectoryHandle = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}

/******************************************************************************
 * NtQueryDirectoryObject [NTDLL.@]
 * ZwQueryDirectoryObject [NTDLL.@]
 *
 * Read information from a namespace directory.
 * 
 * PARAMS
 *  handle        [I]   Handle to a directory object
 *  buffer        [O]   Buffer to hold the read data
 *  size          [I]   Size of the buffer in bytes
 *  single_entry  [I]   If TRUE, return a single entry, if FALSE, return as many as fit in the buffer
 *  restart       [I]   If TRUE, start scanning from the start, if FALSE, scan from Context
 *  context       [I/O] Indicates what point of the directory the scan is at
 *  ret_size      [O]   Caller supplied storage for the number of bytes written (or NULL)
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtQueryDirectoryObject(HANDLE handle, PDIRECTORY_BASIC_INFORMATION buffer,
                                       ULONG size, BOOLEAN single_entry, BOOLEAN restart,
                                       PULONG context, PULONG ret_size)
{
    NTSTATUS ret;

    if (restart) *context = 0;

    if (single_entry)
    {
        if (size <= sizeof(*buffer) + 2*sizeof(WCHAR)) return STATUS_BUFFER_OVERFLOW;

        SERVER_START_REQ( get_directory_entry )
        {
            req->handle = wine_server_obj_handle( handle );
            req->index = *context;
            wine_server_set_reply( req, buffer + 1, size - sizeof(*buffer) - 2*sizeof(WCHAR) );
            if (!(ret = wine_server_call( req )))
            {
                buffer->ObjectName.Buffer = (WCHAR *)(buffer + 1);
                buffer->ObjectName.Length = reply->name_len;
                buffer->ObjectName.MaximumLength = reply->name_len + sizeof(WCHAR);
                buffer->ObjectTypeName.Buffer = (WCHAR *)(buffer + 1) + reply->name_len/sizeof(WCHAR) + 1;
                buffer->ObjectTypeName.Length = wine_server_reply_size( reply ) - reply->name_len;
                buffer->ObjectTypeName.MaximumLength = buffer->ObjectTypeName.Length + sizeof(WCHAR);
                /* make room for the terminating null */
                memmove( buffer->ObjectTypeName.Buffer, buffer->ObjectTypeName.Buffer - 1,
                         buffer->ObjectTypeName.Length );
                buffer->ObjectName.Buffer[buffer->ObjectName.Length/sizeof(WCHAR)] = 0;
                buffer->ObjectTypeName.Buffer[buffer->ObjectTypeName.Length/sizeof(WCHAR)] = 0;
                (*context)++;
            }
        }
        SERVER_END_REQ;
        if (ret_size)
            *ret_size = buffer->ObjectName.MaximumLength + buffer->ObjectTypeName.MaximumLength + sizeof(*buffer);
    }
    else
    {
        FIXME("multiple entries not implemented\n");
        ret = STATUS_NOT_IMPLEMENTED;
    }

    return ret;
}

/*
 *	Link objects
 */

/******************************************************************************
 *  NtOpenSymbolicLinkObject	[NTDLL.@]
 *  ZwOpenSymbolicLinkObject	[NTDLL.@]
 *
 * Open a namespace symbolic link object.
 * 
 * PARAMS
 *  LinkHandle       [O] Destination for the new symbolic link handle
 *  DesiredAccess    [I] Desired access to the symbolic link
 *  ObjectAttributes [I] Structure describing the symbolic link
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess,
                                         IN POBJECT_ATTRIBUTES ObjectAttributes)
{
    NTSTATUS ret;
    TRACE("(%p,0x%08x,%s)\n",LinkHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes));

    if (!LinkHandle) return STATUS_ACCESS_VIOLATION;
    if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
    /* Have to test it here because server won't know difference between
     * ObjectName == NULL and ObjectName == "" */
    if (!ObjectAttributes->ObjectName)
    {
        if (ObjectAttributes->RootDirectory)
            return STATUS_OBJECT_NAME_INVALID;
        else
            return STATUS_OBJECT_PATH_SYNTAX_BAD;
    }

    SERVER_START_REQ(open_symlink)
    {
        req->access = DesiredAccess;
        req->attributes = ObjectAttributes->Attributes;
        req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory );
        if (ObjectAttributes->ObjectName)
            wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
                                 ObjectAttributes->ObjectName->Length);
        ret = wine_server_call( req );
        *LinkHandle = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}

/******************************************************************************
 *  NtCreateSymbolicLinkObject	[NTDLL.@]
 *  ZwCreateSymbolicLinkObject	[NTDLL.@]
 *
 * Open a namespace symbolic link object.
 * 
 * PARAMS
 *  SymbolicLinkHandle [O] Destination for the new symbolic link handle
 *  DesiredAccess      [I] Desired access to the symbolic link
 *  ObjectAttributes   [I] Structure describing the symbolic link
 *  TargetName         [I] Name of the target symbolic link points to
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
	                                   IN POBJECT_ATTRIBUTES ObjectAttributes,
                                           IN PUNICODE_STRING TargetName)
{
    NTSTATUS ret;

    if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
    if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;

    TRACE("(%p,0x%08x,%s -> %s)\n", SymbolicLinkHandle, DesiredAccess,
          debugstr_ObjectAttributes(ObjectAttributes), debugstr_us(TargetName));

    SERVER_START_REQ(create_symlink)
    {
        req->access = DesiredAccess;
        req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
        req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
        if (ObjectAttributes && ObjectAttributes->ObjectName)
        {
            req->name_len = ObjectAttributes->ObjectName->Length;
            wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
                                 ObjectAttributes->ObjectName->Length);
        }
        else
            req->name_len = 0;
        wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
        ret = wine_server_call( req );
        *SymbolicLinkHandle = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}

/******************************************************************************
 *  NtQuerySymbolicLinkObject	[NTDLL.@]
 *  ZwQuerySymbolicLinkObject	[NTDLL.@]
 *
 * Query a namespace symbolic link object target name.
 *
 * PARAMS
 *  handle     [I] Handle to a symbolic link object
 *  target     [O] Destination for the symbolic link target
 *  length     [O] Size of returned data
 *
 * RETURNS
 *  Success: ERROR_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtQuerySymbolicLinkObject( HANDLE handle, PUNICODE_STRING target, PULONG length )
{
    NTSTATUS ret;

    TRACE("(%p,%p,%p)\n", handle, target, length );

    if (!target) return STATUS_ACCESS_VIOLATION;

    SERVER_START_REQ(query_symlink)
    {
        req->handle = wine_server_obj_handle( handle );
        if (target->MaximumLength >= sizeof(WCHAR))
            wine_server_set_reply( req, target->Buffer, target->MaximumLength - sizeof(WCHAR) );
        if (!(ret = wine_server_call( req )))
        {
            target->Length = wine_server_reply_size(reply);
            target->Buffer[target->Length / sizeof(WCHAR)] = 0;
            if (length) *length = reply->total + sizeof(WCHAR);
        }
        else if (length && ret == STATUS_BUFFER_TOO_SMALL) *length = reply->total + sizeof(WCHAR);
    }
    SERVER_END_REQ;
    return ret;
}

/******************************************************************************
 *  NtAllocateUuids   [NTDLL.@]
 */
NTSTATUS WINAPI NtAllocateUuids(
        PULARGE_INTEGER Time,
        PULONG Range,
        PULONG Sequence)
{
        FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);
	return 0;
}

/**************************************************************************
 *  NtMakeTemporaryObject	[NTDLL.@]
 *  ZwMakeTemporaryObject	[NTDLL.@]
 *
 * Make a permanent object temporary.
 *
 * PARAMS
 *  Handle [I] handle to permanent object
 *
 * RETURNS
 *  Success: STATUS_SUCCESS.
 *  Failure: An NTSTATUS error code.
 */
NTSTATUS WINAPI NtMakeTemporaryObject( HANDLE Handle )
{
    FIXME("(%p), stub.\n", Handle);
    return STATUS_SUCCESS;
}
