/*
 * Services.exe - some utility functions
 *
 * Copyright 2007 Google (Mikolaj Zalewski)
 *
 * 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
 */

#define WIN32_LEAN_AND_MEAN

#include <stdarg.h>
#include <windows.h>
#include <winsvc.h>

#include "wine/unicode.h"
#include "wine/debug.h"
#include "services.h"

WINE_DEFAULT_DEBUG_CHANNEL(service);

LPWSTR strdupW(LPCWSTR str)
{
    int len;
    WCHAR *buf;

    if (str == NULL)
        return NULL;
    len = strlenW(str);
    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
    if (buf == NULL)
        return NULL;
    strcpyW(buf, str);
    return buf;
}

BOOL check_multisz(LPCWSTR lpMultiSz, DWORD cbSize)
{
    if (cbSize == 0 || (cbSize == sizeof(WCHAR) && lpMultiSz[0] == 0))
        return TRUE;
    if ((cbSize % sizeof(WCHAR)) != 0 || cbSize < 2*sizeof(WCHAR))
        return FALSE;
    if (lpMultiSz[cbSize/2 - 1] || lpMultiSz[cbSize/2 - 2])
        return FALSE;
    return TRUE;
}

DWORD load_reg_string(HKEY hKey, LPCWSTR szValue, BOOL bExpand, LPWSTR *output)
{
    DWORD size, type;
    LPWSTR buf = NULL;
    DWORD err;

    *output = NULL;
    if ((err = RegQueryValueExW(hKey, szValue, 0, &type, NULL, &size)) != 0)
    {
        if (err == ERROR_FILE_NOT_FOUND)
            return ERROR_SUCCESS;
        goto failed;
    }
    if (!(type == REG_SZ || (type == REG_EXPAND_SZ && bExpand)))
    {
        err = ERROR_INVALID_DATATYPE;
        goto failed;
    }
    buf = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
    if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)buf, &size)) != 0)
        goto failed;
    buf[size/sizeof(WCHAR)] = 0;

    if (type == REG_EXPAND_SZ)
    {
        LPWSTR str;
        if (!(size = ExpandEnvironmentStringsW(buf, NULL, 0)))
        {
            err = GetLastError();
            goto failed;
        }
        str = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
        ExpandEnvironmentStringsW(buf, str, size);
        HeapFree(GetProcessHeap(), 0, buf);
        *output = str;
    }
    else
        *output = buf;
    return ERROR_SUCCESS;

failed:
    WINE_ERR("Error %d while reading value %s\n", err, wine_dbgstr_w(szValue));
    HeapFree(GetProcessHeap(), 0, buf);
    return err;
}

DWORD load_reg_multisz(HKEY hKey, LPCWSTR szValue, BOOL bAllowSingle, LPWSTR *output)
{
    DWORD size, type;
    LPWSTR buf = NULL;
    DWORD err;

    *output = NULL;
    if ((err = RegQueryValueExW(hKey, szValue, 0, &type, NULL, &size)) != 0)
    {
        if (err == ERROR_FILE_NOT_FOUND)
        {
            *output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR));
            return ERROR_SUCCESS;
        }
        goto failed;
    }
    if (!((type == REG_MULTI_SZ) || ((type == REG_SZ) && bAllowSingle)))
    {
        err = ERROR_INVALID_DATATYPE;
        goto failed;
    }
    buf = HeapAlloc(GetProcessHeap(), 0, size + 2*sizeof(WCHAR));
    if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)buf, &size)) != 0)
        goto failed;
    buf[size/sizeof(WCHAR)] = 0;
    buf[size/sizeof(WCHAR) + 1] = 0;
    *output = buf;
    return ERROR_SUCCESS;

failed:
    WINE_ERR("Error %d while reading value %s\n", err, wine_dbgstr_w(szValue));
    HeapFree(GetProcessHeap(), 0, buf);
    return err;
}

DWORD load_reg_dword(HKEY hKey, LPCWSTR szValue, DWORD *output)
{
    DWORD size, type;
    DWORD err;

    *output = 0;
    size = sizeof(DWORD);
    if ((err = RegQueryValueExW(hKey, szValue, 0, &type, (LPBYTE)output, &size)) != 0)
    {
        if (err == ERROR_FILE_NOT_FOUND)
            return ERROR_SUCCESS;
        goto failed;
    }
    if (type != REG_DWORD || size != sizeof(DWORD))
    {
        err = ERROR_INVALID_DATATYPE;
        goto failed;
    }
    return ERROR_SUCCESS;

failed:
    WINE_ERR("Error %d while reading value %s\n", err, wine_dbgstr_w(szValue));
    return err;
}
