///////////////////////////////////////////////////////////////////////////////
-// Name: msw/registry.cpp
+// Name: src/msw/registry.cpp
// Purpose: implementation of registry classes and functions
// Author: Vadim Zeitlin
// Modified by:
// - add high level functions (RegisterOleServer, ...)
///////////////////////////////////////////////////////////////////////////////
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-#pragma implementation "registry.h"
-#endif
-
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
-// other wxWidgets headers
-#include "wx/string.h"
-#include "wx/intl.h"
-#include "wx/log.h"
-#include "wx/file.h"
-#include "wx/wfstream.h"
+#ifndef WX_PRECOMP
+ #include "wx/msw/wrapwin.h"
+ #include "wx/string.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+#endif
-// Windows headers
-#include "wx/msw/wrapwin.h"
+#include "wx/file.h"
+#include "wx/wfstream.h"
+// Windows headers
#ifdef __WXWINCE__
#include "wx/msw/private.h"
#include <winbase.h>
typedef unsigned char *RegString;
typedef BYTE* RegBinary;
+#ifndef HKEY_PERFORMANCE_DATA
+ #define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
+#endif
+
+#ifndef HKEY_CURRENT_CONFIG
+ #define HKEY_CURRENT_CONFIG ((HKEY)0x80000005)
+#endif
+
+#ifndef HKEY_DYN_DATA
+ #define HKEY_DYN_DATA ((HKEY)0x80000006)
+#endif
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
{ HKEY_CURRENT_USER, wxT("HKEY_CURRENT_USER"), wxT("HKCU") },
{ HKEY_LOCAL_MACHINE, wxT("HKEY_LOCAL_MACHINE"), wxT("HKLM") },
{ HKEY_USERS, wxT("HKEY_USERS"), wxT("HKU") }, // short name?
-#ifndef __WXWINCE__
{ HKEY_PERFORMANCE_DATA, wxT("HKEY_PERFORMANCE_DATA"), wxT("HKPD") },
-#endif
-#if WINVER >= 0x0400 && !defined(__WXWINCE__)
{ HKEY_CURRENT_CONFIG, wxT("HKEY_CURRENT_CONFIG"), wxT("HKCC") },
-#if !defined(__GNUWIN32__) && !defined(__WXWINCE__)
{ HKEY_DYN_DATA, wxT("HKEY_DYN_DATA"), wxT("HKDD") }, // short name?
-#endif //GNUWIN32
-#endif //WINVER >= 4.0
};
// the registry name separator (perhaps one day MS will change it to '/' ;-)
{
wxString strRoot = strKey.BeforeFirst(REG_SEPARATOR);
- HKEY hRootKey = 0;
size_t ui;
for ( ui = 0; ui < nStdKeys; ui++ ) {
if ( strRoot.CmpNoCase(aStdKeys[ui].szName) == 0 ||
strRoot.CmpNoCase(aStdKeys[ui].szShortName) == 0 ) {
- hRootKey = aStdKeys[ui].hkey;
break;
}
}
if ( ui == nStdKeys ) {
wxFAIL_MSG(wxT("invalid key prefix in wxRegKey::ExtractKeyName."));
- hRootKey = HKEY_CLASSES_ROOT;
+ ui = HKCR;
}
else {
strKey = strKey.After(REG_SEPARATOR);
- if ( !strKey.IsEmpty() && strKey.Last() == REG_SEPARATOR )
+ if ( !strKey.empty() && strKey.Last() == REG_SEPARATOR )
strKey.Truncate(strKey.Len() - 1);
}
- return (wxRegKey::StdKey)(int)hRootKey;
+ return (StdKey)ui;
}
wxRegKey::StdKey wxRegKey::GetStdKeyFromHkey(WXHKEY hkey)
{
for ( size_t ui = 0; ui < nStdKeys; ui++ ) {
- if ( (int) aStdKeys[ui].hkey == (int) hkey )
+ if ( aStdKeys[ui].hkey == (HKEY)hkey )
return (StdKey)ui;
}
: m_strKey(keyParent.m_strKey)
{
// combine our name with parent's to get the full name
- if ( !m_strKey.IsEmpty() &&
- (strKey.IsEmpty() || strKey[0] != REG_SEPARATOR) ) {
+ if ( !m_strKey.empty() &&
+ (strKey.empty() || strKey[0] != REG_SEPARATOR) ) {
m_strKey += REG_SEPARATOR;
}
// next line!
m_strKey.clear();
m_strKey += keyParent.m_strKey;
- if ( !strKey.IsEmpty() && strKey[0] != REG_SEPARATOR )
+ if ( !strKey.empty() && strKey[0] != REG_SEPARATOR )
m_strKey += REG_SEPARATOR;
m_strKey += strKey;
StdKey key = GetStdKeyFromHkey((WXHKEY) m_hRootKey);
wxString str = bShortPrefix ? aStdKeys[key].szShortName
: aStdKeys[key].szName;
- if ( !m_strKey.IsEmpty() )
+ if ( !m_strKey.empty() )
str << _T("\\") << m_strKey;
return str;
bool wxRegKey::Open(AccessMode mode)
{
if ( IsOpened() )
- return true;
+ {
+ if ( mode <= m_mode )
+ return true;
+
+ // we had been opened in read mode but now must be reopened in write
+ Close();
+ }
HKEY tmpKey;
m_dwLastError = ::RegOpenKeyEx
}
m_hKey = (WXHKEY) tmpKey;
+ m_mode = mode;
+
return true;
}
bool wxRegKey::Rename(const wxChar *szNewName)
{
- wxCHECK_MSG( !m_strKey.IsEmpty(), false, _T("registry hives can't be renamed") );
+ wxCHECK_MSG( !m_strKey.empty(), false, _T("registry hives can't be renamed") );
if ( !Exists() ) {
wxLogError(_("Registry key '%s' does not exist, cannot rename it."),
if ( inSameHive ) {
// rename the key to the new name under the same parent
wxString strKey = m_strKey.BeforeLast(REG_SEPARATOR);
- if ( !strKey.IsEmpty() ) {
+ if ( !strKey.empty() ) {
// don't add '\\' in the start if strFullNewName is empty
strKey += REG_SEPARATOR;
}
// prevent a buggy program from erasing one of the root registry keys or an
// immediate subkey (i.e. one which doesn't have '\\' inside) of any other
// key except HKCR (HKCR has some "deleteable" subkeys)
- if ( m_strKey.IsEmpty() ||
+ if ( m_strKey.empty() ||
((m_hRootKey != (WXHKEY) aStdKeys[HKCR].hkey) &&
(m_strKey.Find(REG_SEPARATOR) == wxNOT_FOUND)) ) {
wxLogError(_("Registry key '%s' is needed for normal system operation,\ndeleting it will leave your system in unusable state:\noperation aborted."),
bool wxRegKey::DeleteValue(const wxChar *szValue)
{
- if ( !Open() )
- return false;
+ if ( !Open() )
+ return false;
m_dwLastError = RegDeleteValue((HKEY) m_hKey, WXSTRINGCAST szValue);
// deleting a value which doesn't exist is not considered an error
if ( (m_dwLastError != ERROR_SUCCESS) &&
- (m_dwLastError != ERROR_FILE_NOT_FOUND) ) {
- wxLogSysError(m_dwLastError, _("Can't delete value '%s' from key '%s'"),
- szValue, GetName().c_str());
- return false;
+ (m_dwLastError != ERROR_FILE_NOT_FOUND) )
+ {
+ wxLogSysError(m_dwLastError, _("Can't delete value '%s' from key '%s'"),
+ szValue, GetName().c_str());
+ return false;
}
- return true;
+ return true;
}
// ----------------------------------------------------------------------------
// return true if value exists
bool wxRegKey::HasValue(const wxChar *szValue) const
{
- // this function should be silent, so suppress possible messages from Open()
- wxLogNull nolog;
+ // this function should be silent, so suppress possible messages from Open()
+ wxLogNull nolog;
if ( !CONST_CAST Open(Read) )
return false;
bool wxRegKey::QueryValue(const wxChar *szValue, wxMemoryBuffer& buffer) const
{
- if ( CONST_CAST Open() ) {
+ if ( CONST_CAST Open(Read) ) {
// first get the type and size of the data
DWORD dwType, dwSize;
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
bool wxRegKey::QueryValue(const wxChar *szValue,
wxString& strValue,
- bool raw) const
+ bool WXUNUSED_IN_WINCE(raw)) const
{
- if ( CONST_CAST Open(Read) ) {
-
- // first get the type and size of the data
- DWORD dwType, dwSize;
- m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
- &dwType, NULL, &dwSize);
- if ( m_dwLastError == ERROR_SUCCESS ) {
- if ( !dwSize ) {
- // must treat this case specially as GetWriteBuf() doesn't like
- // being called with 0 size
- strValue.Empty();
- }
- else {
- m_dwLastError = RegQueryValueEx((HKEY) m_hKey,
- WXSTRINGCAST szValue,
- RESERVED,
- &dwType,
- (RegString)(wxChar*)wxStringBuffer(strValue, dwSize),
- &dwSize);
+ if ( CONST_CAST Open(Read) )
+ {
- // expand the var expansions in the string unless disabled
-#ifndef __WXWINCE__
- if ( (dwType == REG_EXPAND_SZ) && !raw )
+ // first get the type and size of the data
+ DWORD dwType=REG_NONE, dwSize=0;
+ m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
+ &dwType, NULL, &dwSize);
+ if ( m_dwLastError == ERROR_SUCCESS )
+ {
+ if ( !dwSize )
+ {
+ // must treat this case specially as GetWriteBuf() doesn't like
+ // being called with 0 size
+ strValue.Empty();
+ }
+ else
{
- DWORD dwExpSize = ::ExpandEnvironmentStrings(strValue, NULL, 0);
- bool ok = dwExpSize != 0;
- if ( ok )
+ m_dwLastError = RegQueryValueEx((HKEY) m_hKey,
+ WXSTRINGCAST szValue,
+ RESERVED,
+ &dwType,
+ (RegString)(wxChar*)wxStringBuffer(strValue, dwSize),
+ &dwSize);
+
+ // expand the var expansions in the string unless disabled
+#ifndef __WXWINCE__
+ if ( (dwType == REG_EXPAND_SZ) && !raw )
{
- wxString strExpValue;
- ok = ::ExpandEnvironmentStrings
- (
- strValue,
- wxStringBuffer(strExpValue, dwExpSize),
- dwExpSize
- ) != 0;
- strValue = strExpValue;
- }
+ DWORD dwExpSize = ::ExpandEnvironmentStrings(strValue, NULL, 0);
+ bool ok = dwExpSize != 0;
+ if ( ok )
+ {
+ wxString strExpValue;
+ ok = ::ExpandEnvironmentStrings(strValue,
+ wxStringBuffer(strExpValue, dwExpSize),
+ dwExpSize
+ ) != 0;
+ strValue = strExpValue;
+ }
- if ( !ok )
- {
- wxLogLastError(_T("ExpandEnvironmentStrings"));
+ if ( !ok )
+ {
+ wxLogLastError(_T("ExpandEnvironmentStrings"));
+ }
}
- }
-#else
- wxUnusedVar(raw);
#endif
- // __WXWINCE__
- }
+ // __WXWINCE__
+ }
- if ( m_dwLastError == ERROR_SUCCESS ) {
- // check that it was the right type
- wxASSERT_MSG( !IsNumericValue(szValue),
- wxT("Type mismatch in wxRegKey::QueryValue().") );
+ if ( m_dwLastError == ERROR_SUCCESS )
+ {
+ // check that it was the right type
+ wxASSERT_MSG( !IsNumericValue(szValue),
+ wxT("Type mismatch in wxRegKey::QueryValue().") );
- return true;
+ return true;
+ }
}
- }
- }
+ }
- wxLogSysError(m_dwLastError, _("Can't read value of '%s'"),
- GetFullName(this, szValue));
- return false;
+ wxLogSysError(m_dwLastError, _("Can't read value of '%s'"),
+ GetFullName(this, szValue));
+ return false;
}
bool wxRegKey::SetValue(const wxChar *szValue, const wxString& strValue)
{
if ( CONST_CAST Open() ) {
m_dwLastError = RegSetValueEx((HKEY) m_hKey, szValue, (DWORD) RESERVED, REG_SZ,
- (RegString)strValue.c_str(),
+ (RegString)strValue.wx_str(),
(strValue.Len() + 1)*sizeof(wxChar));
if ( m_dwLastError == ERROR_SUCCESS )
return true;
// exporting registry keys to file
// ----------------------------------------------------------------------------
+#if wxUSE_STREAMS
+
// helper functions for writing ASCII strings (even in Unicode build)
static inline bool WriteAsciiChar(wxOutputStream& ostr, char ch)
{
return ostr.IsOk();
}
+#endif // wxUSE_STREAMS
+
bool wxRegKey::Export(const wxString& filename) const
{
+#if wxUSE_FFILE && wxUSE_STREAMS
if ( wxFile::Exists(filename) )
{
wxLogError(_("Exporting registry key: file \"%s\" already exists and won't be overwritten."),
wxFFileOutputStream ostr(filename, _T("w"));
return ostr.Ok() && Export(ostr);
+#else
+ wxUnusedVar(filename);
+ return false;
+#endif
}
+#if wxUSE_STREAMS
bool wxRegKey::Export(wxOutputStream& ostr) const
{
// write out the header
return DoExport(ostr);
}
+#endif // wxUSE_STREAMS
static
wxString
if ( !QueryValue(name, &value) )
break;
- rhs.Printf(_T("dword:%08x"), value);
+ rhs.Printf(_T("dword:%08x"), (unsigned int)value);
}
break;
return rhs;
}
+#if wxUSE_STREAMS
+
bool wxRegKey::DoExportValue(wxOutputStream& ostr, const wxString& name) const
{
// first examine the value type: if it's unsupported, simply skip it
return true;
}
+#endif // wxUSE_STREAMS
+
// ============================================================================
// implementation of global private functions
// ============================================================================
return s_str.c_str();
}
-void RemoveTrailingSeparator(wxString& str)
+inline void RemoveTrailingSeparator(wxString& str)
{
- if ( !str.IsEmpty() && str.Last() == REG_SEPARATOR )
+ if ( !str.empty() && str.Last() == REG_SEPARATOR )
str.Truncate(str.Len() - 1);
}
-