2 Copyright (C) 2010 g10 Code GmbH
4 This file is part of GPGME.
6 GPGME is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of
9 the License, or (at your option) any later version.
11 GPGME is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include <gpg-error.h>
34 /* Return a malloced string encoded in UTF-8 from the wide char input
35 string STRING. Caller must free this value. Returns NULL and sets
36 ERRNO on failure. Calling this function with STRING set to NULL is
39 wchar_to_utf8 (const wchar_t *string)
44 n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
47 gpg_err_set_errno (EINVAL);
51 result = malloc (n+1);
55 n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
59 gpg_err_set_errno (EINVAL);
66 /* Return a malloced wide char string from an UTF-8 encoded input
67 string STRING. Caller must free this value. Returns NULL and sets
68 ERRNO on failure. Calling this function with STRING set to NULL is
71 utf8_to_wchar (const char *string)
77 n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
80 gpg_err_set_errno (EINVAL);
84 nbytes = (size_t)(n+1) * sizeof(*result);
85 if (nbytes / sizeof(*result) != (n+1))
87 gpg_err_set_errno (ENOMEM);
90 result = malloc (nbytes);
94 n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
98 gpg_err_set_errno (EINVAL);
107 char *environ[MAX_ENV + 1];
110 getenv (const char *name)
112 static char *past_result;
122 if (! strcmp (name, "DBUS_VERBOSE"))
123 return past_result = get_verbose_setting ();
124 else if (! strcmp (name, "HOMEPATH"))
125 return past_result = find_my_documents_folder ();
126 else if (! strcmp (name, "DBUS_DATADIR"))
127 return past_result = find_inst_subdir ("share");
130 for (envp = environ; *envp != 0; envp++)
132 const char *varp = name;
135 while (*varp == *ep && *varp != '\0')
141 if (*varp == '\0' && *ep == '=')
150 GetSystemTimeAsFileTime (LPFILETIME ftp)
154 SystemTimeToFileTime (&st, ftp);
159 DeleteFileA (LPCSTR lpFileName)
165 filename = utf8_to_wchar (lpFileName);
169 result = DeleteFileW (filename);
171 err = GetLastError ();
179 CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine,
180 LPSECURITY_ATTRIBUTES psaProcess,
181 LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles,
182 DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir,
183 LPSTARTUPINFOA psiStartInfo,
184 LPPROCESS_INFORMATION pProcInfo)
186 wchar_t *image_name = NULL;
187 wchar_t *cmd_line = NULL;
191 assert (psaProcess == NULL);
192 assert (psaThread == NULL);
193 assert (fInheritHandles == FALSE);
194 assert (pvEnvironment == NULL);
195 assert (pszCurDir == NULL);
196 /* psiStartInfo is generally not NULL. */
200 image_name = utf8_to_wchar (pszImageName);
206 cmd_line = utf8_to_wchar (pszCmdLine);
215 result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE,
216 fdwCreate, NULL, NULL, NULL, pProcInfo);
218 err = GetLastError ();
227 RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions,
228 REGSAM samDesired, PHKEY phkResult)
236 subkey = utf8_to_wchar (lpSubKey);
243 result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult);
245 err = GetLastError ();
253 RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
254 LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
264 name = utf8_to_wchar (lpValueName);
266 return GetLastError ();
272 err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len);
273 if (err || !lpcbData)
279 data = malloc (data_len + sizeof (wchar_t));
283 return ERROR_NOT_ENOUGH_MEMORY;
286 err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len);
290 /* If err is ERROR_MORE_DATA, there probably was a race condition.
291 We can punt this to the caller just as well. */
295 /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they
296 are not needed in this module. */
302 /* This is valid since we allocated one more above. */
303 data[data_len] = '\0';
304 data[data_len + 1] = '\0';
306 data_c = wchar_to_utf8 ((wchar_t*) data);
308 return GetLastError();
310 data_c_len = strlen (data_c) + 1;
311 assert (data_c_len <= data_len + sizeof (wchar_t));
312 memcpy (data, data_c, data_c_len);
313 data_len = data_c_len;
317 /* DATA and DATA_LEN now contain the result. */
320 if (data_len > *lpcbData)
321 err = ERROR_MORE_DATA;
323 memcpy (lpData, data, data_len);
325 *lpcbData = data_len;
331 GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer)
336 len = GetTempPathW (0, dummy);
340 assert (len <= MAX_PATH);
342 /* Better be safe than sorry. MSDN doesn't say if len is with or
343 without terminating 0. */
352 buffer_w = malloc (sizeof (wchar_t) * len);
356 len_w = GetTempPathW (len, buffer_w);
357 /* Give up if we still can't get at it. */
358 if (len_w == 0 || len_w >= len)
364 /* Better be really safe. */
365 buffer_w[len_w] = '\0';
367 buffer_c = wchar_to_utf8 (buffer_w);
372 /* strlen is correct (not _mbstrlen), because we want storage and
373 not string length. */
374 len_c = strlen (buffer_c) + 1;
375 if (len_c > nBufferLength)
378 strcpy (lpBuffer, buffer_c);
386 SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
389 wchar_t path[MAX_PATH];
393 path[0] = (wchar_t) 0;
394 result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate);
395 /* Note: May return false even if succeeds. */
397 path[MAX_PATH - 1] = (wchar_t) 0;
398 path_c = wchar_to_utf8 (path);
402 strncpy (lpszPath, path_c, MAX_PATH);
404 lpszPath[MAX_PATH - 1] = '\0';