* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * License along with this program; if not, see <https://www.gnu.org/licenses/>.
**/
#ifdef HAVE_CONFIG_H
# define F_OK 0
#endif
+/* The Registry key used by GNUPG. */
+#ifdef _WIN64
+# define GNUPG_REGKEY_2 "Software\\Wow6432Node\\GNU\\GnuPG"
+#else
+# define GNUPG_REGKEY_2 "Software\\GNU\\GnuPG"
+#endif
+#ifdef _WIN64
+# define GNUPG_REGKEY_3 "Software\\Wow6432Node\\GnuPG"
+#else
+# define GNUPG_REGKEY_3 "Software\\GnuPG"
+#endif
DEFINE_STATIC_LOCK (get_path_lock);
binaries. The are set only once by gpgme_set_global_flag. */
static char *default_gpg_name;
static char *default_gpgconf_name;
-
+/* If this variable is not NULL the value is assumed to be the
+ installation directory. The variable may only be set once by
+ gpgme_set_global_flag and accessed by _gpgme_get_inst_dir. */
+static char *override_inst_dir;
#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW
dlopen (const char * name, int flag)
{
void * hd = LoadLibrary (name);
+
+ (void)flag;
return hd;
}
{
static char *inst_dir;
+ if (override_inst_dir)
+ return override_inst_dir;
+
LOCK (get_path_lock);
if (!inst_dir)
{
{
char *result;
- result = malloc (strlen (dir) + 1 + strlen (name) + 1);
+ result = _gpgme_strconcat (dir, "\\", name, NULL);
if (!result)
return NULL;
- strcpy (stpcpy (stpcpy (result, dir), "\\"), name);
if (access (result, F_OK))
{
free (result);
char path[MAX_PATH];
char *result = NULL;
- /* See http://wiki.tcl.tk/17492 for details on compatibility. */
+ /* See http://wiki.tcl.tk/17492 for details on compatibility.
+
+ We First try the generic place and then fallback to the x86
+ (i.e. 32 bit) place. This will prefer a 64 bit of the program
+ over a 32 bit version on 64 bit Windows if installed. */
if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0))
{
- result = malloc (strlen (path) + 1 + strlen (name) + 1);
- if (result)
+ result = _gpgme_strconcat (path, "\\", name, NULL);
+ if (result && access (result, F_OK))
{
- strcpy (stpcpy (stpcpy (result, path), "\\"), name);
- if (access (result, F_OK))
- {
- free (result);
- result = NULL;
- }
+ free (result);
+ result = NULL;
+ }
+ }
+ if (!result
+ && SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
+ {
+ result = _gpgme_strconcat (path, "\\", name, NULL);
+ if (result && access (result, F_OK))
+ {
+ free (result);
+ result = NULL;
}
}
return result;
{
if (!default_gpg_name)
{
- default_gpg_name = malloc (strlen (name) + 5);
+ default_gpg_name = _gpgme_strconcat (name, ".exe", NULL);
if (default_gpg_name)
- {
- strcpy (stpcpy (default_gpg_name, name), ".exe");
- replace_slashes (default_gpg_name);
- }
+ replace_slashes (default_gpg_name);
}
return !default_gpg_name;
}
{
if (!default_gpgconf_name)
{
- default_gpgconf_name = malloc (strlen (name) + 5);
+ default_gpgconf_name = _gpgme_strconcat (name, ".exe", NULL);
if (default_gpgconf_name)
+ replace_slashes (default_gpgconf_name);
+ }
+ return !default_gpgconf_name;
+}
+
+
+/* Set the override installation directory. This function may only be
+ called by gpgme_set_global_flag. Returns 0 on success. */
+int
+_gpgme_set_override_inst_dir (const char *dir)
+{
+ if (!override_inst_dir)
+ {
+ override_inst_dir = strdup (dir);
+ if (override_inst_dir)
{
- strcpy (stpcpy (default_gpgconf_name, name), ".exe");
- replace_slashes (default_gpgconf_name);
+ replace_slashes (override_inst_dir);
+ /* Remove a trailing slash. */
+ if (*override_inst_dir
+ && override_inst_dir[strlen (override_inst_dir)-1] == '\\')
+ override_inst_dir[strlen (override_inst_dir)-1] = 0;
}
}
- return !default_gpgconf_name;
+ return !override_inst_dir;
}
char *dir;
dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
- "Software\\GNU\\GnuPG",
+ GNUPG_REGKEY_2,
"Install Directory");
if (dir)
{
gpgconf = find_program_at_standard_place (name2);
}
- /* 3. Try to find gpgconf.exe using that ancient registry key. This
- should eventually be removed. */
+ /* 3. Try to find gpgconf.exe using the Windows registry. */
if (!gpgconf)
{
char *dir;
- dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
- "Software\\GNU\\GnuPG",
+ dir = read_w32_registry_string (NULL,
+ GNUPG_REGKEY_2,
"Install Directory");
+ if (!dir)
+ {
+ char *tmp = read_w32_registry_string (NULL,
+ GNUPG_REGKEY_3,
+ "Install Directory");
+ if (tmp)
+ {
+ dir = _gpgme_strconcat (tmp, "\\bin", NULL);
+ free (tmp);
+ if (!dir)
+ return NULL;
+ }
+ }
if (dir)
{
gpgconf = find_program_in_dir (dir, name);
gpgconf = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
}
+ /* 5. Try to find gpgconf.exe relative to us. */
+ if (!gpgconf && inst_dir)
+ {
+ char *dir = _gpgme_strconcat (inst_dir, "\\..\\..\\GnuPG\\bin");
+ gpgconf = find_program_in_dir (dir, name);
+ free (dir);
+ }
+
/* 5. Print a debug message if not found. */
if (!gpgconf)
_gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",name);
does not exist at the time of the call to mkstemp. TMPL is
overwritten with the result. */
static int
-mkstemp (char *tmpl)
+my_mkstemp (char *tmpl)
{
int len;
char *XXXXXX;
}
}
- tmpname = malloc (strlen (tmp) + 13 + 1);
+ tmpname = _gpgme_strconcat (tmp, "\\gpgme-XXXXXX", NULL);
if (!tmpname)
return -1;
- strcpy (stpcpy (tmpname, tmp), "\\gpgme-XXXXXX");
- *fd = mkstemp (tmpname);
- if (fd < 0)
+ *fd = my_mkstemp (tmpname);
+ if (*fd < 0)
{
free (tmpname);
return -1;