diff options
Diffstat (limited to '')
| -rw-r--r-- | src/dirinfo.c | 2 | ||||
| -rw-r--r-- | src/posix-util.c | 7 | ||||
| -rw-r--r-- | src/sys-util.h | 13 | ||||
| -rw-r--r-- | src/w32-io.c | 20 | ||||
| -rw-r--r-- | src/w32-util.c | 105 | 
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 | 
