diff options
Diffstat (limited to 'src/w32-util.c')
| -rw-r--r-- | src/w32-util.c | 175 | 
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); | 
