source: trunk/src/tools/qsettings_pm.cpp@ 8

Last change on this file since 8 was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 26.9 KB
Line 
1/****************************************************************************
2** $Id: qsettings_pm.cpp 8 2005-11-16 19:36:46Z dmik $
3**
4** Implementation of QSettings class
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qsettings.h"
39#include <private/qsettings_p.h>
40#include "qregexp.h"
41
42#ifndef QT_NO_SETTINGS
43
44/* Define some Win32 stuff to use Open32 Reg* functions from REGISTRY.DLL */
45
46extern "C" {
47
48//@@TODO (dmik): no UNICODE support at the moment
49#define QT_WA( uni, ansi ) ansi
50
51typedef wchar_t WCHAR;
52typedef WCHAR TCHAR;
53
54// These definitions come from os2wdef.h from the OS/2 Toolkit
55
56#define APIENTRY _System
57
58typedef char CHAR , *PCHAR , *LPCHAR;
59typedef int INT, *PINT, *LPINT;
60typedef long LONG, *PLONG, *LPLONG;
61typedef unsigned char UCHAR , *PUCHAR, *LPUCHAR;
62typedef unsigned long ULONG , *PULONG , *LPULONG;
63typedef void VOID, *PVOID, *LPVOID;
64
65typedef UCHAR BYTE, *PBYTE, *LPBYTE;
66typedef ULONG DWORD, *PDWORD, *LPDWORD;
67
68typedef INT BOOL, *PBOOL, *LPBOOL;
69
70typedef WCHAR *LPWSTR, *PWSTR;
71typedef const WCHAR *LPCWSTR, *PCWSTR;
72
73typedef CHAR *LPSTR, *PSTR;
74typedef const CHAR *LPCSTR, *PCSTR;
75
76#define CONST const
77
78// These definitions come from os2win.h from the OS/2 Toolkit
79
80typedef DWORD ACCESS_MASK;
81typedef ACCESS_MASK REGSAM;
82
83typedef DWORD HKEY, *PHKEY;
84
85typedef struct _tagSECURITY_ATTRIBUTES {
86 DWORD nLength;
87 LPVOID lpSecurityDescriptor;
88 BOOL bInheritHandle;
89} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
90
91typedef struct _tagFILETIME {
92 DWORD dwLowDateTime;
93 DWORD dwHighDateTime;
94} FILETIME, *PFILETIME, *LPFILETIME;
95
96#define HKEY_LOCAL_MACHINE 0xFFFFFFEFL
97#define HKEY_CURRENT_USER 0xFFFFFFEEL
98#define HKEY_USERS 0xFFFFFFEDL
99#define HKEY_CLASSES_ROOT 0xFFFFFFECL
100
101//#define DELETE 0x00010000
102#define READ_CONTROL 0x00020000
103//#define WRITE_DAC 0x00040000
104//#define WRITE_OWNER 0x00080000
105//#define SYNCHRONIZE 0x00100000
106
107//#define SPECIFIC_RIGHTS_ALL 0x0000FFFF
108//#define STANDARD_RIGHTS_READ (READ_CONTROL)
109//#define STANDARD_RIGHTS_WRITE (READ_CONTROL)
110//#define STANDARD_RIGHTS_EXECUTE (READ_CONTROL)
111//#define STANDARD_RIGHTS_REQUIRED 0x000F0000
112#define STANDARD_RIGHTS_ALL 0x001F0000
113
114#define KEY_QUERY_VALUE 0x0001
115#define KEY_SET_VALUE 0x0002
116#define KEY_CREATE_SUB_KEY 0x0004
117#define KEY_ENUMERATE_SUB_KEYS 0x0008
118#define KEY_NOTIFY 0x0010
119#define KEY_CREATE_LINK 0x0020
120
121#define REG_OPTION_NON_VOLATILE 0x00000000L
122#define REG_OPTION_VOLATILE 0x00000001L
123#define REG_CREATED_NEW_KEY 0x00000001L
124#define REG_OPENED_EXISTING_KEY 0x00000002L
125
126#define KEY_READ READ_CONTROL | KEY_QUERY_VALUE |\
127 KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY
128
129#define KEY_WRITE READ_CONTROL | KEY_SET_VALUE | KEY_CREATE_SUB_KEY
130
131#define KEY_EXECUTE KEY_READ
132
133#define KEY_ALL_ACCESS STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE |\
134 KEY_SET_VALUE | KEY_CREATE_SUB_KEY |\
135 KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY |\
136 KEY_CREATE_LINK
137
138#define REG_NONE 0
139#define REG_SZ 1
140#define REG_EXPAND_SZ 2
141#define REG_BINARY 3
142#define REG_DWORD 4
143#define REG_DWORD_LITTLE_ENDIAN 4
144#define REG_DWORD_BIG_ENDIAN 5
145#define REG_LINK 6
146#define REG_MULTI_SZ 7
147#define REG_RESOURCE_LIST 8
148
149// These definitions come from winreg.h from MSVC 6.0
150LONG APIENTRY RegCloseKey( HKEY hKey );
151LONG APIENTRY RegCreateKeyExA( HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition );
152LONG APIENTRY RegCreateKeyExW( HKEY hKey,LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition );
153LONG APIENTRY RegDeleteKeyA( HKEY hKey, LPCSTR lpSubKey);
154LONG APIENTRY RegDeleteKeyW( HKEY hKey, LPCWSTR lpSubKey);
155LONG APIENTRY RegDeleteValueA( HKEY hKey, LPCSTR lpValueName );
156LONG APIENTRY RegDeleteValueW( HKEY hKey, LPCWSTR lpValueName );
157LONG APIENTRY RegEnumKeyExA( HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, PFILETIME lpftLastWriteTime );
158LONG APIENTRY RegEnumKeyExW( HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPWSTR lpClass, LPDWORD lpcbClass, PFILETIME lpftLastWriteTime);
159LONG APIENTRY RegEnumValueA( HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
160LONG APIENTRY RegEnumValueW( HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
161LONG APIENTRY RegFlushKey( HKEY hKey );
162LONG APIENTRY RegOpenKeyExA( HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult );
163LONG APIENTRY RegOpenKeyExW( HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult );
164LONG APIENTRY RegQueryInfoKeyA( HKEY hKey, LPSTR lpClass, LPDWORD lpcbClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime );
165LONG APIENTRY RegQueryInfoKeyW( HKEY hKey, LPWSTR lpClass, LPDWORD lpcbClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime );
166LONG APIENTRY RegQueryValueExA( HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
167LONG APIENTRY RegQueryValueExW( HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
168LONG APIENTRY RegSetValueExA( HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData );
169LONG APIENTRY RegSetValueExW( HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData );
170
171// These definitions come from winerror.h from MSVC 6.0
172#define ERROR_SUCCESS 0L
173#define ERROR_FILE_NOT_FOUND 2L
174#define ERROR_ACCESS_DENIED 5L
175#define ERROR_NO_MORE_ITEMS 259L
176
177} // extern "C"
178
179/* End of Win32 definitions */
180
181
182static bool settingsTryUser = TRUE;
183static bool settingsTryLocal = TRUE;
184static QString *settingsBasePath = 0;
185
186void Q_EXPORT qt_setSettingsTryUser( bool tryUser )
187{
188 settingsTryUser = tryUser;
189}
190
191void Q_EXPORT qt_setSettingsTryLocal( bool tryLocal )
192{
193 settingsTryLocal = tryLocal;
194}
195
196void Q_EXPORT qt_setSettingsBasePath( const QString &base )
197{
198 if ( settingsBasePath ) {
199 qWarning( "qt_setSettingsBasePath has to be called without any settings object being instantiated!" );
200 return;
201 }
202 settingsBasePath = new QString( base );
203}
204
205class QSettingsSysPrivate
206{
207public:
208 QSettingsSysPrivate( QSettingsPrivate *priv );
209 ~QSettingsSysPrivate();
210
211 HKEY user;
212 HKEY local;
213
214 QString folder( const QString& );
215 QString entry( const QString& );
216
217 QString validateKey( const QString &key );
218
219 bool writeKey( const QString &key, const QByteArray &value, ulong type );
220 QByteArray readKey( const QString &key, ulong &type );
221 HKEY readKeyHelper( HKEY root, const QString &folder, const QString &entry, ulong &size );
222
223 HKEY openKey( const QString &key, bool write, bool remove = FALSE );
224
225 QStringList paths;
226
227private:
228 QSettingsPrivate *d;
229
230 static uint refCount;
231};
232
233uint QSettingsSysPrivate::refCount = 0;
234
235QSettingsSysPrivate::QSettingsSysPrivate( QSettingsPrivate *priv )
236 : d( priv )
237{
238 paths.append( "" );
239 if ( !settingsBasePath ) {
240 settingsBasePath = new QString("Software");
241 }
242 refCount++;
243 local = 0;
244 user = 0 ;
245
246 LONG res = ERROR_SUCCESS;
247 if ( settingsTryLocal ) {
248 QT_WA( {
249 res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, NULL, 0, KEY_ALL_ACCESS, &local );
250 } , {
251 res = RegOpenKeyExA( HKEY_LOCAL_MACHINE, NULL, 0, KEY_ALL_ACCESS, &local );
252 } );
253
254 if ( res != ERROR_SUCCESS ) {
255 QT_WA( {
256 res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ, &local );
257 } , {
258 res = RegOpenKeyExA( HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ, &local );
259 } );
260 if ( res != ERROR_SUCCESS ) {
261 local = NULL;
262 }
263 }
264 }
265
266 if ( settingsTryUser ) {
267 QT_WA( {
268 res = RegOpenKeyExW( HKEY_CURRENT_USER, NULL, 0, KEY_ALL_ACCESS, &user );
269 } , {
270 res = RegOpenKeyExA( HKEY_CURRENT_USER, NULL, 0, KEY_ALL_ACCESS, &user );
271 } );
272
273 if ( res != ERROR_SUCCESS ) {
274 QT_WA( {
275 res = RegOpenKeyExW( HKEY_CURRENT_USER, NULL, 0, KEY_READ, &user );
276 } , {
277 res = RegOpenKeyExA( HKEY_CURRENT_USER, NULL, 0, KEY_READ, &user );
278 } );
279 if ( res != ERROR_SUCCESS ) {
280 user = NULL;
281 }
282 }
283 }
284
285#if defined(QT_CHECK_STATE)
286 if ( !local && !user )
287 qSystemWarning( "Error opening registry!", res );
288#endif
289}
290
291QSettingsSysPrivate::~QSettingsSysPrivate()
292{
293 LONG res;
294 if ( local ) {
295 res = RegCloseKey( local );
296#if defined(QT_CHECK_STATE)
297 if ( res != ERROR_SUCCESS )
298 qSystemWarning( "Error closing local machine!", res );
299#endif
300 }
301 if ( user ) {
302 res = RegCloseKey( user );
303#if defined(QT_CHECK_STATE)
304 if ( res != ERROR_SUCCESS )
305 qSystemWarning( "Error closing current user!", res );
306#endif
307 }
308
309 // Make sure that we only delete the base path if no one else is using it anymore
310 if (refCount > 0) {
311 refCount--;
312
313 if (refCount == 0) {
314 delete settingsBasePath;
315 settingsBasePath = 0;
316 }
317 }
318}
319
320QString QSettingsSysPrivate::validateKey( const QString &key )
321{
322 if ( key.isEmpty() )
323 return key;
324
325 QString newKey = key;
326 newKey = newKey.replace( QRegExp( "[/]+" ), "\\" );
327
328 if ( newKey[0] != '\\' )
329 newKey = "\\" + newKey;
330 if ( newKey[(int)newKey.length() - 1] == '\\' )
331 newKey = newKey.left( newKey.length() - 1 );
332
333 return newKey;
334}
335
336QString QSettingsSysPrivate::folder( const QString &key )
337{
338 QString k = validateKey( key );
339 Q_ASSERT(settingsBasePath);
340 return *settingsBasePath + k.left( k.findRev( "\\" ) );
341}
342
343QString QSettingsSysPrivate::entry( const QString &key )
344{
345 QString k = validateKey( key );
346 return k.right( k.length() - k.findRev( "\\" ) - 1 );
347}
348
349HKEY QSettingsSysPrivate::openKey( const QString &key, bool write, bool remove )
350{
351 QString f = folder( key );
352
353 HKEY handle = 0;
354 LONG res = ERROR_FILE_NOT_FOUND;
355
356 // if we write and there is a user specific setting, overwrite that
357 if ( (write||remove) && user ) {
358 QT_WA( {
359 if ( remove )
360 res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle );
361 else
362 res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_WRITE, &handle );
363 } , {
364 if ( remove )
365 res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle );
366 else
367 res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_WRITE, &handle );
368 } );
369 }
370
371 if ( res != ERROR_SUCCESS && local && d->globalScope ) {
372 QT_WA( {
373 if ( write && !remove )
374 res = RegCreateKeyExW( local, (TCHAR*)f.ucs2(), 0, empty_t, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL );
375 else if ( !write && !remove )
376 res = RegOpenKeyExW( local, (TCHAR*)f.ucs2(), 0, KEY_READ, &handle );
377 else
378 res = RegOpenKeyExW( local, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle );
379 } , {
380 if ( write && !remove )
381 res = RegCreateKeyExA( local, f.local8Bit(), 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL );
382 else if ( !write && !remove )
383 res = RegOpenKeyExA( local, f.local8Bit(), 0, KEY_READ, &handle );
384 else
385 res = RegOpenKeyExA( local, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle );
386 } );
387 }
388 if ( !handle && user ) {
389 QT_WA( {
390 if ( write && !remove )
391 res = RegCreateKeyExW( user, (TCHAR*)f.ucs2(), 0, empty_t, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL );
392 else if ( !write && !remove )
393 res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_READ, &handle );
394 else
395 res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle );
396 } , {
397 if ( write && !remove )
398 res = RegCreateKeyExA( user, f.local8Bit(), 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL );
399 else if ( !write && !remove )
400 res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_READ, &handle );
401 else
402 res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle );
403 } );
404 }
405 return handle;
406}
407
408bool QSettingsSysPrivate::writeKey( const QString &key, const QByteArray &value, ulong type )
409{
410 QString e;
411 LONG res = ERROR_ACCESS_DENIED;
412
413 HKEY handle = 0;
414 for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) {
415 QString k = *it + "/" + key;
416 e = entry( k );
417 handle = openKey( k, TRUE );
418 if ( handle )
419 break;
420 }
421 if ( !handle )
422 return FALSE;
423
424 if (e == "Default" || e == "." )
425 e = "";
426
427 if ( value.size() ) {
428 QT_WA( {
429 res = RegSetValueExW( handle, e.isEmpty() ? 0 : (TCHAR*)e.ucs2(), 0, type, (const uchar*)value.data(), value.size() );
430 } , {
431 res = RegSetValueExA( handle, e.isEmpty() ? (const char*)0 : (const char*)e.local8Bit(), 0, type, (const uchar*)value.data(), value.size() );
432 } );
433
434 if ( res != ERROR_SUCCESS ) {
435#if defined(QT_CHECK_STATE)
436 qSystemWarning( "Couldn't write value " + key, res );
437#endif
438 return FALSE;
439 }
440 }
441
442 RegCloseKey( handle );
443 return TRUE;
444}
445
446HKEY QSettingsSysPrivate::readKeyHelper( HKEY root, const QString &folder, const QString &entry, ulong &size )
447{
448 HKEY handle;
449 LONG res = ERROR_ACCESS_DENIED;
450 QT_WA( {
451 res = RegOpenKeyExW( root, (TCHAR*)folder.ucs2(), 0, KEY_READ, &handle );
452 } , {
453 res = RegOpenKeyExA( root, folder.local8Bit(), 0, KEY_READ, &handle );
454 } );
455
456 if ( res == ERROR_SUCCESS ) {
457 QT_WA( {
458 res = RegQueryValueExW( handle, entry.isEmpty() ? 0 : (TCHAR*)entry.ucs2(), NULL, NULL, NULL, &size );
459 } , {
460 res = RegQueryValueExA( handle, entry.isEmpty() ? (const char*)0 : (const char*)entry.local8Bit(), NULL, NULL, NULL, &size );
461 } );
462 }
463 if ( res != ERROR_SUCCESS ) {
464 RegCloseKey( handle );
465 size = 0;
466 handle = 0;
467 }
468
469 return handle;
470}
471
472QByteArray QSettingsSysPrivate::readKey( const QString &key, ulong &type )
473{
474 HKEY handle = 0;
475 ulong size = 0;
476 QString e;
477 type = REG_NONE;
478
479 if ( user ) {
480 for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) {
481 if ( handle ) {
482 RegCloseKey( handle );
483 handle = 0;
484 }
485 QString k = *it + "/" + key;
486 QString f = folder( k );
487 e = entry( k );
488 if ( e == "Default" || e == "." )
489 e = "";
490
491 handle = readKeyHelper( user, f, e, size );
492
493 if ( !handle )
494 size = 0;
495 else if ( size )
496 break;
497 }
498 }
499
500 if ( !size && local ) {
501 for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) {
502 if ( handle ) {
503 RegCloseKey( handle );
504 handle = 0;
505 }
506
507 QString k = *it + "/" + key;
508 QString f = folder( k );
509 e = entry( k );
510 if ( e == "Default" || e == "." )
511 e = "";
512
513 handle = readKeyHelper( local, f, e, size );
514
515 if ( !handle )
516 size = 0;
517 else if ( size )
518 break;
519 }
520 }
521
522 if ( !size ) {
523 if ( handle )
524 RegCloseKey( handle );
525 return QByteArray();
526 }
527
528 uchar* data = new uchar[ size ];
529 QT_WA( {
530 RegQueryValueExW( handle, e.isEmpty() ? 0 : (TCHAR*)e.ucs2(), NULL, &type, data, &size );
531 } , {
532 RegQueryValueExA( handle, e.isEmpty() ? (const char*)0 : (const char*)e.local8Bit(), NULL, &type, data, &size );
533 } );
534
535 QByteArray result;
536 result.setRawData( (const char*)data, size );
537 RegCloseKey( handle );
538
539 return result;
540}
541
542void QSettingsPrivate::sysInit()
543{
544 sysd = new QSettingsSysPrivate( this );
545}
546
547void QSettingsPrivate::sysClear()
548{
549 delete sysd;
550}
551
552bool QSettingsPrivate::sysSync()
553{
554 if ( sysd->local )
555 RegFlushKey( sysd->local );
556 if ( sysd->user )
557 RegFlushKey( sysd->user );
558 return TRUE;
559}
560
561bool QSettingsPrivate::sysReadBoolEntry(const QString &key, bool def, bool *ok ) const
562{
563 return sysReadNumEntry( key, def, ok );
564}
565
566double QSettingsPrivate::sysReadDoubleEntry( const QString &key, double def, bool *ok ) const
567{
568 Q_ASSERT(sysd);
569
570 if ( ok )
571 *ok = FALSE;
572 ulong type;
573 QByteArray array = sysd->readKey( key, type );
574 if ( type != REG_BINARY ) {
575 char *data = array.data();
576 array.resetRawData( data, array.size() );
577 delete[] data;
578 return def;
579 }
580 if ( array.size() != sizeof(double) )
581 return def;
582
583 if ( ok )
584 *ok = TRUE;
585
586 double res = 0;
587 char* data = (char*)&res;
588 for ( unsigned int i = 0; i < sizeof(double); ++i )
589 data[i] = array[ i ];
590
591 char *adata = array.data();
592 array.resetRawData( adata, array.size() );
593 delete[] adata;
594 return res;
595}
596
597int QSettingsPrivate::sysReadNumEntry(const QString &key, int def, bool *ok ) const
598{
599 Q_ASSERT(sysd);
600
601 if ( ok )
602 *ok = FALSE;
603 ulong type;
604 QByteArray array = sysd->readKey( key, type );
605 if ( type != REG_DWORD ) {
606 char *data = array.data();
607 array.resetRawData( data, array.size() );
608 delete[] data;
609
610 return def;
611 }
612
613 if ( array.size() != sizeof(int) )
614 return def;
615
616 if ( ok )
617 *ok = TRUE;
618
619 int res = 0;
620 char* data = (char*)&res;
621 for ( unsigned int i = 0; i < sizeof(int); ++i )
622 data[i] = array[ i ];
623
624 char *adata = array.data();
625 array.resetRawData( adata, array.size() );
626 delete[] adata;
627 return res;
628}
629
630QString QSettingsPrivate::sysReadEntry(const QString &key, const QString &def, bool *ok ) const
631{
632 if ( ok ) // no, everything is not ok
633 *ok = FALSE;
634
635 ulong type;
636 QByteArray array = sysd->readKey( key, type );
637 if ( type != REG_SZ ) {
638 char *data = array.data();
639 array.resetRawData( data, array.size() );
640 delete[] data;
641 return def;
642 }
643
644 if ( ok )
645 *ok = TRUE;
646 QString result = QString::null;
647
648 QT_WA( {
649 int s = array.size();
650 for ( int i = 0; i < s; i+=2 ) {
651 QChar c( array[ i ], array[ i+1 ] );
652 if( !c.isNull() )
653 result+=c;
654 }
655 } , {
656 result = QString::fromLocal8Bit( array );
657 } );
658
659 if ( array.size() == 2 && result.isNull() )
660 result = "";
661
662 char *data = array.data();
663 array.resetRawData( data, array.size() );
664 delete[] data;
665
666 return result;
667}
668
669bool QSettingsPrivate::sysWriteEntry( const QString &key, bool value )
670{
671 return sysWriteEntry( key, (int)value );
672}
673
674bool QSettingsPrivate::sysWriteEntry( const QString &key, double value )
675{
676 Q_ASSERT(sysd);
677
678 QByteArray array( sizeof(double) );
679 const char *data = (char*)&value;
680
681 for ( unsigned int i = 0; i < sizeof(double); ++i )
682 array[i] = data[i];
683
684 return sysd->writeKey( key, array, REG_BINARY );
685}
686
687bool QSettingsPrivate::sysWriteEntry( const QString &key, int value )
688{
689 Q_ASSERT(sysd);
690
691 QByteArray array( sizeof(int) );
692 const char* data = (char*)&value;
693 for ( unsigned int i = 0; i < sizeof(int ); ++i )
694 array[i] = data[i];
695
696 return sysd->writeKey( key, array, REG_DWORD );
697}
698
699bool QSettingsPrivate::sysWriteEntry( const QString &key, const QString &value )
700{
701 Q_ASSERT(sysd);
702
703 QByteArray array( 0 );
704 QT_WA( {
705 array.resize( value.length() * 2 + 2 );
706 const QChar *data = value.unicode();
707 int i;
708 for ( i = 0; i < (int)value.length(); ++i ) {
709 array[ 2*i ] = data[ i ].cell();
710 array[ (2*i)+1 ] = data[ i ].row();
711 }
712
713 array[ (2*i) ] = 0;
714 array[ (2*i)+1 ] = 0;
715 } , {
716 array.resize( value.length() );
717 array = value.local8Bit();
718 } );
719
720 return sysd->writeKey( key, array, REG_SZ );
721}
722
723bool QSettingsPrivate::sysRemoveEntry( const QString &key )
724{
725 Q_ASSERT(sysd);
726
727 QString e;
728 LONG res;
729
730 HKEY handle = 0;
731 for ( QStringList::Iterator it = sysd->paths.fromLast(); it != sysd->paths.end(); --it ) {
732 QString k = (*it).isEmpty() ? key : *it + "/" + key;
733 handle = sysd->openKey( k, FALSE, TRUE );
734 e = sysd->entry( k );
735 if ( handle )
736 break;
737 }
738 if ( !handle )
739 return TRUE;
740 if ( e == "Default" || e == "." )
741 e = "";
742 QT_WA( {
743 res = RegDeleteValueW( handle, (TCHAR*)e.ucs2() );
744 } , {
745 res = RegDeleteValueA( handle, e.local8Bit() );
746 } );
747
748 if ( res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND ) {
749#if defined(QT_CHECK_STATE)
750 qSystemWarning( "Error deleting value " + key, res );
751#endif
752 return FALSE;
753 }
754 char vname[2];
755 DWORD vnamesz = 1;
756 FILETIME lastWrite;
757#ifdef Q_OS_TEMP
758 LONG res2 = RegEnumValue( handle, 0, (LPWSTR)vname, &vnamesz, NULL, NULL, NULL, NULL );
759 LONG res3 = RegEnumKeyEx( handle, 0, (LPWSTR)vname, &vnamesz, NULL, NULL, NULL, &lastWrite );
760#else
761 LONG res2 = RegEnumValueA( handle, 0, vname, &vnamesz, NULL, NULL, NULL, NULL );
762 LONG res3 = RegEnumKeyExA( handle, 0, vname, &vnamesz, NULL, NULL, NULL, &lastWrite );
763#endif
764 if ( res2 == ERROR_NO_MORE_ITEMS && res3 == ERROR_NO_MORE_ITEMS )
765#ifdef Q_OS_TEMP
766 RegDeleteKeyW( handle, L"" );
767#else
768 RegDeleteKeyA( handle, "" );
769#endif
770 else
771 RegCloseKey( handle );
772 return TRUE;
773}
774
775QStringList QSettingsPrivate::sysEntryList( const QString &key ) const
776{
777 Q_ASSERT(sysd);
778
779 QStringList result;
780
781 HKEY handle = 0;
782 for ( QStringList::Iterator it = sysd->paths.fromLast(); it != sysd->paths.end(); --it ) {
783 QString k = (*it).isEmpty() ? key + "/fake" : *it + "/" + key + "/fake";
784 handle = sysd->openKey( k, FALSE );
785 if ( handle )
786 break;
787 }
788 if ( !handle )
789 return result;
790
791 DWORD count;
792 DWORD maxlen;
793
794 QT_WA( {
795 RegQueryInfoKeyW( handle, NULL, NULL, NULL, NULL, NULL, NULL, &count, &maxlen, NULL, NULL, NULL );
796 } , {
797 RegQueryInfoKeyA( handle, NULL, NULL, NULL, NULL, NULL, NULL, &count, &maxlen, NULL, NULL, NULL );
798 } );
799 maxlen++;
800 DWORD index = 0;
801
802 TCHAR *vnameT = new TCHAR[ maxlen ];
803 char *vnameA = new char[ maxlen ];
804 QString qname;
805
806 DWORD vnamesz = 0;
807 LONG res = ERROR_SUCCESS;
808
809 while ( res != ERROR_NO_MORE_ITEMS ) {
810 vnamesz = maxlen;
811 QT_WA( {
812 res = RegEnumValueW( handle, index, vnameT, &vnamesz, NULL, NULL, NULL, NULL );
813 if ( res == ERROR_SUCCESS )
814 qname = QString::fromUcs2( (ushort*)vnameT );
815 } , {
816 res = RegEnumValueA( handle, index, vnameA, &vnamesz, NULL, NULL, NULL, NULL );
817 if ( res == ERROR_SUCCESS )
818 qname = vnameA;
819 } );
820 if ( res == ERROR_NO_MORE_ITEMS )
821 break;
822 if ( qname.isEmpty() )
823 result.append( "Default" );
824 else
825 result.append( qname );
826 ++index;
827 }
828
829 delete [] vnameA;
830 delete [] vnameT;
831
832 RegCloseKey( handle );
833 return result;
834}
835
836QStringList QSettingsPrivate::sysSubkeyList( const QString &key ) const
837{
838 Q_ASSERT(sysd);
839
840 QStringList result;
841
842 HKEY handle = 0;
843 for ( QStringList::Iterator it = sysd->paths.fromLast(); it != sysd->paths.end(); --it ) {
844 QString k = (*it).isEmpty() ? key + "/fake" : *it + "/" + key + "/fake";
845 handle = sysd->openKey( k, FALSE );
846 if ( handle )
847 break;
848 }
849 if ( !handle )
850 return result;
851
852 DWORD count;
853 DWORD maxlen;
854 QT_WA( {
855 RegQueryInfoKeyW( handle, NULL, NULL, NULL, &count, &maxlen, NULL, NULL, NULL, NULL, NULL, NULL );
856 maxlen++;
857 } , {
858 RegQueryInfoKeyA( handle, NULL, NULL, NULL, &count, &maxlen, NULL, NULL, NULL, NULL, NULL, NULL );
859 } );
860
861 DWORD index = 0;
862 FILETIME lastWrite;
863
864 TCHAR *vnameT = new TCHAR[ maxlen ];
865 char *vnameA = new char[ maxlen ];
866 QString qname;
867
868 DWORD vnamesz = 0;
869 LONG res = ERROR_SUCCESS;
870
871 while ( res != ERROR_NO_MORE_ITEMS ) {
872 vnamesz = maxlen;
873 QT_WA( {
874 res = RegEnumKeyExW( handle, index, vnameT, &vnamesz, NULL, NULL, NULL, &lastWrite );
875 if ( res == ERROR_SUCCESS )
876 qname = QString::fromUcs2( (ushort*)vnameT );
877 } , {
878 res = RegEnumKeyExA( handle, index, vnameA, &vnamesz, NULL, NULL, NULL, &lastWrite );
879 if ( res == ERROR_SUCCESS )
880 qname = vnameA;
881 } );
882
883 if ( res == ERROR_NO_MORE_ITEMS )
884 break;
885 result.append( qname );
886 ++index;
887 }
888
889 delete [] vnameA;
890 delete [] vnameT;
891
892 RegCloseKey( handle );
893 return result;
894}
895
896void QSettingsPrivate::sysInsertSearchPath( QSettings::System s, const QString &path )
897{
898 Q_ASSERT(sysd);
899
900 if ( s != QSettings::Windows || path.isEmpty() )
901 return;
902 QString p = path;
903 if ( p[0] != '/' )
904 p = "/" + p;
905 sysd->paths.append( p );
906}
907
908void QSettingsPrivate::sysRemoveSearchPath( QSettings::System s, const QString &path )
909{
910 Q_ASSERT(sysd);
911
912 if ( s != QSettings::Windows || path.isEmpty() )
913 return;
914 QString p = path;
915 if ( p[0] != '/' )
916 p = "/" + p;
917 sysd->paths.remove( p );
918}
919
920#endif //QT_NO_SETTINGS
Note: See TracBrowser for help on using the repository browser.