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:
Vadim Zeitlin
2011-02-06 01:01:01 +00:00
parent e615d356fc
commit a5c468483d
5 changed files with 302 additions and 59 deletions

View File

@@ -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());