[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-cygwin
Subject:    Re: [PATCH] qsettings_win - registry support
From:       Christian Ehrlicher <Ch.Ehrlicher () gmx ! de>
Date:       2004-09-19 13:45:29
Message-ID: 414D8D79.80806 () gmx ! de
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Thx, I've moved ret out of the inner brackets and forgot to remove the
declarations. So here the new version, including fixes for mingw.

Since qmake now uses qsettings_win.cpp we must link it wth advapi32.dll.
~ I'll send the patches when cvs.sf.net is working again.

Thx,
Christian

Andy Goossens schrieb:
| On Sunday 19 September 2004 13:27, Christian Ehrlicher wrote:
|
|>bool QSettingsPrivate::sysWriteEntry( const QString &key, int data )
|>{
|
| (...snip...)
|
|>    long ret = -1;
|
|       ^^^^
|
|>    QString value;
|>
|>    HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope
|>); if ( hkey ) {
|>        long ret = QT_WA_INLINE(
|
|           ^^^^
| (...snip...)
|
|>    }
|>    return ( ret == ERROR_SUCCESS );
|>}
|
|
| Pay attention to the scope of the 'ret' variable here (and in some other
| functions).
|

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFBTY15nNKwkgf+zVMRAkEFAJ970zytcBm1PfB6qq2UBEFSAjG01QCdHStJ
IWiFoLHIpVfWPWjKJ1aqEZ0=
=Ex2t
-----END PGP SIGNATURE-----

["qsettings_win.cpp" (text/plain)]

/****************************************************************************
** $Id: qsettings_win.cpp,v 1.1.2.4.2.1 2004/08/28 00:19:40 habacker Exp $
**
** Implementation of QSettingsPrivate class for Windows
**
** Created: 2004.09.18
**
** Copyright (C) 2004 Christian Ehrlicher
**
** This file is part of the tools module of the
** "Qt GUI Toolkit for Windows licensed under the GPL or QPL".
**
** For more informations about the project see:
**      http://kde-cygwin.sourceforge.net/qt3-win32/
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
**********************************************************************/

#include "qsettings.h"
#ifndef QT_NO_SETTINGS

#include "qt_windows.h"
#include <winreg.h>
#include <shlwapi.h>

#include "qstring.h"
#include "qregexp.h"
#include "qsettings_p.h"

/* MSVC++ 6.0 doesn't define this :( */
#ifndef REG_QWORD
#define REG_QWORD_LITTLE_ENDIAN (11)
#define REG_QWORD (11)
#endif

bool qt_verify_key( const QString & ); //qsettings.cpp

class QSettingsSysPrivate
{
public:
    QSettingsSysPrivate();
    QStringList searchPaths;

    /* Helper functions */
    /* Opens a key, first tries in HKEY_CURRENT_USER/Software, then
       in HKEY_LOCAL_MACHINE/Software unless global == true (than only HKLM).
       If key doesn't exist, it is created --> for writing. */
    HKEY createKey( const QString &key, REGSAM access , QString &value, bool global \
);  /* Opens a key, first tries in HKEY_CURRENT_USER/Software, then
       in HKEY_LOCAL_MACHINE/Software  unless global == true (than only HKLM).
       If key doesn't exist, open will fail --> for reading. */
    HKEY openKey( const QString &key, REGSAM access , QString &value, bool global );
    /* Splits a key in main_key and value */
    void splitKey ( const QString &key, QString &main_key, QString &value );
};

QSettingsSysPrivate::QSettingsSysPrivate()
{}

HKEY QSettingsSysPrivate::createKey( const QString &key, REGSAM access, QString \
&value , bool global ) {
    const HKEY scopes[ 2 ] = {
                                 HKEY_CURRENT_USER,
                                 HKEY_LOCAL_MACHINE
                             };
    HKEY res_key = NULL;
    QString main_key;

    splitKey( key, main_key, value );
    QString whole_key = "Software\\" + main_key;

    for ( QStringList::Iterator it = searchPaths.fromLast(); it != searchPaths.end(); \
--it ) {  QString search_key = ( *it ) + main_key;
        //try local, then global (unless global == true, then just global)
        int i = global ? 1 : 0;
        for ( i ; i < 2; i++ ) {
            long ret = QT_WA_INLINE(
                           RegCreateKeyExW( scopes[ i ], ( LPCTSTR ) \
                whole_key.ucs2(), 0,
                                            NULL, REG_OPTION_NON_VOLATILE, access, \
NULL,  &res_key , NULL ),
                           RegCreateKeyExA( scopes[ i ], ( LPCSTR ) \
                whole_key.latin1(), 0,
                                            NULL, REG_OPTION_NON_VOLATILE, access, \
NULL,  &res_key , NULL ) );
            if ( ret == ERROR_SUCCESS )
                return res_key;
        }
    }
    return res_key;
}

HKEY QSettingsSysPrivate::openKey( const QString &key, REGSAM access, QString &value \
, bool global ) {
    const HKEY scopes[ 2 ] = {
                                 HKEY_CURRENT_USER,
                                 HKEY_LOCAL_MACHINE
                             };
    HKEY res_key = NULL;
    QString main_key;

    splitKey( key, main_key, value );
    QString whole_key = "Software\\" + main_key;

    for ( QStringList::Iterator it = searchPaths.fromLast(); it != searchPaths.end(); \
--it ) {  QString search_key = ( *it ) + main_key;
        //try local, then global (unless global == true, then just global)
        int i = global ? 1 : 0;
        for ( i ; i < 2; i++ ) {
            long ret = QT_WA_INLINE(
                           RegOpenKeyExW( scopes[ i ], ( LPCTSTR ) whole_key.ucs2(),
                                          0, access, &res_key ),
                           RegOpenKeyExA( scopes[ i ], ( LPCSTR ) whole_key.latin1(),
                                          0, access, &res_key ) );
            if ( ret == ERROR_SUCCESS )
                return res_key;
        }
    }
    return res_key;
}

void QSettingsSysPrivate::splitKey ( const QString &key, QString &main_key, QString \
&value ) {
    int pos = key.findRev( QRegExp( "(/|\\\\)" ) );
    if ( pos == -1 ) {
        main_key = QString( "" );
        value = key;
    } else {
        main_key = key.left( pos );
        value = key.right( key.length() - pos - 1 );
    }

    while ( ( main_key[ 0 ] == '/' ) || ( main_key[ 0 ] == '\\' ) )
        main_key.remove( 0, 1 );
    while ( ( main_key.right( 1 ) == "/" ) || ( main_key.right( 1 ) == "\\" ) )
        main_key.truncate( main_key.length() - 1 );
}


/* from qsettings_mac.cpp 3.3.2 */
void QSettingsPrivate::sysInit( void )
{
    sysd = new QSettingsSysPrivate;
    Q_CHECK_PTR( sysd );
    sysInsertSearchPath( QSettings::Windows, "" );
}

/* from qsettings_mac.cpp 3.3.2 */
void QSettingsPrivate::sysClear( void )
{
    delete sysd;
    sysd = NULL;
}

/* obsolete functions since already handled in public class
   QStringList sysReadListEntry( const QString &, bool * = 0 ) const;
   QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) \
const;  bool sysWriteEntry( const QString &, const QStringList &, const QChar& sep )
   bool sysWriteEntry( const QString&key, const QStringList&data )
*/

#if !defined(Q_NO_BOOL_TYPE)
bool QSettingsPrivate::sysWriteEntry( const QString &key, bool data )
{
    return sysWriteEntry( key, ( int ) data );
}
#endif

bool QSettingsPrivate::sysWriteEntry( const QString &key, double data )
{
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." );
        return false;
    }
#endif // QT_CHECK_STATE
    long ret = -1;
    QString value;

    HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope );
    if ( hkey ) {
        ret = QT_WA_INLINE(
                  RegSetValueExW( hkey, ( LPCTSTR ) value.ucs2(), 0, REG_QWORD,
                                  ( LPBYTE ) & data, sizeof( double ) ),
                  RegSetValueExA( hkey, ( LPCSTR ) value.latin1(), 0, REG_QWORD,
                                  ( LPBYTE ) & data, sizeof( double ) ) );
        RegCloseKey( hkey );
    }
    return ( ret == ERROR_SUCCESS );
}

bool QSettingsPrivate::sysWriteEntry( const QString &key, int data )
{
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." );
        return false;
    }
#endif // QT_CHECK_STATE
    long ret = -1;
    QString value;

    HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope );
    if ( hkey ) {
        ret = QT_WA_INLINE(
                  RegSetValueExW( hkey, ( LPCTSTR ) value.ucs2(), 0, REG_DWORD,
                                  ( LPBYTE ) & data, sizeof( int ) ),
                  RegSetValueExA( hkey, ( LPCSTR ) value.latin1(), 0, REG_DWORD,
                                  ( LPBYTE ) & data, sizeof( int ) ) );
        RegCloseKey( hkey );
    }
    return ( ret == ERROR_SUCCESS );
}

bool QSettingsPrivate::sysWriteEntry( const QString &key, const QString &data )
{
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." );
        return false;
    }
#endif // QT_CHECK_STATE
    long ret = -1;
    QString value;

    HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope );
    if ( hkey ) {
        int len = ( data.length() + 1 ) * sizeof( TCHAR );
        ret = QT_WA_INLINE(
                  RegSetValueExW( hkey, ( LPCTSTR ) value.ucs2(), 0, REG_SZ,
                                  ( LPBYTE ) data.ucs2(), len ),
                  RegSetValueExA( hkey, ( LPCSTR ) value.latin1(), 0, REG_SZ,
                                  ( LPBYTE ) data.latin1(), len ) );
        RegCloseKey( hkey );
    }
    return ( ret == ERROR_SUCCESS );
}

QStringList QSettingsPrivate::sysEntryList( const QString &key ) const
{
    QString value;
    QStringList list;

    HKEY hkey = sysd->openKey( key + "\\", KEY_QUERY_VALUE, value, globalScope );
    if ( hkey ) {
        int idx = 0;
        unsigned long count = QT_WA_INLINE( 16383, 260 );
        QByteArray ba( ( count + 1 ) * sizeof( TCHAR ) );

        while ( QT_WA_INLINE(
                    RegEnumValueW( hkey, idx, ( LPTSTR ) ba.data(),
                                   &count, NULL, NULL, NULL, NULL ),
                    RegEnumValueA( hkey, idx, ( LPSTR ) ba.data(),
                                   &count, NULL, NULL, NULL, NULL ) )
                == ERROR_SUCCESS ) {
            list.append ( QT_WA_INLINE( QString::fromUcs2( ( unsigned short * ) \
                ba.data() ),
                                        QString::fromLatin1( ( LPCSTR ) ba.data() ) ) \
);  idx++;
            count = QT_WA_INLINE( 16383, 260 );        /* !! */
        }
        RegCloseKey( hkey );
    }
    return list;
}

QStringList QSettingsPrivate::sysSubkeyList( const QString &key ) const
{
    QString value;
    QStringList list;

    HKEY hkey = sysd->openKey( key + "\\", KEY_ENUMERATE_SUB_KEYS, value, globalScope \
);  if ( hkey ) {
        int idx = 0;
        unsigned long count = 255;
        QByteArray ba( ( count + 1 ) * sizeof( TCHAR ) );
        FILETIME time;

        while ( QT_WA_INLINE(
                    RegEnumKeyExW( hkey, idx, ( LPTSTR ) ba.data(),
                                   &count, NULL, NULL, NULL, &time ),
                    RegEnumKeyExA( hkey, idx, ( LPSTR ) ba.data(),
                                   &count, NULL, NULL, NULL, &time ) )
                == ERROR_SUCCESS ) {
            list.append ( QT_WA_INLINE( QString::fromUcs2( ( unsigned short * ) \
                ba.data() ),
                                        QString::fromLatin1( ( LPCSTR ) ba.data() ) ) \
);  idx++;
            count = 255;        /* !! */
        }
        RegCloseKey( hkey );
    }
    return list;
}

QString QSettingsPrivate::sysReadEntry( const QString &key, const QString &def, bool \
*ok ) const {
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysReadEntry: invalid null/empty key." );
        if ( ok )
            * ok = FALSE;
        return def;
    }
#endif // QT_CHECK_STATE
    QString value;

    if ( ok )
        * ok = FALSE;

    HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope );
    if ( hkey ) {
        unsigned long ret, len = sizeof( int );

        /* First get the size of the data */
        ret = QT_WA_INLINE(
                  RegQueryValueExW( hkey, ( LPCTSTR ) value.ucs2(), NULL, NULL, NULL, \
                &len ),
                  RegQueryValueExA( hkey, ( LPCSTR ) value.latin1(), NULL, NULL, \
NULL, &len ) );  if ( ret != ERROR_SUCCESS )
            return def;

        /* now create buffer to store data */
        QByteArray ba( len + 1 );   /* +1 to be sure :) */

        ret = QT_WA_INLINE(
                  RegQueryValueExW( hkey, ( LPCTSTR ) value.ucs2(), NULL, NULL,
                                    ( LPBYTE ) ba.data(), &len ),
                  RegQueryValueExA( hkey, ( LPCSTR ) value.latin1(), NULL, NULL,
                                    ( LPBYTE ) ba.data(), &len ) );
        RegCloseKey( hkey );
        if ( ( ret == ERROR_SUCCESS ) ) {
            QString str;

            str = QT_WA_INLINE( QString::fromUcs2( ( unsigned short * ) ba.data() ),
                                QString::fromLatin1( ( LPCSTR ) ba.data() ) );

            if ( ok )
                * ok = true;
            return str;
        }
    }
    return def;
}

int QSettingsPrivate::sysReadNumEntry( const QString &key, int def, bool * ok ) const
{
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysReadNumEntry: invalid null/empty key." );
        if ( ok )
            * ok = false;
        return def;
    }
#endif // QT_CHECK_STATE
    QString value;

    if ( ok )
        * ok = false;

    HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value , globalScope );
    if ( hkey ) {
        int num;
        unsigned long ret, len = sizeof( int );

        ret = QT_WA_INLINE(
                  RegQueryValueExW( hkey, ( LPCTSTR ) value.ucs2(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ),
                  RegQueryValueExA( hkey, ( LPCSTR ) value.latin1(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ) );
        RegCloseKey( hkey );
        if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( int ) ) ) {
            if ( ok )
                * ok = true;
            return num;
        }
    }
    return def;
}

double QSettingsPrivate::sysReadDoubleEntry( const QString &key, double def, bool * \
ok ) const {
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysReadDoubleEntry: invalid null/empty key." );
        if ( ok )
            * ok = false;
        return def;
    }
#endif // QT_CHECK_STATE
    QString value;

    if ( ok )
        * ok = false;

    HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope );
    if ( hkey ) {
        double num;
        unsigned long ret, len = sizeof( double );

        ret = QT_WA_INLINE(
                  RegQueryValueExW( hkey, ( LPCTSTR ) value.ucs2(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ),
                  RegQueryValueExA( hkey, ( LPCSTR ) value.latin1(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ) );
        RegCloseKey( hkey );
        if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( double ) ) ) {
            if ( ok )
                * ok = true;
            return num;
        }
    }
    return def;
}

bool QSettingsPrivate::sysReadBoolEntry( const QString &key, bool def, bool * ok ) \
const {
#ifdef QT_CHECK_STATE
    if ( key.isNull() || key.isEmpty() ) {
        qWarning( "QSettingsPrivate::sysReadBoolEntry: invalid null/empty key." );
        if ( ok )
            * ok = false;
        return def;
    }
#endif // QT_CHECK_STATE
    QString value;

    if ( ok )
        * ok = false;

    HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope );
    if ( hkey ) {
        bool num;
        unsigned long ret, len = sizeof( bool );

        ret = QT_WA_INLINE(
                  RegQueryValueExW( hkey, ( LPCTSTR ) value.ucs2(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ),
                  RegQueryValueExA( hkey, ( LPCSTR ) value.latin1(), NULL,
                                    NULL, ( LPBYTE ) & num, &len ) );
        RegCloseKey( hkey );
        if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( bool ) ) ) {
            if ( ok )
                * ok = true;
            return num;
        }
    }
    return def;
}

bool QSettingsPrivate::sysRemoveEntry( const QString &key )
{
    QString value;
    long ret == -1;

    HKEY hkey = sysd->openKey( key , KEY_SET_VALUE, value, globalScope );
    if ( hkey ) {
        /* This just deletes a value, not a subkey ... */
        ret = QT_WA_INLINE( RegDeleteValueW( hkey, ( LPCTSTR ) value.ucs2() ),
                            RegDeleteValueA( hkey, ( LPCSTR ) value.latin1() ) );
        RegCloseKey( hkey );
    }
    return ( ret == ERROR_SUCCESS );
}

/* what to do here? */
bool QSettingsPrivate::sysSync( void )
{
    return true;
}

/* from qsettings_mac.cpp 3.3.2 */
void QSettingsPrivate::sysInsertSearchPath( QSettings::System s, const QString &path \
) {
    if ( s != QSettings::Windows )
        return ;
    if ( !path.isEmpty() && !qt_verify_key( path ) ) {
#if defined(QT_CHECK_STATE)
        qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? \
"(null)" : path.latin1() ); #endif

        return ;
    }

    QString realpath = path;
    while ( ( realpath.right( 1 ) == "/" ) || ( realpath.right( 1 ) == "\\" ) )
        realpath.truncate( realpath.length() - 1 );
    sysd->searchPaths.append( realpath );
}

/* from qsettings_mac.cpp 3.3.2 */
void QSettingsPrivate::sysRemoveSearchPath( QSettings::System s, const QString &path \
) {
    if ( s != QSettings::Windows )
        return ;
    QString realpath = path;
    while ( realpath.right( 1 ) == "/" )
        realpath.truncate( realpath.length() - 1 );
    sysd->searchPaths.remove( realpath );
}

#endif //QT_NO_SETTINGS



_______________________________________________
kde-cygwin mailing list
kde-cygwin@kde.org
https://mail.kde.org/mailman/listinfo/kde-cygwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic