/*
 * Implementation of the ODBC driver installer
 *
 * Copyright 2005 Mike McCormack for CodeWeavers
 * Copyright 2005 Hans Leidekker
 * Copyright 2007 Bill Medland
 *
 * 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 <assert.h>
#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "wine/unicode.h"
#include "wine/debug.h"

#include "odbcinst.h"

WINE_DEFAULT_DEBUG_CHANNEL(odbc);

/* Registry key names */
static const WCHAR drivers_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\','O','D','B','C',' ','D','r','i','v','e','r','s',0};
static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C',0};
static const WCHAR odbcini[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\',0};
static const WCHAR odbcdrivers[] = {'O','D','B','C',' ','D','r','i','v','e','r','s',0};
static const WCHAR odbctranslators[] = {'O','D','B','C',' ','T','r','a','n','s','l','a','t','o','r','s',0};

/* This config mode is known to be process-wide.
 * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
 * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
 */
static UWORD config_mode = ODBC_BOTH_DSN;

/* MSDN documentation suggests that the error subsystem handles errors 1 to 8
 * only and experimentation (Windows 2000) shows that the errors are process-
 * wide so go for the simple solution; static arrays.
 */
static int num_errors;
static int error_code[8];
static const WCHAR *error_msg[8];
static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d',' ','b','u','f','f','e','r',' ','l','e','n','g','t','h',0};
static const WCHAR odbc_error_component_not_found[] = {'C','o','m','p','o','n','e','n','t',' ','n','o','t',' ','f','o','u','n','d',0};
static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0};
static const WCHAR odbc_error_invalid_param_string[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','t','r','i','n','g',0};
static const WCHAR odbc_error_invalid_dsn[] = {'I','n','v','a','l','i','d',' ','D','S','N',0};
static const WCHAR odbc_error_load_lib_failed[] = {'L','o','a','d',' ','L','i','b','r','a','r','y',' ','F','a','i','l','e','d',0};
static const WCHAR odbc_error_request_failed[] = {'R','e','q','u','e','s','t',' ','F','a','i','l','e','d',0};
static const WCHAR odbc_error_invalid_keyword[] = {'I','n','v','a','l','i','d',' ','k','e','y','w','o','r','d',' ','v','a','l','u','e',0};

/* Push an error onto the error stack, taking care of ranges etc. */
static void push_error(int code, LPCWSTR msg)
{
    if (num_errors < sizeof error_code/sizeof error_code[0])
    {
        error_code[num_errors] = code;
        error_msg[num_errors] = msg;
        num_errors++;
    }
}

/* Clear the error stack */
static void clear_errors(void)
{
    num_errors = 0;
}

static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
{
    return HeapAlloc(GetProcessHeap(), 0, size);
}

static inline BOOL heap_free(void *mem)
{
    return HeapFree(GetProcessHeap(), 0, mem);
}

static inline WCHAR *heap_strdupAtoW(const char *str)
{
    LPWSTR ret = NULL;

    if(str) {
        DWORD len;

        len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
        ret = heap_alloc(len*sizeof(WCHAR));
        if(ret)
            MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
    }

    return ret;
}


BOOL WINAPI ODBCCPlApplet( LONG i, LONG j, LONG * p1, LONG * p2)
{
    clear_errors();
    FIXME( "( %d %d %p %p) : stub!\n", i, j, p1, p2);
    return FALSE;
}

static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
{
    LPCSTR p;
    LPWSTR ret = NULL;
    DWORD len;

    if (!str)
        return ret;

    for (p = str; *p; p += lstrlenA(p) + 1)
        ;

    len = MultiByteToWideChar(CP_ACP, 0, str, p - str, NULL, 0 );
    ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, str, p - str, ret, len );
    ret[len] = 0;

    return ret;
}

static LPWSTR SQLInstall_strdup(LPCSTR str)
{
    DWORD len;
    LPWSTR ret = NULL;

    if (!str)
        return ret;

    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0 );
    ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len );

    return ret;
}

/* Convert the wide string or zero-length-terminated list of wide strings to a
 * narrow string or zero-length-terminated list of narrow strings.
 * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
 * to a list)
 * Arguments
 *   mode Indicates the sort of string.
 *     1 denotes that the buffers contain strings terminated by a single nul
 *       character
 *     2 denotes that the buffers contain zero-length-terminated lists
 *       (frequently erroneously referred to as double-null-terminated)
 *   buffer The narrow-character buffer into which to place the result.  This
 *          must be a non-null pointer to the first element of a buffer whose
 *          length is passed in buffer_length.
 *   str The wide-character buffer containing the string or list of strings to
 *       be converted.  str_length defines how many wide characters in the
 *       buffer are to be converted, including all desired terminating nul
 *       characters.
 *   str_length Effective length of str
 *   buffer_length Length of buffer
 *   returned_length A pointer to a variable that will receive the number of
 *                   narrow characters placed into the buffer.  This pointer
 *                   may be NULL.
 */
static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
{
    LPSTR pbuf; /* allows us to allocate a temporary buffer only if needed */
    int len; /* Length of the converted list */
    BOOL success = FALSE;
    assert(mode == 1 || mode == 2);
    assert(buffer_length);
    len = WideCharToMultiByte(CP_ACP, 0, str, str_length, 0, 0, NULL, NULL);
    if (len > 0)
    {
        if (len > buffer_length)
        {
            pbuf = HeapAlloc(GetProcessHeap(), 0, len);
        }
        else
        {
            pbuf = buffer;
        }
        len = WideCharToMultiByte(CP_ACP, 0, str, str_length, pbuf, len, NULL, NULL);
        if (len > 0)
        {
            if (pbuf != buffer)
            {
                if (buffer_length > (mode - 1))
                {
                    memcpy (buffer, pbuf, buffer_length-mode);
                    *(buffer+buffer_length-mode) = '\0';
                }
                *(buffer+buffer_length-1) = '\0';
            }
            if (returned_length)
            {
                *returned_length = pbuf == buffer ? len : buffer_length;
            }
            success = TRUE;
        }
        else
        {
            ERR("transferring wide to narrow\n");
        }
        if (pbuf != buffer)
        {
            HeapFree(GetProcessHeap(), 0, pbuf);
        }
    }
    else
    {
        ERR("measuring wide to narrow\n");
    }
    return success;
}

BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest,
               LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
{
    LPCWSTR p;

    clear_errors();
    FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
          debugstr_w(lpszAttributes));

    for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
        FIXME("%s\n", debugstr_w(p));

    return TRUE;
}

BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
               LPCSTR lpszDriver, LPCSTR lpszAttributes)
{
    FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
          debugstr_a(lpszAttributes));
    clear_errors();
    return TRUE;
}

static HMODULE load_config_driver(const WCHAR *driver)
{
    static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
    long ret;
    HMODULE hmod;
    WCHAR *filename = NULL;
    DWORD size = 0, type;
    HKEY hkey;

    if ((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
    {
        HKEY hkeydriver;

        if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
        {
            ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, NULL, &size);
            if(ret == ERROR_MORE_DATA)
            {
                filename = HeapAlloc(GetProcessHeap(), 0, size);
                if(!filename)
                {
                    RegCloseKey(hkeydriver);
                    RegCloseKey(hkey);
                    push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);

                    return NULL;
                }
                ret = RegGetValueW(hkeydriver, NULL, driver, RRF_RT_REG_SZ, &type, filename, &size);
            }

            RegCloseKey(hkeydriver);
        }

        RegCloseKey(hkey);
    }

    if(ret != ERROR_SUCCESS)
    {
        HeapFree(GetProcessHeap(), 0, filename);
        push_error(ODBC_ERROR_INVALID_DSN, odbc_error_invalid_dsn);
        return NULL;
    }

    hmod = LoadLibraryW(filename);
    HeapFree(GetProcessHeap(), 0, filename);

    if(!hmod)
        push_error(ODBC_ERROR_LOAD_LIB_FAILED, odbc_error_load_lib_failed);

    return hmod;
}

static BOOL write_config_value(const WCHAR *driver, const WCHAR *args)
{
    long ret;
    HKEY hkey, hkeydriver;
    WCHAR *name = NULL;

    if(!args)
        return FALSE;

    if((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
    {
        if((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
        {
            WCHAR *divider, *value;

            name = heap_alloc( (strlenW(args) + 1) * sizeof(WCHAR));
            if(!name)
            {
                push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
                goto fail;
            }
            lstrcpyW(name, args);

            divider = strchrW(name,'=');
            if(!divider)
            {
                push_error(ODBC_ERROR_INVALID_KEYWORD_VALUE, odbc_error_invalid_keyword);
                goto fail;
            }

            value = divider + 1;
            *divider = '\0';

            TRACE("Write pair: %s = %s\n", debugstr_w(name), debugstr_w(value));
            if(RegSetValueExW(hkeydriver, name, 0, REG_SZ, (BYTE*)value,
                               (strlenW(value)+1) * sizeof(WCHAR)) != ERROR_SUCCESS)
                ERR("Failed to write registry installed key\n");
            heap_free(name);

            RegCloseKey(hkeydriver);
        }

        RegCloseKey(hkey);
    }

    if(ret != ERROR_SUCCESS)
        push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);

    return ret == ERROR_SUCCESS;

fail:
    RegCloseKey(hkeydriver);
    RegCloseKey(hkey);
    heap_free(name);

    return FALSE;
}

BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver,
               LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
{
    BOOL (WINAPI *pConfigDriverW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *args, const WCHAR *msg, WORD msgmax, WORD *msgout);
    HMODULE hmod;
    BOOL funcret = FALSE;

    clear_errors();
    TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_w(driver),
          debugstr_w(args), msg, msgmax, msgout);

    if(request == ODBC_CONFIG_DRIVER)
    {
        return write_config_value(driver, args);
    }

    hmod = load_config_driver(driver);
    if(!hmod)
        return FALSE;

    pConfigDriverW = (void*)GetProcAddress(hmod, "ConfigDriverW");
    if(pConfigDriverW)
        funcret = pConfigDriverW(hwnd, request, driver, args, msg, msgmax, msgout);

    if(!funcret)
        push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);

    FreeLibrary(hmod);

    return funcret;
}

BOOL WINAPI SQLConfigDriver(HWND hwnd, WORD request, LPCSTR driver,
               LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
{
    BOOL (WINAPI *pConfigDriverA)(HWND hwnd, WORD request, const char *driver, const char *args, const char *msg, WORD msgmax, WORD *msgout);
    HMODULE hmod;
    WCHAR *driverW;
    BOOL funcret = FALSE;

    clear_errors();
    TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_a(driver),
          debugstr_a(args), msg, msgmax, msgout);

    driverW = heap_strdupAtoW(driver);
    if(!driverW)
    {
        push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
        return FALSE;
    }
    if(request == ODBC_CONFIG_DRIVER)
    {
        BOOL ret = FALSE;
        WCHAR *argsW = heap_strdupAtoW(args);
        if(argsW)
        {
            ret = write_config_value(driverW, argsW);
            HeapFree(GetProcessHeap(), 0, argsW);
        }
        else
        {
            push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
        }

        HeapFree(GetProcessHeap(), 0, driverW);

        return ret;
    }

    hmod = load_config_driver(driverW);
    HeapFree(GetProcessHeap(), 0, driverW);
    if(!hmod)
        return FALSE;

    pConfigDriverA = (void*)GetProcAddress(hmod, "ConfigDriver");
    if(pConfigDriverA)
        funcret = pConfigDriverA(hwnd, request, driver, args, msg, msgmax, msgout);

    if(!funcret)
        push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);

    FreeLibrary(hmod);

    return funcret;
}

BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
{
    clear_errors();
    FIXME("%p %s\n", hwnd, debugstr_w(lpszDS));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
{
    clear_errors();
    FIXME("%p %s\n", hwnd, debugstr_a(lpszDS));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf,
               WORD cbBufMax, WORD *pcbBufOut)
{
    clear_errors();
    FIXME("%s %p %d %p\n", debugstr_w(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf,
               WORD cbBufMax, WORD *pcbBufOut)
{
    clear_errors();
    FIXME("%s %p %d %p\n", debugstr_a(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
{
    clear_errors();
    TRACE("%p\n", pwConfigMode);
    if (pwConfigMode)
        *pwConfigMode = config_mode;
    return TRUE;
}

/* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations
 * e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer).
 * e.g. If the key has no drivers then version 3.525.1117.0 does not modify the buffer at all, not even a nul character.
 */
BOOL WINAPI SQLGetInstalledDriversW(LPWSTR lpszBuf, WORD cbBufMax,
               WORD *pcbBufOut)
{
    HKEY hDrivers; /* Registry handle to the Drivers key */
    LONG reg_ret; /* Return code from registry functions */
    BOOL success = FALSE; /* The value we will return */

    clear_errors();

    TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut);

    if (!lpszBuf || cbBufMax == 0)
    {
        push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
    }
    else if ((reg_ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE /* The drivers does not depend on the config mode */,
            drivers_key, 0, KEY_READ /* Maybe overkill */,
            &hDrivers)) == ERROR_SUCCESS)
    {
        DWORD index = 0;
        cbBufMax--;
        success = TRUE;
        while (cbBufMax > 0)
        {
            DWORD size_name;
            size_name = cbBufMax;
            if ((reg_ret = RegEnumValueW(hDrivers, index, lpszBuf, &size_name, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
            {
                index++;
                assert (size_name < cbBufMax && *(lpszBuf + size_name) == 0);
                size_name++;
                cbBufMax-= size_name;
                lpszBuf+=size_name;
            }
            else
            {
                if (reg_ret != ERROR_NO_MORE_ITEMS)
                {
                    success = FALSE;
                    push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
                }
                break;
            }
        }
        *lpszBuf = 0;
        if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
            TRACE ("Error %d closing ODBC Drivers key\n", reg_ret);
    }
    else
    {
        /* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case.
         * Version 3.525.1117.0 (Windows 2000) does not; it actually returns success.
         * I doubt if it will actually be an issue.
         */
        push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
    }
    return success;
}

BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax,
               WORD *pcbBufOut)
{
    BOOL ret;
    int size_wbuf = cbBufMax;
    LPWSTR wbuf;
    WORD size_used;

    TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut);

    wbuf = HeapAlloc(GetProcessHeap(), 0, size_wbuf*sizeof(WCHAR));
    if (wbuf)
    {
        ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used);
        if (ret)
        {
            if (!(ret = SQLInstall_narrow(2, lpszBuf, wbuf, size_used, cbBufMax, pcbBufOut)))
            {
                push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
            }
        }
        HeapFree(GetProcessHeap(), 0, wbuf);
        /* ignore failure; we have achieved the aim */
    }
    else
    {
        push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
        ret = FALSE;
    }
    return ret;
}

static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename)
{
    HKEY hkey, hkeyfilename, hkeysection;
    LONG ret;

    if (RegOpenKeyW(HKEY_CURRENT_USER, odbcW, &hkey))
        return NULL;

    ret = RegOpenKeyW(hkey, filename, &hkeyfilename);
    RegCloseKey(hkey);
    if (ret)
        return NULL;

    ret = RegOpenKeyW(hkeyfilename, section, &hkeysection);
    RegCloseKey(hkeyfilename);

    return ret ? NULL : hkeysection;
}

int WINAPI SQLGetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
    LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
{
    BOOL usedefault = TRUE;
    HKEY sectionkey;
    LONG ret = 0;

    TRACE("%s %s %s %p %d %s\n", debugstr_w(section), debugstr_w(entry),
               debugstr_w(defvalue), buff, buff_len, debugstr_w(filename));

    clear_errors();

    if (buff_len <= 0 || !section)
        return 0;

    if(buff)
        buff[0] = 0;

    if (!defvalue || !buff)
        return 0;

    sectionkey = get_privateprofile_sectionkey(section, filename);
    if (sectionkey)
    {
        DWORD type, size;

        if (entry)
        {
            size = buff_len * sizeof(*buff);
            if (RegGetValueW(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
            {
                usedefault = FALSE;
                ret = (size / sizeof(*buff)) - 1;
            }
        }
        else
        {
            WCHAR name[MAX_PATH];
            DWORD index = 0;
            DWORD namelen;

            usedefault = FALSE;

            memset(buff, 0, buff_len);

            namelen = sizeof(name);
            while (RegEnumValueW(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
            {
                if ((ret +  namelen+1) > buff_len)
                    break;

                lstrcpyW(buff+ret, name);
                ret += namelen+1;
                namelen = sizeof(name);
                index++;
            }
        }

        RegCloseKey(sectionkey);
    }
    else
        usedefault = entry != NULL;

    if (usedefault)
    {
        lstrcpynW(buff, defvalue, buff_len);
        ret = lstrlenW(buff);
    }

    return ret;
}

int WINAPI SQLGetPrivateProfileString(LPCSTR section, LPCSTR entry,
    LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
{
    WCHAR *sectionW, *filenameW;
    BOOL usedefault = TRUE;
    HKEY sectionkey;
    LONG ret = 0;

    TRACE("%s %s %s %p %d %s\n", debugstr_a(section), debugstr_a(entry),
               debugstr_a(defvalue), buff, buff_len, debugstr_a(filename));

    clear_errors();

    if (buff_len <= 0)
        return 0;

    if (buff)
        buff[0] = 0;

    if (!section || !defvalue || !buff)
        return 0;

    sectionW = heap_strdupAtoW(section);
    filenameW = heap_strdupAtoW(filename);

    sectionkey = get_privateprofile_sectionkey(sectionW, filenameW);

    heap_free(sectionW);
    heap_free(filenameW);

    if (sectionkey)
    {
        DWORD type, size;

        if (entry)
        {
            size = buff_len * sizeof(*buff);
            if (RegGetValueA(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
            {
                usedefault = FALSE;
                ret = (size / sizeof(*buff)) - 1;
            }
        }
        else
        {
            char name[MAX_PATH] = {0};
            DWORD index = 0;
            DWORD namelen;

            usedefault = FALSE;

            memset(buff, 0, buff_len);

            namelen = sizeof(name);
            while (RegEnumValueA(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
            {
                if ((ret +  namelen+1) > buff_len)
                    break;

                lstrcpyA(buff+ret, name);

                ret += namelen+1;
                namelen = sizeof(name);
                index++;
            }
        }

        RegCloseKey(sectionkey);
    }
    else
        usedefault = entry != NULL;

    if (usedefault)
    {
        lstrcpynA(buff, defvalue, buff_len);
        ret = strlen(buff);
    }

    return ret;
}

BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax,
               WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax,
               WORD *pcbPathOut, DWORD *pvOption)
{
    clear_errors();
    FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_w(lpszName), cbNameMax,
               pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax,
               WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax,
               WORD *pcbPathOut, DWORD *pvOption)
{
    clear_errors();
    FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_a(lpszName), cbNameMax,
               pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver,
               LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
{
    DWORD usage;

    clear_errors();
    TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile),
          debugstr_w(lpszDriver), lpszPath, cbPathMax, pcbPathOut);

    if (lpszInfFile)
        return FALSE;

    return SQLInstallDriverExW(lpszDriver, NULL, lpszPath, cbPathMax,
                               pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
}

BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver,
               LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
{
    DWORD usage;

    clear_errors();
    TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile),
          debugstr_a(lpszDriver), lpszPath, cbPathMax, pcbPathOut);

    if (lpszInfFile)
        return FALSE;
   
    return SQLInstallDriverEx(lpszDriver, NULL, lpszPath, cbPathMax,
                              pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
}

static void write_registry_values(const WCHAR *regkey, const WCHAR *driver, const  WCHAR *path_in, WCHAR *path,
                                  DWORD *usage_count)
{
    static const WCHAR installed[] = {'I','n','s','t','a','l','l','e','d',0};
    static const WCHAR slash[] = {'\\', 0};
    static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
    static const WCHAR setupW[] = {'S','e','t','u','p',0};
    static const WCHAR translator[] = {'T','r','a','n','s','l','a','t','o','r',0};
    HKEY hkey, hkeydriver;

    if (RegCreateKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey) == ERROR_SUCCESS)
    {
        if (RegCreateKeyW(hkey, regkey, &hkeydriver) == ERROR_SUCCESS)
        {
            if(RegSetValueExW(hkeydriver, driver, 0, REG_SZ, (BYTE*)installed, sizeof(installed)) != ERROR_SUCCESS)
                ERR("Failed to write registry installed key\n");

            RegCloseKey(hkeydriver);
        }

        if (RegCreateKeyW(hkey, driver, &hkeydriver) == ERROR_SUCCESS)
        {
            WCHAR entry[1024];
            const WCHAR *p;
            DWORD usagecount = 0;
            DWORD type, size;

            /* Skip name entry */
            p = driver;
            p += lstrlenW(p) + 1;

            if (!path_in)
                GetSystemDirectoryW(path, MAX_PATH);
            else
                lstrcpyW(path, path_in);

            /* Store Usage */
            size = sizeof(usagecount);
            RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
            TRACE("Usage count %d\n", usagecount);

            for (; *p; p += lstrlenW(p) + 1)
            {
                WCHAR *divider = strchrW(p,'=');

                if (divider)
                {
                    WCHAR *value;
                    int len;

                    /* Write pair values to the registry. */
                    lstrcpynW(entry, p, divider - p + 1);

                    divider++;
                    TRACE("Writing pair %s,%s\n", debugstr_w(entry), debugstr_w(divider));

                    /* Driver, Setup, Translator entries use the system path unless a path is specified. */
                    if(lstrcmpiW(driverW, entry) == 0 || lstrcmpiW(setupW, entry) == 0 ||
                       lstrcmpiW(translator, entry) == 0)
                    {
                        len = lstrlenW(path) + lstrlenW(slash) + lstrlenW(divider) + 1;
                        value = heap_alloc(len * sizeof(WCHAR));
                        if(!value)
                        {
                            ERR("Out of memory\n");
                            return;
                        }

                        lstrcpyW(value, path);
                        lstrcatW(value, slash);
                        lstrcatW(value, divider);
                    }
                    else
                    {
                        len = lstrlenW(divider) + 1;
                        value = heap_alloc(len * sizeof(WCHAR));
                        lstrcpyW(value, divider);
                    }

                    if (RegSetValueExW(hkeydriver, entry, 0, REG_SZ, (BYTE*)value,
                                    (lstrlenW(value)+1)*sizeof(WCHAR)) != ERROR_SUCCESS)
                        ERR("Failed to write registry data %s %s\n", debugstr_w(entry), debugstr_w(value));
                    heap_free(value);
                }
                else
                {
                    ERR("No pair found. %s\n", debugstr_w(p));
                    break;
                }
            }

            /* Set Usage Count */
            usagecount++;
            if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&usagecount, sizeof(usagecount)) != ERROR_SUCCESS)
                ERR("Failed to write registry UsageCount key\n");

            if (usage_count)
                *usage_count = usagecount;

            RegCloseKey(hkeydriver);
        }

        RegCloseKey(hkey);
    }
}

BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn,
               LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
               WORD fRequest, LPDWORD lpdwUsageCount)
{
    UINT len;
    WCHAR path[MAX_PATH];

    clear_errors();
    TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver),
          debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
          fRequest, lpdwUsageCount);

    write_registry_values(odbcdrivers, lpszDriver, lpszPathIn, path, lpdwUsageCount);

    len = lstrlenW(path);

    if (pcbPathOut)
        *pcbPathOut = len;

    if (lpszPathOut && cbPathOutMax > len)
    {
        lstrcpyW(lpszPathOut, path);
        return TRUE;
    }
    return FALSE;
}

BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn,
               LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
               WORD fRequest, LPDWORD lpdwUsageCount)
{
    LPWSTR driver, pathin;
    WCHAR pathout[MAX_PATH];
    BOOL ret;
    WORD cbOut = 0;

    clear_errors();
    TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver),
          debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
          fRequest, lpdwUsageCount);

    driver = SQLInstall_strdup_multi(lpszDriver);
    pathin = SQLInstall_strdup(lpszPathIn);

    ret = SQLInstallDriverExW(driver, pathin, pathout, MAX_PATH, &cbOut,
                              fRequest, lpdwUsageCount);
    if (ret)
    {
        int len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
                                       0, NULL, NULL);
        if (len)
        {
            if (pcbPathOut)
                *pcbPathOut = len - 1;

            if (!lpszPathOut || cbPathOutMax < len)
            {
                ret = FALSE;
                goto out;
            }
            len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
                                       cbPathOutMax, NULL, NULL);
        }
    }

out:
    HeapFree(GetProcessHeap(), 0, driver);
    HeapFree(GetProcessHeap(), 0, pathin);
    return ret;
}

BOOL WINAPI SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax,
               WORD *pcbPathOut)
{
    UINT len;
    WCHAR path[MAX_PATH];

    TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);

    if (cbPathMax < MAX_PATH)
        return FALSE;

    clear_errors();

    len = GetSystemDirectoryW(path, MAX_PATH);

    if (pcbPathOut)
        *pcbPathOut = len;

    if (lpszPath && cbPathMax > len)
    {
    	lstrcpyW(lpszPath, path);
    	return TRUE;
    }
    return FALSE;
}

BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax,
               WORD *pcbPathOut)
{
    BOOL ret;
    WORD len, cbOut = 0;
    WCHAR path[MAX_PATH];

    TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);

    if (cbPathMax < MAX_PATH)
        return FALSE;

    clear_errors();

    ret = SQLInstallDriverManagerW(path, MAX_PATH, &cbOut);
    if (ret)
    {
        len =  WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath, 0,
                                   NULL, NULL);
        if (len)
        {
            if (pcbPathOut)
                *pcbPathOut = len - 1;

            if (!lpszPath || cbPathMax < len)
                return FALSE;

            len =  WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath,
                                       cbPathMax, NULL, NULL);
        }
    }
    return ret;
}

BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile,
               LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
{
    clear_errors();
    FIXME("%p %s %s %s\n", hwndParent, debugstr_w(lpszInfFile),
               debugstr_w(lpszSrcPath), debugstr_w(lpszDrivers));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile,
               LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
{
    clear_errors();
    FIXME("%p %s %s %s\n", hwndParent, debugstr_a(lpszInfFile),
               debugstr_a(lpszSrcPath), debugstr_a(lpszDrivers));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode,
               LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
{
    TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
          cbErrorMsgMax, pcbErrorMsg);

    if (iError == 0)
    {
        return SQL_ERROR;
    }
    else if (iError <= num_errors)
    {
        BOOL truncated = FALSE;
        WORD len;
        LPCWSTR msg;
        iError--;
        if (pfErrorCode)
            *pfErrorCode = error_code[iError];
        msg = error_msg[iError];
        len = msg ? lstrlenW(msg) : 0;
        if (pcbErrorMsg)
            *pcbErrorMsg = len;
        len++;
        if (cbErrorMsgMax < len)
        {
            len = cbErrorMsgMax;
            truncated = TRUE;
        }
        if (lpszErrorMsg && len)
        {
            if (msg)
            {
                memcpy (lpszErrorMsg, msg, len * sizeof(WCHAR));
            }
            else
            {
                assert(len==1);
                *lpszErrorMsg = 0;
            }
        }
        else
        {
            /* Yes.  If you pass a null pointer and a large length it is not an error! */
            truncated = TRUE;
        }

        return truncated ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
    }

    /* At least on Windows 2000 , the buffers are not altered in this case.  However that is a little too dangerous a test for just now */
    if (pcbErrorMsg)
        *pcbErrorMsg = 0;

    if (lpszErrorMsg && cbErrorMsgMax > 0)
        *lpszErrorMsg = '\0';

    return SQL_NO_DATA;
}

SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode,
               LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
{
    SQLRETURN ret;
    LPWSTR wbuf;
    WORD cbwbuf;
    TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
          cbErrorMsgMax, pcbErrorMsg);

    wbuf = 0;
    if (lpszErrorMsg && cbErrorMsgMax)
    {
        wbuf = HeapAlloc(GetProcessHeap(), 0, cbErrorMsgMax*sizeof(WCHAR));
        if (!wbuf)
            return SQL_ERROR;
    }
    ret = SQLInstallerErrorW(iError, pfErrorCode, wbuf, cbErrorMsgMax, &cbwbuf);
    if (wbuf)
    {
        WORD cbBuf = 0;
        SQLInstall_narrow(1, lpszErrorMsg, wbuf, cbwbuf+1, cbErrorMsgMax, &cbBuf);
        HeapFree(GetProcessHeap(), 0, wbuf);
        if (pcbErrorMsg)
            *pcbErrorMsg = cbBuf-1;
    }
    return ret;
}

BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn,
               LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
               WORD fRequest, LPDWORD lpdwUsageCount)
{
    UINT len;
    WCHAR path[MAX_PATH];

    clear_errors();
    TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator),
          debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
          fRequest, lpdwUsageCount);

    write_registry_values(odbctranslators, lpszTranslator, lpszPathIn, path, lpdwUsageCount);

    len = lstrlenW(path);

    if (pcbPathOut)
        *pcbPathOut = len;

    if (lpszPathOut && cbPathOutMax > len)
    {
        lstrcpyW(lpszPathOut, path);
        return TRUE;
    }
    return FALSE;
}

BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn,
               LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
               WORD fRequest, LPDWORD lpdwUsageCount)
{
    LPCSTR p;
    LPWSTR translator, pathin;
    WCHAR pathout[MAX_PATH];
    BOOL ret;
    WORD cbOut = 0;

    clear_errors();
    TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator),
          debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
          fRequest, lpdwUsageCount);

    for (p = lpszTranslator; *p; p += lstrlenA(p) + 1)
        TRACE("%s\n", debugstr_a(p));

    translator = SQLInstall_strdup_multi(lpszTranslator);
    pathin = SQLInstall_strdup(lpszPathIn);

    ret = SQLInstallTranslatorExW(translator, pathin, pathout, MAX_PATH,
                                  &cbOut, fRequest, lpdwUsageCount);
    if (ret)
    {
        int len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
                                       0, NULL, NULL);
        if (len)
        {
            if (pcbPathOut)
                *pcbPathOut = len - 1;

            if (!lpszPathOut || cbPathOutMax < len)
            {
                ret = FALSE;
                goto out;
            }
            len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
                                       cbPathOutMax, NULL, NULL);
        }
    }

out:
    HeapFree(GetProcessHeap(), 0, translator);
    HeapFree(GetProcessHeap(), 0, pathin);
    return ret;
}

BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator,
               LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax,
               WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
{
    clear_errors();
    TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile),
          debugstr_a(lpszTranslator), debugstr_a(lpszPathIn), lpszPathOut,
          cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);

    if (lpszInfFile)
        return FALSE;

    return SQLInstallTranslatorEx(lpszTranslator, lpszPathIn, lpszPathOut,
                       cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
}

BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator,
              LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax,
              WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
{
    clear_errors();
    TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile),
          debugstr_w(lpszTranslator), debugstr_w(lpszPathIn), lpszPathOut,
          cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);

    if (lpszInfFile)
        return FALSE;

    return SQLInstallTranslatorExW(lpszTranslator, lpszPathIn, lpszPathOut,
                        cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
}

BOOL WINAPI SQLManageDataSources(HWND hwnd)
{
    clear_errors();
    FIXME("%p\n", hwnd);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
{
    FIXME("%u %s\n", fErrorCode, debugstr_w(szErrorMsg));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
{
    FIXME("%u %s\n", fErrorCode, debugstr_a(szErrorMsg));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
               LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString,
               WORD *pcbString)
{
    clear_errors();
    FIXME("%s %s %s %s %d %p\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
               debugstr_w(lpszKeyName), debugstr_w(lpszString), cbString, pcbString);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
               LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString,
               WORD *pcbString)
{
    clear_errors();
    FIXME("%s %s %s %s %d %p\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
               debugstr_a(lpszKeyName), debugstr_a(lpszString), cbString, pcbString);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLRemoveDefaultDataSource(void)
{
    clear_errors();
    FIXME("\n");
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
{
    HKEY hkey;
    DWORD usagecount = 1;

    clear_errors();
    TRACE("%s %d %p\n", debugstr_w(drivername), remove_dsn, usage_count);

    if (RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey) == ERROR_SUCCESS)
    {
        HKEY hkeydriver;

        if (RegOpenKeyW(hkey, drivername, &hkeydriver) == ERROR_SUCCESS)
        {
            DWORD size, type;
            DWORD count;

            size = sizeof(usagecount);
            RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
            TRACE("Usage count %d\n", usagecount);
            count = usagecount - 1;
            if (count)
            {
                 if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
                    ERR("Failed to write registry UsageCount key\n");
            }

            RegCloseKey(hkeydriver);
        }

        if (usagecount)
            usagecount--;

        if (!usagecount)
        {
            if (RegDeleteKeyW(hkey, drivername) != ERROR_SUCCESS)
                ERR("Failed to delete registry key: %s\n", debugstr_w(drivername));

            if (RegOpenKeyW(hkey, odbcdrivers, &hkeydriver) == ERROR_SUCCESS)
            {
                if(RegDeleteValueW(hkeydriver, drivername) != ERROR_SUCCESS)
                    ERR("Failed to delete registry value: %s\n", debugstr_w(drivername));
                RegCloseKey(hkeydriver);
            }
        }

        RegCloseKey(hkey);
    }

    if (usage_count)
        *usage_count = usagecount;

    return TRUE;
}

BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN,
               LPDWORD lpdwUsageCount)
{
    WCHAR *driver;
    BOOL ret;

    clear_errors();
    TRACE("%s %d %p\n", debugstr_a(lpszDriver), fRemoveDSN, lpdwUsageCount);

    driver = SQLInstall_strdup(lpszDriver);

    ret =  SQLRemoveDriverW(driver, fRemoveDSN, lpdwUsageCount);

    HeapFree(GetProcessHeap(), 0, driver);
    return ret;
}

BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
{
    clear_errors();
    FIXME("%p\n", pdwUsageCount);
    if (pdwUsageCount) *pdwUsageCount = 1;
    return TRUE;
}

BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
{
    clear_errors();
    FIXME("%s\n", debugstr_w(lpszDSN));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
{
    clear_errors();
    FIXME("%s\n", debugstr_a(lpszDSN));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
{
    HKEY hkey;
    DWORD usagecount = 1;
    BOOL ret = TRUE;

    clear_errors();
    TRACE("%s %p\n", debugstr_w(translator), usage_count);

    if (RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey) == ERROR_SUCCESS)
    {
        HKEY hkeydriver;

        if (RegOpenKeyW(hkey, translator, &hkeydriver) == ERROR_SUCCESS)
        {
            DWORD size, type;
            DWORD count;

            size = sizeof(usagecount);
            RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
            TRACE("Usage count %d\n", usagecount);
            count = usagecount - 1;
            if (count)
            {
                 if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
                    ERR("Failed to write registry UsageCount key\n");
            }

            RegCloseKey(hkeydriver);
        }

        if (usagecount)
            usagecount--;

        if (!usagecount)
        {
            if(RegDeleteKeyW(hkey, translator) != ERROR_SUCCESS)
            {
                push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
                WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
                ret = FALSE;
            }

            if (ret && RegOpenKeyW(hkey, odbctranslators, &hkeydriver) == ERROR_SUCCESS)
            {
                if(RegDeleteValueW(hkeydriver, translator) != ERROR_SUCCESS)
                {
                    push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
                    WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
                    ret = FALSE;
                }

                RegCloseKey(hkeydriver);
            }
        }

        RegCloseKey(hkey);
    }

    if (ret && usage_count)
        *usage_count = usagecount;

    return ret;
}

BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
{
    WCHAR *translator;
    BOOL ret;

    clear_errors();
    TRACE("%s %p\n", debugstr_a(lpszTranslator), lpdwUsageCount);

    translator = SQLInstall_strdup(lpszTranslator);
    ret =  SQLRemoveTranslatorW(translator, lpdwUsageCount);

    HeapFree(GetProcessHeap(), 0, translator);
    return ret;
}

BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
{
    clear_errors();
    TRACE("%u\n", wConfigMode);

    if (wConfigMode > ODBC_SYSTEM_DSN)
    {
        push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE, odbc_error_invalid_param_sequence);
        return FALSE;
    }
    else
    {
        config_mode = wConfigMode;
        return TRUE;
    }
}

BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
{
    clear_errors();
    FIXME("%s\n", debugstr_w(lpszDSN));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
{
    clear_errors();
    FIXME("%s\n", debugstr_a(lpszDSN));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
{
    clear_errors();
    FIXME("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
{
    clear_errors();
    FIXME("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
               LPCWSTR lpszKeyName, LPCWSTR lpszString)
{
    clear_errors();
    FIXME("%s %s %s %s\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
                 debugstr_w(lpszKeyName), debugstr_w(lpszString));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
               LPCSTR lpszKeyName, LPCSTR lpszString)
{
    clear_errors();
    FIXME("%s %s %s %s\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
                 debugstr_a(lpszKeyName), debugstr_a(lpszString));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry,
               LPCWSTR lpszString, LPCWSTR lpszFilename)
{
    LONG ret;
    HKEY hkey;

    clear_errors();
    TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry),
                debugstr_w(lpszString), debugstr_w(lpszFilename));

    if(!lpszFilename || !*lpszFilename)
    {
        push_error(ODBC_ERROR_INVALID_STR, odbc_error_invalid_param_string);
        return FALSE;
    }

    if ((ret = RegCreateKeyW(HKEY_CURRENT_USER, odbcW, &hkey)) == ERROR_SUCCESS)
    {
         HKEY hkeyfilename;

         if ((ret = RegCreateKeyW(hkey, lpszFilename, &hkeyfilename)) == ERROR_SUCCESS)
         {
              HKEY hkey_section;

              if ((ret = RegCreateKeyW(hkeyfilename, lpszSection, &hkey_section)) == ERROR_SUCCESS)
              {
                  ret = RegSetValueExW(hkey_section, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR));
                  RegCloseKey(hkey_section);
              }

              RegCloseKey(hkeyfilename);
         }

         RegCloseKey(hkey);
    }

    return ret == ERROR_SUCCESS;
}

BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry,
               LPCSTR lpszString, LPCSTR lpszFilename)
{
    BOOL ret;
    WCHAR *sect, *entry, *string, *file;
    clear_errors();
    TRACE("%s %s %s %s\n", lpszSection, lpszEntry, lpszString, lpszFilename);

    sect = heap_strdupAtoW(lpszSection);
    entry = heap_strdupAtoW(lpszEntry);
    string = heap_strdupAtoW(lpszString);
    file = heap_strdupAtoW(lpszFilename);

    ret = SQLWritePrivateProfileStringW(sect, entry, string, file);

    heap_free(sect);
    heap_free(entry);
    heap_free(string);
    heap_free(file);

    return ret;
}
