///////////////////////////////////////////////////////////////////////////////
-// 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
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
#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 __WXWINCE__
{ HKEY_PERFORMANCE_DATA, wxT("HKEY_PERFORMANCE_DATA"), wxT("HKPD") },
#endif
-#if WINVER >= 0x0400 && !defined(__WXWINCE__)
+#ifdef HKEY_CURRENT_CONFIG
{ HKEY_CURRENT_CONFIG, wxT("HKEY_CURRENT_CONFIG"), wxT("HKCC") },
-#if !defined(__GNUWIN32__) && !defined(__WXWINCE__)
+#endif
+#ifdef HKEY_DYN_DATA
{ HKEY_DYN_DATA, wxT("HKEY_DYN_DATA"), wxT("HKDD") }, // short name?
-#endif //GNUWIN32
-#endif //WINVER >= 4.0
+#endif
};
// the registry name separator (perhaps one day MS will change it to '/' ;-)
}
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);
}
: 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 )
{
- DWORD dwExpSize = ::ExpandEnvironmentStrings(strValue, NULL, 0);
- bool ok = dwExpSize != 0;
- if ( ok )
+ // 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);
+
+ // 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)
// 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 ( n )
value << _T(',');
- value << wxString::Format(_T("%02x"), p[n]);
+ value << wxString::Format(_T("%02x"), (unsigned char)p[n]);
}
return value;
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
// ============================================================================
void RemoveTrailingSeparator(wxString& str)
{
- if ( !str.IsEmpty() && str.Last() == REG_SEPARATOR )
+ if ( !str.empty() && str.Last() == REG_SEPARATOR )
str.Truncate(str.Len() - 1);
}
-