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: 29
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: 80
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: 1101
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: 1101
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