/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsettings.h"

#ifndef QT_NO_SETTINGS

#include "qsettings_p.h"
#include "qvector.h"
#include "qmap.h"
#include "qt_windows.h"
#include "qdebug.h"

QT_BEGIN_NAMESPACE

/*  Keys are stored in QStrings. If the variable name starts with 'u', this is a "user"
    key, ie. "foo/bar/alpha/beta". If the variable name starts with 'r', this is a "registry"
    key, ie. "\foo\bar\alpha\beta". */

/*******************************************************************************
** Some convenience functions
*/

/*
  We don't use KEY_ALL_ACCESS because it gives more rights than what we
  need. See task 199061.
 */
static const REGSAM registryPermissions = KEY_READ | KEY_WRITE;

static QString keyPath(const QString &rKey)
{
    int idx = rKey.lastIndexOf(QLatin1Char('\\'));
    if (idx == -1)
        return QString();
    return rKey.left(idx + 1);
}

static QString keyName(const QString &rKey)
{
    int idx = rKey.lastIndexOf(QLatin1Char('\\'));

    QString res;
    if (idx == -1)
        res = rKey;
    else
        res = rKey.mid(idx + 1);

    if (res == QLatin1String("Default") || res == QLatin1String("."))
        res = QLatin1String("");

    return res;
}

static QString escapedKey(QString uKey)
{
    QChar *data = uKey.data();
    int l = uKey.length();
    for (int i = 0; i < l; ++i) {
        ushort &ucs = data[i].unicode();
        if (ucs == '\\')
            ucs = '/';
        else if (ucs == '/')
            ucs = '\\';
    }
    return uKey;
}

static QString unescapedKey(QString rKey)
{
    return escapedKey(rKey);
}

typedef QMap<QString, QString> NameSet;

static void mergeKeySets(NameSet *dest, const NameSet &src)
{
    NameSet::const_iterator it = src.constBegin();
    for (; it != src.constEnd(); ++it)
        dest->insert(unescapedKey(it.key()), QString());
}

static void mergeKeySets(NameSet *dest, const QStringList &src)
{
    QStringList::const_iterator it = src.constBegin();
    for (; it != src.constEnd(); ++it)
        dest->insert(unescapedKey(*it), QString());
}

/*******************************************************************************
** Wrappers for the insane windows registry API
*/

static QString errorCodeToString(DWORD errorCode)
{
    wchar_t *data = 0;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, data, 0, 0);
    QString result = QString::fromWCharArray(data);

    if (data != 0)
        LocalFree(data);

    if (result.endsWith(QLatin1Char('\n')))
        result.truncate(result.length() - 1);

    return result;
}

// Open a key with the specified perms
static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey)
{
    HKEY resultHandle = 0;
    LONG res = RegOpenKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()),
                            0, perms, &resultHandle);

    if (res == ERROR_SUCCESS)
        return resultHandle;

    return 0;
}

// Open a key with the specified perms, create it if it does not exist
static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey)
{
    // try to open it
    HKEY resultHandle = openKey(parentHandle, perms, rSubKey);
    if (resultHandle != 0)
        return resultHandle;

    // try to create it
    LONG res = RegCreateKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()), 0, 0,
                              REG_OPTION_NON_VOLATILE, perms, 0, &resultHandle, 0);

    if (res == ERROR_SUCCESS)
        return resultHandle;

    //qWarning("QSettings: Failed to create subkey \"%s\": %s",
    //        rSubKey.toLatin1().data(), errorCodeToString(res).toLatin1().data());

    return 0;
}

// Open or create a key in read-write mode if possible, otherwise read-only
static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *readOnly)
{
    // try to open or create it read/write
    HKEY resultHandle = createOrOpenKey(parentHandle, registryPermissions, rSubKey);
    if (resultHandle != 0) {
        if (readOnly != 0)
            *readOnly = false;
        return resultHandle;
    }

    // try to open or create it read/only
    resultHandle = createOrOpenKey(parentHandle, KEY_READ, rSubKey);
    if (resultHandle != 0) {
        if (readOnly != 0)
            *readOnly = true;
        return resultHandle;
    }
    return 0;
}

static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildSpec spec)
{
    QStringList result;
    DWORD numKeys;
    DWORD maxKeySize;
    DWORD numSubgroups;
    DWORD maxSubgroupSize;

    // Find the number of keys and subgroups, as well as the max of their lengths.
    LONG res = RegQueryInfoKey(parentHandle, 0, 0, 0, &numSubgroups, &maxSubgroupSize, 0,
                               &numKeys, &maxKeySize, 0, 0, 0);

    if (res != ERROR_SUCCESS) {
        qWarning("QSettings: RegQueryInfoKey() failed: %s", errorCodeToString(res).toLatin1().data());
        return result;
    }

    ++maxSubgroupSize;
    ++maxKeySize;

    int n;
    int m;
    if (spec == QSettingsPrivate::ChildKeys) {
        n = numKeys;
        m = maxKeySize;
    } else {
        n = numSubgroups;
        m = maxSubgroupSize;
    }

    /* The size does not include the terminating null character. */
    ++m;

    // Get the list
    QByteArray buff(m * sizeof(wchar_t), 0);
    for (int i = 0; i < n; ++i) {
        QString item;
        DWORD l = buff.size() / sizeof(wchar_t);
        if (spec == QSettingsPrivate::ChildKeys) {
            res = RegEnumValue(parentHandle, i, reinterpret_cast<wchar_t *>(buff.data()), &l, 0, 0, 0, 0);
        } else {
            res = RegEnumKeyEx(parentHandle, i, reinterpret_cast<wchar_t *>(buff.data()), &l, 0, 0, 0, 0);
        }
        if (res == ERROR_SUCCESS)
            item = QString::fromWCharArray((const wchar_t *)buff.constData(), l);

        if (res != ERROR_SUCCESS) {
            qWarning("QSettings: RegEnumValue failed: %s", errorCodeToString(res).toLatin1().data());
            continue;
        }
        if (item.isEmpty())
            item = QLatin1String(".");
        result.append(item);
    }
    return result;
}

static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result)
{
    HKEY handle = openKey(parentHandle, KEY_READ, rSubKey);
    if (handle == 0)
        return;

    QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys);
    QStringList childGroups = childKeysOrGroups(handle, QSettingsPrivate::ChildGroups);
    RegCloseKey(handle);

    for (int i = 0; i < childKeys.size(); ++i) {
        QString s = rSubKey;
        if (!s.isEmpty())
            s += QLatin1Char('\\');
        s += childKeys.at(i);
        result->insert(s, QString());
    }

    for (int i = 0; i < childGroups.size(); ++i) {
        QString s = rSubKey;
        if (!s.isEmpty())
            s += QLatin1Char('\\');
        s += childGroups.at(i);
        allKeys(parentHandle, s, result);
    }
}

static void deleteChildGroups(HKEY parentHandle)
{
    QStringList childGroups = childKeysOrGroups(parentHandle, QSettingsPrivate::ChildGroups);

    for (int i = 0; i < childGroups.size(); ++i) {
        QString group = childGroups.at(i);

        // delete subgroups in group
        HKEY childGroupHandle = openKey(parentHandle, registryPermissions, group);
        if (childGroupHandle == 0)
            continue;
        deleteChildGroups(childGroupHandle);
        RegCloseKey(childGroupHandle);

        // delete group itself
        LONG res = RegDeleteKey(parentHandle, reinterpret_cast<const wchar_t *>(group.utf16()));
        if (res != ERROR_SUCCESS) {
            qWarning("QSettings: RegDeleteKey failed on subkey \"%s\": %s",
                      group.toLatin1().data(), errorCodeToString(res).toLatin1().data());
            return;
        }
    }
}

/*******************************************************************************
** class RegistryKey
*/

class RegistryKey
{
public:
    RegistryKey(HKEY parent_handle = 0, const QString &key = QString(), bool read_only = true);
    QString key() const;
    HKEY handle() const;
    HKEY parentHandle() const;
    bool readOnly() const;
    void close();
private:
    HKEY m_parent_handle;
    mutable HKEY m_handle;
    QString m_key;
    mutable bool m_read_only;
};

RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only)
{
    m_parent_handle = parent_handle;
    m_handle = 0;
    m_read_only = read_only;
    m_key = key;
}

QString RegistryKey::key() const
{
    return m_key;
}

HKEY RegistryKey::handle() const
{
    if (m_handle != 0)
        return m_handle;

    if (m_read_only)
        m_handle = openKey(m_parent_handle, KEY_READ, m_key);
    else
        m_handle = createOrOpenKey(m_parent_handle, m_key, &m_read_only);

    return m_handle;
}

HKEY RegistryKey::parentHandle() const
{
    return m_parent_handle;
}

bool RegistryKey::readOnly() const
{
    return m_read_only;
}

void RegistryKey::close()
{
    if (m_handle != 0)
        RegCloseKey(m_handle);
    m_handle = 0;
}

typedef QVector<RegistryKey> RegistryKeyList;

/*******************************************************************************
** class QWinSettingsPrivate
*/

class QWinSettingsPrivate : public QSettingsPrivate
{
public:
    QWinSettingsPrivate(QSettings::Scope scope, const QString &organization,
                        const QString &application);
    QWinSettingsPrivate(QString rKey);
    ~QWinSettingsPrivate();

    void remove(const QString &uKey);
    void set(const QString &uKey, const QVariant &value);
    bool get(const QString &uKey, QVariant *value) const;
    QStringList children(const QString &uKey, ChildSpec spec) const;
    void clear();
    void sync();
    void flush();
    bool isWritable() const;
    HKEY writeHandle() const;
    bool readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const;
    QString fileName() const;

private:
    RegistryKeyList regList; // list of registry locations to search for keys
    bool deleteWriteHandleOnExit;
};

QWinSettingsPrivate::QWinSettingsPrivate(QSettings::Scope scope, const QString &organization,
                                         const QString &application)
    : QSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
{
    deleteWriteHandleOnExit = false;

    if (!organization.isEmpty()) {
        QString prefix = QLatin1String("Software\\") + organization;
        QString orgPrefix = prefix + QLatin1String("\\OrganizationDefaults");
        QString appPrefix = prefix + QLatin1Char('\\') + application;

        if (scope == QSettings::UserScope) {
            if (!application.isEmpty())
                regList.append(RegistryKey(HKEY_CURRENT_USER, appPrefix, !regList.isEmpty()));

            regList.append(RegistryKey(HKEY_CURRENT_USER, orgPrefix, !regList.isEmpty()));
        }

        if (!application.isEmpty())
            regList.append(RegistryKey(HKEY_LOCAL_MACHINE, appPrefix, !regList.isEmpty()));

        regList.append(RegistryKey(HKEY_LOCAL_MACHINE, orgPrefix, !regList.isEmpty()));
    }

    if (regList.isEmpty())
        setStatus(QSettings::AccessError);
}

QWinSettingsPrivate::QWinSettingsPrivate(QString rPath)
    : QSettingsPrivate(QSettings::NativeFormat)
{
    deleteWriteHandleOnExit = false;

    if (rPath.startsWith(QLatin1String("\\")))
        rPath = rPath.mid(1);

    if (rPath.startsWith(QLatin1String("HKEY_CURRENT_USER\\")))
        regList.append(RegistryKey(HKEY_CURRENT_USER, rPath.mid(18), false));
    else if (rPath == QLatin1String("HKEY_CURRENT_USER"))
        regList.append(RegistryKey(HKEY_CURRENT_USER, QString(), false));
    else if (rPath.startsWith(QLatin1String("HKEY_LOCAL_MACHINE\\")))
        regList.append(RegistryKey(HKEY_LOCAL_MACHINE, rPath.mid(19), false));
    else if (rPath == QLatin1String("HKEY_LOCAL_MACHINE"))
        regList.append(RegistryKey(HKEY_LOCAL_MACHINE, QString(), false));
    else if (rPath.startsWith(QLatin1String("HKEY_CLASSES_ROOT\\")))
        regList.append(RegistryKey(HKEY_CLASSES_ROOT, rPath.mid(18), false));
    else if (rPath == QLatin1String("HKEY_CLASSES_ROOT"))
        regList.append(RegistryKey(HKEY_CLASSES_ROOT, QString(), false));
    else if (rPath.startsWith(QLatin1String("HKEY_USERS\\")))
        regList.append(RegistryKey(HKEY_USERS, rPath.mid(11), false));
    else if (rPath == QLatin1String(QLatin1String("HKEY_USERS")))
        regList.append(RegistryKey(HKEY_USERS, QString(), false));
    else
        regList.append(RegistryKey(HKEY_LOCAL_MACHINE, rPath, false));
}

bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const
{
    QString rSubkeyName = keyName(rSubKey);
    QString rSubkeyPath = keyPath(rSubKey);

    // open a handle on the subkey
    HKEY handle = openKey(parentHandle, KEY_READ, rSubkeyPath);
    if (handle == 0)
        return false;

    // get the size and type of the value
    DWORD dataType;
    DWORD dataSize;
    LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, &dataType, 0, &dataSize);
    if (res != ERROR_SUCCESS) {
        RegCloseKey(handle);
        return false;
    }

    // get the value
    QByteArray data(dataSize, 0);
    res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, 0,
                           reinterpret_cast<unsigned char*>(data.data()), &dataSize);
    if (res != ERROR_SUCCESS) {
        RegCloseKey(handle);
        return false;
    }

    switch (dataType) {
        case REG_EXPAND_SZ:
        case REG_SZ: {
            QString s;
            if (dataSize) {
                s = QString::fromWCharArray(((const wchar_t *)data.constData()));
            }
            if (value != 0)
                *value = stringToVariant(s);
            break;
        }

        case REG_MULTI_SZ: {
            QStringList l;
            if (dataSize) {
                int i = 0;
                for (;;) {
                    QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
                    i += s.length() + 1;

                    if (s.isEmpty())
                        break;
                    l.append(s);
                }
            }
            if (value != 0)
                *value = stringListToVariantList(l);
            break;
        }

        case REG_NONE:
        case REG_BINARY: {
            QString s;
            if (dataSize) {
                s = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
            }
            if (value != 0)
                *value = stringToVariant(s);
            break;
        }

        case REG_DWORD_BIG_ENDIAN:
        case REG_DWORD: {
            Q_ASSERT(data.size() == sizeof(int));
            int i;
            memcpy((char*)&i, data.constData(), sizeof(int));
            if (value != 0)
                *value = i;
            break;
        }

        case REG_QWORD: {
            Q_ASSERT(data.size() == sizeof(qint64));
            qint64 i;
            memcpy((char*)&i, data.constData(), sizeof(qint64));
            if (value != 0)
                *value = i;
            break;
        }

        default:
            qWarning("QSettings: Unknown data %d type in Windows registry", static_cast<int>(dataType));
            if (value != 0)
                *value = QVariant();
            break;
    }

    RegCloseKey(handle);
    return true;
}

HKEY QWinSettingsPrivate::writeHandle() const
{
    if (regList.isEmpty())
        return 0;
    const RegistryKey &key = regList.at(0);
    if (key.handle() == 0 || key.readOnly())
        return 0;
    return key.handle();
}

QWinSettingsPrivate::~QWinSettingsPrivate()
{
    if (deleteWriteHandleOnExit && writeHandle() != 0) {
#if defined(Q_OS_WINCE)
        remove(regList.at(0).key()); 
#else
        QString emptyKey;
        DWORD res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(emptyKey.utf16()));
        if (res != ERROR_SUCCESS) {
            qWarning("QSettings: Failed to delete key \"%s\": %s",
                    regList.at(0).key().toLatin1().data(), errorCodeToString(res).toLatin1().data());
        }
#endif
    }

    for (int i = 0; i < regList.size(); ++i)
        regList[i].close();
}

void QWinSettingsPrivate::remove(const QString &uKey)
{
    if (writeHandle() == 0) {
        setStatus(QSettings::AccessError);
        return;
    }

    QString rKey = escapedKey(uKey);

    // try to delete value bar in key foo
    LONG res;
    HKEY handle = openKey(writeHandle(), registryPermissions, keyPath(rKey));
    if (handle != 0) {
        res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()));
        RegCloseKey(handle);
    }

    // try to delete key foo/bar and all subkeys
    handle = openKey(writeHandle(), registryPermissions, rKey);
    if (handle != 0) {
        deleteChildGroups(handle);

        if (rKey.isEmpty()) {
            QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys);

            for (int i = 0; i < childKeys.size(); ++i) {
                QString group = childKeys.at(i);

                LONG res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(group.utf16()));
                if (res != ERROR_SUCCESS) {
                    qWarning("QSettings: RegDeleteValue failed on subkey \"%s\": %s",
                              group.toLatin1().data(), errorCodeToString(res).toLatin1().data());
                }
            }
        } else {
#if defined(Q_OS_WINCE)
            // For WinCE always Close the handle first.
            RegCloseKey(handle);
#endif
            res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(rKey.utf16()));

            if (res != ERROR_SUCCESS) {
                qWarning("QSettings: RegDeleteKey failed on key \"%s\": %s",
                            rKey.toLatin1().data(), errorCodeToString(res).toLatin1().data());
            }
        }
        RegCloseKey(handle);
    }
}

static bool stringContainsNullChar(const QString &s)
{
    for (int i = 0; i < s.length(); ++i) {
        if (s.at(i).unicode() == 0)
            return true;
    }
    return false;
}

void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
{
    if (writeHandle() == 0) {
        setStatus(QSettings::AccessError);
        return;
    }

    QString rKey = escapedKey(uKey);

    HKEY handle = createOrOpenKey(writeHandle(), registryPermissions, keyPath(rKey));
    if (handle == 0) {
        setStatus(QSettings::AccessError);
        return;
    }

    DWORD type;
    QByteArray regValueBuff;

    // Determine the type
    switch (value.type()) {
        case QVariant::List:
        case QVariant::StringList: {
            // If none of the elements contains '\0', we can use REG_MULTI_SZ, the
            // native registry string list type. Otherwise we use REG_BINARY.
            type = REG_MULTI_SZ;
            QStringList l = variantListToStringList(value.toList());
            QStringList::const_iterator it = l.constBegin();
            for (; it != l.constEnd(); ++it) {
                if ((*it).length() == 0 || stringContainsNullChar(*it)) {
                    type = REG_BINARY;
                    break;
                }
            }

            if (type == REG_BINARY) {
                QString s = variantToString(value);
                regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2);
            } else {
                QStringList::const_iterator it = l.constBegin();
                for (; it != l.constEnd(); ++it) {
                    const QString &s = *it;
                    regValueBuff += QByteArray((const char*)s.utf16(), (s.length() + 1) * 2);
                }
                regValueBuff.append((char)0);
                regValueBuff.append((char)0);
            }
            break;
        }

        case QVariant::Int:
        case QVariant::UInt: {
            type = REG_DWORD;
            qint32 i = value.toInt();
            regValueBuff = QByteArray((const char*)&i, sizeof(qint32));
            break;
        }

        case QVariant::LongLong:
        case QVariant::ULongLong: {
            type = REG_QWORD;
            qint64 i = value.toLongLong();
            regValueBuff = QByteArray((const char*)&i, sizeof(qint64));
            break;
        }

        case QVariant::ByteArray:
            // fallthrough intended

        default: {
            // If the string does not contain '\0', we can use REG_SZ, the native registry
            // string type. Otherwise we use REG_BINARY.
            QString s = variantToString(value);
            type = stringContainsNullChar(s) ? REG_BINARY : REG_SZ;
            if (type == REG_BINARY) {
                regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2);
            } else {
                regValueBuff = QByteArray((const char*)s.utf16(), (s.length() + 1) * 2);
            }
            break;
        }
    }

    // set the value
    LONG res = RegSetValueEx(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()), 0, type,
                             reinterpret_cast<const unsigned char*>(regValueBuff.constData()),
                             regValueBuff.size());

    if (res == ERROR_SUCCESS) {
        deleteWriteHandleOnExit = false;
    } else {
        qWarning("QSettings: failed to set subkey \"%s\": %s",
                rKey.toLatin1().data(), errorCodeToString(res).toLatin1().data());
        setStatus(QSettings::AccessError);
    }

    RegCloseKey(handle);
}

bool QWinSettingsPrivate::get(const QString &uKey, QVariant *value) const
{
    QString rKey = escapedKey(uKey);

    for (int i = 0; i < regList.size(); ++i) {
        HKEY handle = regList.at(i).handle();
        if (handle != 0 && readKey(handle, rKey, value))
            return true;

        if (!fallbacks)
            return false;
    }

    return false;
}

QStringList QWinSettingsPrivate::children(const QString &uKey, ChildSpec spec) const
{
    NameSet result;
    QString rKey = escapedKey(uKey);

    for (int i = 0; i < regList.size(); ++i) {
        HKEY parent_handle = regList.at(i).handle();
        if (parent_handle == 0)
            continue;
        HKEY handle = openKey(parent_handle, KEY_READ, rKey);
        if (handle == 0)
            continue;

        if (spec == AllKeys) {
            NameSet keys;
            allKeys(handle, QLatin1String(""), &keys);
            mergeKeySets(&result, keys);
        } else { // ChildGroups or ChildKeys
            QStringList names = childKeysOrGroups(handle, spec);
            mergeKeySets(&result, names);
        }

        RegCloseKey(handle);

        if (!fallbacks)
            return result.keys();
    }

    return result.keys();
}

void QWinSettingsPrivate::clear()
{
    remove(QString());
    deleteWriteHandleOnExit = true;
}

void QWinSettingsPrivate::sync()
{
    RegFlushKey(writeHandle());
}

void QWinSettingsPrivate::flush()
{
    // Windows does this for us.
}

QString QWinSettingsPrivate::fileName() const
{
    if (regList.isEmpty())
        return QString();

    const RegistryKey &key = regList.at(0);
    QString result;
    if (key.parentHandle() == HKEY_CURRENT_USER)
        result = QLatin1String("\\HKEY_CURRENT_USER\\");
    else
        result = QLatin1String("\\HKEY_LOCAL_MACHINE\\");

    return result + regList.at(0).key();
}

bool QWinSettingsPrivate::isWritable() const
{
    return writeHandle() != 0;
}

QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
                                           const QString &organization, const QString &application)
{
    if (format == QSettings::NativeFormat) {
        return new QWinSettingsPrivate(scope, organization, application);
    } else {
        return new QConfFileSettingsPrivate(format, scope, organization, application);
    }
}

QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
    if (format == QSettings::NativeFormat) {
        return new QWinSettingsPrivate(fileName);
    } else {
        return new QConfFileSettingsPrivate(fileName, format);
    }
}

QT_END_NAMESPACE
#endif // QT_NO_SETTINGS
