1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Replace all calls to access by gnupg_access

* common/sysutils.c (gnupg_access): New.  Replace all calls to access
by this wrapper.
* common/homedir.c (w32_shgetfolderpath): Change to return UTF-8
directory name.
(standard_homedir): Adjust for change.
(w32_commondir, gnupg_cachedir): Ditto.
--

Also use SHGetFolderPathW instead of SHGetFolderPathA on Windows.

This is required to correctly handle non-ascii filenames on Windows.

GnuPG-bug-id: 5098
(cherry picked from commit c94ee1386e)
This commit is contained in:
Werner Koch 2020-10-20 10:43:55 +02:00
parent 25bec16d0b
commit dd5fd4a760
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
28 changed files with 163 additions and 115 deletions

View file

@ -117,14 +117,16 @@ w32_try_mkdir (const char *dir)
#endif
/* This is a helper function to load a Windows function from either of
one DLLs. */
/* This is a helper function to load and call a Windows function from
* either of one DLLs. On success an UTF-8 file name is returned.
* ERRNO is _not_ set on error. */
#ifdef HAVE_W32_SYSTEM
static HRESULT
w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
static char *
w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d)
{
static int initialized;
static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPWSTR);
wchar_t wfname[MAX_PATH];
if (!initialized)
{
@ -139,7 +141,7 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
handle = dlopen (dllnames[i], RTLD_LAZY);
if (handle)
{
func = dlsym (handle, "SHGetFolderPathA");
func = dlsym (handle, "SHGetFolderPathW");
if (!func)
{
dlclose (handle);
@ -149,10 +151,10 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
}
}
if (func)
return func (a,b,c,d,e);
if (func && func (a,b,c,d,wfname) >= 0)
return wchar_to_utf8 (wfname);
else
return -1;
return NULL;
}
#endif /*HAVE_W32_SYSTEM*/
@ -248,25 +250,17 @@ standard_homedir (void)
}
else
{
char path[MAX_PATH];
char *path;
/* It might be better to use LOCAL_APPDATA because this is
defined as "non roaming" and thus more likely to be kept
locally. For private keys this is desired. However,
given that many users copy private keys anyway forth and
back, using a system roaming services might be better
than to let them do it manually. A security conscious
user will anyway use the registry entry to have better
control. */
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0, path) >= 0)
path = w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0);
if (path)
{
char *tmp = xmalloc (strlen (path) + 6 +1);
strcpy (stpcpy (tmp, path), "\\gnupg");
dir = tmp;
dir = xstrconcat (path, "\\gnupg", NULL);
xfree (path);
/* Try to create the directory if it does not yet exists. */
if (access (dir, F_OK))
if (gnupg_access (dir, F_OK))
w32_try_mkdir (dir);
}
else
@ -360,10 +354,10 @@ check_portable_app (const char *dir)
char *fname;
fname = xstrconcat (dir, DIRSEP_S "gpgconf.exe", NULL);
if (!access (fname, F_OK))
if (!gnupg_access (fname, F_OK))
{
strcpy (fname + strlen (fname) - 3, "ctl");
if (!access (fname, F_OK))
if (!gnupg_access (fname, F_OK))
{
/* gpgconf.ctl file found. Record this fact. */
w32_portable_app = 1;
@ -440,7 +434,7 @@ w32_commondir (void)
if (!dir)
{
const char *rdir;
char path[MAX_PATH];
char *path;
/* Make sure that w32_rootdir has been called so that we are
able to check the portable application flag. The common dir
@ -450,19 +444,17 @@ w32_commondir (void)
if (w32_portable_app)
return rdir;
if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
NULL, 0, path) >= 0)
path = w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, NULL, 0);
if (path)
{
char *tmp = xmalloc (strlen (path) + 4 +1);
strcpy (stpcpy (tmp, path), "\\GNU");
dir = tmp;
dir = xstrconcat (path, "\\GNU", NULL);
/* No auto create of the directory. Either the installer or
the admin has to create these directories. */
* the admin has to create these directories. */
}
else
{
/* Ooops: Not defined - probably an old Windows version.
Use the installation directory instead. */
/* Folder not found or defined - probably an old Windows
* version. Use the installation directory instead. */
dir = xstrdup (rdir);
}
}
@ -903,7 +895,7 @@ gnupg_cachedir (void)
}
else
{
char path[MAX_PATH];
char *path;
const char *s1[] = { "GNU", "cache", "gnupg", NULL };
int s1_len;
const char **comp;
@ -912,8 +904,10 @@ gnupg_cachedir (void)
for (comp = s1; *comp; comp++)
s1_len += 1 + strlen (*comp);
if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0, path) >= 0)
path = w32_shgetfolderpath (NULL,
CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0);
if (path)
{
char *tmp = xmalloc (strlen (path) + s1_len + 1);
char *p;
@ -924,11 +918,12 @@ gnupg_cachedir (void)
p = stpcpy (p, "\\");
p = stpcpy (p, *comp);
if (access (tmp, F_OK))
if (gnupg_access (tmp, F_OK))
w32_try_mkdir (tmp);
}
dir = tmp;
xfree (path);
}
else
{
@ -1002,7 +997,7 @@ get_default_pinentry_name (int reset)
char *name2;
name2 = xstrconcat (names[i].rfnc (), names[i].name, NULL);
if (!access (name2, F_OK))
if (!gnupg_access (name2, F_OK))
{
/* Use that pinentry. */
xfree (name);