core: Fail loudly in case w32 spawner not found
[gpgme.git] / src / w32-ce.c
index 076eaae..e42f053 100644 (file)
@@ -1,22 +1,22 @@
-/* w32-ce.h 
+/* w32-ce.h
    Copyright (C) 2010 g10 Code GmbH
+   Copyright (C) 1991,92,97,2000,02 Free Software Foundation, Inc.
 
    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.  */
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 
 #include <gpg-error.h>
 
-#include "w32-ce.h"
+#define _WIN32_IE 0x0400 /* Required for SHGetSpecialFolderPathW.  */
+
+/* We need to include the windows stuff here prior to shlobj.h so that
+   we get the right winsock version.  This is usually done in w32-ce.h
+   but that header also redefines some Windows functions which we need
+   to avoid unless having included shlobj.h.  */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <shlobj.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
@@ -82,7 +92,7 @@ utf8_to_wchar (const char *string)
     }
 
   nbytes = (size_t)(n+1) * sizeof(*result);
-  if (nbytes / sizeof(*result) != (n+1)) 
+  if (nbytes / sizeof(*result) != (n+1))
     {
       gpg_err_set_errno (ENOMEM);
       return NULL;
@@ -175,6 +185,31 @@ DeleteFileA (LPCSTR lpFileName)
 }
 
 
+HANDLE
+CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode,
+            LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+            DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
+            HANDLE hTemplateFile)
+{
+  wchar_t *filename;
+  HANDLE result;
+  int err;
+
+  filename = utf8_to_wchar (lpFileName);
+  if (!filename)
+    return INVALID_HANDLE_VALUE;
+
+  result = CreateFileW (filename, dwDesiredAccess, dwSharedMode,
+                       lpSecurityAttributes, dwCreationDisposition,
+                       dwFlagsAndAttributes, hTemplateFile);
+
+  err = GetLastError ();
+  free (filename);
+  SetLastError (err);
+  return result;
+}
+
+
 BOOL
 CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine,
                 LPSECURITY_ATTRIBUTES psaProcess,
@@ -255,7 +290,7 @@ RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
 {
   wchar_t *name;
   LONG err;
-  BYTE *data;
+  void *data;
   DWORD data_len;
   DWORD type;
 
@@ -282,7 +317,7 @@ RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
       free (name);
       return ERROR_NOT_ENOUGH_MEMORY;
     }
-  
+
   err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len);
   if (lpType)
     *lpType = type;
@@ -300,9 +335,9 @@ RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved,
       int data_c_len;
 
       /* This is valid since we allocated one more above.  */
-      data[data_len] = '\0';
-      data[data_len + 1] = '\0';
-      
+      ((char*)data)[data_len] = '\0';
+      ((char*)data)[data_len + 1] = '\0';
+
       data_c = wchar_to_utf8 ((wchar_t*) data);
       if (!data_c)
         return GetLastError();
@@ -382,6 +417,12 @@ GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer)
 }
 
 
+/* The symbol is named SHGetSpecialFolderPath and not
+   SHGetSpecialFolderPathW but shlobj.h from cegcc redefines it to *W
+   which is a bug.  Work around it.  */
+#ifdef __MINGW32CE__
+# undef SHGetSpecialFolderPath
+#endif
 BOOL
 SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
                          BOOL fCreate)
@@ -391,16 +432,76 @@ SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder,
   BOOL result;
 
   path[0] = (wchar_t) 0;
-  result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate);
+  result = SHGetSpecialFolderPath (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;
 }
+
+/* Replacement for the access function.  Note that we can't use fopen
+   here because wince might now allow to have a shared read for an
+   executable; it is better to to read the file attributes.
+
+   Limitation:  Only F_OK is supported.
+*/
+int
+_gpgme_wince_access (const char *fname, int mode)
+{
+  DWORD attr;
+  wchar_t *wfname;
+
+  (void)mode;
+
+  wfname = utf8_to_wchar (fname);
+  if (!wfname)
+    return -1;
+
+  attr = GetFileAttributes (wfname);
+  free (wfname);
+  if (attr == (DWORD)(-1))
+    {
+      gpg_err_set_errno (ENOENT);
+      return -1;
+    }
+  return 0;
+}
+
+
+/* Perform a binary search for KEY in BASE which has NMEMB elements
+   of SIZE bytes each.  The comparisons are done by (*COMPAR)().
+   Code taken from glibc-2.6. */
+void *
+_gpgme_wince_bsearch (const void *key, const void *base,
+                      size_t nmemb, size_t size,
+                      int (*compar) (const void *, const void *))
+{
+  size_t l, u, idx;
+  const void *p;
+  int comparison;
+
+  l = 0;
+  u = nmemb;
+  while (l < u)
+    {
+      idx = (l + u) / 2;
+      p = (void *) (((const char *) base) + (idx * size));
+      comparison = (*compar) (key, p);
+      if (comparison < 0)
+       u = idx;
+      else if (comparison > 0)
+       l = idx + 1;
+      else
+       return (void *) p;
+    }
+
+  return NULL;
+}
+