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>
31 #define _WIN32_IE 0x0400 /* Required for SHGetSpecialFolderPathW. */
33 /* We need to include the windows stuff here prior to shlobj.h so that
34 we get the right winsock version. This is usually done in w32-ce.h
35 but that header also redefines some Windows functions which we need
36 to avoid unless having included shlobj.h. */
44 /* Return a malloced string encoded in UTF-8 from the wide char input
45 string STRING. Caller must free this value. Returns NULL and sets
46 ERRNO on failure. Calling this function with STRING set to NULL is
49 wchar_to_utf8 (const wchar_t *string)
54 n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
57 gpg_err_set_errno (EINVAL);
61 result = malloc (n+1);
65 n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
69 gpg_err_set_errno (EINVAL);
76 /* Return a malloced wide char string from an UTF-8 encoded input
77 string STRING. Caller must free this value. Returns NULL and sets
78 ERRNO on failure. Calling this function with STRING set to NULL is
81 utf8_to_wchar (const char *string)
87 n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
90 gpg_err_set_errno (EINVAL);
94 nbytes = (size_t)(n+1) * sizeof(*result);
95 if (nbytes / sizeof(*result) != (n+1))
97 gpg_err_set_errno (ENOMEM);
100 result = malloc (nbytes);
104 n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
108 gpg_err_set_errno (EINVAL);
117 char *environ[MAX_ENV + 1];
120 getenv (const char *name)
122 static char *past_result;
132 if (! strcmp (name, "DBUS_VERBOSE"))
133 return past_result = get_verbose_setting ();
134 else if (! strcmp (name, "HOMEPATH"))
135 return past_result = find_my_documents_folder ();
136 else if (! strcmp (name, "DBUS_DATADIR"))
137 return past_result = find_inst_subdir ("share");
140 for (envp = environ; *envp != 0; envp++)
142 const char *varp = name;
145 while (*varp == *ep && *varp != '\0')
151 if (*varp == '\0' && *ep == '=')
160 GetSystemTimeAsFileTime (LPFILETIME ftp)
164 SystemTimeToFileTime (&st, ftp);
169 DeleteFileA (LPCSTR lpFileName)
175 filename = utf8_to_wchar (lpFileName);
179 result = DeleteFileW (filename);
181 err = GetLastError ();
189 CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode,
190 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
191 DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
192 HANDLE hTemplateFile)
198 filename = utf8_to_wchar (lpFileName);
200 return INVALID_HANDLE_VALUE;
202 result = CreateFileW (filename, dwDesiredAccess, dwSharedMode,
203 lpSecurityAttributes, dwCreationDisposition,
204 dwFlagsAndAttributes, hTemplateFile);
206 err = GetLastError ();
214 CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine,
215 LPSECURITY_ATTRIBUTES psaProcess,
216 LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles,
217 DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir,
218 LPSTARTUPINFOA psiStartInfo,
219 LPPROCESS_INFORMATION pProcInfo)
221 wchar_t *image_name = NULL;
222 wchar_t *cmd_line = NULL;
226 assert (psaProcess == NULL);
227 assert (psaThread == NULL);
228 assert (fInheritHandles == FALSE);
229 assert (pvEnvironment == NULL);
230 assert (pszCurDir == NULL);
231 /* psiStartInfo is generally not NULL. */
235 image_name = utf8_to_wchar (pszImageName);
241 cmd_line = utf8_to_wchar (pszCmdLine);
250 result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE,
251 fdwCreate, NULL, NULL, NULL, pProcInfo);
253 err = GetLastError ();
262 RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions,
263 REGSAM samDesired, PHKEY phkResult)
271 subkey = utf8_to_wchar (lpSubKey);
278 result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult);
280 err = GetLastError ();
288 RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
289 LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
299 name = utf8_to_wchar (lpValueName);
301 return GetLastError ();
307 err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len);
308 if (err || !lpcbData)
314 data = malloc (data_len + sizeof (wchar_t));
318 return ERROR_NOT_ENOUGH_MEMORY;
321 err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len);
325 /* If err is ERROR_MORE_DATA, there probably was a race condition.
326 We can punt this to the caller just as well. */
330 /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they
331 are not needed in this module. */
337 /* This is valid since we allocated one more above. */
338 data[data_len] = '\0';
339 data[data_len + 1] = '\0';
341 data_c = wchar_to_utf8 ((wchar_t*) data);
343 return GetLastError();
345 data_c_len = strlen (data_c) + 1;
346 assert (data_c_len <= data_len + sizeof (wchar_t));
347 memcpy (data, data_c, data_c_len);
348 data_len = data_c_len;
352 /* DATA and DATA_LEN now contain the result. */
355 if (data_len > *lpcbData)
356 err = ERROR_MORE_DATA;
358 memcpy (lpData, data, data_len);
360 *lpcbData = data_len;
366 GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer)
371 len = GetTempPathW (0, dummy);
375 assert (len <= MAX_PATH);
377 /* Better be safe than sorry. MSDN doesn't say if len is with or
378 without terminating 0. */
387 buffer_w = malloc (sizeof (wchar_t) * len);
391 len_w = GetTempPathW (len, buffer_w);
392 /* Give up if we still can't get at it. */
393 if (len_w == 0 || len_w >= len)
399 /* Better be really safe. */
400 buffer_w[len_w] = '\0';
402 buffer_c = wchar_to_utf8 (buffer_w);
407 /* strlen is correct (not _mbstrlen), because we want storage and
408 not string length. */
409 len_c = strlen (buffer_c) + 1;
410 if (len_c > nBufferLength)
413 strcpy (lpBuffer, buffer_c);
420 /* The symbol is named SHGetSpecialFolderPath and not
421 SHGetSpecialFolderPathW but shlobj.h from cegcc redefines it to *W
422 which is a bug. Work around it. */
424 # undef SHGetSpecialFolderPath
427 SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
430 wchar_t path[MAX_PATH];
434 path[0] = (wchar_t) 0;
435 result = SHGetSpecialFolderPath (hwndOwner, path, nFolder, fCreate);
436 /* Note: May return false even if succeeds. */
438 path[MAX_PATH - 1] = (wchar_t) 0;
439 path_c = wchar_to_utf8 (path);
443 strncpy (lpszPath, path_c, MAX_PATH);
445 lpszPath[MAX_PATH - 1] = '\0';