aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32-util.c
diff options
context:
space:
mode:
authorJustus Winter <[email protected]>2016-05-10 11:03:34 +0000
committerJustus Winter <[email protected]>2016-05-10 11:03:34 +0000
commitf531608539b45f0bbd036f430943b390ec21aa65 (patch)
tree56cf3f4db0c38e668645668ebb3dec418bed77a5 /src/w32-util.c
parentMore GTK2 removal (diff)
parentAllow cc to detect missing cases in a switch. (diff)
downloadgpgme-f531608539b45f0bbd036f430943b390ec21aa65.tar.gz
gpgme-f531608539b45f0bbd036f430943b390ec21aa65.zip
Merge branch 'master' into justus/pyme3
Diffstat (limited to 'src/w32-util.c')
-rw-r--r--src/w32-util.c175
1 files changed, 111 insertions, 64 deletions
diff --git a/src/w32-util.c b/src/w32-util.c
index daf3bd2d..a27955b5 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -85,7 +85,10 @@ static HMODULE my_hmodule;
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
@@ -347,6 +350,9 @@ _gpgme_get_inst_dir (void)
{
static char *inst_dir;
+ if (override_inst_dir)
+ return override_inst_dir;
+
LOCK (get_path_lock);
if (!inst_dir)
{
@@ -398,47 +404,18 @@ find_program_in_dir (const char *dir, const char *name)
static char *
-find_program_in_inst_dir (const char *inst_dir, const char *name)
-{
- char *result;
- char *dir;
-
- /* If an installation directory has been passed, this overrides a
- location given by the registry. The idea here is that we prefer
- a program installed alongside with gpgme. We don't want the
- registry to override this to have a better isolation of an gpgme
- aware applications for other effects. Note that the "Install
- Directory" registry item has been used for ages in Gpg4win and
- earlier GnuPG windows installers. It is technically not anymore
- required. */
- if (inst_dir)
- {
- result = find_program_in_dir (inst_dir, name);
- if (result)
- return result;
- }
-
- dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
- "Software\\GNU\\GnuPG",
- "Install Directory");
- if (dir)
- {
- result = find_program_in_dir (dir, name);
- free (dir);
- return result;
- }
- return NULL;
-}
-
-
-static char *
find_program_at_standard_place (const char *name)
{
char path[MAX_PATH];
char *result = NULL;
- /* See http://wiki.tcl.tk/17492 for details on compatibility. */
- if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0))
+ /* 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)
+ || SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
{
result = malloc (strlen (path) + 1 + strlen (name) + 1);
if (result)
@@ -490,30 +467,73 @@ _gpgme_set_default_gpgconf_name (const char *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 = malloc (strlen (dir) + 1);
+ if (override_inst_dir)
+ {
+ strcpy (override_inst_dir, dir);
+ 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 !override_inst_dir;
+}
+
+
/* Return the full file name of the GPG binary. This function is used
- if gpgconf was not found and thus it can be assumed that gpg2 is
+ iff gpgconf was not found and thus it can be assumed that gpg2 is
not installed. This function is only called by get_gpgconf_item
and may not be called concurrently. */
char *
_gpgme_get_gpg_path (void)
{
- char *gpg;
- const char *inst_dir, *name;
+ char *gpg = NULL;
+ const char *name, *inst_dir;
+ name = default_gpg_name? get_basename (default_gpg_name) : "gpg.exe";
+
+ /* 1. Try to find gpg.exe in the installation directory of gpgme. */
inst_dir = _gpgme_get_inst_dir ();
- gpg = find_program_in_inst_dir
- (inst_dir,
- default_gpg_name? get_basename (default_gpg_name) : "gpg.exe");
+ if (inst_dir)
+ {
+ gpg = find_program_in_dir (inst_dir, name);
+ }
+
+ /* 2. Try to find gpg.exe using that ancient registry key. */
+ if (!gpg)
+ {
+ char *dir;
+
+ dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
+ "Software\\GNU\\GnuPG",
+ "Install Directory");
+ if (dir)
+ {
+ gpg = find_program_in_dir (dir, name);
+ free (dir);
+ }
+ }
+
+ /* 3. Try to find gpg.exe below CSIDL_PROGRAM_FILES. */
if (!gpg)
{
- name = (default_gpg_name? default_gpg_name
- /* */ : "GNU\\GnuPG\\gpg.exe");
+ name = default_gpg_name? default_gpg_name : "GNU\\GnuPG\\gpg.exe";
gpg = find_program_at_standard_place (name);
- if (!gpg)
- _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found",
- name);
}
+ /* 4. Print a debug message if not found. */
+ if (!gpg)
+ _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found", name);
+
return gpg;
}
@@ -523,22 +543,52 @@ _gpgme_get_gpg_path (void)
char *
_gpgme_get_gpgconf_path (void)
{
- char *gpgconf;
+ char *gpgconf = NULL;
const char *inst_dir, *name;
+ name = default_gpgconf_name? get_basename(default_gpgconf_name):"gpgconf.exe";
+
+ /* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
inst_dir = _gpgme_get_inst_dir ();
- gpgconf = find_program_in_inst_dir
- (inst_dir,
- default_gpgconf_name? get_basename (default_gpgconf_name) : "gpgconf.exe");
+ if (inst_dir)
+ {
+ gpgconf = find_program_in_dir (inst_dir, name);
+ }
+
+ /* 2. Try to find gpgconf.exe from GnuPG >= 2.1 below CSIDL_PROGRAM_FILES. */
if (!gpgconf)
{
- name = (default_gpgconf_name? default_gpgconf_name
- /* */ : "GNU\\GnuPG\\gpgconf.exe");
- gpgconf = find_program_at_standard_place (name);
- if (!gpgconf)
- _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",
- name);
+ const char *name2 = (default_gpgconf_name ? default_gpgconf_name
+ /**/ : "GnuPG\\bin\\gpgconf.exe");
+ gpgconf = find_program_at_standard_place (name2);
}
+
+ /* 3. Try to find gpgconf.exe using that ancient registry key. This
+ should eventually be removed. */
+ if (!gpgconf)
+ {
+ char *dir;
+
+ dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
+ "Software\\GNU\\GnuPG",
+ "Install Directory");
+ if (dir)
+ {
+ gpgconf = find_program_in_dir (dir, name);
+ free (dir);
+ }
+ }
+
+ /* 4. Try to find gpgconf.exe from Gpg4win below CSIDL_PROGRAM_FILES. */
+ if (!gpgconf)
+ {
+ gpgconf = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
+ }
+
+ /* 5. Print a debug message if not found. */
+ if (!gpgconf)
+ _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",name);
+
return gpgconf;
}
@@ -552,10 +602,7 @@ _gpgme_get_w32spawn_path (void)
inst_dir = _gpgme_get_inst_dir ();
LOCK (get_path_lock);
if (!w32spawn_program)
- w32spawn_program = find_program_in_inst_dir (inst_dir,"gpgme-w32spawn.exe");
- if (!w32spawn_program)
- w32spawn_program
- = find_program_at_standard_place ("GNU\\GnuPG\\gpgme-w32spawn.exe");
+ w32spawn_program = find_program_in_dir (inst_dir, "gpgme-w32spawn.exe");
UNLOCK (get_path_lock);
return w32spawn_program;
}
@@ -600,7 +647,7 @@ static const char letters[] =
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;
@@ -708,7 +755,7 @@ _gpgme_mkstemp (int *fd, char **name)
if (!tmpname)
return -1;
strcpy (stpcpy (tmpname, tmp), "\\gpgme-XXXXXX");
- *fd = mkstemp (tmpname);
+ *fd = my_mkstemp (tmpname);
if (fd < 0)
{
free (tmpname);