Overview
Features
Download
Documentation
Community
Add-Ons & Services

Patch for WinRegistryKey to read 32-bit and 64-bit keys

General discussion regarding the development of POCO for contributors.

Patch for WinRegistryKey to read 32-bit and 64-bit keys

Postby SalvorHardin » 27 Jan 2011, 17:36

The attached patches (diff -Nu) allow us to read both 32-bit and 64-bit registry paths from the same Windows application.

Without this patch, it is not possible to read the registry to obtain a complete list of uninstallable apps on Windows 64-bit (because 32-bit installers write to one branch and 64-bit write to another branch). A 32-bit app cannot read from the 64-bit branch without the extra parameter, and 64-bit apps should not read 32-bit branch without the extra parameter.

The patch is backwards compatible and tested on Windows 7 64-bit with a 32-bit app. It simply adds an optional parameter to constructor of WinRegistryKey.

I was unable to attach (".txt" and ".patch" extensions were not allowed), so I'll just embed here:
Code: Select all
--- WinRegistryKey.h.orig   2011-01-03 22:30:31.889648400 -0600
+++ WinRegistryKey.h   2011-01-16 16:58:47.992578200 -0600
@@ -67,7 +67,7 @@
      REGT_DWORD = 4
   };

-   WinRegistryKey(const std::string& key, bool readOnly = false);
+   WinRegistryKey(const std::string& key, bool readOnly = false, unsigned long extraSam = 0);
      /// Creates the WinRegistryKey.
      ///
      /// The key must start with one of the root key names
@@ -77,7 +77,7 @@
      /// is available and any attempt to write to the registry will
      /// result in an exception.

-   WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly = false);
+   WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly = false, unsigned long extraSam = 0);
      /// Creates the WinRegistryKey.
      ///
      /// If readOnly is true, then only read access to the registry
@@ -162,6 +162,7 @@
   std::string _subKey;
   HKEY        _hKey;
   bool        _readOnly;
+   unsigned long _extraSam;
};


Code: Select all
--- WinRegistryKey.cpp.orig   2011-01-03 22:30:32.231445300 -0600
+++ WinRegistryKey.cpp   2011-01-16 17:02:19.300195400 -0600
@@ -50,9 +50,10 @@
namespace Util {


-WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly):
+WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly, unsigned long extraSam):
   _hKey(0),
-   _readOnly(readOnly)
+   _readOnly(readOnly),
+   _extraSam(extraSam)
{
   std::string::size_type pos = key.find('\\');
   if (pos != std::string::npos)
@@ -65,11 +66,12 @@
}


-WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly):
+WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly, unsigned long extraSam):
   _hRootKey(hRootKey),
   _subKey(subKey),
   _hKey(0),
-   _readOnly(readOnly)
+   _readOnly(readOnly),
+   _extraSam(extraSam)
{
}

@@ -282,13 +284,13 @@
#if defined(POCO_WIN32_UTF8)
   std::wstring usubKey;
   Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
-   if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+   if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
   {
      RegCloseKey(hKey);
      return true;
   }
#else
-   if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+   if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &hKey) != ERROR_SUCCESS)
   {
      RegCloseKey(hKey);
      return true;
@@ -327,7 +329,7 @@
#if defined(POCO_WIN32_UTF8)
   std::wstring usubKey;
   Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
-   if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+   if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
   {
      std::wstring uname;
      Poco::UnicodeConverter::toUTF16(name, uname);
@@ -335,7 +337,7 @@
      RegCloseKey(hKey);
   }
#else
-   if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+   if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &hKey) != ERROR_SUCCESS)
   {
      exists = RegQueryValueEx(hKey, name.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
      RegCloseKey(hKey);
@@ -354,23 +356,23 @@
      Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
      if (_readOnly)
      {
-         if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &_hKey) != ERROR_SUCCESS)
+         if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &_hKey) != ERROR_SUCCESS)
            throw NotFoundException("Cannot open registry key: ", key());
      }
      else
      {
-         if (RegCreateKeyExW(_hRootKey, usubKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
+         if (RegCreateKeyExW(_hRootKey, usubKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | _extraSam, NULL, &_hKey, NULL) != ERROR_SUCCESS)
            throw SystemException("Cannot open registry key: ", key());
      }
#else
      if (_readOnly)
      {
-         if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &_hKey) != ERROR_SUCCESS)
+         if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &_hKey) != ERROR_SUCCESS)
            throw NotFoundException("Cannot open registry key: ", key());
      }
      else
      {
-         if (RegCreateKeyEx(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
+         if (RegCreateKeyEx(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | _extraSam, NULL, &_hKey, NULL) != ERROR_SUCCESS)
            throw SystemException("Cannot open registry key: ", key());
      }
#endif
SalvorHardin
 
Posts: 30
Joined: 24 Aug 2010, 14:47

Re: Patch for WinRegistryKey to read 32-bit and 64-bit keys

Postby marlowabnp » 25 Aug 2012, 23:30

SalvorHardin wrote:The attached patches (diff -Nu) allow us to read both 32-bit and 64-bit registry paths from the same Windows application.

Without this patch, it is not possible to read the registry to obtain a complete list of uninstallable apps on Windows 64-bit (because 32-bit installers write to one branch and 64-bit write to another branch). A 32-bit app cannot read from the 64-bit branch without the extra parameter, and 64-bit apps should not read 32-bit branch without the extra parameter.

The patch is backwards compatible and tested on Windows 7 64-bit with a 32-bit app. It simply adds an optional parameter to constructor of WinRegistryKey.

Sounds great! Has this patch been included? It was submitted quite some time ago...
marlowabnp
 
Posts: 74
Joined: 08 Nov 2010, 17:29

Re: Patch for WinRegistryKey to read 32-bit and 64-bit keys

Postby alex » 26 Aug 2012, 02:51

Filed in SF Tracker. Will be in 1.5
alex
 
Posts: 975
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Patch for WinRegistryKey to read 32-bit and 64-bit keys

Postby alex » 26 Aug 2012, 04:28

Actually, this was added in 1.4.3.
alex
 
Posts: 975
Joined: 11 Jul 2006, 16:27
Location: United_States


Return to Contributors

Who is online

Users browsing this forum: No registered users and 1 guest

cron