diff --git a/src/ChangeLog b/src/ChangeLog index 7c6d4297..562d2977 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,18 @@ 2010-11-02 Werner Koch + * data-fd.c (read, write, lseek) [W32CE && ! __MINGW32CE__]: New. + Taken from Pedro Alves Public Domain code. + + * w32-ce.h (SHGetSpecialFolderPath): Remove our defines and + prototypes. We use the system provided prototypes now. + * w32-ce.c: Include shlobj.h + (_WIN32_IE): Define to 0x0400 + (CreateFileA): New. + * w32-util.c: Explicitly include windows headers before util.h. + (_gpgme_w32ce_get_debug_envvar): Do not use wchar_t strings for + read_w32_registry_string. + (mkstemp): Use CreateFile instead of open. + * w32-io.c (handle_to_fd, fd_tohandle): Add. We need them for W32. * w32-util.c (_WIN32_IE): Define to 0x0400. diff --git a/src/Makefile.am b/src/Makefile.am index ecda9047..0065c073 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,7 +102,6 @@ else uiserver_components = endif - # These are the source files common to all library versions. We used # to build a non-installed library for that, but that does not work # correctly on all platforms (in particular, one can not specify the diff --git a/src/data-fd.c b/src/data-fd.c index 1ada70f7..779202e2 100644 --- a/src/data-fd.c +++ b/src/data-fd.c @@ -30,6 +30,62 @@ #include "debug.h" #include "data.h" + + +#if defined(HAVE_W32CE_SYSTEM) && !defined(__MINGW32CE__) +/* We need to provide replacements for read, write and lseek. They + are taken from the cegcc runtime files, written by Pedro Alves + in Feb 2007 and placed in the public + domain. (cf. cegcc/src/mingw/mingwex/wince/) */ + +#include + +static int +read (int fildes, void *buf, unsigned int bufsize) +{ + DWORD NumberOfBytesRead; + if (bufsize > 0x7fffffff) + bufsize = 0x7fffffff; + if (!ReadFile ((HANDLE) fildes, buf, bufsize, &NumberOfBytesRead, NULL)) + return -1; + return (int) NumberOfBytesRead; +} + +static int +write (int fildes, const void *buf, unsigned int bufsize) +{ + DWORD NumberOfBytesWritten; + if (bufsize > 0x7fffffff) + bufsize = 0x7fffffff; + if (!WriteFile ((HANDLE) fildes, buf, bufsize, &NumberOfBytesWritten, NULL)) + return -1; + return (int) NumberOfBytesWritten; +} + +static long +lseek (int fildes, long offset, int whence) +{ + DWORD mode; + switch (whence) + { + case SEEK_SET: + mode = FILE_BEGIN; + break; + case SEEK_CUR: + mode = FILE_CURRENT; + break; + case SEEK_END: + mode = FILE_END; + break; + default: + /* Specify an invalid mode so SetFilePointer catches it. */ + mode = (DWORD)-1; + } + return (long) SetFilePointer ((HANDLE) fildes, offset, NULL, mode); +} +#endif /*HAVE_W32CE_SYSTEM && !__MINGW32CE__*/ + + static ssize_t fd_read (gpgme_data_t dh, void *buffer, size_t size) diff --git a/src/w32-ce.c b/src/w32-ce.c index 076eaae5..e6c512ce 100644 --- a/src/w32-ce.c +++ b/src/w32-ce.c @@ -28,8 +28,18 @@ #include -#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 +#include +#include +#include + +#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 @@ -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, @@ -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,7 +432,7 @@ 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; diff --git a/src/w32-ce.h b/src/w32-ce.h index bcd5344c..f34eb1b3 100644 --- a/src/w32-ce.h +++ b/src/w32-ce.h @@ -33,13 +33,6 @@ typedef int pid_t; #include -/* shlobj.h declares these only for _WIN32_IE that we don't want to define. - In any case, with mingw32ce we only get a SHGetSpecialFolderPath. */ -#define SHGetSpecialFolderPathW SHGetSpecialFolderPath -BOOL WINAPI SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); -BOOL WINAPI SHGetSpecialFolderPathW(HWND,LPWSTR,int,BOOL); - - #define getenv _gpgme_wince_getenv char *getenv (const char *name); @@ -55,6 +48,10 @@ void GetSystemTimeAsFileTime (LPFILETIME ftp); #define DeleteFileA _gpgme_wince_DeleteFileA BOOL DeleteFileA(LPCSTR); +#define CreateFileA _gpgme_wince_CreateFileA +HANDLE CreateFileA (LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, + DWORD, DWORD, HANDLE); + #define CreateProcessA _gpgme_wince_CreateProcessA BOOL CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); diff --git a/src/w32-util.c b/src/w32-util.c index cbbc1260..ec2fe50f 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -42,8 +42,16 @@ #define _WIN32_IE 0x0400 /* Required for SHGetSpecialFolderPathA. */ -#include "util.h" +/* 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 util.h + but that header also redefines some Windows functions which we need + to avoid unless having included shlobj.h. */ +#include +#include +#include #include + +#include "util.h" #include "ath.h" #include "sema.h" #include "debug.h" @@ -488,7 +496,7 @@ mkstemp (char *tmpl) static uint64_t value; uint64_t random_time_bits; unsigned int count; - int fd = -1; + HANDLE fd = INVALID_HANDLE_VALUE; int save_errno = errno; /* A lower bound on the number of temporary files to attempt to @@ -544,14 +552,23 @@ mkstemp (char *tmpl) v /= 62; XXXXXX[5] = letters[v % 62]; - fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd >= 0) + fd = CreateFileA (tmpl, + GENERIC_WRITE|GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd != INVALID_HANDLE_VALUE) { gpg_err_set_errno (save_errno); - return fd; + return (int)fd; } - else if (errno != EEXIST) - return -1; + else if (GetLastError () != ERROR_FILE_EXISTS) + { + gpg_err_set_errno (EIO); + return -1; + } } /* We got out of the loop because we ran out of combinations to try. */ @@ -608,7 +625,7 @@ _gpgme_w32ce_get_debug_envvar (void) { char *tmp; - tmp = read_w32_registry_string (NULL, L"\\Software\\GNU\\gpgme", L"debug"); + tmp = read_w32_registry_string (NULL, "\\Software\\GNU\\gpgme", "debug"); if (tmp && !*tmp) { free (tmp);