X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/04a18b0d958a3c7507089dc374e71bdad143981d..d2b23b67301bd2d286366d4326a21da3132558fa:/src/msw/registry.cpp diff --git a/src/msw/registry.cpp b/src/msw/registry.cpp index 70dd768c12..224927aa1b 100644 --- a/src/msw/registry.cpp +++ b/src/msw/registry.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: msw/registry.cpp +// Name: src/msw/registry.cpp // Purpose: implementation of registry classes and functions // Author: Vadim Zeitlin // Modified by: @@ -12,27 +12,24 @@ // - 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 @@ -54,6 +51,18 @@ 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 // ---------------------------------------------------------------------------- @@ -72,15 +81,9 @@ aStdKeys[] = { 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 '/' ;-) @@ -146,12 +149,10 @@ wxRegKey::StdKey wxRegKey::ExtractKeyName(wxString& strKey) { 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; } } @@ -159,21 +160,21 @@ wxRegKey::StdKey wxRegKey::ExtractKeyName(wxString& strKey) 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; } @@ -214,8 +215,8 @@ wxRegKey::wxRegKey(const wxRegKey& keyParent, const wxString& strKey) : 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; } @@ -270,7 +271,7 @@ void wxRegKey::SetName(const wxRegKey& keyParent, const wxString& strKey) // 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; @@ -304,7 +305,7 @@ wxString wxRegKey::GetName(bool bShortPrefix) const 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; @@ -364,7 +365,13 @@ bool wxRegKey::GetKeyInfo(size_t *pnSubKeys, 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 @@ -384,6 +391,8 @@ bool wxRegKey::Open(AccessMode mode) } m_hKey = (WXHKEY) tmpKey; + m_mode = mode; + return true; } @@ -515,7 +524,7 @@ bool wxRegKey::CopyValue(const wxChar *szValue, 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."), @@ -533,7 +542,7 @@ bool wxRegKey::Rename(const wxChar *szNewName) 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; } @@ -647,7 +656,7 @@ bool wxRegKey::DeleteSelf() // 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."), @@ -702,20 +711,21 @@ bool wxRegKey::DeleteKey(const wxChar *szKey) 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; } // ---------------------------------------------------------------------------- @@ -725,8 +735,8 @@ bool wxRegKey::DeleteValue(const wxChar *szValue) // 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; @@ -850,7 +860,7 @@ bool wxRegKey::SetValue(const wxChar *szValue,const wxMemoryBuffer& buffer) 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, @@ -886,77 +896,78 @@ bool wxRegKey::QueryValue(const wxChar *szValue, wxMemoryBuffer& buffer) const 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; @@ -1088,6 +1099,8 @@ bool wxRegKey::IsNumericValue(const wxChar *szValue) const // 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) { @@ -1112,14 +1125,17 @@ static inline bool WriteAsciiString(wxOutputStream& ostr, const wxString& s) wxCharBuffer name(s.mb_str()); ostr.Write(name, strlen(name)); #else - ostr.Write(s, s.length()); + ostr.Write(s.mb_str(), s.length()); #endif 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."), @@ -1130,8 +1146,13 @@ bool wxRegKey::Export(const wxString& filename) const 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 @@ -1140,6 +1161,7 @@ bool wxRegKey::Export(wxOutputStream& ostr) const return DoExport(ostr); } +#endif // wxUSE_STREAMS static wxString @@ -1270,6 +1292,8 @@ wxString wxRegKey::FormatValue(const wxString& name) const 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 @@ -1349,6 +1373,8 @@ bool wxRegKey::DoExport(wxOutputStream& ostr) const return true; } +#endif // wxUSE_STREAMS + // ============================================================================ // implementation of global private functions // ============================================================================ @@ -1387,9 +1413,8 @@ const wxChar *GetFullName(const wxRegKey *pKey, const wxChar *szValue) 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); } -