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

@@ -651,6 +651,7 @@ MSW:
- In some rare cases wxOwnerDrawnComboBox drop-down animation could display - In some rare cases wxOwnerDrawnComboBox drop-down animation could display
as garbage. This has now been greatly reduced (mcben). as garbage. This has now been greatly reduced (mcben).
- Fixed wxComboCtrl::SetButtonPosition() on Vista/Win7. - Fixed wxComboCtrl::SetButtonPosition() on Vista/Win7.
- Allow accessing 64/32 bit registry from 32/64 bit code (Rickard Westerlund).
i18n: i18n:

View 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 // information about standard (predefined) registry keys
// number of standard keys // number of standard keys
static const size_t nStdKeys; static const size_t nStdKeys;
@@ -82,11 +98,17 @@ public:
// ctors // ctors
// root key is set to HKCR (the only root key under Win16) // 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 // strKey is the name of key under (previously created) keyParent
wxRegKey(const wxRegKey& keyParent, const wxString& strKey); wxRegKey(const wxRegKey& keyParent, const wxString& strKey);
// dtor closes the key // dtor closes the key
@@ -105,6 +127,8 @@ public:
// get infomation about the key // get infomation about the key
// get the (full) key name. Abbreviate std root keys if bShortPrefix. // get the (full) key name. Abbreviate std root keys if bShortPrefix.
wxString GetName(bool bShortPrefix = true) const; 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 // return true if the key exists
bool Exists() const; bool Exists() const;
// get the info about key (any number of these pointers may be NULL) // get the info about key (any number of these pointers may be NULL)
@@ -238,7 +262,7 @@ private:
WXHKEY m_hKey, // our handle WXHKEY m_hKey, // our handle
m_hRootKey; // handle of the top key (i.e. StdKey) m_hRootKey; // handle of the top key (i.e. StdKey)
wxString m_strKey; // key name (relative to m_hRootKey) 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 AccessMode m_mode; // valid only if key is opened
long m_dwLastError; // last error (0 if none) long m_dwLastError; // last error (0 if none)

View File

@@ -71,20 +71,27 @@ class wxRegKey
public: public:
/** /**
Default constructor, initializes to @c HKEY_CLASSES_ROOT. 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 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. 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 The constructor to set the full name of the key under a previously
parent. 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.
*/ */

View File

@@ -102,6 +102,7 @@ public:
void CreateNewKey(const wxString& strName); void CreateNewKey(const wxString& strName);
void CreateNewTextValue(const wxString& strName); void CreateNewTextValue(const wxString& strName);
void CreateNewBinaryValue(const wxString& strName); void CreateNewBinaryValue(const wxString& strName);
void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
// information // information
bool IsKeySelected() const; bool IsKeySelected() const;
@@ -119,6 +120,7 @@ private:
TreeChildren m_aChildren; // array of subkeys/values TreeChildren m_aChildren; // array of subkeys/values
bool m_bKey; // key or value? bool m_bKey; // key or value?
wxRegKey *m_pKey; // only may be !NULL if m_bKey == true wxRegKey *m_pKey; // only may be !NULL if m_bKey == true
wxRegKey::WOW64ViewMode m_viewMode; // How to view the registry.
// trivial accessors // trivial accessors
wxTreeItemId Id() const { return m_id; } wxTreeItemId Id() const { return m_id; }
@@ -135,6 +137,7 @@ private:
bool DeleteChild(TreeNode *child); bool DeleteChild(TreeNode *child);
void DestroyChildren(); void DestroyChildren();
const wxChar *FullName() const; const wxChar *FullName() const;
void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
// get the associated key: make sure the pointer is !NULL // get the associated key: make sure the pointer is !NULL
wxRegKey& Key() { if ( !m_pKey ) OnExpand(); return *m_pKey; } 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) TreeNode *GetNode(const wxTreeEvent& event)
{ return (TreeNode *)GetItemData(event.GetItem()); } { return (TreeNode *)GetItemData(event.GetItem()); }
@@ -163,7 +168,8 @@ public:
TreeNode *InsertNewTreeNode(TreeNode *pParent, TreeNode *InsertNewTreeNode(TreeNode *pParent,
const wxString& strName, const wxString& strName,
int idImage = RegImageList::ClosedKey, int idImage = RegImageList::ClosedKey,
const wxString *pstrValue = NULL); const wxString *pstrValue = NULL,
wxRegKey::WOW64ViewMode viewMode = wxRegKey::WOW64ViewMode_Default);
// add standard registry keys // add standard registry keys
void AddStdKeys(); void AddStdKeys();
@@ -203,6 +209,8 @@ public:
void OnInfo (wxCommandEvent& event); void OnInfo (wxCommandEvent& event);
void OnViewChange (wxCommandEvent& event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
private: private:
@@ -232,6 +240,10 @@ enum
Menu_NewBinary, Menu_NewBinary,
Menu_Delete, Menu_Delete,
Menu_Info, Menu_Info,
Menu_View,
Menu_ViewDefault,
Menu_View32,
Menu_View64,
Ctrl_RegTree = 200 Ctrl_RegTree = 200
}; };
@@ -254,6 +266,9 @@ BEGIN_EVENT_TABLE(RegFrame, wxFrame)
EVT_MENU(Menu_NewText, RegFrame::OnNewText) EVT_MENU(Menu_NewText, RegFrame::OnNewText)
EVT_MENU(Menu_NewBinary, RegFrame::OnNewBinary) EVT_MENU(Menu_NewBinary, RegFrame::OnNewBinary)
EVT_MENU(Menu_Info, RegFrame::OnInfo) 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() END_EVENT_TABLE()
#if DO_REGTEST #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_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_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; wxMenu *pMenuReg = new wxMenu;
pMenuReg->Append(Menu_New, wxT("&New"), pMenuNew); pMenuReg->Append(Menu_New, wxT("&New"), pMenuNew);
pMenuReg->Append(Menu_Delete, wxT("&Delete..."), wxT("Delete selected key/value")); 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->Append(Menu_Toggle, wxT("&Toggle"), wxT("Toggle current key"));
pMenuReg->AppendSeparator(); pMenuReg->AppendSeparator();
pMenuReg->Append(Menu_Refresh, wxT("&Refresh"), wxT("Refresh the subtree")); pMenuReg->Append(Menu_Refresh, wxT("&Refresh"), wxT("Refresh the subtree"));
pMenuReg->Append(Menu_View, wxT("&View"), pMenuView);
pMenuReg->AppendSeparator(); pMenuReg->AppendSeparator();
pMenuReg->Append(Menu_Info, wxT("&Properties"),wxT("Information about current selection")); 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, RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(
TreeNode *pParent,
const wxString& strName, const wxString& strName,
int idImage, int idImage,
const wxString *pstrValue) const wxString *pstrValue,
wxRegKey::WOW64ViewMode viewMode)
{ {
// create new item & insert it // create new item & insert it
TreeNode *pNewNode = new TreeNode; TreeNode *pNewNode = new TreeNode;
@@ -527,6 +586,7 @@ RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(TreeNode *pParent,
pNewNode->m_strName = strName; pNewNode->m_strName = strName;
pNewNode->m_bKey = pstrValue == NULL; pNewNode->m_bKey = pstrValue == NULL;
pNewNode->m_pKey = NULL; pNewNode->m_pKey = NULL;
pNewNode->m_viewMode = viewMode;
if (pParent) if (pParent)
{ {
pNewNode->m_id = AppendItem(pParent->Id(), pNewNode->m_id = AppendItem(pParent->Id(),
@@ -572,6 +632,7 @@ RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id)
// init members // init members
m_draggedItem = NULL; m_draggedItem = NULL;
m_restoreStatus = false; 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() ) if ( Parent()->IsRoot() )
{ {
// we're a standard key // 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); bCont = m_pKey->GetFirstKey(str, l);
while ( bCont ) 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); bCont = m_pKey->GetNextKey(str, l);
// we have at least this key... // 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); bCont = m_pKey->GetNextValue(str, l);
// we have at least this value... // 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() void RegTreeCtrl::ShowProperties()
{ {
wxTreeItemId lCurrent = GetSelection(); wxTreeItemId lCurrent = GetSelection();

View File

@@ -27,8 +27,10 @@
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/crt.h" #include "wx/crt.h"
#include "wx/utils.h"
#endif #endif
#include "wx/dynlib.h"
#include "wx/file.h" #include "wx/file.h"
#include "wx/wfstream.h" #include "wx/wfstream.h"
@@ -114,7 +116,19 @@ aStdKeys[] =
static inline void RemoveTrailingSeparator(wxString& str); static inline void RemoveTrailingSeparator(wxString& str);
// returns true if given registry key exists // 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 // combines value and key name
static wxString GetFullName(const wxRegKey *pKey); 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; m_hRootKey = (WXHKEY) aStdKeys[HKCR].hkey;
Init(); 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); RemoveTrailingSeparator(m_strKey);
m_hRootKey = (WXHKEY) aStdKeys[keyParent].hkey; 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 // parent is a normal regkey
wxRegKey::wxRegKey(const wxRegKey& keyParent, const wxString& strKey) 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 // combine our name with parent's to get the full name
if ( !m_strKey.empty() && if ( !m_strKey.empty() &&
@@ -316,7 +334,9 @@ void wxRegKey::SetHkey(WXHKEY hKey)
bool wxRegKey::Exists() const bool wxRegKey::Exists() const
{ {
// opened key has to exist, try to open it if not done yet // 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, (HKEY) m_hRootKey,
m_strKey.t_str(), m_strKey.t_str(),
RESERVED, 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; return true;
HKEY tmpKey; HKEY tmpKey;
#ifdef __WXWINCE__
DWORD disposition; DWORD disposition;
m_dwLastError = RegCreateKeyEx((HKEY) m_hRootKey, m_strKey.wx_str(), // Minimum supported OS for RegCreateKeyEx: Win 95, Win NT 3.1, Win CE 1.0
NULL, // reserved m_dwLastError = RegCreateKeyEx((HKEY) m_hRootKey, m_strKey.t_str(),
NULL, // class string 0, // reserved and must be 0
0, NULL, // The user-defined class type of this key.
0, REG_OPTION_NON_VOLATILE, // supports other values as well; see MS docs
NULL, GetMSWAccessFlags(wxRegKey::Write, m_viewMode),
NULL, // pointer to a SECURITY_ATTRIBUTES structure
&tmpKey, &tmpKey,
&disposition); &disposition);
#else
m_dwLastError = RegCreateKey((HKEY) m_hRootKey, m_strKey.t_str(), &tmpKey);
#endif
if ( m_dwLastError != ERROR_SUCCESS ) { if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("Can't create registry key '%s'"), wxLogSysError(m_dwLastError, _("Can't create registry key '%s'"),
GetName().c_str()); GetName().c_str());
@@ -710,8 +728,25 @@ bool wxRegKey::DeleteSelf()
// now delete this key itself // now delete this key itself
Close(); 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 && if ( m_dwLastError != ERROR_SUCCESS &&
m_dwLastError != ERROR_FILE_NOT_FOUND ) { m_dwLastError != ERROR_FILE_NOT_FOUND ) {
wxLogSysError(m_dwLastError, _("Can't delete key '%s'"), wxLogSysError(m_dwLastError, _("Can't delete key '%s'"),
@@ -803,7 +838,7 @@ bool wxRegKey::HasSubKey(const wxString& szKey) const
if ( !CONST_CAST Open(Read) ) if ( !CONST_CAST Open(Read) )
return false; 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, m_dwLastError = RegSetValueEx((HKEY) m_hKey,
RegValueStr(szValue), RegValueStr(szValue),
(DWORD) RESERVED, REG_SZ, (DWORD) RESERVED, REG_SZ,
(RegString)strValue.wx_str(), (RegString)strValue.t_str(),
(strValue.Len() + 1)*sizeof(wxChar)); (strValue.Len() + 1)*sizeof(wxChar));
if ( m_dwLastError == ERROR_SUCCESS ) if ( m_dwLastError == ERROR_SUCCESS )
return true; 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! // don't close this key itself for the case of empty szKey!
if ( szKey.empty() ) if ( szKey.empty() )
@@ -1422,7 +1459,8 @@ bool KeyExists(WXHKEY hRootKey, const wxString& szKey)
(HKEY)hRootKey, (HKEY)hRootKey,
szKey.t_str(), szKey.t_str(),
RESERVED, 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 &hkeyDummy
) == ERROR_SUCCESS ) ) == 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 GetFullName(const wxRegKey *pKey, const wxString& szValue)
{ {
wxString str(pKey->GetName()); wxString str(pKey->GetName());