- In some rare cases wxOwnerDrawnComboBox drop-down animation could display
as garbage. This has now been greatly reduced (mcben).
- Fixed wxComboCtrl::SetButtonPosition() on Vista/Win7.
+- Allow accessing 64/32 bit registry from 32/64 bit code (Rickard Westerlund).
i18n:
Write // read and write
};
+ // Different registry views supported under WOW64.
+ enum WOW64ViewMode
+ {
+ // 32 bit registry for 32 bit applications, 64 bit registry
+ // for 64 bit ones.
+ WOW64ViewMode_Default,
+
+ // Can be used in 64 bit apps to access 32 bit registry,
+ // has no effect (i.e. treated as default) in 32 bit apps.
+ WOW64ViewMode_32,
+
+ // Can be used in 32 bit apps to access 64 bit registry,
+ // has no effect (i.e. treated as default) in 64 bit apps.
+ WOW64ViewMode_64
+ };
+
// information about standard (predefined) registry keys
// number of standard keys
static const size_t nStdKeys;
// ctors
// root key is set to HKCR (the only root key under Win16)
- wxRegKey();
+ wxRegKey(WOW64ViewMode viewMode = WOW64ViewMode_Default);
+
// strKey is the full name of the key (i.e. starting with HKEY_xxx...)
- wxRegKey(const wxString& strKey);
+ wxRegKey(const wxString& strKey,
+ WOW64ViewMode viewMode = WOW64ViewMode_Default);
+
// strKey is the name of key under (standard key) keyParent
- wxRegKey(StdKey keyParent, const wxString& strKey);
+ wxRegKey(StdKey keyParent,
+ const wxString& strKey,
+ WOW64ViewMode viewMode = WOW64ViewMode_Default);
+
// strKey is the name of key under (previously created) keyParent
wxRegKey(const wxRegKey& keyParent, const wxString& strKey);
// dtor closes the key
// get infomation about the key
// get the (full) key name. Abbreviate std root keys if bShortPrefix.
wxString GetName(bool bShortPrefix = true) const;
+ // Retrieves the registry view used by this key.
+ WOW64ViewMode GetView() const { return m_viewMode; }
// return true if the key exists
bool Exists() const;
// get the info about key (any number of these pointers may be NULL)
wxString FormatValue(const wxString& name) const;
- WXHKEY m_hKey, // our handle
- m_hRootKey; // handle of the top key (i.e. StdKey)
- wxString m_strKey; // key name (relative to m_hRootKey)
-
- AccessMode m_mode; // valid only if key is opened
- long m_dwLastError; // last error (0 if none)
+ WXHKEY m_hKey, // our handle
+ m_hRootKey; // handle of the top key (i.e. StdKey)
+ wxString m_strKey; // key name (relative to m_hRootKey)
+ WOW64ViewMode m_viewMode; // which view to select under WOW64
+ AccessMode m_mode; // valid only if key is opened
+ long m_dwLastError; // last error (0 if none)
wxDECLARE_NO_COPY_CLASS(wxRegKey);
public:
/**
Default constructor, initializes to @c HKEY_CLASSES_ROOT.
+
+ The @a viewMode parameter is new since wxWidgets 2.9.2.
*/
- wxRegKey();
+ wxRegKey(WOW64ViewMode viewMode = WOW64ViewMode_Default);
/**
The constructor to set the full name of the key.
+
+ The @a viewMode parameter is new since wxWidgets 2.9.2.
*/
- wxRegKey(const wxString& strKey);
+ wxRegKey(const wxString& strKey,
+ WOW64ViewMode viewMode = WOW64ViewMode_Default);
/**
The constructor to set the full name of the key using one of the
standard keys, that is, HKCR, HKCU, HKLM, HKUSR, HKPD, HKCC or HKDD.
+ The @a viewMode parameter is new since wxWidgets 2.9.2.
*/
- wxRegKey(StdKey keyParent, const wxString& strKey);
+ wxRegKey(StdKey keyParent, const wxString& strKey,
+ WOW64ViewMode viewMode = WOW64ViewMode_Default);
/**
- The constructor to set the full name of the key under a previously created
- parent.
+ The constructor to set the full name of the key under a previously
+ created parent. The registry view is inherited from the parent.
*/
wxRegKey(const wxRegKey& keyParent, const wxString& strKey);
Type_Resource_requirements_list ///<
};
+ /**
+ Used to determine how the registry will be viewed, either as
+ 32-bit or 64-bit.
+
+ @since 2.9.2
+ */
+ enum WOW64ViewMode
+ {
+ /**
+ Uses 32-bit registry for 32-bit applications and
+ 64-bit registry for 64-bit ones.
+ */
+ WOW64ViewMode_Default,
+
+ /**
+ Can be used in 64-bit apps to access the 32-bit registry,
+ has no effect (i.e. treated as default) in 32-bit apps.
+ */
+ WOW64ViewMode_32,
+
+ /**
+ Can be used in 32-bit apps to access the 64-bit registry,
+ has no effect (i.e. treated as default) in 64-bit apps.
+ */
+ WOW64ViewMode_64
+ };
+
/**
Closes the key.
*/
*/
wxString GetName(bool bShortPrefix = true) const;
+ /**
+ Retrieves the registry view used by this key.
+
+ @since 2.9.2
+
+ @return The registry view given at the object's construction.
+ */
+ WOW64ViewMode GetView() const { return m_viewMode; }
+
/**
Gets the next key. Returns @true if successful.
*/
void CreateNewKey(const wxString& strName);
void CreateNewTextValue(const wxString& strName);
void CreateNewBinaryValue(const wxString& strName);
+ void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
// information
bool IsKeySelected() const;
TreeChildren m_aChildren; // array of subkeys/values
bool m_bKey; // key or value?
wxRegKey *m_pKey; // only may be !NULL if m_bKey == true
+ wxRegKey::WOW64ViewMode m_viewMode; // How to view the registry.
// trivial accessors
wxTreeItemId Id() const { return m_id; }
bool DeleteChild(TreeNode *child);
void DestroyChildren();
const wxChar *FullName() const;
+ void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
// get the associated key: make sure the pointer is !NULL
wxRegKey& Key() { if ( !m_pKey ) OnExpand(); return *m_pKey; }
wxString m_nameOld; // the initial value of item being renamed
+ wxRegKey::WOW64ViewMode m_viewMode; // Registry view to use for keys.
+
TreeNode *GetNode(const wxTreeEvent& event)
{ return (TreeNode *)GetItemData(event.GetItem()); }
TreeNode *InsertNewTreeNode(TreeNode *pParent,
const wxString& strName,
int idImage = RegImageList::ClosedKey,
- const wxString *pstrValue = NULL);
+ const wxString *pstrValue = NULL,
+ wxRegKey::WOW64ViewMode viewMode = wxRegKey::WOW64ViewMode_Default);
// add standard registry keys
void AddStdKeys();
void OnInfo (wxCommandEvent& event);
+ void OnViewChange (wxCommandEvent& event);
+
DECLARE_EVENT_TABLE()
private:
Menu_NewBinary,
Menu_Delete,
Menu_Info,
+ Menu_View,
+ Menu_ViewDefault,
+ Menu_View32,
+ Menu_View64,
Ctrl_RegTree = 200
};
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(RegFrame, wxFrame)
- EVT_MENU(Menu_Test, RegFrame::OnTest)
- EVT_MENU(Menu_About, RegFrame::OnAbout)
- EVT_MENU(Menu_Quit, RegFrame::OnQuit)
- EVT_MENU(Menu_GoTo, RegFrame::OnGoTo)
- EVT_MENU(Menu_Expand, RegFrame::OnExpand)
- EVT_MENU(Menu_Collapse, RegFrame::OnCollapse)
- EVT_MENU(Menu_Toggle, RegFrame::OnToggle)
- EVT_MENU(Menu_Refresh, RegFrame::OnRefresh)
- EVT_MENU(Menu_Delete, RegFrame::OnDelete)
- EVT_MENU(Menu_NewKey, RegFrame::OnNewKey)
- EVT_MENU(Menu_NewText, RegFrame::OnNewText)
- EVT_MENU(Menu_NewBinary,RegFrame::OnNewBinary)
- EVT_MENU(Menu_Info, RegFrame::OnInfo)
+ EVT_MENU(Menu_Test, RegFrame::OnTest)
+ EVT_MENU(Menu_About, RegFrame::OnAbout)
+ EVT_MENU(Menu_Quit, RegFrame::OnQuit)
+ EVT_MENU(Menu_GoTo, RegFrame::OnGoTo)
+ EVT_MENU(Menu_Expand, RegFrame::OnExpand)
+ EVT_MENU(Menu_Collapse, RegFrame::OnCollapse)
+ EVT_MENU(Menu_Toggle, RegFrame::OnToggle)
+ EVT_MENU(Menu_Refresh, RegFrame::OnRefresh)
+ EVT_MENU(Menu_Delete, RegFrame::OnDelete)
+ EVT_MENU(Menu_NewKey, RegFrame::OnNewKey)
+ EVT_MENU(Menu_NewText, RegFrame::OnNewText)
+ EVT_MENU(Menu_NewBinary, RegFrame::OnNewBinary)
+ EVT_MENU(Menu_Info, RegFrame::OnInfo)
+ EVT_MENU(Menu_ViewDefault, RegFrame::OnViewChange)
+ EVT_MENU(Menu_View32, RegFrame::OnViewChange)
+ EVT_MENU(Menu_View64, RegFrame::OnViewChange)
END_EVENT_TABLE()
#if DO_REGTEST
pMenuNew->Append(Menu_NewText, wxT("&Text value"), wxT("Create a new text value"));
pMenuNew->Append(Menu_NewBinary, wxT("&Binary value"), wxT("Create a new binary value"));
+ wxMenu *pMenuView = new wxMenu;
+ pMenuView->AppendRadioItem(
+ Menu_ViewDefault,
+ wxT("&Default"),
+ wxT("Default registry view for the program environment."));
+ pMenuView->AppendRadioItem(
+ Menu_View32,
+ wxT("32-bit Registry"),
+ wxT("View 32-bit registry."));
+ pMenuView->AppendRadioItem(
+ Menu_View64,
+ wxT("64-bit Registry"),
+ wxT("View 64-bit registry."));
+
wxMenu *pMenuReg = new wxMenu;
pMenuReg->Append(Menu_New, wxT("&New"), pMenuNew);
pMenuReg->Append(Menu_Delete, wxT("&Delete..."), wxT("Delete selected key/value"));
pMenuReg->Append(Menu_Toggle, wxT("&Toggle"), wxT("Toggle current key"));
pMenuReg->AppendSeparator();
pMenuReg->Append(Menu_Refresh, wxT("&Refresh"), wxT("Refresh the subtree"));
+ pMenuReg->Append(Menu_View, wxT("&View"), pMenuView);
pMenuReg->AppendSeparator();
pMenuReg->Append(Menu_Info, wxT("&Properties"),wxT("Information about current selection"));
#endif
}
+void RegFrame::OnViewChange(wxCommandEvent& event)
+{
+#if DO_REGTEST
+ wxRegKey::WOW64ViewMode view;
+ switch ( event.GetId() )
+ {
+ case Menu_ViewDefault:
+ view = wxRegKey::WOW64ViewMode_Default;
+ break;
+
+ case Menu_View32:
+ view = wxRegKey::WOW64ViewMode_32;
+ break;
+
+ case Menu_View64:
+ view = wxRegKey::WOW64ViewMode_64;
+ break;
+
+ default:
+ wxFAIL_MSG("Unexpected event source for view change.");
+ return;
+ }
+
+ m_treeCtrl->SetRegistryView(view);
+#endif
+}
+
// ----------------------------------------------------------------------------
// RegImageList
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// create a new tree item and insert it into the tree
-RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(TreeNode *pParent,
- const wxString& strName,
- int idImage,
- const wxString *pstrValue)
+RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(
+ TreeNode *pParent,
+ const wxString& strName,
+ int idImage,
+ const wxString *pstrValue,
+ wxRegKey::WOW64ViewMode viewMode)
{
// create new item & insert it
TreeNode *pNewNode = new TreeNode;
pNewNode->m_strName = strName;
pNewNode->m_bKey = pstrValue == NULL;
pNewNode->m_pKey = NULL;
+ pNewNode->m_viewMode = viewMode;
if (pParent)
{
pNewNode->m_id = AppendItem(pParent->Id(),
// init members
m_draggedItem = NULL;
m_restoreStatus = false;
+ m_viewMode = wxRegKey::WOW64ViewMode_Default;
// create the image list
// ---------------------
// create root keys
// ----------------
- m_pRoot = InsertNewTreeNode(NULL, wxT("Registry Root"), RegImageList::Root);
+ m_pRoot =
+ InsertNewTreeNode(
+ NULL,
+ wxT("Registry Root"),
+ RegImageList::Root,
+ NULL,
+ m_viewMode);
// create popup menu
// -----------------
{
for ( unsigned int ui = 0; ui < wxRegKey::nStdKeys; ui++ )
{
- InsertNewTreeNode(m_pRoot, wxRegKey::GetStdKeyName(ui));
+ InsertNewTreeNode(
+ m_pRoot,
+ wxRegKey::GetStdKeyName(ui),
+ RegImageList::ClosedKey,
+ NULL,
+ m_viewMode);
}
}
if ( Parent()->IsRoot() )
{
// we're a standard key
- m_pKey = new wxRegKey(m_strName);
+ m_pKey = new wxRegKey(m_strName, m_viewMode);
}
else
{
bCont = m_pKey->GetFirstKey(str, l);
while ( bCont )
{
- m_pTree->InsertNewTreeNode(this, str, RegImageList::ClosedKey);
+ m_pTree->InsertNewTreeNode(
+ this,
+ str,
+ RegImageList::ClosedKey,
+ NULL,
+ m_viewMode);
bCont = m_pKey->GetNextKey(str, l);
// we have at least this key...
icon = RegImageList::BinaryValue;
}
- m_pTree->InsertNewTreeNode(this, str, icon, &strItem);
+ m_pTree->InsertNewTreeNode(this, str, icon, &strItem, m_viewMode);
bCont = m_pKey->GetNextValue(str, l);
// we have at least this value...
}
}
+void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
+{
+ m_viewMode = viewMode;
+
+ // Update children with new view.
+ size_t nCount = m_aChildren.GetCount();
+ for (size_t n = 0; n < nCount; n++)
+ m_aChildren[n]->SetRegistryView(viewMode);
+}
+
// ----------------------------------------------------------------------------
// operations on RegTreeCtrl
// ----------------------------------------------------------------------------
pCurrent->Refresh();
}
+void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
+{
+ m_viewMode = viewMode;
+ m_pRoot->SetRegistryView(viewMode);
+ m_pRoot->Refresh();
+}
+
void RegTreeCtrl::ShowProperties()
{
wxTreeItemId lCurrent = GetSelection();
#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"
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);
// 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;
}
// 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;
// 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() &&
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)
(HKEY) m_hRootKey,
m_strKey.t_str(),
RESERVED,
- mode == Read ? KEY_READ : KEY_ALL_ACCESS,
+ GetMSWAccessFlags(mode, m_viewMode),
&tmpKey
);
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());
// 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'"),
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
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;
// 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() )
(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 )
{
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());