diff options
Diffstat (limited to 'src/w32-ce.c')
-rw-r--r-- | src/w32-ce.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/src/w32-ce.c b/src/w32-ce.c new file mode 100644 index 00000000..57590fa9 --- /dev/null +++ b/src/w32-ce.c @@ -0,0 +1,405 @@ +/* w32-ce.h + Copyright (C) 2010 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. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <assert.h> + +#include <gpg-error.h> + +#include "w32-ce.h" + + +/* 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. */ +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; +} + + +/* Return a malloced wide char string from an UTF-8 encoded 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. */ +wchar_t * +utf8_to_wchar (const char *string) +{ + int n; + size_t nbytes; + wchar_t *result; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0); + if (n < 0) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + nbytes = (size_t)(n+1) * sizeof(*result); + if (nbytes / sizeof(*result) != (n+1)) + { + gpg_err_set_errno (ENOMEM); + return NULL; + } + result = malloc (nbytes); + if (!result) + return NULL; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n); + if (n < 0) + { + free (result); + gpg_err_set_errno (EINVAL); + result = NULL; + } + return result; +} + + +#define MAX_ENV 30 + +char *environ[MAX_ENV + 1]; + +char * +getenv (const char *name) +{ + static char *past_result; + char **envp; + + if (past_result) + { + free (past_result); + past_result = NULL; + } + +#if 0 + if (! strcmp (name, "DBUS_VERBOSE")) + return past_result = get_verbose_setting (); + else if (! strcmp (name, "HOMEPATH")) + return past_result = find_my_documents_folder (); + else if (! strcmp (name, "DBUS_DATADIR")) + return past_result = find_inst_subdir ("share"); +#endif + + for (envp = environ; *envp != 0; envp++) + { + const char *varp = name; + char *ep = *envp; + + while (*varp == *ep && *varp != '\0') + { + ++ep; + ++varp; + }; + + if (*varp == '\0' && *ep == '=') + return ep + 1; + } + + return NULL; +} + + +void +GetSystemTimeAsFileTime (LPFILETIME ftp) +{ + SYSTEMTIME st; + GetSystemTime (&st); + SystemTimeToFileTime (&st, ftp); +} + + +BOOL +DeleteFileA (LPCSTR lpFileName) +{ + wchar_t *filename; + BOOL result; + int err; + + filename = utf8_to_wchar (lpFileName); + if (!filename) + return FALSE; + + result = DeleteFileW (filename); + + err = GetLastError (); + free (filename); + SetLastError (err); + return result; +} + + +BOOL +CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine, + LPSECURITY_ATTRIBUTES psaProcess, + LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles, + DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir, + LPSTARTUPINFOA psiStartInfo, + LPPROCESS_INFORMATION pProcInfo) +{ + wchar_t *image_name = NULL; + wchar_t *cmd_line = NULL; + BOOL result; + int err; + + assert (psaProcess == NULL); + assert (psaThread == NULL); + assert (fInheritHandles == FALSE); + assert (pvEnvironment == NULL); + assert (pszCurDir == NULL); + /* psiStartInfo is generally not NULL. */ + + if (pszImageName) + { + image_name = utf8_to_wchar (pszImageName); + if (!image_name) + return 0; + } + if (pszCmdLine) + { + cmd_line = utf8_to_wchar (pszCmdLine); + if (!cmd_line) + { + if (image_name) + free (image_name); + return 0; + } + } + + result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE, + fdwCreate, NULL, NULL, NULL, pProcInfo); + + err = GetLastError (); + free (image_name); + free (cmd_line); + SetLastError (err); + return result; +} + + +LONG +RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, + REGSAM samDesired, PHKEY phkResult) +{ + wchar_t *subkey; + LONG result; + int err; + + if (lpSubKey) + { + subkey = utf8_to_wchar (lpSubKey); + if (!subkey) + return 0; + } + else + subkey = NULL; + + result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult); + + err = GetLastError (); + free (subkey); + SetLastError (err); + return result; +} + + +LONG +RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, + LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) +{ + wchar_t *name; + LONG err; + BYTE *data; + DWORD data_len; + DWORD type; + + if (lpValueName) + { + name = utf8_to_wchar (lpValueName); + if (!name) + return GetLastError (); + } + else + name = NULL; + + data_len = 0; + err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len); + if (err || !lpcbData) + { + free (name); + return err; + } + + data = malloc (data_len + sizeof (wchar_t)); + if (!data) + { + free (name); + return ERROR_NOT_ENOUGH_MEMORY; + } + + err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len); + if (lpType) + *lpType = type; + free (name); + /* If err is ERROR_MORE_DATA, there probably was a race condition. + We can punt this to the caller just as well. */ + if (err) + return err; + + /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they + are not needed in this module. */ + if (type == REG_SZ) + { + char *data_c; + int data_c_len; + + /* This is valid since we allocated one more above. */ + data[data_len] = '\0'; + data[data_len + 1] = '\0'; + + data_c = wchar_to_utf8 ((wchar_t*) data); + if (!data_c) + return GetLastError(); + + data_c_len = strlen (data_c) + 1; + assert (data_c_len <= data_len + sizeof (wchar_t)); + memcpy (data, data_c, data_c_len); + data_len = data_c_len; + free (data_c); + } + + /* DATA and DATA_LEN now contain the result. */ + if (lpData) + { + if (data_len > *lpcbData) + err = ERROR_MORE_DATA; + else + memcpy (lpData, data, data_len); + } + *lpcbData = data_len; + return err; +} + + +DWORD +GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer) +{ + wchar_t dummy[1]; + DWORD len; + + len = GetTempPathW (0, dummy); + if (len == 0) + return 0; + + assert (len <= MAX_PATH); + + /* Better be safe than sorry. MSDN doesn't say if len is with or + without terminating 0. */ + len++; + + { + wchar_t *buffer_w; + DWORD len_w; + char *buffer_c; + DWORD len_c; + + buffer_w = malloc (sizeof (wchar_t) * len); + if (! buffer_w) + return 0; + + len_w = GetTempPathW (len, buffer_w); + /* Give up if we still can't get at it. */ + if (len_w == 0 || len_w >= len) + { + free (buffer_w); + return 0; + } + + /* Better be really safe. */ + buffer_w[len_w] = '\0'; + + buffer_c = wchar_to_utf8 (buffer_w); + free (buffer_w); + if (! buffer_c) + return 0; + + /* strlen is correct (not _mbstrlen), because we want storage and + not string length. */ + len_c = strlen (buffer_c) + 1; + if (len_c > nBufferLength) + return len_c; + + strcpy (lpBuffer, buffer_c); + free (buffer_c); + return len_c - 1; + } +} + + +BOOL +SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder, + BOOL fCreate) +{ + wchar_t path[MAX_PATH]; + char *path_c; + BOOL result; + + path[0] = (wchar_t) 0; + result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate); + /* Note: May return false even if succeeds. */ + + path[MAX_PATH - 1] = (wchar_t) 0; + path_c = wchar_to_utf8 (path); + if (! path_c) + return 0; + + strncpy (lpszPath, path_c, MAX_PATH); + free (path_c); + lpszPath[MAX_PATH - 1] = '\0'; + return result; +} |