From: Vadim Zeitlin Date: Sun, 6 Feb 2011 01:01:01 +0000 (+0000) Subject: Allow accessing 64 bit registry from 32 bit MSW code and vice versa. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a5c468483d43741305217e0a9acc42c7154dd166 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 --- diff --git a/docs/changes.txt b/docs/changes.txt index 905066a051..2d77036063 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -651,6 +651,7 @@ MSW: - 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: diff --git a/include/wx/msw/registry.h b/include/wx/msw/registry.h index 654290ea2f..9b38eeec98 100644 --- a/include/wx/msw/registry.h +++ b/include/wx/msw/registry.h @@ -66,6 +66,22 @@ public: 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; @@ -82,11 +98,17 @@ public: // 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 @@ -105,6 +127,8 @@ public: // 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) @@ -235,12 +259,12 @@ private: 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); diff --git a/interface/wx/msw/registry.h b/interface/wx/msw/registry.h index a5af85c694..db873eb93d 100644 --- a/interface/wx/msw/registry.h +++ b/interface/wx/msw/registry.h @@ -71,20 +71,27 @@ 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); @@ -132,6 +139,33 @@ public: 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. */ @@ -224,6 +258,15 @@ public: */ 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. */ diff --git a/samples/regtest/regtest.cpp b/samples/regtest/regtest.cpp index 64a96ef3ef..2623dcc272 100644 --- a/samples/regtest/regtest.cpp +++ b/samples/regtest/regtest.cpp @@ -102,6 +102,7 @@ public: void CreateNewKey(const wxString& strName); void CreateNewTextValue(const wxString& strName); void CreateNewBinaryValue(const wxString& strName); + void SetRegistryView(wxRegKey::WOW64ViewMode viewMode); // information bool IsKeySelected() const; @@ -119,6 +120,7 @@ private: 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; } @@ -135,6 +137,7 @@ private: 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; } @@ -155,6 +158,8 @@ private: 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()); } @@ -163,7 +168,8 @@ public: 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(); @@ -203,6 +209,8 @@ public: void OnInfo (wxCommandEvent& event); + void OnViewChange (wxCommandEvent& event); + DECLARE_EVENT_TABLE() private: @@ -232,6 +240,10 @@ enum Menu_NewBinary, Menu_Delete, Menu_Info, + Menu_View, + Menu_ViewDefault, + Menu_View32, + Menu_View64, Ctrl_RegTree = 200 }; @@ -241,19 +253,22 @@ enum // ---------------------------------------------------------------------------- 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 @@ -295,6 +310,20 @@ wxMenu *CreateRegistryMenu() 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")); @@ -305,6 +334,7 @@ wxMenu *CreateRegistryMenu() 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")); @@ -494,6 +524,33 @@ void RegFrame::OnInfo(wxCommandEvent& WXUNUSED(event)) #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 // ---------------------------------------------------------------------------- @@ -515,10 +572,12 @@ RegImageList::RegImageList() : wxImageList(16, 16, true) // ---------------------------------------------------------------------------- // 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; @@ -527,6 +586,7 @@ RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(TreeNode *pParent, 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(), @@ -572,6 +632,7 @@ RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id) // init members m_draggedItem = NULL; m_restoreStatus = false; + m_viewMode = wxRegKey::WOW64ViewMode_Default; // create the image list // --------------------- @@ -580,7 +641,13 @@ RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id) // 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 // ----------------- @@ -598,7 +665,12 @@ void RegTreeCtrl::AddStdKeys() { 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); } } @@ -928,7 +1000,7 @@ bool RegTreeCtrl::TreeNode::OnExpand() if ( Parent()->IsRoot() ) { // we're a standard key - m_pKey = new wxRegKey(m_strName); + m_pKey = new wxRegKey(m_strName, m_viewMode); } else { @@ -954,7 +1026,12 @@ bool RegTreeCtrl::TreeNode::OnExpand() 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... @@ -1005,7 +1082,7 @@ bool RegTreeCtrl::TreeNode::OnExpand() 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... @@ -1120,6 +1197,16 @@ const wxChar *RegTreeCtrl::TreeNode::FullName() const } } +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 // ---------------------------------------------------------------------------- @@ -1274,6 +1361,13 @@ void RegTreeCtrl::CreateNewBinaryValue(const wxString& strName) pCurrent->Refresh(); } +void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode) +{ + m_viewMode = viewMode; + m_pRoot->SetRegistryView(viewMode); + m_pRoot->Refresh(); +} + void RegTreeCtrl::ShowProperties() { wxTreeItemId lCurrent = GetSelection(); diff --git a/src/msw/registry.cpp b/src/msw/registry.cpp index 57eea64341..0825e131fc 100644 --- a/src/msw/registry.cpp +++ b/src/msw/registry.cpp @@ -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());