/*
 * Registry management
 *
 * Copyright (C) 1999 Alexandre Julliard
 *
 * Based on misc/registry.c code
 * Copyright (C) 1996 Marcus Meissner
 * Copyright (C) 1998 Matthew Becker
 * Copyright (C) 1999 Sylvain St-Germain
 *
 * This file is concerned about handle management and interaction with the Wine server.
 * Registry file I/O is in misc/registry.c.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "wine/winbase16.h"
#include "wine/unicode.h"
#include "wine/winestring.h"
#include "heap.h"
#include "server.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(reg);


/* Ansi->Unicode conversion without string delimiters */
static LPWSTR memcpyAtoW( LPWSTR dst, LPCSTR src, INT n )
{
    LPWSTR p = dst;
    while (n-- > 0) *p++ = (WCHAR)*src++;
    return dst;
}

/* Unicode->Ansi conversion without string delimiters */
static LPSTR memcpyWtoA( LPSTR dst, LPCWSTR src, INT n )
{
    LPSTR p = dst;
    while (n-- > 0) *p++ = (CHAR)*src++;
    return dst;
}

/* check if value type needs string conversion (Ansi<->Unicode) */
static inline int is_string( DWORD type )
{
    return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
}

/* copy a key name into the request buffer */
static inline DWORD copy_nameW( LPWSTR dest, LPCWSTR name )
{
    if (name)
    {
        if (strlenW(name) > MAX_PATH) return ERROR_MORE_DATA;
        strcpyW( dest, name );
    }
    else dest[0] = 0;
    return ERROR_SUCCESS;
}

/* copy a key name into the request buffer */
static inline DWORD copy_nameAtoW( LPWSTR dest, LPCSTR name )
{
    if (name)
    {
        if (strlen(name) > MAX_PATH) return ERROR_MORE_DATA;
        lstrcpyAtoW( dest, name );
    }
    else dest[0] = 0;
    return ERROR_SUCCESS;
}

/* do a server call without setting the last error code */
static inline int reg_server_call( enum request req )
{
    unsigned int res = server_call_noerr( req );
    if (res) res = RtlNtStatusToDosError(res);
    return res;
}

/******************************************************************************
 *           RegCreateKeyExW   [ADVAPI32.131]
 *
 * PARAMS
 *    hkey       [I] Handle of an open key
 *    name       [I] Address of subkey name
 *    reserved   [I] Reserved - must be 0
 *    class      [I] Address of class string
 *    options    [I] Special options flag
 *    access     [I] Desired security access
 *    sa         [I] Address of key security structure
 *    retkey     [O] Address of buffer for opened handle
 *    dispos     [O] Receives REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY
 *
 * NOTES
 *  in case of failing retkey remains untouched
 */
DWORD WINAPI RegCreateKeyExW( HKEY hkey, LPCWSTR name, DWORD reserved, LPWSTR class,
                              DWORD options, REGSAM access, SECURITY_ATTRIBUTES *sa, 
                              LPHKEY retkey, LPDWORD dispos )
{
    DWORD ret;
    struct create_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", hkey, debugstr_w(name), reserved,
           debugstr_w(class), options, access, sa, retkey, dispos );

    if (reserved) return ERROR_INVALID_PARAMETER;
    if (!(access & KEY_ALL_ACCESS) || (access & ~KEY_ALL_ACCESS)) return ERROR_ACCESS_DENIED;

    req->parent  = hkey;
    req->access  = access;
    req->options = options;
    req->modif   = time(NULL);
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    lstrcpynW( req->class, class ? class : (LPWSTR)"\0\0",
               server_remaining(req->class) / sizeof(WCHAR) );
    if ((ret = reg_server_call( REQ_CREATE_KEY )) == ERROR_SUCCESS)
    {
        *retkey = req->hkey;
        if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
    }
    return ret;
}


/******************************************************************************
 *           RegCreateKeyExA   [ADVAPI32.130]
 */
DWORD WINAPI RegCreateKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, LPSTR class,
                              DWORD options, REGSAM access, SECURITY_ATTRIBUTES *sa, 
                              LPHKEY retkey, LPDWORD dispos )
{
    DWORD ret;
    struct create_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", hkey, debugstr_a(name), reserved,
           debugstr_a(class), options, access, sa, retkey, dispos );

    if (reserved) return ERROR_INVALID_PARAMETER;
    if (!(access & KEY_ALL_ACCESS) || (access & ~KEY_ALL_ACCESS)) return ERROR_ACCESS_DENIED;

    req->parent  = hkey;
    req->access  = access;
    req->options = options;
    req->modif   = time(NULL);
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    lstrcpynAtoW( req->class, class ? class : "",
                  server_remaining(req->class) / sizeof(WCHAR) );
    if ((ret = reg_server_call( REQ_CREATE_KEY )) == ERROR_SUCCESS)
    {
        *retkey = req->hkey;
        if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
    }
    return ret;
}


/******************************************************************************
 *           RegCreateKeyW   [ADVAPI32.132]
 */
DWORD WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR name, LPHKEY retkey )
{
    /* FIXME: previous implementation converted ERROR_INVALID_HANDLE to ERROR_BADKEY, */
    /* but at least my version of NT (4.0 SP5) doesn't do this.  -- AJ */
    return RegCreateKeyExW( hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
                            KEY_ALL_ACCESS, NULL, retkey, NULL );
}


/******************************************************************************
 *           RegCreateKeyA   [ADVAPI32.129]
 */
DWORD WINAPI RegCreateKeyA( HKEY hkey, LPCSTR name, LPHKEY retkey )
{
    return RegCreateKeyExA( hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
                            KEY_ALL_ACCESS, NULL, retkey, NULL );
}



/******************************************************************************
 *           RegOpenKeyExW   [ADVAPI32.150]
 *
 * Opens the specified key
 *
 * Unlike RegCreateKeyEx, this does not create the key if it does not exist.
 *
 * PARAMS
 *    hkey       [I] Handle of open key
 *    name       [I] Name of subkey to open
 *    reserved   [I] Reserved - must be zero
 *    access     [I] Security access mask
 *    retkey     [O] Handle to open key
 *
 * RETURNS
 *    Success: ERROR_SUCCESS
 *    Failure: Error code
 *
 * NOTES
 *  in case of failing is retkey = 0
 */
DWORD WINAPI RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD reserved, REGSAM access, LPHKEY retkey )
{
    DWORD ret;
    struct open_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s,%ld,%lx,%p)\n", hkey, debugstr_w(name), reserved, access, retkey );

    if (!retkey) return ERROR_INVALID_PARAMETER;
    *retkey = 0;

    req->parent = hkey;
    req->access = access;
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    if ((ret = reg_server_call( REQ_OPEN_KEY )) == ERROR_SUCCESS) *retkey = req->hkey;
    return ret;
}


/******************************************************************************
 *           RegOpenKeyExA   [ADVAPI32.149]
 */
DWORD WINAPI RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, REGSAM access, LPHKEY retkey )
{
    DWORD ret;
    struct open_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s,%ld,%lx,%p)\n", hkey, debugstr_a(name), reserved, access, retkey );

    if (!retkey) return ERROR_INVALID_PARAMETER;
    *retkey = 0;

    req->parent = hkey;
    req->access = access;
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    if ((ret = reg_server_call( REQ_OPEN_KEY )) == ERROR_SUCCESS) *retkey = req->hkey;
    return ret;
}


/******************************************************************************
 *           RegOpenKeyW   [ADVAPI32.151]
 *
 * PARAMS
 *    hkey    [I] Handle of open key
 *    name    [I] Address of name of subkey to open
 *    retkey  [O] Handle to open key
 *
 * RETURNS
 *    Success: ERROR_SUCCESS
 *    Failure: Error code
 *
 * NOTES
 *  in case of failing is retkey = 0
 */
DWORD WINAPI RegOpenKeyW( HKEY hkey, LPCWSTR name, LPHKEY retkey )
{
    return RegOpenKeyExW( hkey, name, 0, KEY_ALL_ACCESS, retkey );
}


/******************************************************************************
 *           RegOpenKeyA   [ADVAPI32.148]
 */
DWORD WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, LPHKEY retkey )
{
    return RegOpenKeyExA( hkey, name, 0, KEY_ALL_ACCESS, retkey );
}



/******************************************************************************
 *           RegEnumKeyExW   [ADVAPI32.139]
 *
 * PARAMS
 *    hkey         [I] Handle to key to enumerate
 *    index        [I] Index of subkey to enumerate
 *    name         [O] Buffer for subkey name
 *    name_len     [O] Size of subkey buffer
 *    reserved     [I] Reserved
 *    class        [O] Buffer for class string
 *    class_len    [O] Size of class buffer
 *    ft           [O] Time key last written to
 */
DWORD WINAPI RegEnumKeyExW( HKEY hkey, DWORD index, LPWSTR name, LPDWORD name_len,
                            LPDWORD reserved, LPWSTR class, LPDWORD class_len, FILETIME *ft )
{
    DWORD ret, len, cls_len;
    struct enum_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%ld,%p,%p(%ld),%p,%p,%p,%p)\n", hkey, index, name, name_len,
           name_len ? *name_len : -1, reserved, class, class_len, ft );

    if (reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->index = index;
    if ((ret = reg_server_call( REQ_ENUM_KEY )) != ERROR_SUCCESS) return ret;

    len = strlenW( req->name ) + 1;
    cls_len = strlenW( req->class ) + 1;
    if (len > *name_len) return ERROR_MORE_DATA;
    if (class_len && (cls_len > *class_len)) return ERROR_MORE_DATA;

    memcpy( name, req->name, len * sizeof(WCHAR) );
    *name_len = len - 1;
    if (class_len)
    {
        if (class) memcpy( class, req->class, cls_len * sizeof(WCHAR) );
        *class_len = cls_len - 1;
    }
    if (ft) RtlSecondsSince1970ToTime( req->modif, ft );
    return ERROR_SUCCESS;
}


/******************************************************************************
 *           RegEnumKeyExA   [ADVAPI32.138]
 */
DWORD WINAPI RegEnumKeyExA( HKEY hkey, DWORD index, LPSTR name, LPDWORD name_len,
                            LPDWORD reserved, LPSTR class, LPDWORD class_len, FILETIME *ft )
{
    DWORD ret, len, cls_len;
    struct enum_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%ld,%p,%p(%ld),%p,%p,%p,%p)\n", hkey, index, name, name_len,
           name_len ? *name_len : -1, reserved, class, class_len, ft );

    if (reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->index = index;
    if ((ret = reg_server_call( REQ_ENUM_KEY )) != ERROR_SUCCESS) return ret;

    len = strlenW( req->name ) + 1;
    cls_len = strlenW( req->class ) + 1;
    if (len > *name_len) return ERROR_MORE_DATA;
    if (class_len && (cls_len > *class_len)) return ERROR_MORE_DATA;

    memcpyWtoA( name, req->name, len );
    *name_len = len - 1;
    if (class_len)
    {
        if (class) memcpyWtoA( class, req->class, cls_len );
        *class_len = cls_len - 1;
    }
    if (ft) RtlSecondsSince1970ToTime( req->modif, ft );
    return ERROR_SUCCESS;
}


/******************************************************************************
 *           RegEnumKeyW   [ADVAPI32.140]
 */
DWORD WINAPI RegEnumKeyW( HKEY hkey, DWORD index, LPWSTR name, DWORD name_len )
{
    return RegEnumKeyExW( hkey, index, name, &name_len, NULL, NULL, NULL, NULL );
}


/******************************************************************************
 *           RegEnumKeyA   [ADVAPI32.137]
 */
DWORD WINAPI RegEnumKeyA( HKEY hkey, DWORD index, LPSTR name, DWORD name_len )
{
    return RegEnumKeyExA( hkey, index, name, &name_len, NULL, NULL, NULL, NULL );
}


/******************************************************************************
 *           RegQueryInfoKeyW   [ADVAPI32.153]
 *
 * PARAMS
 *    hkey       [I] Handle to key to query
 *    class      [O] Buffer for class string
 *    class_len  [O] Size of class string buffer
 *    reserved   [I] Reserved
 *    subkeys    [O] Buffer for number of subkeys
 *    max_subkey [O] Buffer for longest subkey name length
 *    max_class  [O] Buffer for longest class string length
 *    values     [O] Buffer for number of value entries
 *    max_value  [O] Buffer for longest value name length
 *    max_data   [O] Buffer for longest value data length
 *    security   [O] Buffer for security descriptor length
 *    modif      [O] Modification time
 *
 * - win95 allows class to be valid and class_len to be NULL 
 * - winnt returns ERROR_INVALID_PARAMETER if class is valid and class_len is NULL
 * - both allow class to be NULL and class_len to be NULL 
 * (it's hard to test validity, so test !NULL instead)
 */
DWORD WINAPI RegQueryInfoKeyW( HKEY hkey, LPWSTR class, LPDWORD class_len, LPDWORD reserved,
                               LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
                               LPDWORD values, LPDWORD max_value, LPDWORD max_data,
                               LPDWORD security, FILETIME *modif )
{
    DWORD ret;
    struct query_key_info_request *req = get_req_buffer();


    TRACE( "(0x%x,%p,%ld,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0,
           reserved, subkeys, max_subkey, values, max_value, max_data, security, modif );

    if (class && !class_len && !(GetVersion() & 0x80000000 /*NT*/))
        return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    if ((ret = reg_server_call( REQ_QUERY_KEY_INFO )) != ERROR_SUCCESS) return ret;

    if (class)
    {
        if (class_len && (strlenW(req->class) + 1 > *class_len))
        {
            *class_len = strlenW(req->class);
            return ERROR_MORE_DATA;
        }
        strcpyW( class, req->class );
    }
    if (class_len) *class_len = strlenW( req->class );
    if (subkeys) *subkeys = req->subkeys;
    if (max_subkey) *max_subkey = req->max_subkey;
    if (max_class) *max_class = req->max_class;
    if (values) *values = req->values;
    if (max_value) *max_value = req->max_value;
    if (max_data) *max_data = req->max_data;
    if (modif) RtlSecondsSince1970ToTime( req->modif, modif );
    return ERROR_SUCCESS;
}


/******************************************************************************
 *           RegQueryInfoKeyA   [ADVAPI32.152]
 */
DWORD WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
                               LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
                               LPDWORD values, LPDWORD max_value, LPDWORD max_data,
                               LPDWORD security, FILETIME *modif )
{
    DWORD ret;
    struct query_key_info_request *req = get_req_buffer();


    TRACE( "(0x%x,%p,%ld,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0,
           reserved, subkeys, max_subkey, values, max_value, max_data, security, modif );

    if (class && !class_len && !(GetVersion() & 0x80000000 /*NT*/))
        return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    if ((ret = reg_server_call( REQ_QUERY_KEY_INFO )) != ERROR_SUCCESS) return ret;

    if (class)
    {
        if (class_len && (strlenW(req->class) + 1 > *class_len))
        {
            *class_len = strlenW(req->class);
            return ERROR_MORE_DATA;
        }
        lstrcpyWtoA( class, req->class );
    }
    if (class_len) *class_len = strlenW( req->class );
    if (subkeys) *subkeys = req->subkeys;
    if (max_subkey) *max_subkey = req->max_subkey;
    if (max_class) *max_class = req->max_class;
    if (values) *values = req->values;
    if (max_value) *max_value = req->max_value;
    if (max_data) *max_data = req->max_data;
    if (modif) RtlSecondsSince1970ToTime( req->modif, modif );
    return ERROR_SUCCESS;
}


/******************************************************************************
 *           RegCloseKey   [ADVAPI32.126]
 *
 * Releases the handle of the specified key
 *
 * PARAMS
 *    hkey [I] Handle of key to close
 *
 * RETURNS
 *    Success: ERROR_SUCCESS
 *    Failure: Error code
 */
DWORD WINAPI RegCloseKey( HKEY hkey )
{
    struct close_key_request *req = get_req_buffer();
    TRACE( "(0x%x)\n", hkey );
    req->hkey = hkey;
    return reg_server_call( REQ_CLOSE_KEY );
}


/******************************************************************************
 *           RegDeleteKeyW   [ADVAPI32.134]
 *
 * PARAMS
 *    hkey   [I] Handle to open key
 *    name   [I] Name of subkey to delete
 *
 * RETURNS
 *    Success: ERROR_SUCCESS
 *    Failure: Error code
 */
DWORD WINAPI RegDeleteKeyW( HKEY hkey, LPCWSTR name )
{
    DWORD ret;
    struct delete_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s)\n", hkey, debugstr_w(name) );

    req->hkey = hkey;
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    return reg_server_call( REQ_DELETE_KEY );
}


/******************************************************************************
 *           RegDeleteKeyA   [ADVAPI32.133]
 */
DWORD WINAPI RegDeleteKeyA( HKEY hkey, LPCSTR name )
{
    DWORD ret;
    struct delete_key_request *req = get_req_buffer();

    TRACE( "(0x%x,%s)\n", hkey, debugstr_a(name) );

    req->hkey = hkey;
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
    if (req->name[0] == '\\') return ERROR_BAD_PATHNAME;
    return reg_server_call( REQ_DELETE_KEY );
}



/******************************************************************************
 *           RegSetValueExW   [ADVAPI32.170]
 *
 * Sets the data and type of a value under a register key
 *
 * PARAMS
 *    hkey       [I] Handle of key to set value for
 *    name       [I] Name of value to set
 *    reserved   [I] Reserved - must be zero
 *    type       [I] Flag for value type
 *    data       [I] Address of value data
 *    count      [I] Size of value data
 *
 * RETURNS
 *    Success: ERROR_SUCCESS
 *    Failure: Error code
 *
 * NOTES
 *   win95 does not care about count for REG_SZ and finds out the len by itself (js) 
 *   NT does definitely care (aj)
 */
DWORD WINAPI RegSetValueExW( HKEY hkey, LPCWSTR name, DWORD reserved,
                             DWORD type, CONST BYTE *data, DWORD count )
{
    DWORD ret;
    struct set_key_value_request *req = get_req_buffer();
    unsigned int max, pos;

    TRACE( "(0x%x,%s,%ld,%ld,%p,%ld)\n", hkey, debugstr_w(name), reserved, type, data, count );

    if (reserved) return ERROR_INVALID_PARAMETER;

    if (count && type == REG_SZ)
    {
        LPCWSTR str = (LPCWSTR)data;
        /* if user forgot to count terminating null, add it (yes NT does this) */
        if (str[count / sizeof(WCHAR) - 1] && !str[count / sizeof(WCHAR)])
            count += sizeof(WCHAR);
    }

    req->hkey = hkey;
    req->type = type;
    req->total = count;
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;

    max = server_remaining( req->data );
    pos = 0;
    while (pos < count)
    {
        unsigned int len = count - pos;
        if (len > max) len = max;
        req->offset = pos;
        req->len    = len;
        memcpy( req->data, data + pos, len );
        if ((ret = reg_server_call( REQ_SET_KEY_VALUE )) != ERROR_SUCCESS) break;
        pos += len;
    }
    return ret;
}


/******************************************************************************
 *           RegSetValueExA   [ADVAPI32.169]
 */
DWORD WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type,
			     CONST BYTE *data, DWORD count )
{
    DWORD ret;
    struct set_key_value_request *req = get_req_buffer();
    unsigned int max, pos;

    TRACE( "(0x%x,%s,%ld,%ld,%p,%ld)\n", hkey, debugstr_a(name), reserved, type, data, count );

    if (reserved) return ERROR_INVALID_PARAMETER;

    if (count && type == REG_SZ)
    {
        /* if user forgot to count terminating null, add it (yes NT does this) */
        if (data[count-1] && !data[count]) count++;
    }
    if (is_string( type )) /* need to convert to Unicode */
        count *= sizeof(WCHAR);

    req->hkey = hkey;
    req->type = type;
    req->total = count;
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;

    max = server_remaining( req->data );
    pos = 0;
    while (pos < count)
    {
        unsigned int len = count - pos;
        if (len > max) len = max;
        req->offset = pos;
        req->len    = len;

        if (is_string( type ))
            memcpyAtoW( (LPWSTR)req->data, data + pos/sizeof(WCHAR), len/sizeof(WCHAR) );
        else
            memcpy( req->data, data + pos, len );
        if ((ret = reg_server_call( REQ_SET_KEY_VALUE )) != ERROR_SUCCESS) break;
        pos += len;
    }
    return ret;
}


/******************************************************************************
 *           RegSetValueW   [ADVAPI32.171]
 */
DWORD WINAPI RegSetValueW( HKEY hkey, LPCWSTR name, DWORD type, LPCWSTR data, DWORD count )
{
    HKEY subkey = hkey;
    DWORD ret;

    TRACE("(0x%x,%s,%ld,%s,%ld)\n", hkey, debugstr_w(name), type, debugstr_w(data), count );

    if (type != REG_SZ) return ERROR_INVALID_PARAMETER;

    if (name && name[0])  /* need to create the subkey */
    {
        if ((ret = RegCreateKeyW( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
    }

    ret = RegSetValueExW( subkey, NULL, 0, REG_SZ, (LPBYTE)data,
                          (strlenW( data ) + 1) * sizeof(WCHAR) );
    if (subkey != hkey) RegCloseKey( subkey );
    return ret;
}


/******************************************************************************
 *           RegSetValueA   [ADVAPI32.168]
 */
DWORD WINAPI RegSetValueA( HKEY hkey, LPCSTR name, DWORD type, LPCSTR data, DWORD count )
{
    HKEY subkey = hkey;
    DWORD ret;

    TRACE("(0x%x,%s,%ld,%s,%ld)\n", hkey, debugstr_a(name), type, debugstr_a(data), count );

    if (type != REG_SZ) return ERROR_INVALID_PARAMETER;

    if (name && name[0])  /* need to create the subkey */
    {
        if ((ret = RegCreateKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
    }
    ret = RegSetValueExA( subkey, NULL, 0, REG_SZ, (LPBYTE)data, strlen(data)+1 );
    if (subkey != hkey) RegCloseKey( subkey );
    return ret;
}



/******************************************************************************
 *           RegQueryValueExW   [ADVAPI32.158]
 *
 * Retrieves type and data for a specified name associated with an open key
 *
 * PARAMS
 *    hkey      [I]   Handle of key to query
 *    name      [I]   Name of value to query
 *    reserved  [I]   Reserved - must be NULL
 *    type      [O]   Address of buffer for value type.  If NULL, the type
 *                        is not required.
 *    data      [O]   Address of data buffer.  If NULL, the actual data is
 *                        not required.
 *    count     [I/O] Address of data buffer size
 *
 * RETURNS 
 *    ERROR_SUCCESS:   Success
 *    ERROR_MORE_DATA: !!! if the specified buffer is not big enough to hold the data
 * 		       buffer is left untouched. The MS-documentation is wrong (js) !!!
 */
DWORD WINAPI RegQueryValueExW( HKEY hkey, LPCWSTR name, LPDWORD reserved, LPDWORD type,
			       LPBYTE data, LPDWORD count )
{
    DWORD ret;
    struct get_key_value_request *req = get_req_buffer();

    TRACE("(0x%x,%s,%p,%p,%p,%p=%ld)\n",
          hkey, debugstr_w(name), reserved, type, data, count, count ? *count : 0 );

    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->offset = 0;
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
    if ((ret = reg_server_call( REQ_GET_KEY_VALUE )) != ERROR_SUCCESS) return ret;

    if (data)
    {
        if (*count < req->len) ret = ERROR_MORE_DATA;
        else
        {
            /* copy the data */
            unsigned int max = server_remaining( req->data );
            unsigned int pos = 0;
            while (pos < req->len)
            {
                unsigned int len = min( req->len - pos, max );
                memcpy( data + pos, req->data, len );
                if ((pos += len) >= req->len) break;
                req->offset = pos;
                if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
                if ((ret = reg_server_call( REQ_GET_KEY_VALUE )) != ERROR_SUCCESS) return ret;
            }
        }
        /* if the type is REG_SZ and data is not 0-terminated
         * and there is enough space in the buffer NT appends a \0 */
        if (req->len && is_string(req->type) &&
            (req->len < *count) && ((WCHAR *)data)[req->len-1]) ((WCHAR *)data)[req->len] = 0;
    }
    if (type) *type = req->type;
    if (count) *count = req->len;
    return ret;
}


/******************************************************************************
 *           RegQueryValueExA   [ADVAPI32.157]
 *
 * NOTES:
 * the documentation is wrong: if the buffer is to small it remains untouched 
 */
DWORD WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type,
			       LPBYTE data, LPDWORD count )
{
    DWORD ret, total_len;
    struct get_key_value_request *req = get_req_buffer();

    TRACE("(0x%x,%s,%p,%p,%p,%p=%ld)\n",
          hkey, debugstr_a(name), reserved, type, data, count, count ? *count : 0 );

    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->offset = 0;
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
    if ((ret = reg_server_call( REQ_GET_KEY_VALUE )) != ERROR_SUCCESS) return ret;

    total_len = is_string( req->type ) ? req->len/sizeof(WCHAR) : req->len;

    if (data)
    {
        if (*count < total_len) ret = ERROR_MORE_DATA;
        else
        {
            /* copy the data */
            unsigned int max = server_remaining( req->data );
            unsigned int pos = 0;
            while (pos < req->len)
            {
                unsigned int len = min( req->len - pos, max );
                if (is_string( req->type ))
                    memcpyWtoA( data + pos/sizeof(WCHAR), (WCHAR *)req->data, len/sizeof(WCHAR) );
                else
                    memcpy( data + pos, req->data, len );
                if ((pos += len) >= req->len) break;
                req->offset = pos;
                if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
                if ((ret = reg_server_call( REQ_GET_KEY_VALUE )) != ERROR_SUCCESS) return ret;
            }
        }
        /* if the type is REG_SZ and data is not 0-terminated
         * and there is enough space in the buffer NT appends a \0 */
        if (total_len && is_string(req->type) && (total_len < *count) && data[total_len-1])
            data[total_len] = 0;
    }

    if (count) *count = total_len;
    if (type) *type = req->type;
    return ret;
}


/******************************************************************************
 *           RegQueryValueW   [ADVAPI32.159]
 */
DWORD WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count )
{
    DWORD ret;
    HKEY subkey = hkey;

    TRACE("(%x,%s,%p,%ld)\n", hkey, debugstr_w(name), data, count ? *count : 0 );

    if (name && name[0])
    {
        if ((ret = RegOpenKeyW( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
    }
    ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, count );
    if (subkey != hkey) RegCloseKey( subkey );
    if (ret == ERROR_FILE_NOT_FOUND)
    {
        /* return empty string if default value not found */
        if (data) *data = 0;
        if (count) *count = 1;
        ret = ERROR_SUCCESS;
    }
    return ret;
}


/******************************************************************************
 *           RegQueryValueA   [ADVAPI32.156]
 */
DWORD WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count )
{
    DWORD ret;
    HKEY subkey = hkey;

    TRACE("(%x,%s,%p,%ld)\n", hkey, debugstr_a(name), data, count ? *count : 0 );

    if (name && name[0])
    {
        if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
    }
    ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, count );
    if (subkey != hkey) RegCloseKey( subkey );
    if (ret == ERROR_FILE_NOT_FOUND)
    {
        /* return empty string if default value not found */
        if (data) *data = 0;
        if (count) *count = 1;
        ret = ERROR_SUCCESS;
    }
    return ret;
}


/******************************************************************************
 *           RegEnumValueW   [ADVAPI32.142]
 *
 * PARAMS
 *    hkey       [I] Handle to key to query
 *    index      [I] Index of value to query
 *    value      [O] Value string
 *    val_count  [I/O] Size of value buffer (in wchars)
 *    reserved   [I] Reserved
 *    type       [O] Type code
 *    data       [O] Value data
 *    count      [I/O] Size of data buffer (in bytes)
 */

DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_count,
                            LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count )
{
    DWORD ret, len;
    struct enum_key_value_request *req = get_req_buffer();

    TRACE("(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
          hkey, index, value, val_count, reserved, type, data, count );

    /* NT only checks count, not val_count */
    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->index = index;
    req->offset = 0;
    if ((ret = reg_server_call( REQ_ENUM_KEY_VALUE )) != ERROR_SUCCESS) return ret;

    len = strlenW( req->name ) + 1;
    if (len > *val_count) return ERROR_MORE_DATA;
    memcpy( value, req->name, len * sizeof(WCHAR) );
    *val_count = len - 1;

    if (data)
    {
        if (*count < req->len) ret = ERROR_MORE_DATA;
        else
        {
            /* copy the data */
            unsigned int max = server_remaining( req->data );
            unsigned int pos = 0;
            while (pos < req->len)
            {
                unsigned int len = min( req->len - pos, max );
                memcpy( data + pos, req->data, len );
                if ((pos += len) >= req->len) break;
                req->offset = pos;
                if ((ret = reg_server_call( REQ_ENUM_KEY_VALUE )) != ERROR_SUCCESS) return ret;
            }
        }
        /* if the type is REG_SZ and data is not 0-terminated
         * and there is enough space in the buffer NT appends a \0 */
        if (req->len && is_string(req->type) &&
            (req->len < *count) && ((WCHAR *)data)[req->len-1]) ((WCHAR *)data)[req->len] = 0;
    }
    if (type) *type = req->type;
    if (count) *count = req->len;
    return ret;
}


/******************************************************************************
 *           RegEnumValueA   [ADVAPI32.141]
 */
DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
                            LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count )
{
    DWORD ret, len, total_len;
    struct enum_key_value_request *req = get_req_buffer();

    TRACE("(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
          hkey, index, value, val_count, reserved, type, data, count );

    /* NT only checks count, not val_count */
    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;

    req->hkey = hkey;
    req->index = index;
    req->offset = 0;
    if ((ret = reg_server_call( REQ_ENUM_KEY_VALUE )) != ERROR_SUCCESS) return ret;

    len = strlenW( req->name ) + 1;
    if (len > *val_count) return ERROR_MORE_DATA;
    memcpyWtoA( value, req->name, len );
    *val_count = len - 1;

    total_len = is_string( req->type ) ? req->len/sizeof(WCHAR) : req->len;

    if (data)
    {
        if (*count < total_len) ret = ERROR_MORE_DATA;
        else
        {
            /* copy the data */
            unsigned int max = server_remaining( req->data );
            unsigned int pos = 0;
            while (pos < req->len)
            {
                unsigned int len = min( req->len - pos, max );
                if (is_string( req->type ))
                    memcpyWtoA( data + pos/sizeof(WCHAR), (WCHAR *)req->data, len/sizeof(WCHAR) );
                else
                    memcpy( data + pos, req->data, len );
                if ((pos += len) >= req->len) break;
                req->offset = pos;
                if ((ret = reg_server_call( REQ_ENUM_KEY_VALUE )) != ERROR_SUCCESS) return ret;
            }
        }
        /* if the type is REG_SZ and data is not 0-terminated
         * and there is enough space in the buffer NT appends a \0 */
        if (total_len && is_string(req->type) && (total_len < *count) && data[total_len-1])
            data[total_len] = 0;
    }

    if (count) *count = total_len;
    if (type) *type = req->type;
    return ret;
}



/******************************************************************************
 *           RegDeleteValueW   [ADVAPI32.136]
 *
 * PARAMS
 *    hkey   [I] handle to key
 *    name   [I] name of value to delete
 *
 * RETURNS
 *    error status
 */
DWORD WINAPI RegDeleteValueW( HKEY hkey, LPCWSTR name )
{
    DWORD ret;
    struct delete_key_value_request *req = get_req_buffer();

    TRACE( "(0x%x,%s)\n", hkey, debugstr_w(name) );

    req->hkey = hkey;
    if ((ret = copy_nameW( req->name, name )) != ERROR_SUCCESS) return ret;
    return reg_server_call( REQ_DELETE_KEY_VALUE );
}


/******************************************************************************
 *           RegDeleteValueA   [ADVAPI32.135]
 */
DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name )
{
    DWORD ret;
    struct delete_key_value_request *req = get_req_buffer();

    TRACE( "(0x%x,%s)\n", hkey, debugstr_a(name) );

    req->hkey = hkey;
    if ((ret = copy_nameAtoW( req->name, name )) != ERROR_SUCCESS) return ret;
    return reg_server_call( REQ_DELETE_KEY_VALUE );
}


/******************************************************************************
 *           RegLoadKeyW   [ADVAPI32.185]
 *
 * PARAMS
 *    hkey      [I] Handle of open key
 *    subkey    [I] Address of name of subkey
 *    filename  [I] Address of filename for registry information
 */
LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
{
    struct load_registry_request *req = get_req_buffer();
    HANDLE file;
    DWORD ret, err = GetLastError();

    TRACE( "(%x,%s,%s)\n", hkey, debugstr_w(subkey), debugstr_w(filename) );

    if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
    if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;

    if ((file = CreateFileW( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
    {
        ret = GetLastError();
        goto done;
    }
    req->hkey  = hkey;
    req->file  = file;
    if ((ret = copy_nameW( req->name, subkey )) != ERROR_SUCCESS) goto done;
    ret = reg_server_call( REQ_LOAD_REGISTRY );
    CloseHandle( file );

 done:
    SetLastError( err );  /* restore the last error code */
    return ret;
}


/******************************************************************************
 *           RegLoadKeyA   [ADVAPI32.184]
 */
LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
{
    struct load_registry_request *req = get_req_buffer();
    HANDLE file;
    DWORD ret, err = GetLastError();

    TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) );

    if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
    if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;

    if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
    {
        ret = GetLastError();
        goto done;
    }
    req->hkey  = hkey;
    req->file  = file;
    if ((ret = copy_nameAtoW( req->name, subkey )) != ERROR_SUCCESS) goto done;
    ret = reg_server_call( REQ_LOAD_REGISTRY );
    CloseHandle( file );

 done:
    SetLastError( err );  /* restore the last error code */
    return ret;
}


/******************************************************************************
 *           RegSaveKeyA   [ADVAPI32.165]
 *
 * PARAMS
 *    hkey   [I] Handle of key where save begins
 *    lpFile [I] Address of filename to save to
 *    sa     [I] Address of security structure
 */
LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
{
    struct save_registry_request *req = get_req_buffer();
    char buffer[1024];
    int count = 0;
    LPSTR name;
    DWORD ret, err;
    HFILE handle;

    TRACE( "(%x,%s,%p)\n", hkey, debugstr_a(file), sa );

    if (!file || !*file) return ERROR_INVALID_PARAMETER;

    err = GetLastError();
    GetFullPathNameA( file, sizeof(buffer), buffer, &name );
    for (;;)
    {
        sprintf( name, "reg%04x.tmp", count++ );
        handle = CreateFileA( buffer, GENERIC_WRITE, 0, NULL,
                            CREATE_NEW, FILE_ATTRIBUTE_NORMAL, -1 );
        if (handle != INVALID_HANDLE_VALUE) break;
        if ((ret = GetLastError()) != ERROR_ALREADY_EXISTS) goto done;

        /* Something gone haywire ? Please report if this happens abnormally */
        if (count >= 100)
            MESSAGE("Wow, we are already fiddling with a temp file %s with an ordinal as high as %d !\nYou might want to delete all corresponding temp files in that directory.\n", buffer, count);
    }

    req->hkey = hkey;
    req->file = handle;
    ret = reg_server_call( REQ_SAVE_REGISTRY );
    CloseHandle( handle );
    if (!ret)
    {
        if (!MoveFileExA( buffer, file, MOVEFILE_REPLACE_EXISTING ))
        {
            ERR( "Failed to move %s to %s\n", buffer, file );
            ret = GetLastError();
        }
    }
    if (ret) DeleteFileA( buffer );

done:
    SetLastError( err );  /* restore last error code */
    return ret;
}


/******************************************************************************
 *           RegSaveKeyW   [ADVAPI32.166]
 */
LONG WINAPI RegSaveKeyW( HKEY hkey, LPCWSTR file, LPSECURITY_ATTRIBUTES sa )
{
    LPSTR fileA = HEAP_strdupWtoA( GetProcessHeap(), 0, file );
    DWORD ret = RegSaveKeyA( hkey, fileA, sa );
    if (fileA) HeapFree( GetProcessHeap(), 0, fileA );
    return ret;
}
