Add helpers to store string map in registry
authorAndre Heinecke <aheinecke@intevation.de>
Mon, 5 Mar 2018 10:45:51 +0000 (11:45 +0100)
committerAndre Heinecke <aheinecke@intevation.de>
Mon, 5 Mar 2018 10:45:51 +0000 (11:45 +0100)
* src/common.c (store_extension_subkey_value): New.
(GPGOL_REGPATH): Move into header.
* src/common.h: Expose store_extension_subkey_value.
* src/cpphelp.cpp (get_registry_subkeys): New.
(gpgol_split): New Helper.
* src/cpphelp.h: Update accordingly.

src/common.c
src/common.h
src/cpphelp.cpp
src/cpphelp.h

index 8997b16..adda352 100644 (file)
@@ -40,9 +40,6 @@
 
 #include "dialogs.h"
 
-/* Registry path to store plugin settings */
-#define GPGOL_REGPATH "Software\\GNU\\GpgOL"
-
 HINSTANCE glob_hinst = NULL;
 
 void
@@ -1178,3 +1175,16 @@ load_extension_value (const char *key, char **val)
 {
   return load_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val);
 }
+
+int
+store_extension_subkey_value (const char *subkey,
+                              const char *key,
+                              const char *val)
+{
+  int ret;
+  char *path;
+  gpgrt_asprintf (&path, "%s\\%s", GPGOL_REGPATH, subkey);
+  ret = store_config_value (HKEY_CURRENT_USER, path, key, val);
+  xfree (path);
+  return ret;
+}
index ed7b87a..c8e32df 100644 (file)
@@ -39,6 +39,9 @@
 # define MIME_UI_DEFAULT 0
 #endif
 
+/* Registry path to store plugin settings */
+#define GPGOL_REGPATH "Software\\GNU\\GpgOL"
+
 #ifdef __cplusplus
 extern "C" {
 #if 0
@@ -60,6 +63,11 @@ const char *default_homedir (void);
 char *get_data_dir (void);
 char *get_gpg4win_dir (void);
 
+int store_extension_value (const char *key, const char *val);
+int store_extension_subkey_value (const char *subkey, const char *key,
+                                  const char *val);
+int load_extension_value (const char *key, char **val);
+
 /* Get a temporary filename with and its name */
 wchar_t *get_tmp_outfile (wchar_t *name, HANDLE *outHandle);
 
@@ -81,8 +89,6 @@ const char *get_pubkey_algo_str (gpgme_pubkey_algo_t id);
 
 /*-- config-dialog.c --*/
 void config_dialog_box (HWND parent);
-int store_extension_value (const char *key, const char *val);
-int load_extension_value (const char *key, char **val);
 
 /*-- verify-dialog.c --*/
 int verify_dialog_box (gpgme_protocol_t protocol,
index 85c8db3..8d38feb 100644 (file)
 
 #include "config.h"
 
-#include <algorithm>
 #include "cpphelp.h"
 
+#include <algorithm>
+#include <sstream>
+#include <vector>
+#include <iterator>
+
 #include "common.h"
 
 #include <gpgme++/context.h>
 #include <gpgme++/error.h>
 #include <gpgme++/configuration.h>
 
+#include <windows.h>
+
 void
 release_cArray (char **carray)
 {
@@ -111,3 +117,110 @@ in_de_vs_mode()
   vs_mode = false;
   return false;
 }
+
+std::map<std::string, std::string>
+get_registry_subkeys (const char *path)
+{
+  HKEY theKey;
+  std::map<std::string, std::string> ret;
+
+  std::string regPath = GPGOL_REGPATH;
+  regPath += "\\";
+  regPath += path;
+
+  if (RegOpenKeyEx (HKEY_CURRENT_USER,
+                    regPath.c_str (),
+                    0, KEY_ENUMERATE_SUB_KEYS | KEY_READ,
+                    &theKey) != ERROR_SUCCESS)
+    {
+      TRACEPOINT;
+      return ret;
+    }
+
+  DWORD values = 0,
+        maxValueName = 0,
+        maxValueLen = 0;
+
+  DWORD err = RegQueryInfoKey (theKey,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               &values,
+                               &maxValueName,
+                               &maxValueLen,
+                               nullptr,
+                               nullptr);
+
+  if (err != ERROR_SUCCESS)
+    {
+      TRACEPOINT;
+      RegCloseKey (theKey);
+      return ret;
+    }
+
+  /* Add space for NULL */
+  maxValueName++;
+  maxValueLen++;
+
+  char name[maxValueName + 1];
+  char value[maxValueLen + 1];
+  for (int i = 0; i < values; i++)
+    {
+      DWORD nameLen = maxValueName;
+      err = RegEnumValue (theKey, i,
+                          name,
+                          &nameLen,
+                          nullptr,
+                          nullptr,
+                          nullptr,
+                          nullptr);
+
+      if (err != ERROR_SUCCESS)
+        {
+          TRACEPOINT;
+          continue;
+        }
+
+      DWORD type;
+      DWORD valueLen = maxValueLen;
+      err = RegQueryValueEx (theKey, name,
+                             NULL, &type,
+                             (BYTE*)value, &valueLen);
+
+      if (err != ERROR_SUCCESS)
+        {
+          TRACEPOINT;
+          continue;
+        }
+      if (type != REG_SZ)
+        {
+          TRACEPOINT;
+          continue;
+        }
+      ret.insert (std::make_pair (std::string (name, nameLen),
+                                  std::string (value, valueLen)));
+    }
+  RegCloseKey (theKey);
+  return ret;
+}
+
+template<typename Out> void
+internal_split (const std::string &s, char delim, Out result) {
+  std::stringstream ss(s);
+  std::string item;
+  while (std::getline (ss, item, delim))
+    {
+      *(result++) = item;
+    }
+}
+
+std::vector<std::string>
+gpgol_split (const std::string &s, char delim)
+{
+  std::vector<std::string> elems;
+  internal_split (s, delim, std::back_inserter (elems));
+  return elems;
+}
index bbf68e0..51ffe80 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <string>
 #include <vector>
+#include <map>
 
 /* Stuff that should be in common but is c++ so it does not fit in there. */
 
@@ -39,4 +40,8 @@ char **vector_to_cArray (const std::vector<std::string> &vec);
 /* Check if we are in de_vs mode. */
 bool in_de_vs_mode ();
 
+/* Get a map of all subkey value pairs in a registry key */
+std::map<std::string, std::string> get_registry_subkeys (const char *path);
+
+std::vector<std::string> gpgol_split(const std::string &s, char delim);
 #endif // CPPHELP_H