]> git.saurik.com Git - wxWidgets.git/commitdiff
Allow accessing 64 bit registry from 32 bit MSW code and vice versa.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 6 Feb 2011 01:01:01 +0000 (01:01 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 6 Feb 2011 01:01:01 +0000 (01:01 +0000)
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

docs/changes.txt
include/wx/msw/registry.h
interface/wx/msw/registry.h
samples/regtest/regtest.cpp
src/msw/registry.cpp

index 905066a05137cd4c571573b3b5d3bb0fdcb8f48c..2d7703606398e7ab9858007d9f6d8e88c8968e8e 100644 (file)
@@ -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.
 - 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:
 
 
 i18n:
 
index 654290ea2f2c8eb96e59d9da19bc0510cea3a640..9b38eeec988b0dd423f0e8eb48d3f230ac79e9e3 100644 (file)
@@ -66,6 +66,22 @@ public:
       Write     // read and write
   };
 
       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;
   // 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)
 
   // 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...)
     // 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
     // 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
     // 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;
   // 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)
     // 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;
 
 
   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);
 
 
   wxDECLARE_NO_COPY_CLASS(wxRegKey);
index a5af85c694236d35b5e3f74a048509457b63f238..db873eb93d8c9b0f4b01e8512f273aa690689ba9 100644 (file)
@@ -71,20 +71,27 @@ class wxRegKey
 public:
     /**
         Default constructor, initializes to @c HKEY_CLASSES_ROOT.
 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 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 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);
 
     */
     wxRegKey(const wxRegKey& keyParent, const wxString& strKey);
 
@@ -132,6 +139,33 @@ public:
     Type_Resource_requirements_list ///<
     };
 
     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.
     */
     /**
         Closes the key.
     */
@@ -224,6 +258,15 @@ public:
     */
     wxString GetName(bool bShortPrefix = true) const;
 
     */
     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.
     */
     /**
         Gets the next key. Returns @true if successful.
     */
index 64a96ef3efcedd84c5323359cb7d0d3a45428e99..2623dcc272bd8bab913abe24ed786c51d9db1494 100644 (file)
@@ -102,6 +102,7 @@ public:
     void CreateNewKey(const wxString& strName);
     void CreateNewTextValue(const wxString& strName);
     void CreateNewBinaryValue(const wxString& strName);
     void CreateNewKey(const wxString& strName);
     void CreateNewTextValue(const wxString& strName);
     void CreateNewBinaryValue(const wxString& strName);
+    void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
 
     // information
     bool IsKeySelected() const;
 
     // 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
         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;              }
 
         // trivial accessors
         wxTreeItemId  Id()     const { return m_id;              }
@@ -135,6 +137,7 @@ private:
         bool DeleteChild(TreeNode *child);
         void DestroyChildren();
         const wxChar *FullName() const;
         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; }
 
         // 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
 
 
     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 *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,
     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();
 
     // add standard registry keys
     void AddStdKeys();
@@ -203,6 +209,8 @@ public:
 
     void OnInfo     (wxCommandEvent& event);
 
 
     void OnInfo     (wxCommandEvent& event);
 
+    void OnViewChange (wxCommandEvent& event);
+
     DECLARE_EVENT_TABLE()
 
 private:
     DECLARE_EVENT_TABLE()
 
 private:
@@ -232,6 +240,10 @@ enum
     Menu_NewBinary,
     Menu_Delete,
     Menu_Info,
     Menu_NewBinary,
     Menu_Delete,
     Menu_Info,
+    Menu_View,
+    Menu_ViewDefault,
+    Menu_View32,
+    Menu_View64,
 
     Ctrl_RegTree  = 200
 };
 
     Ctrl_RegTree  = 200
 };
@@ -241,19 +253,22 @@ enum
 // ----------------------------------------------------------------------------
 
 BEGIN_EVENT_TABLE(RegFrame, wxFrame)
 // ----------------------------------------------------------------------------
 
 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
 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"));
 
     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"));
     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_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"));
 
     pMenuReg->AppendSeparator();
     pMenuReg->Append(Menu_Info,     wxT("&Properties"),wxT("Information about current selection"));
 
@@ -494,6 +524,33 @@ void RegFrame::OnInfo(wxCommandEvent& WXUNUSED(event))
 #endif
 }
 
 #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
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // RegImageList
 // ----------------------------------------------------------------------------
@@ -515,10 +572,12 @@ RegImageList::RegImageList() : wxImageList(16, 16, true)
 // ----------------------------------------------------------------------------
 
 // create a new tree item and insert it into the tree
 // ----------------------------------------------------------------------------
 
 // 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;
 {
     // 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_strName = strName;
     pNewNode->m_bKey    = pstrValue == NULL;
     pNewNode->m_pKey    = NULL;
+    pNewNode->m_viewMode = viewMode;
     if (pParent)
     {
         pNewNode->m_id  = AppendItem(pParent->Id(),
     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;
     // init members
     m_draggedItem = NULL;
     m_restoreStatus = false;
+    m_viewMode = wxRegKey::WOW64ViewMode_Default;
 
     // create the image list
     // ---------------------
 
     // create the image list
     // ---------------------
@@ -580,7 +641,13 @@ RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id)
 
     // create root keys
     // ----------------
 
     // 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
     // -----------------
 
     // create popup menu
     // -----------------
@@ -598,7 +665,12 @@ void RegTreeCtrl::AddStdKeys()
 {
     for ( unsigned int ui = 0; ui < wxRegKey::nStdKeys; ui++ )
     {
 {
     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
     if ( Parent()->IsRoot() )
     {
         // we're a standard key
-        m_pKey = new wxRegKey(m_strName);
+        m_pKey = new wxRegKey(m_strName, m_viewMode);
     }
     else
     {
     }
     else
     {
@@ -954,7 +1026,12 @@ bool RegTreeCtrl::TreeNode::OnExpand()
     bCont = m_pKey->GetFirstKey(str, l);
     while ( bCont )
     {
     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...
         bCont = m_pKey->GetNextKey(str, l);
 
         // we have at least this key...
@@ -1005,7 +1082,7 @@ bool RegTreeCtrl::TreeNode::OnExpand()
             icon = RegImageList::BinaryValue;
         }
 
             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...
         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
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // operations on RegTreeCtrl
 // ----------------------------------------------------------------------------
@@ -1274,6 +1361,13 @@ void RegTreeCtrl::CreateNewBinaryValue(const wxString& strName)
         pCurrent->Refresh();
 }
 
         pCurrent->Refresh();
 }
 
+void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
+{
+    m_viewMode = viewMode;
+    m_pRoot->SetRegistryView(viewMode);
+    m_pRoot->Refresh();
+}
+
 void RegTreeCtrl::ShowProperties()
 {
     wxTreeItemId lCurrent = GetSelection();
 void RegTreeCtrl::ShowProperties()
 {
     wxTreeItemId lCurrent = GetSelection();
index 57eea64341e2381f4d5b7d9737bbe82568d086c6..0825e131fc1247967ac2f67e97b95cfb00478800 100644 (file)
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/crt.h"
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/crt.h"
+    #include "wx/utils.h"
 #endif
 
 #endif
 
+#include "wx/dynlib.h"
 #include "wx/file.h"
 #include "wx/wfstream.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 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);
 
 // combines value and key name
 static wxString GetFullName(const wxRegKey *pKey);
@@ -195,14 +209,15 @@ wxRegKey::StdKey wxRegKey::GetStdKeyFromHkey(WXHKEY hkey)
 // ctors and dtor
 // ----------------------------------------------------------------------------
 
 // ctors and dtor
 // ----------------------------------------------------------------------------
 
-wxRegKey::wxRegKey()
+wxRegKey::wxRegKey(WOW64ViewMode viewMode) : m_viewMode(viewMode)
 {
   m_hRootKey = (WXHKEY) aStdKeys[HKCR].hkey;
 
   Init();
 }
 
 {
   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;
 
 {
   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
 }
 
 // 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;
 {
   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)
 
 // 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() &&
 {
   // 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
 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)
 }
 
 // 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,
                         (HKEY) m_hRootKey,
                         m_strKey.t_str(),
                         RESERVED,
-                        mode == Read ? KEY_READ : KEY_ALL_ACCESS,
+                        GetMSWAccessFlags(mode, m_viewMode),
                         &tmpKey
                     );
 
                         &tmpKey
                     );
 
@@ -427,19 +447,17 @@ bool wxRegKey::Create(bool bOkIfExists)
     return true;
 
   HKEY tmpKey;
     return true;
 
   HKEY tmpKey;
-#ifdef __WXWINCE__
   DWORD disposition;
   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);
       &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());
   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();
 
   // 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
   // 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 ( 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;
 
   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
 }
 
 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,
       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;
                                     (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
 // ============================================================================
 
 // 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() )
 {
     // 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,
             (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 )
     {
             &hkeyDummy
          ) == ERROR_SUCCESS )
     {
@@ -1434,6 +1472,49 @@ bool KeyExists(WXHKEY hRootKey, const wxString& szKey)
     return false;
 }
 
     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());
 wxString GetFullName(const wxRegKey *pKey, const wxString& szValue)
 {
   wxString str(pKey->GetName());