w32: Try to locate gpg in the gpgme installation dir.
* src/w32-util.c (my_hmodule): New. (wchar_to_utf8): New. (DllMain): New. (_gpgme_get_inst_dir): New. (find_program_in_dir): New. (find_program_in_inst_dir): Add arg INST_DIR. (_gpgme_get_gpg_path): Get inst_dir before acquiring the lock. (_gpgme_get_gpgconf_path): Ditto. (_gpgme_get_g13_path): Ditto. (_gpgme_get_w32spawn_path): Ditto.
This commit is contained in:
parent
393a9471f2
commit
3881ea4e83
229
src/w32-util.c
229
src/w32-util.c
@ -1,24 +1,23 @@
|
||||
/* w32-util.c - Utility functions for the W32 API
|
||||
Copyright (C) 1999 Free Software Foundation, Inc
|
||||
Copyright (C) 2001 Werner Koch (dd9jn)
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2007 g10 Code GmbH
|
||||
|
||||
This file is part of GPGME.
|
||||
|
||||
GPGME is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
GPGME is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc
|
||||
* Copyright (C) 2001 Werner Koch (dd9jn)
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2007, 2013 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* GPGME is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* 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/>.
|
||||
**/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@ -75,6 +74,12 @@
|
||||
|
||||
DEFINE_STATIC_LOCK (get_path_lock);
|
||||
|
||||
/* The module handle of this DLL. If we are linked statically,
|
||||
dllmain does not exists and thus the value of my_hmodule will be
|
||||
NULL. The effect is that a GetModuleFileName always returns the
|
||||
file name of the DLL or executable which contains the gpgme code. */
|
||||
static HMODULE my_hmodule;
|
||||
|
||||
|
||||
#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW
|
||||
|
||||
@ -112,6 +117,39 @@ dlclose (void * hd)
|
||||
}
|
||||
#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */
|
||||
|
||||
|
||||
/* Return a malloced string encoded in UTF-8 from the wide char input
|
||||
string STRING. Caller must free this value. Returns NULL and sets
|
||||
ERRNO on failure. Calling this function with STRING set to NULL is
|
||||
not defined. */
|
||||
static char *
|
||||
wchar_to_utf8 (const wchar_t *string)
|
||||
{
|
||||
int n;
|
||||
char *result;
|
||||
|
||||
n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
|
||||
if (n < 0)
|
||||
{
|
||||
gpg_err_set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = malloc (n+1);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
|
||||
if (n < 0)
|
||||
{
|
||||
free (result);
|
||||
gpg_err_set_errno (EINVAL);
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_allow_set_foreground_window (pid_t pid)
|
||||
{
|
||||
@ -270,51 +308,53 @@ read_w32_registry_string (const char *root, const char *dir, const char *name)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
find_program_in_registry (const char *name)
|
||||
/* Return the name of the directory with the gpgme DLL or the EXE (if
|
||||
statically linked). May return NULL on severe errors. */
|
||||
const char *
|
||||
_gpgme_get_inst_dir (void)
|
||||
{
|
||||
char *program = NULL;
|
||||
static char *inst_dir;
|
||||
|
||||
program = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", name);
|
||||
if (program)
|
||||
LOCK (get_path_lock);
|
||||
if (!inst_dir)
|
||||
{
|
||||
int i;
|
||||
wchar_t *moddir;
|
||||
|
||||
TRACE2 (DEBUG_CTX, "gpgme:find_program_in_registry", 0,
|
||||
"found %s in registry: `%s'", name, program);
|
||||
for (i = 0; program[i]; i++)
|
||||
{
|
||||
if (program[i] == '/')
|
||||
program[i] = '\\';
|
||||
}
|
||||
moddir = malloc ((MAX_PATH+5) * sizeof *moddir);
|
||||
if (moddir)
|
||||
{
|
||||
if (!GetModuleFileNameW (my_hmodule, moddir, MAX_PATH))
|
||||
*moddir = 0;
|
||||
if (!*moddir)
|
||||
gpg_err_set_errno (ENOENT);
|
||||
else
|
||||
{
|
||||
inst_dir = wchar_to_utf8 (moddir);
|
||||
if (inst_dir)
|
||||
{
|
||||
char *p = strrchr (inst_dir, '\\');
|
||||
if (p)
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
free (moddir);
|
||||
}
|
||||
}
|
||||
return program;
|
||||
UNLOCK (get_path_lock);
|
||||
return inst_dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static char *
|
||||
find_program_in_inst_dir (const char *name)
|
||||
find_program_in_dir (const char *dir, const char *name)
|
||||
{
|
||||
char *result = NULL;
|
||||
char *tmp;
|
||||
char *result;
|
||||
|
||||
tmp = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
|
||||
"Software\\GNU\\GnuPG",
|
||||
"Install Directory");
|
||||
if (!tmp)
|
||||
result = malloc (strlen (dir) + 1 + strlen (name) + 1);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
result = malloc (strlen (tmp) + 1 + strlen (name) + 1);
|
||||
if (!result)
|
||||
{
|
||||
free (tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (stpcpy (stpcpy (result, tmp), "\\"), name);
|
||||
free (tmp);
|
||||
strcpy (stpcpy (stpcpy (result, dir), "\\"), name);
|
||||
if (access (result, F_OK))
|
||||
{
|
||||
free (result);
|
||||
@ -325,6 +365,40 @@ find_program_in_inst_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 bu the registry. The idea here is that we prefer
|
||||
a 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)
|
||||
{
|
||||
@ -353,14 +427,12 @@ const char *
|
||||
_gpgme_get_gpg_path (void)
|
||||
{
|
||||
static char *gpg_program;
|
||||
const char *inst_dir;
|
||||
|
||||
inst_dir = _gpgme_get_inst_dir ();
|
||||
LOCK (get_path_lock);
|
||||
#if 0
|
||||
if (!gpg_program)
|
||||
gpg_program = find_program_in_registry ("gpgProgram");
|
||||
#endif
|
||||
if (!gpg_program)
|
||||
gpg_program = find_program_in_inst_dir ("gpg.exe");
|
||||
gpg_program = find_program_in_inst_dir (inst_dir, "gpg.exe");
|
||||
if (!gpg_program)
|
||||
gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe");
|
||||
UNLOCK (get_path_lock);
|
||||
@ -372,14 +444,12 @@ const char *
|
||||
_gpgme_get_gpgsm_path (void)
|
||||
{
|
||||
static char *gpgsm_program;
|
||||
const char *inst_dir;
|
||||
|
||||
inst_dir = _gpgme_get_inst_dir ();
|
||||
LOCK (get_path_lock);
|
||||
#if 0
|
||||
if (!gpgsm_program)
|
||||
gpgsm_program = find_program_in_registry ("gpgsmProgram");
|
||||
#endif
|
||||
if (!gpgsm_program)
|
||||
gpgsm_program = find_program_in_inst_dir ("gpgsm.exe");
|
||||
gpgsm_program = find_program_in_inst_dir (inst_dir, "gpgsm.exe");
|
||||
if (!gpgsm_program)
|
||||
gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");
|
||||
UNLOCK (get_path_lock);
|
||||
@ -391,14 +461,12 @@ const char *
|
||||
_gpgme_get_gpgconf_path (void)
|
||||
{
|
||||
static char *gpgconf_program;
|
||||
const char *inst_dir;
|
||||
|
||||
inst_dir = _gpgme_get_inst_dir ();
|
||||
LOCK (get_path_lock);
|
||||
#if 0
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program = find_program_in_registry ("gpgconfProgram");
|
||||
#endif
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program = find_program_in_inst_dir ("gpgconf.exe");
|
||||
gpgconf_program = find_program_in_inst_dir (inst_dir, "gpgconf.exe");
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program
|
||||
= find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
|
||||
@ -411,14 +479,12 @@ const char *
|
||||
_gpgme_get_g13_path (void)
|
||||
{
|
||||
static char *g13_program;
|
||||
const char *inst_dir;
|
||||
|
||||
inst_dir = _gpgme_get_inst_dir ();
|
||||
LOCK (get_path_lock);
|
||||
#if 0
|
||||
if (!g13_program)
|
||||
g13_program = find_program_in_registry ("g13Program");
|
||||
#endif
|
||||
if (!g13_program)
|
||||
g13_program = find_program_in_inst_dir ("g13.exe");
|
||||
g13_program = find_program_in_inst_dir (inst_dir, "g13.exe");
|
||||
if (!g13_program)
|
||||
g13_program = find_program_at_standard_place ("GNU\\GnuPG\\g13.exe");
|
||||
UNLOCK (get_path_lock);
|
||||
@ -453,10 +519,12 @@ const char *
|
||||
_gpgme_get_w32spawn_path (void)
|
||||
{
|
||||
static char *w32spawn_program;
|
||||
const char *inst_dir;
|
||||
|
||||
inst_dir = _gpgme_get_inst_dir ();
|
||||
LOCK (get_path_lock);
|
||||
if (!w32spawn_program)
|
||||
w32spawn_program = find_program_in_inst_dir ("gpgme-w32spawn.exe");
|
||||
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");
|
||||
@ -641,3 +709,18 @@ _gpgme_w32ce_get_debug_envvar (void)
|
||||
return tmp;
|
||||
}
|
||||
#endif /*HAVE_W32CE_SYSTEM*/
|
||||
|
||||
|
||||
/* Entry point called by the DLL loader. */
|
||||
#ifdef DLL_EXPORT
|
||||
int WINAPI
|
||||
DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
(void)reserved;
|
||||
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
my_hmodule = hinst;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /*DLL_EXPORT*/
|
||||
|
Loading…
Reference in New Issue
Block a user