|
Packit |
d7e8d0 |
/* w32-ce.h
|
|
Packit |
d7e8d0 |
Copyright (C) 2010 g10 Code GmbH
|
|
Packit |
d7e8d0 |
Copyright (C) 1991,92,97,2000,02 Free Software Foundation, Inc.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
This file is part of GPGME.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
GPGME is free software; you can redistribute it and/or modify it
|
|
Packit |
d7e8d0 |
under the terms of the GNU Lesser General Public License as
|
|
Packit |
d7e8d0 |
published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
d7e8d0 |
the License, or (at your option) any later version.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
GPGME is distributed in the hope that it will be useful, but
|
|
Packit |
d7e8d0 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
d7e8d0 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
d7e8d0 |
Lesser General Public License for more details.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
d7e8d0 |
License along with this program; if not, see <https://www.gnu.org/licenses/>.
|
|
Packit |
d7e8d0 |
*/
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
d7e8d0 |
#include <config.h>
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#include <string.h>
|
|
Packit |
d7e8d0 |
#include <errno.h>
|
|
Packit |
d7e8d0 |
#include <assert.h>
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#include <gpg-error.h>
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#define _WIN32_IE 0x0400 /* Required for SHGetSpecialFolderPathW. */
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* We need to include the windows stuff here prior to shlobj.h so that
|
|
Packit |
d7e8d0 |
we get the right winsock version. This is usually done in w32-ce.h
|
|
Packit |
d7e8d0 |
but that header also redefines some Windows functions which we need
|
|
Packit |
d7e8d0 |
to avoid unless having included shlobj.h. */
|
|
Packit |
d7e8d0 |
#include <winsock2.h>
|
|
Packit |
d7e8d0 |
#include <ws2tcpip.h>
|
|
Packit |
d7e8d0 |
#include <windows.h>
|
|
Packit |
d7e8d0 |
#include <shlobj.h>
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#include "w32-ce.h"
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Return a malloced string encoded in UTF-8 from the wide char input
|
|
Packit |
d7e8d0 |
string STRING. Caller must free this value. Returns NULL and sets
|
|
Packit |
d7e8d0 |
ERRNO on failure. Calling this function with STRING set to NULL is
|
|
Packit |
d7e8d0 |
not defined. */
|
|
Packit |
d7e8d0 |
char *
|
|
Packit |
d7e8d0 |
wchar_to_utf8 (const wchar_t *string)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
int n;
|
|
Packit |
d7e8d0 |
char *result;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
|
|
Packit |
d7e8d0 |
if (n < 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (EINVAL);
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
result = malloc (n+1);
|
|
Packit |
d7e8d0 |
if (!result)
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
|
|
Packit |
d7e8d0 |
if (n < 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (result);
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (EINVAL);
|
|
Packit |
d7e8d0 |
result = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Return a malloced wide char string from an UTF-8 encoded input
|
|
Packit |
d7e8d0 |
string STRING. Caller must free this value. Returns NULL and sets
|
|
Packit |
d7e8d0 |
ERRNO on failure. Calling this function with STRING set to NULL is
|
|
Packit |
d7e8d0 |
not defined. */
|
|
Packit |
d7e8d0 |
wchar_t *
|
|
Packit |
d7e8d0 |
utf8_to_wchar (const char *string)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
int n;
|
|
Packit |
d7e8d0 |
size_t nbytes;
|
|
Packit |
d7e8d0 |
wchar_t *result;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
|
|
Packit |
d7e8d0 |
if (n < 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (EINVAL);
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
nbytes = (size_t)(n+1) * sizeof(*result);
|
|
Packit |
d7e8d0 |
if (nbytes / sizeof(*result) != (n+1))
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (ENOMEM);
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
result = malloc (nbytes);
|
|
Packit |
d7e8d0 |
if (!result)
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
|
|
Packit |
d7e8d0 |
if (n < 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (result);
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (EINVAL);
|
|
Packit |
d7e8d0 |
result = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#define MAX_ENV 30
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
char *environ[MAX_ENV + 1];
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
char *
|
|
Packit |
d7e8d0 |
getenv (const char *name)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
static char *past_result;
|
|
Packit |
d7e8d0 |
char **envp;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (past_result)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (past_result);
|
|
Packit |
d7e8d0 |
past_result = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#if 0
|
|
Packit |
d7e8d0 |
if (! strcmp (name, "DBUS_VERBOSE"))
|
|
Packit |
d7e8d0 |
return past_result = get_verbose_setting ();
|
|
Packit |
d7e8d0 |
else if (! strcmp (name, "HOMEPATH"))
|
|
Packit |
d7e8d0 |
return past_result = find_my_documents_folder ();
|
|
Packit |
d7e8d0 |
else if (! strcmp (name, "DBUS_DATADIR"))
|
|
Packit |
d7e8d0 |
return past_result = find_inst_subdir ("share");
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
for (envp = environ; *envp != 0; envp++)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
const char *varp = name;
|
|
Packit |
d7e8d0 |
char *ep = *envp;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
while (*varp == *ep && *varp != '\0')
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
++ep;
|
|
Packit |
d7e8d0 |
++varp;
|
|
Packit |
d7e8d0 |
};
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (*varp == '\0' && *ep == '=')
|
|
Packit |
d7e8d0 |
return ep + 1;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
GetSystemTimeAsFileTime (LPFILETIME ftp)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
SYSTEMTIME st;
|
|
Packit |
d7e8d0 |
GetSystemTime (&st);
|
|
Packit |
d7e8d0 |
SystemTimeToFileTime (&st, ftp);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
BOOL
|
|
Packit |
d7e8d0 |
DeleteFileA (LPCSTR lpFileName)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *filename;
|
|
Packit |
d7e8d0 |
BOOL result;
|
|
Packit |
d7e8d0 |
int err;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
filename = utf8_to_wchar (lpFileName);
|
|
Packit |
d7e8d0 |
if (!filename)
|
|
Packit |
d7e8d0 |
return FALSE;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
result = DeleteFileW (filename);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
err = GetLastError ();
|
|
Packit |
d7e8d0 |
free (filename);
|
|
Packit |
d7e8d0 |
SetLastError (err);
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
HANDLE
|
|
Packit |
d7e8d0 |
CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode,
|
|
Packit |
d7e8d0 |
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
Packit |
d7e8d0 |
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
|
Packit |
d7e8d0 |
HANDLE hTemplateFile)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *filename;
|
|
Packit |
d7e8d0 |
HANDLE result;
|
|
Packit |
d7e8d0 |
int err;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
filename = utf8_to_wchar (lpFileName);
|
|
Packit |
d7e8d0 |
if (!filename)
|
|
Packit |
d7e8d0 |
return INVALID_HANDLE_VALUE;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
result = CreateFileW (filename, dwDesiredAccess, dwSharedMode,
|
|
Packit |
d7e8d0 |
lpSecurityAttributes, dwCreationDisposition,
|
|
Packit |
d7e8d0 |
dwFlagsAndAttributes, hTemplateFile);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
err = GetLastError ();
|
|
Packit |
d7e8d0 |
free (filename);
|
|
Packit |
d7e8d0 |
SetLastError (err);
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
BOOL
|
|
Packit |
d7e8d0 |
CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine,
|
|
Packit |
d7e8d0 |
LPSECURITY_ATTRIBUTES psaProcess,
|
|
Packit |
d7e8d0 |
LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles,
|
|
Packit |
d7e8d0 |
DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir,
|
|
Packit |
d7e8d0 |
LPSTARTUPINFOA psiStartInfo,
|
|
Packit |
d7e8d0 |
LPPROCESS_INFORMATION pProcInfo)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *image_name = NULL;
|
|
Packit |
d7e8d0 |
wchar_t *cmd_line = NULL;
|
|
Packit |
d7e8d0 |
BOOL result;
|
|
Packit |
d7e8d0 |
int err;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
assert (psaProcess == NULL);
|
|
Packit |
d7e8d0 |
assert (psaThread == NULL);
|
|
Packit |
d7e8d0 |
assert (fInheritHandles == FALSE);
|
|
Packit |
d7e8d0 |
assert (pvEnvironment == NULL);
|
|
Packit |
d7e8d0 |
assert (pszCurDir == NULL);
|
|
Packit |
d7e8d0 |
/* psiStartInfo is generally not NULL. */
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (pszImageName)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
image_name = utf8_to_wchar (pszImageName);
|
|
Packit |
d7e8d0 |
if (!image_name)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
if (pszCmdLine)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
cmd_line = utf8_to_wchar (pszCmdLine);
|
|
Packit |
d7e8d0 |
if (!cmd_line)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
if (image_name)
|
|
Packit |
d7e8d0 |
free (image_name);
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE,
|
|
Packit |
d7e8d0 |
fdwCreate, NULL, NULL, NULL, pProcInfo);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
err = GetLastError ();
|
|
Packit |
d7e8d0 |
free (image_name);
|
|
Packit |
d7e8d0 |
free (cmd_line);
|
|
Packit |
d7e8d0 |
SetLastError (err);
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
LONG
|
|
Packit |
d7e8d0 |
RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions,
|
|
Packit |
d7e8d0 |
REGSAM samDesired, PHKEY phkResult)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *subkey;
|
|
Packit |
d7e8d0 |
LONG result;
|
|
Packit |
d7e8d0 |
int err;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (lpSubKey)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
subkey = utf8_to_wchar (lpSubKey);
|
|
Packit |
d7e8d0 |
if (!subkey)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
subkey = NULL;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
err = GetLastError ();
|
|
Packit |
d7e8d0 |
free (subkey);
|
|
Packit |
d7e8d0 |
SetLastError (err);
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
LONG WINAPI
|
|
Packit |
d7e8d0 |
RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
|
|
Packit |
d7e8d0 |
LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *name;
|
|
Packit |
d7e8d0 |
LONG err;
|
|
Packit |
d7e8d0 |
void *data;
|
|
Packit |
d7e8d0 |
DWORD data_len;
|
|
Packit |
d7e8d0 |
DWORD type;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (lpValueName)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
name = utf8_to_wchar (lpValueName);
|
|
Packit |
d7e8d0 |
if (!name)
|
|
Packit |
d7e8d0 |
return GetLastError ();
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
name = NULL;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
data_len = 0;
|
|
Packit |
d7e8d0 |
err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len);
|
|
Packit |
d7e8d0 |
if (err || !lpcbData)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (name);
|
|
Packit |
d7e8d0 |
return err;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
data = malloc (data_len + sizeof (wchar_t));
|
|
Packit |
d7e8d0 |
if (!data)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (name);
|
|
Packit |
d7e8d0 |
return ERROR_NOT_ENOUGH_MEMORY;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len);
|
|
Packit |
d7e8d0 |
if (lpType)
|
|
Packit |
d7e8d0 |
*lpType = type;
|
|
Packit |
d7e8d0 |
free (name);
|
|
Packit |
d7e8d0 |
/* If err is ERROR_MORE_DATA, there probably was a race condition.
|
|
Packit |
d7e8d0 |
We can punt this to the caller just as well. */
|
|
Packit |
d7e8d0 |
if (err)
|
|
Packit |
d7e8d0 |
return err;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they
|
|
Packit |
d7e8d0 |
are not needed in this module. */
|
|
Packit |
d7e8d0 |
if (type == REG_SZ)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
char *data_c;
|
|
Packit |
d7e8d0 |
int data_c_len;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* This is valid since we allocated one more above. */
|
|
Packit |
d7e8d0 |
((char*)data)[data_len] = '\0';
|
|
Packit |
d7e8d0 |
((char*)data)[data_len + 1] = '\0';
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
data_c = wchar_to_utf8 ((wchar_t*) data);
|
|
Packit |
d7e8d0 |
if (!data_c)
|
|
Packit |
d7e8d0 |
return GetLastError();
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
data_c_len = strlen (data_c) + 1;
|
|
Packit |
d7e8d0 |
assert (data_c_len <= data_len + sizeof (wchar_t));
|
|
Packit |
d7e8d0 |
memcpy (data, data_c, data_c_len);
|
|
Packit |
d7e8d0 |
data_len = data_c_len;
|
|
Packit |
d7e8d0 |
free (data_c);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* DATA and DATA_LEN now contain the result. */
|
|
Packit |
d7e8d0 |
if (lpData)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
if (data_len > *lpcbData)
|
|
Packit |
d7e8d0 |
err = ERROR_MORE_DATA;
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
memcpy (lpData, data, data_len);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
*lpcbData = data_len;
|
|
Packit |
d7e8d0 |
return err;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
DWORD
|
|
Packit |
d7e8d0 |
GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t dummy[1];
|
|
Packit |
d7e8d0 |
DWORD len;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
len = GetTempPathW (0, dummy);
|
|
Packit |
d7e8d0 |
if (len == 0)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
assert (len <= MAX_PATH);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Better be safe than sorry. MSDN doesn't say if len is with or
|
|
Packit |
d7e8d0 |
without terminating 0. */
|
|
Packit |
d7e8d0 |
len++;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t *buffer_w;
|
|
Packit |
d7e8d0 |
DWORD len_w;
|
|
Packit |
d7e8d0 |
char *buffer_c;
|
|
Packit |
d7e8d0 |
DWORD len_c;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
buffer_w = malloc (sizeof (wchar_t) * len);
|
|
Packit |
d7e8d0 |
if (! buffer_w)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
len_w = GetTempPathW (len, buffer_w);
|
|
Packit |
d7e8d0 |
/* Give up if we still can't get at it. */
|
|
Packit |
d7e8d0 |
if (len_w == 0 || len_w >= len)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (buffer_w);
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Better be really safe. */
|
|
Packit |
d7e8d0 |
buffer_w[len_w] = '\0';
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
buffer_c = wchar_to_utf8 (buffer_w);
|
|
Packit |
d7e8d0 |
free (buffer_w);
|
|
Packit |
d7e8d0 |
if (! buffer_c)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* strlen is correct (not _mbstrlen), because we want storage and
|
|
Packit |
d7e8d0 |
not string length. */
|
|
Packit |
d7e8d0 |
len_c = strlen (buffer_c) + 1;
|
|
Packit |
d7e8d0 |
if (len_c > nBufferLength)
|
|
Packit |
d7e8d0 |
return len_c;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
strcpy (lpBuffer, buffer_c);
|
|
Packit |
d7e8d0 |
free (buffer_c);
|
|
Packit |
d7e8d0 |
return len_c - 1;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* The symbol is named SHGetSpecialFolderPath and not
|
|
Packit |
d7e8d0 |
SHGetSpecialFolderPathW but shlobj.h from cegcc redefines it to *W
|
|
Packit |
d7e8d0 |
which is a bug. Work around it. */
|
|
Packit |
d7e8d0 |
#ifdef __MINGW32CE__
|
|
Packit |
d7e8d0 |
# undef SHGetSpecialFolderPath
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
BOOL
|
|
Packit |
d7e8d0 |
SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
|
|
Packit |
d7e8d0 |
BOOL fCreate)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
wchar_t path[MAX_PATH];
|
|
Packit |
d7e8d0 |
char *path_c;
|
|
Packit |
d7e8d0 |
BOOL result;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
path[0] = (wchar_t) 0;
|
|
Packit |
d7e8d0 |
result = SHGetSpecialFolderPath (hwndOwner, path, nFolder, fCreate);
|
|
Packit |
d7e8d0 |
/* Note: May return false even if succeeds. */
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
path[MAX_PATH - 1] = (wchar_t) 0;
|
|
Packit |
d7e8d0 |
path_c = wchar_to_utf8 (path);
|
|
Packit |
d7e8d0 |
if (! path_c)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
strncpy (lpszPath, path_c, MAX_PATH);
|
|
Packit |
d7e8d0 |
free (path_c);
|
|
Packit |
d7e8d0 |
lpszPath[MAX_PATH - 1] = '\0';
|
|
Packit |
d7e8d0 |
return result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Replacement for the access function. Note that we can't use fopen
|
|
Packit |
d7e8d0 |
here because wince might now allow to have a shared read for an
|
|
Packit |
d7e8d0 |
executable; it is better to to read the file attributes.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
Limitation: Only F_OK is supported.
|
|
Packit |
d7e8d0 |
*/
|
|
Packit |
d7e8d0 |
int
|
|
Packit |
d7e8d0 |
_gpgme_wince_access (const char *fname, int mode)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
DWORD attr;
|
|
Packit |
d7e8d0 |
wchar_t *wfname;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
(void)mode;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
wfname = utf8_to_wchar (fname);
|
|
Packit |
d7e8d0 |
if (!wfname)
|
|
Packit |
d7e8d0 |
return -1;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
attr = GetFileAttributes (wfname);
|
|
Packit |
d7e8d0 |
free (wfname);
|
|
Packit |
d7e8d0 |
if (attr == (DWORD)(-1))
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (ENOENT);
|
|
Packit |
d7e8d0 |
return -1;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Perform a binary search for KEY in BASE which has NMEMB elements
|
|
Packit |
d7e8d0 |
of SIZE bytes each. The comparisons are done by (*COMPAR)().
|
|
Packit |
d7e8d0 |
Code taken from glibc-2.6. */
|
|
Packit |
d7e8d0 |
void *
|
|
Packit |
d7e8d0 |
_gpgme_wince_bsearch (const void *key, const void *base,
|
|
Packit |
d7e8d0 |
size_t nmemb, size_t size,
|
|
Packit |
d7e8d0 |
int (*compar) (const void *, const void *))
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
size_t l, u, idx;
|
|
Packit |
d7e8d0 |
const void *p;
|
|
Packit |
d7e8d0 |
int comparison;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
l = 0;
|
|
Packit |
d7e8d0 |
u = nmemb;
|
|
Packit |
d7e8d0 |
while (l < u)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
idx = (l + u) / 2;
|
|
Packit |
d7e8d0 |
p = (void *) (((const char *) base) + (idx * size));
|
|
Packit |
d7e8d0 |
comparison = (*compar) (key, p);
|
|
Packit |
d7e8d0 |
if (comparison < 0)
|
|
Packit |
d7e8d0 |
u = idx;
|
|
Packit |
d7e8d0 |
else if (comparison > 0)
|
|
Packit |
d7e8d0 |
l = idx + 1;
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
return (void *) p;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
return NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|