Allow accessing 64 bit registry from 32 bit MSW code and vice versa.
Implement support for KEY_WOW64_32KEY and KEY_WOW64_64KEY in wxRegKey code. Closes #10792. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66851 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -27,8 +27,10 @@
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/crt.h"
|
||||
#include "wx/utils.h"
|
||||
#endif
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
#include "wx/file.h"
|
||||
#include "wx/wfstream.h"
|
||||
|
||||
@@ -114,7 +116,19 @@ aStdKeys[] =
|
||||
static inline void RemoveTrailingSeparator(wxString& str);
|
||||
|
||||
// returns true if given registry key exists
|
||||
static bool KeyExists(WXHKEY hRootKey, const wxString& szKey);
|
||||
static bool KeyExists(
|
||||
WXHKEY hRootKey,
|
||||
const wxString& szKey,
|
||||
wxRegKey::WOW64ViewMode viewMode = wxRegKey::WOW64ViewMode_Default);
|
||||
|
||||
// return the WOW64 registry view flag which can be used with MSW registry
|
||||
// functions for opening the key in the specified view
|
||||
static long GetMSWViewFlags(wxRegKey::WOW64ViewMode viewMode);
|
||||
|
||||
// return the access rights which can be used with MSW registry functions for
|
||||
// opening the key in the specified mode
|
||||
static long
|
||||
GetMSWAccessFlags(wxRegKey::AccessMode mode, wxRegKey::WOW64ViewMode viewMode);
|
||||
|
||||
// combines value and key name
|
||||
static wxString GetFullName(const wxRegKey *pKey);
|
||||
@@ -195,14 +209,15 @@ wxRegKey::StdKey wxRegKey::GetStdKeyFromHkey(WXHKEY hkey)
|
||||
// ctors and dtor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxRegKey::wxRegKey()
|
||||
wxRegKey::wxRegKey(WOW64ViewMode viewMode) : m_viewMode(viewMode)
|
||||
{
|
||||
m_hRootKey = (WXHKEY) aStdKeys[HKCR].hkey;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
wxRegKey::wxRegKey(const wxString& strKey) : m_strKey(strKey)
|
||||
wxRegKey::wxRegKey(const wxString& strKey, WOW64ViewMode viewMode)
|
||||
: m_strKey(strKey), m_viewMode(viewMode)
|
||||
{
|
||||
m_hRootKey = (WXHKEY) aStdKeys[ExtractKeyName(m_strKey)].hkey;
|
||||
|
||||
@@ -210,7 +225,10 @@ wxRegKey::wxRegKey(const wxString& strKey) : m_strKey(strKey)
|
||||
}
|
||||
|
||||
// parent is a predefined (and preopened) key
|
||||
wxRegKey::wxRegKey(StdKey keyParent, const wxString& strKey) : m_strKey(strKey)
|
||||
wxRegKey::wxRegKey(StdKey keyParent,
|
||||
const wxString& strKey,
|
||||
WOW64ViewMode viewMode)
|
||||
: m_strKey(strKey), m_viewMode(viewMode)
|
||||
{
|
||||
RemoveTrailingSeparator(m_strKey);
|
||||
m_hRootKey = (WXHKEY) aStdKeys[keyParent].hkey;
|
||||
@@ -220,7 +238,7 @@ wxRegKey::wxRegKey(StdKey keyParent, const wxString& strKey) : m_strKey(strKey)
|
||||
|
||||
// parent is a normal regkey
|
||||
wxRegKey::wxRegKey(const wxRegKey& keyParent, const wxString& strKey)
|
||||
: m_strKey(keyParent.m_strKey)
|
||||
: m_strKey(keyParent.m_strKey), m_viewMode(keyParent.GetView())
|
||||
{
|
||||
// combine our name with parent's to get the full name
|
||||
if ( !m_strKey.empty() &&
|
||||
@@ -316,7 +334,9 @@ void wxRegKey::SetHkey(WXHKEY hKey)
|
||||
bool wxRegKey::Exists() const
|
||||
{
|
||||
// opened key has to exist, try to open it if not done yet
|
||||
return IsOpened() ? true : KeyExists(m_hRootKey, m_strKey.wx_str());
|
||||
return IsOpened()
|
||||
? true
|
||||
: KeyExists(m_hRootKey, m_strKey, m_viewMode);
|
||||
}
|
||||
|
||||
// returns the full name of the key (prefix is abbreviated if bShortPrefix)
|
||||
@@ -399,7 +419,7 @@ bool wxRegKey::Open(AccessMode mode)
|
||||
(HKEY) m_hRootKey,
|
||||
m_strKey.t_str(),
|
||||
RESERVED,
|
||||
mode == Read ? KEY_READ : KEY_ALL_ACCESS,
|
||||
GetMSWAccessFlags(mode, m_viewMode),
|
||||
&tmpKey
|
||||
);
|
||||
|
||||
@@ -427,19 +447,17 @@ bool wxRegKey::Create(bool bOkIfExists)
|
||||
return true;
|
||||
|
||||
HKEY tmpKey;
|
||||
#ifdef __WXWINCE__
|
||||
DWORD disposition;
|
||||
m_dwLastError = RegCreateKeyEx((HKEY) m_hRootKey, m_strKey.wx_str(),
|
||||
NULL, // reserved
|
||||
NULL, // class string
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
// Minimum supported OS for RegCreateKeyEx: Win 95, Win NT 3.1, Win CE 1.0
|
||||
m_dwLastError = RegCreateKeyEx((HKEY) m_hRootKey, m_strKey.t_str(),
|
||||
0, // reserved and must be 0
|
||||
NULL, // The user-defined class type of this key.
|
||||
REG_OPTION_NON_VOLATILE, // supports other values as well; see MS docs
|
||||
GetMSWAccessFlags(wxRegKey::Write, m_viewMode),
|
||||
NULL, // pointer to a SECURITY_ATTRIBUTES structure
|
||||
&tmpKey,
|
||||
&disposition);
|
||||
#else
|
||||
m_dwLastError = RegCreateKey((HKEY) m_hRootKey, m_strKey.t_str(), &tmpKey);
|
||||
#endif
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't create registry key '%s'"),
|
||||
GetName().c_str());
|
||||
@@ -710,8 +728,25 @@ bool wxRegKey::DeleteSelf()
|
||||
// now delete this key itself
|
||||
Close();
|
||||
|
||||
m_dwLastError = RegDeleteKey((HKEY) m_hRootKey, m_strKey.t_str());
|
||||
// deleting a key which doesn't exist is not considered an error
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
wxDynamicLibrary dllAdvapi32(wxT("advapi32"));
|
||||
// Minimum supported OS for RegDeleteKeyEx: Vista, XP Pro x64, Win Server 2008, Win Server 2003 SP1
|
||||
if(dllAdvapi32.HasSymbol(wxT("RegDeleteKeyEx")))
|
||||
{
|
||||
typedef LONG (WINAPI *RegDeleteKeyEx_t)(HKEY, LPCTSTR, REGSAM, DWORD);
|
||||
wxDYNLIB_FUNCTION(RegDeleteKeyEx_t, RegDeleteKeyEx, dllAdvapi32);
|
||||
|
||||
m_dwLastError = (*pfnRegDeleteKeyEx)((HKEY) m_hRootKey, m_strKey.t_str(),
|
||||
GetMSWViewFlags(m_viewMode),
|
||||
0); // This parameter is reserved and must be zero.
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_DYNLIB_CLASS
|
||||
{
|
||||
m_dwLastError = RegDeleteKey((HKEY) m_hRootKey, m_strKey.t_str());
|
||||
}
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS &&
|
||||
m_dwLastError != ERROR_FILE_NOT_FOUND ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't delete key '%s'"),
|
||||
@@ -803,7 +838,7 @@ bool wxRegKey::HasSubKey(const wxString& szKey) const
|
||||
if ( !CONST_CAST Open(Read) )
|
||||
return false;
|
||||
|
||||
return KeyExists(m_hKey, szKey);
|
||||
return KeyExists(m_hKey, szKey, m_viewMode);
|
||||
}
|
||||
|
||||
wxRegKey::ValueType wxRegKey::GetValueType(const wxString& szValue) const
|
||||
@@ -997,7 +1032,7 @@ bool wxRegKey::SetValue(const wxString& szValue, const wxString& strValue)
|
||||
m_dwLastError = RegSetValueEx((HKEY) m_hKey,
|
||||
RegValueStr(szValue),
|
||||
(DWORD) RESERVED, REG_SZ,
|
||||
(RegString)strValue.wx_str(),
|
||||
(RegString)strValue.t_str(),
|
||||
(strValue.Len() + 1)*sizeof(wxChar));
|
||||
if ( m_dwLastError == ERROR_SUCCESS )
|
||||
return true;
|
||||
@@ -1410,7 +1445,9 @@ bool wxRegKey::DoExport(wxOutputStream& ostr) const
|
||||
// implementation of global private functions
|
||||
// ============================================================================
|
||||
|
||||
bool KeyExists(WXHKEY hRootKey, const wxString& szKey)
|
||||
bool KeyExists(WXHKEY hRootKey,
|
||||
const wxString& szKey,
|
||||
wxRegKey::WOW64ViewMode viewMode)
|
||||
{
|
||||
// don't close this key itself for the case of empty szKey!
|
||||
if ( szKey.empty() )
|
||||
@@ -1422,7 +1459,8 @@ bool KeyExists(WXHKEY hRootKey, const wxString& szKey)
|
||||
(HKEY)hRootKey,
|
||||
szKey.t_str(),
|
||||
RESERVED,
|
||||
KEY_READ, // we might not have enough rights for rw access
|
||||
// we might not have enough rights for rw access
|
||||
GetMSWAccessFlags(wxRegKey::Read, viewMode),
|
||||
&hkeyDummy
|
||||
) == ERROR_SUCCESS )
|
||||
{
|
||||
@@ -1434,6 +1472,49 @@ bool KeyExists(WXHKEY hRootKey, const wxString& szKey)
|
||||
return false;
|
||||
}
|
||||
|
||||
long GetMSWViewFlags(wxRegKey::WOW64ViewMode viewMode)
|
||||
{
|
||||
long samWOW64ViewMode = 0;
|
||||
|
||||
switch ( viewMode )
|
||||
{
|
||||
case wxRegKey::WOW64ViewMode_32:
|
||||
#ifdef __WIN64__ // the flag is only needed by 64 bit apps
|
||||
samWOW64ViewMode = KEY_WOW64_32KEY;
|
||||
#endif // Win64
|
||||
break;
|
||||
|
||||
case wxRegKey::WOW64ViewMode_64:
|
||||
#ifndef __WIN64__ // the flag is only needed by 32 bit apps
|
||||
// 64 bit registry can only be accessed under 64 bit platforms
|
||||
if ( wxIsPlatform64Bit() )
|
||||
samWOW64ViewMode = KEY_WOW64_64KEY;
|
||||
#endif // Win32
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG("Unknown registry view.");
|
||||
// fall through
|
||||
|
||||
case wxRegKey::WOW64ViewMode_Default:
|
||||
// Use default registry view for the current application,
|
||||
// i.e. 32 bits for 32 bit ones and 64 bits for 64 bit apps
|
||||
;
|
||||
}
|
||||
|
||||
return samWOW64ViewMode;
|
||||
}
|
||||
|
||||
long GetMSWAccessFlags(wxRegKey::AccessMode mode,
|
||||
wxRegKey::WOW64ViewMode viewMode)
|
||||
{
|
||||
long sam = mode == wxRegKey::Read ? KEY_READ : KEY_ALL_ACCESS;
|
||||
|
||||
sam |= GetMSWViewFlags(viewMode);
|
||||
|
||||
return sam;
|
||||
}
|
||||
|
||||
wxString GetFullName(const wxRegKey *pKey, const wxString& szValue)
|
||||
{
|
||||
wxString str(pKey->GetName());
|
||||
|
||||
Reference in New Issue
Block a user