aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dirinfo.c2
-rw-r--r--src/posix-util.c7
-rw-r--r--src/sys-util.h13
-rw-r--r--src/w32-io.c20
-rw-r--r--src/w32-util.c105
5 files changed, 128 insertions, 19 deletions
diff --git a/src/dirinfo.c b/src/dirinfo.c
index d4811990..5db61093 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -260,7 +260,7 @@ get_gpgconf_item (int what)
char *pgmname;
pgmname = dirinfo.disable_gpgconf? NULL : _gpgme_get_gpgconf_path ();
- if (pgmname && access (pgmname, F_OK))
+ if (pgmname && _gpgme_access (pgmname, F_OK))
{
_gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpgconf='%s' [not installed]\n", pgmname);
diff --git a/src/posix-util.c b/src/posix-util.c
index 881856ca..cddb31f4 100644
--- a/src/posix-util.c
+++ b/src/posix-util.c
@@ -157,3 +157,10 @@ _gpgme_allow_set_foreground_window (pid_t pid)
(void)pid;
/* Not needed. */
}
+
+/* See w32-util.c */
+int
+_gpgme_access (const char *path, int mode)
+{
+ return access (path, mode);
+}
diff --git a/src/sys-util.h b/src/sys-util.h
index 6cb22245..e5376133 100644
--- a/src/sys-util.h
+++ b/src/sys-util.h
@@ -28,9 +28,22 @@ int _gpgme_set_override_inst_dir (const char *dir);
char *_gpgme_get_gpg_path (void);
char *_gpgme_get_gpgconf_path (void);
+int _gpgme_access (const char *path_utf8, int mode);
+
#ifdef HAVE_W32_SYSTEM
const char *_gpgme_get_inst_dir (void);
void _gpgme_w32_cancel_synchronous_io (HANDLE thread);
+/* See CreateProcessA returns true on success */
+int _gpgme_create_process_utf8 (const char *application_name_utf8,
+ char *command_line_utf8,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ BOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ void *lpEnvironment,
+ char *working_directory_utf8,
+ LPSTARTUPINFOA lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation);
#endif
#endif /* SYS_UTIL_H */
diff --git a/src/w32-io.c b/src/w32-io.c
index 67f93baa..c5c21f59 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -1481,16 +1481,16 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
free (tmp_name);
return TRACE_SYSRES (-1);
}
- if (!CreateProcessA (spawnhelper,
- arg_string,
- &sec_attr, /* process security attributes */
- &sec_attr, /* thread security attributes */
- FALSE, /* inherit handles */
- cr_flags, /* creation flags */
- NULL, /* environment */
- NULL, /* use current drive/directory */
- &si, /* startup information */
- &pi)) /* returns process information */
+ if (!_gpgme_create_process_utf8 (spawnhelper,
+ arg_string,
+ &sec_attr, /* process security attributes */
+ &sec_attr, /* thread security attributes */
+ FALSE, /* inherit handles */
+ cr_flags, /* creation flags */
+ NULL, /* environment */
+ NULL, /* use current drive/directory */
+ &si, /* startup information */
+ &pi)) /* returns process information */
{
int lasterr = (int)GetLastError ();
TRACE_LOG ("CreateProcess failed: ec=%d", lasterr);
diff --git a/src/w32-util.c b/src/w32-util.c
index 9802d9cc..eced1396 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -168,6 +168,48 @@ wchar_to_utf8 (const wchar_t *string)
}
+/* Return a malloced wide char string from an UTF-8 encoded input
+ string STRING. Caller must free this value. On failure returns
+ NULL; caller may use GetLastError to get the actual error number.
+ Calling this function with STRING set to NULL is not defined. */
+static wchar_t *
+utf8_to_wchar (const char *string)
+{
+ int n;
+ wchar_t *result;
+
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+ if (n < 0)
+ return NULL;
+
+ result = (wchar_t *) malloc ((n+1) * sizeof *result);
+ if (!result)
+ return NULL;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ if (n < 0)
+ {
+ free (result);
+ return NULL;
+ }
+ return result;
+}
+
+
+/* Same as utf8_to_wchar but calling it with NULL returns
+ NULL. So a return value of NULL only indicates failure
+ if STRING is not set to NULL. */
+static wchar_t *
+utf8_to_wchar0 (const char *string)
+{
+ if (!string)
+ return NULL;
+
+ return utf8_to_wchar (string);
+}
+
+
/* Replace all forward slashes by backslashes. */
static void
replace_slashes (char *string)
@@ -395,7 +437,7 @@ find_program_in_dir (const char *dir, const char *name)
if (!result)
return NULL;
- if (access (result, F_OK))
+ if (_gpgme_access (result, F_OK))
{
free (result);
return NULL;
@@ -408,7 +450,7 @@ find_program_in_dir (const char *dir, const char *name)
static char *
find_program_at_standard_place (const char *name)
{
- char path[MAX_PATH];
+ wchar_t path[MAX_PATH];
char *result = NULL;
/* See https://wiki.tcl-lang.org/page/Getting+Windows+%22special+folders%22+with+Ffidl for details on compatibility.
@@ -416,20 +458,24 @@ find_program_at_standard_place (const char *name)
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))
+ if (SHGetSpecialFolderPathW (NULL, path, CSIDL_PROGRAM_FILES, 0))
{
- result = _gpgme_strconcat (path, "\\", name, NULL);
- if (result && access (result, F_OK))
+ char *utf8_path = wchar_to_utf8 (path);
+ result = _gpgme_strconcat (utf8_path, "\\", name, NULL);
+ free (utf8_path);
+ if (result && _gpgme_access (result, F_OK))
{
free (result);
result = NULL;
}
}
if (!result
- && SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
+ && SHGetSpecialFolderPathW (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
{
- result = _gpgme_strconcat (path, "\\", name, NULL);
- if (result && access (result, F_OK))
+ char *utf8_path = wchar_to_utf8 (path);
+ result = _gpgme_strconcat (utf8_path, "\\", name, NULL);
+ free (utf8_path);
+ if (result && _gpgme_access (result, F_OK))
{
free (result);
result = NULL;
@@ -781,6 +827,49 @@ _gpgme_mkstemp (int *fd, char **name)
}
+/* Like access but using windows _waccess */
+int
+_gpgme_access (const char *path, int mode)
+{
+ wchar_t *u16 = utf8_to_wchar0 (path);
+ int r = _waccess (u16, F_OK);
+
+ free(u16);
+ return r;
+}
+
+/* Like CreateProcessA but mapping the arguments to wchar API */
+int _gpgme_create_process_utf8 (const char *application_name_utf8,
+ char *command_line_utf8,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ BOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ void *lpEnvironment,
+ char *working_directory_utf8,
+ LPSTARTUPINFOA lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation)
+{
+ BOOL ret;
+ wchar_t *application_name = utf8_to_wchar0 (application_name_utf8);
+ wchar_t *command_line = utf8_to_wchar0 (command_line_utf8);
+ wchar_t *working_directory = utf8_to_wchar0 (working_directory_utf8);
+
+ ret = CreateProcessW (application_name,
+ command_line,
+ lpProcessAttributes,
+ lpThreadAttributes,
+ bInheritHandles,
+ dwCreationFlags,
+ lpEnvironment,
+ working_directory,
+ lpStartupInfo,
+ lpProcessInformation);
+ free (application_name);
+ free (command_line);
+ free (working_directory);
+ return ret;
+}
/* Entry point called by the DLL loader. */
#ifdef DLL_EXPORT