You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Ioan Popescu <ip...@dataq.com> on 2007/10/09 17:50:58 UTC

[PATCH] libapr-1.2.11 on WinCE 5

Index: dso/win32/dso.c
===================================================================
--- dso/win32/dso.c	(revision 574284)
+++ dso/win32/dso.c	(working copy)
@@ -141,7 +141,7 @@
     apr_wchar_t wsymname[256];
     apr_status_t rv;
 
-    rv = apr_conv_utf8_to_ucs2(wsymname, &wsymlen, symname, &symlen);
+    rv = apr_conv_utf8_to_ucs2(symname, &symlen, wsymname, &wsymlen);
     if (rv != APR_SUCCESS) {
         return rv;
     }
Index: file_io/unix/tempdir.c
===================================================================
--- file_io/unix/tempdir.c	(revision 574284)
+++ file_io/unix/tempdir.c	(working copy)
@@ -17,8 +17,8 @@
 #include "apr_file_io.h"
 #include "apr_strings.h"
 #include "apr_env.h"
+#include "apr_arch_file_io.h"
 
-
 /* Try to open a temporary file in the temporary dir, write to it,
    and then close it. */
 static int test_tempdir(const char *temp_dir, apr_pool_t *p)
@@ -41,6 +41,7 @@
                                            apr_pool_t *p)
 {
     apr_status_t apr_err;
+#ifndef _WIN32_WCE
     const char *try_dirs[] = { "/tmp", "/usr/tmp", "/var/tmp" };
     const char *try_envs[] = { "TMP", "TEMP", "TMPDIR" };
     const char *dir;
@@ -126,5 +127,22 @@
 
 end:
     *temp_dir = apr_pstrdup(p, dir);
+#else
+    char *dir;
+    apr_wchar_t wdir[APR_PATH_MAX] = {0};
+    DWORD len;
+
+    len = GetTempPathW(APR_PATH_MAX, wdir);
+    if (!len)
+        return APR_EGENERAL;
+    /* Need to remove the trailing back-slash. */
+    wdir[len-1] = 0;
+    dir = apr_pcalloc(p, APR_PATH_MAX);
+    apr_err = unicode_to_utf8_path(dir, APR_PATH_MAX, wdir);
+    if (apr_err != APR_SUCCESS)
+        return apr_err;
+    if (test_tempdir(dir, p))
+        *temp_dir = dir;
+#endif
     return APR_SUCCESS;
 }
Index: file_io/win32/dir.c
===================================================================
--- file_io/win32/dir.c	(revision 574284)
+++ file_io/win32/dir.c	(working copy)
@@ -94,8 +94,14 @@
     apr_pool_cleanup_register((*new)->pool, (void *)(*new), dir_cleanup,
                         apr_pool_cleanup_null);
 
+    /* CE fails apr_dir_read() on an *empty* directory
+     * (no "." nor ".." files).
+     */
     rv = apr_dir_read(NULL, 0, *new);
-    if (rv != APR_SUCCESS) {
+    if (rv == APR_FROM_OS_ERROR(ERROR_NO_MORE_FILES)) {
+        rv = APR_SUCCESS;
+    }
+    else if (rv != APR_SUCCESS) {
         dir_cleanup(*new);
         *new = NULL;
     }
@@ -268,6 +274,12 @@
 
     if (rv == APR_SUCCESS)
         rv = apr_dir_read(NULL, 0, dir);
+    /* CE fails apr_dir_read() on an *empty* directory
+     * (no "." nor ".." files).
+     */
+    if (rv == APR_FROM_OS_ERROR(ERROR_NO_MORE_FILES)) {
+        rv = APR_SUCCESS;
+    }
 
     return rv;
 }
Index: file_io/win32/filepath.c
===================================================================
--- file_io/win32/filepath.c	(revision 574284)
+++ file_io/win32/filepath.c	(working copy)
@@ -265,7 +265,8 @@
             return APR_EINCOMPLETE;
         }
 
-        /* Left with a path of '/', what drive are we asking about? 
+#ifndef _WIN32_WCE
+        /* Left with a path of '/', what drive are we asking about?
          */
         *inpath = testpath + 1;
         newpath = apr_palloc(p, 2);
@@ -276,8 +277,37 @@
         newpath[1] = '\0';
         *rootpath = newpath;
         return APR_EINCOMPLETE;
+#else
+        /* Evaluate path of '/' (root on CE). */
+        do {
+            apr_status_t rv;
+            /* Validate that '/' drive exists, test must be rooted
+             */
+            newpath = apr_palloc(p, 2);
+            newpath[0] = seperator[0];
+            newpath[1] = '\0';
+            if (flags & APR_FILEPATH_TRUENAME) {
+                rv = filepath_root_test(newpath, p);
+                if (rv)
+                    return rv;
+            }
+
+            /* strip off remaining slashes that designate the root,
+             * give the caller back their original choice of slash
+             * unless this is NATIVED'ed
+             */
+            *inpath = testpath + 1;
+            while (**inpath == '/' || **inpath == '\\')
+                ++*inpath;
+            if (!(flags & APR_FILEPATH_NATIVE))
+                newpath[0] = testpath[0];
+            *rootpath = newpath;
+            return APR_SUCCESS;
+        } while(0);
+#endif
     }
 
+#ifndef _WIN32_WCE
     /* Evaluate path of 'd:[/]' */
     if (IS_FNCHAR(*testpath) && testpath[1] == ':') 
     {
@@ -320,6 +350,7 @@
         *rootpath = newpath;
         return APR_SUCCESS;
     }
+#endif
 
     /* Nothing interesting */
     return APR_ERELATIVE;
Index: file_io/win32/filestat.c
===================================================================
--- file_io/win32/filestat.c	(revision 574284)
+++ file_io/win32/filestat.c	(working copy)
@@ -15,15 +15,19 @@
  */
 
 #include "apr.h"
+#include "apr_private.h"
+#if HAVE_ACLAPI
 #include <aclapi.h>
-#include "apr_private.h"
+#endif
 #include "apr_arch_file_io.h"
 #include "apr_file_io.h"
 #include "apr_general.h"
 #include "apr_strings.h"
 #include "apr_errno.h"
 #include "apr_time.h"
+#ifndef _WIN32_WCE
 #include <sys/stat.h>
+#endif
 #include "apr_arch_atime.h"
 #include "apr_arch_misc.h"
 
@@ -50,6 +54,7 @@
     return APR_SUCCESS;
 }
 
+#ifndef _WIN32_WCE
 static apr_status_t free_localheap(void *heap) {
     LocalFree(heap);
     return APR_SUCCESS;
@@ -64,6 +69,7 @@
         worldid = NULL;
     }
 }
+#endif
 
 /* Left bit shifts from World scope to given scope */
 typedef enum prot_scope_e {
@@ -88,6 +94,7 @@
     return (prot << scope);
 }
 
+#ifndef _WIN32_WCE
 static void resolve_prot(apr_finfo_t *finfo, apr_int32_t wanted, PACL dacl)
 {
     TRUSTEE_W ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID};
@@ -138,6 +145,7 @@
         }
     }
 }
+#endif
 
 static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname,
                                   apr_int32_t wanted, apr_pool_t *pool)
@@ -152,12 +160,12 @@
      * We must open the file with READ_CONTROL if we plan to retrieve the
      * user, group or permissions.
      */
-    
-    if ((rv = apr_file_open(&thefile, fname, APR_OPENINFO
-                          | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0)
-                          | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
-                                ? APR_READCONTROL : 0),
-                            APR_OS_DEFAULT, pool)) == APR_SUCCESS) {
+    rv = apr_file_open(&thefile, fname, APR_OPENINFO
+                       | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0)
+                       | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
+                           ? APR_READCONTROL : 0),
+                       APR_OS_DEFAULT, pool);
+    if (rv == APR_SUCCESS) {
         rv = apr_file_info_get(finfo, wanted, thefile);
         finfo->filehand = NULL;
         apr_file_close(thefile);
@@ -167,9 +175,10 @@
         /* We have a backup plan.  Perhaps we couldn't grab READ_CONTROL?
          * proceed without asking for that permission...
          */
-        if ((rv = apr_file_open(&thefile, fname, APR_OPENINFO
-                              | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0),
-                                APR_OS_DEFAULT, pool)) == APR_SUCCESS) {
+        rv = apr_file_open(&thefile, fname, APR_OPENINFO
+                           | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0),
+                           APR_OS_DEFAULT, pool);
+        if (rv == APR_SUCCESS) {
             rv = apr_file_info_get(finfo, wanted & ~(APR_FINFO_PROT 
                                                  | APR_FINFO_OWNER),
                                  thefile);
@@ -210,12 +219,15 @@
 apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, 
                         apr_int32_t wanted, int whatfile)
 {
+#ifndef _WIN32_WCE
     PSID user = NULL, grp = NULL;
     PACL dacl = NULL;
     apr_status_t rv;
+#endif
 
     if (apr_os_level < APR_WIN_NT)
         guess_protection_bits(finfo);
+#ifndef _WIN32_WCE
     else if (wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
     {
         /* On NT this request is incredibly expensive, but accurate.
@@ -288,6 +300,7 @@
         else if (wanted & APR_FINFO_PROT)
             guess_protection_bits(finfo);
     }
+#endif
 
     return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);
 }
@@ -389,6 +402,7 @@
 
     if (finfo->filetype == APR_REG)
     {
+#ifndef _WIN32_WCE
         /* Go the extra mile to be -certain- that we have a real, regular
          * file, since the attribute bits aren't a certain thing.  Even
          * though fillin should have hinted if we *must* do this, we
@@ -405,6 +419,7 @@
             /* Otherwise leave the original conclusion alone 
              */
         }
+#endif
     }
 
     finfo->pool = thefile->pool;
@@ -481,7 +496,7 @@
              * on a Junction always returns the junction, opening the target
              * is the only way to resolve the target's attributes.
              */
-            if ((ident_rv = resolve_ident(finfo, fname, wanted, pool)) 
+            if ((ident_rv = resolve_ident(finfo, fname, wanted, pool))
                     == APR_SUCCESS)
                 return ident_rv;
             else if (ident_rv == APR_INCOMPLETE)
@@ -579,6 +594,7 @@
         if (fillin_fileinfo(finfo, (WIN32_FILE_ATTRIBUTE_DATA *) &FileInfo, 
                             0, wanted))
         {
+#ifndef _WIN32_WCE
             /* Go the extra mile to assure we have a file.  WinNT/2000 seems
              * to reliably translate char devices to the path '\\.\device'
              * so go ask for the full path.
@@ -634,6 +650,9 @@
             else {
                 finfo->valid &= ~APR_FINFO_TYPE;
             }
+#else
+            finfo->valid &= ~APR_FINFO_TYPE;
+#endif
         }
         finfo->pool = pool;
     }
@@ -646,7 +665,7 @@
     if (wanted &= ~finfo->valid) {
         /* Caller wants more than APR_FINFO_MIN | APR_FINFO_NAME */
 #if APR_HAS_UNICODE_FS
-        if (apr_os_level >= APR_WIN_NT)
+        if (apr_os_level > APR_WIN_UNICODE)
             return more_finfo(finfo, wfname, wanted, MORE_OF_WFSPEC);
 #endif
         return more_finfo(finfo, fname, wanted, MORE_OF_FSPEC);
Index: file_io/win32/filesys.c
===================================================================
--- file_io/win32/filesys.c	(revision 574284)
+++ file_io/win32/filesys.c	(working copy)
@@ -66,6 +66,7 @@
 apr_status_t filepath_root_test(char *path, apr_pool_t *p)
 {
     apr_status_t rv;
+#ifndef _WIN32_WCE
 #if APR_HAS_UNICODE_FS
     if (apr_os_level >= APR_WIN_NT)
     {
@@ -81,6 +82,19 @@
 
     if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
         return APR_EBADPATH;
+#else
+    apr_wchar_t wpath[APR_PATH_MAX];
+    if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
+        / sizeof(apr_wchar_t), path))
+        return rv;
+    if (!CeGetCanonicalPathNameW(wpath, wpath, sizeof(wpath) / sizeof(apr_wchar_t), 0))
+        return apr_get_os_error();
+    /* CE doesn't have "drives"; instead, it uses unix-style paths with a root. Check
+     * for the root at the beginning of a canonical path.
+     */
+    if (wpath[0] != L'\\' && wpath[0] != L'/')
+        return APR_EBADPATH;
+#endif
     return APR_SUCCESS;
 }
 
@@ -92,10 +106,11 @@
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
     {
+        apr_wchar_t wpath[APR_PATH_MAX];
+        apr_status_t rv;
+#ifndef _WIN32_WCE
         apr_wchar_t *ignored;
         apr_wchar_t wdrive[8];
-        apr_wchar_t wpath[APR_PATH_MAX];
-        apr_status_t rv;
         /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:" 
          * as if that is useful for anything.
          */
@@ -103,6 +118,13 @@
         wdrive[0] = (apr_wchar_t)(unsigned char)drive;
         if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
             return apr_get_os_error();
+#else
+        apr_wchar_t wpath2[APR_PATH_MAX];
+        if ((rv = utf8_to_unicode_path(wpath2, sizeof(wpath2) / sizeof(apr_wchar_t), *rootpath)))
+            return rv;
+        if (!CeGetCanonicalPathNameW(wpath2, wpath, sizeof(wpath2) / sizeof(apr_wchar_t), 0))
+            return apr_get_os_error();
+#endif
         if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
             return rv;
     }
@@ -136,7 +158,9 @@
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
     {
+#ifndef _WIN32_WCE
         apr_wchar_t *ignored;
+#endif
         apr_wchar_t wpath[APR_PATH_MAX];
         apr_status_t rv;
         apr_wchar_t wroot[APR_PATH_MAX];
@@ -146,8 +170,13 @@
         if (rv = utf8_to_unicode_path(wroot, sizeof(wroot) 
                                            / sizeof(apr_wchar_t), root))
             return rv;
+#ifndef _WIN32_WCE
         if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
             return apr_get_os_error();
+#else
+        if (!CeGetCanonicalPathNameW(wroot, wpath, sizeof(wpath) / sizeof(apr_wchar_t), 0))
+            return apr_get_os_error();
+#endif
 
         /* Borrow wroot as a char buffer (twice as big as necessary) 
          */
@@ -173,6 +202,9 @@
 APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath, apr_int32_t flags,
                                            apr_pool_t *p)
 {
+#ifdef _WIN32_WCE
+    return APR_ENOTIMPL;
+#else
     char path[APR_PATH_MAX];
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
@@ -200,12 +232,16 @@
     }
     *rootpath = apr_pstrdup(p, path);
     return APR_SUCCESS;
+#endif
 }
 
 
 APR_DECLARE(apr_status_t) apr_filepath_set(const char *rootpath,
                                            apr_pool_t *p)
 {
+#ifdef _WIN32_WCE
+    return APR_ENOTIMPL;
+#else
 #if APR_HAS_UNICODE_FS
     IF_WIN_OS_IS_UNICODE
     {
@@ -226,4 +262,5 @@
     }
 #endif
     return APR_SUCCESS;
+#endif
 }
Index: file_io/win32/flock.c
===================================================================
--- file_io/win32/flock.c	(revision 574284)
+++ file_io/win32/flock.c	(working copy)
@@ -18,23 +18,20 @@
 
 APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type)
 {
-#ifdef _WIN32_WCE
-    /* The File locking is unsuported on WCE */
-    return APR_ENOTIMPL;
-#else
     const DWORD len = 0xffffffff;
     DWORD flags; 
 
     flags = ((type & APR_FLOCK_NONBLOCK) ? LOCKFILE_FAIL_IMMEDIATELY : 0)
           + (((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED) 
                                        ? 0 : LOCKFILE_EXCLUSIVE_LOCK);
-    if (apr_os_level >= APR_WIN_NT) {
+    if (apr_os_level >= APR_WIN_CE_5) {
         /* Syntax is correct, len is passed for LengthLow and LengthHigh*/
         OVERLAPPED offset;
         memset (&offset, 0, sizeof(offset));
         if (!LockFileEx(thefile->filehand, flags, 0, len, len, &offset))
             return apr_get_os_error();
     }
+#ifndef _WIN32_WCE
     else {
         /* On Win9x, LockFile() never blocks.  Hack in a crufty poll.
          *
@@ -57,30 +54,36 @@
             return APR_FROM_OS_ERROR(err);
         }
     }
+#else
+    else {
+        return APR_ENOTIMPL;
+    }
+#endif
 
     return APR_SUCCESS;
-#endif /* !defined(_WIN32_WCE) */
 }
 
 APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile)
 {
-#ifdef _WIN32_WCE
-    return APR_ENOTIMPL;
-#else
     DWORD len = 0xffffffff;
 
-    if (apr_os_level >= APR_WIN_NT) {
+    if (apr_os_level >= APR_WIN_CE_5) {
         /* Syntax is correct, len is passed for LengthLow and LengthHigh*/
         OVERLAPPED offset;
         memset (&offset, 0, sizeof(offset));
         if (!UnlockFileEx(thefile->filehand, 0, len, len, &offset))
             return apr_get_os_error();
     }
+#ifndef _WIN32_WCE
     else {
         if (!UnlockFile(thefile->filehand, 0, 0, len, 0))
             return apr_get_os_error();
     }
+#else
+    else {
+        return APR_ENOTIMPL;
+    }
+#endif
 
     return APR_SUCCESS;
-#endif /* !defined(_WIN32_WCE) */
 }
Index: file_io/win32/open.c
===================================================================
--- file_io/win32/open.c	(revision 574284)
+++ file_io/win32/open.c	(working copy)
@@ -226,11 +226,11 @@
     apr_status_t flush_rv = APR_SUCCESS;
 
     if (file->filehand != INVALID_HANDLE_VALUE) {
-
         /* In order to avoid later segfaults with handle 'reuse',
          * we must protect against the case that a dup2'ed handle
          * is being closed, and invalidate the corresponding StdHandle 
          */
+#ifndef _WIN32_WCE
         if (file->filehand == GetStdHandle(STD_ERROR_HANDLE)) {
             SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
         }
@@ -240,12 +240,20 @@
         if (file->filehand == GetStdHandle(STD_INPUT_HANDLE)) {
             SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);
         }
-
+#endif
         if (file->buffered) {
             /* XXX: flush here is not mutex protected */
             flush_rv = apr_file_flush((apr_file_t *)thefile);
         }
+#ifdef _WIN32_WCE
+        if (file->filehand != STDIN_FILENO
+            && file->filehand != STDOUT_FILENO
+            && file->filehand != STDERR_FILENO) {
+            CloseHandle(file->filehand);
+        }
+#else
         CloseHandle(file->filehand);
+#endif
         file->filehand = INVALID_HANDLE_VALUE;
     }
     if (file->pOverlapped && file->pOverlapped->hEvent) {
@@ -272,8 +280,10 @@
     if (flag & APR_WRITE) {
         oflags |= GENERIC_WRITE;
     }
-    if (flag & APR_WRITEATTRS) {
-        oflags |= FILE_WRITE_ATTRIBUTES;
+    if (apr_os_level < APR_WIN_CE_3 || apr_os_level >= APR_WIN_NT) {
+        if (flag & APR_WRITEATTRS) {
+            oflags |= FILE_WRITE_ATTRIBUTES;
+        }
     }
 
     if (apr_os_level >= APR_WIN_NT) 
@@ -302,12 +312,14 @@
         return APR_EACCES;
     }   
     
-    if (flag & APR_DELONCLOSE) {
-        attributes |= FILE_FLAG_DELETE_ON_CLOSE;
-    }
+    if (apr_os_level < APR_WIN_CE_3 || apr_os_level >= APR_WIN_NT) {
+        if (flag & APR_DELONCLOSE) {
+            attributes |= FILE_FLAG_DELETE_ON_CLOSE;
+        }
 
-    if (flag & APR_OPENLINK) {
-       attributes |= FILE_FLAG_OPEN_REPARSE_POINT;
+        if (flag & APR_OPENLINK) {
+           attributes |= FILE_FLAG_OPEN_REPARSE_POINT;
+        }
     }
 
     /* Without READ or WRITE, we fail unless apr called apr_file_open
@@ -326,15 +338,19 @@
         else {
             return APR_EACCES;
         }
-        if (flag & APR_READCONTROL)
-            oflags |= READ_CONTROL;
+        if (apr_os_level < APR_WIN_CE_3 || apr_os_level >= APR_WIN_NT) {
+            if (flag & APR_READCONTROL)
+                oflags |= READ_CONTROL;
+        }
     }
 
-    if (flag & APR_XTHREAD) {
-        /* This win32 specific feature is required 
-         * to allow multiple threads to work with the file.
-         */
-        attributes |= FILE_FLAG_OVERLAPPED;
+    if (apr_os_level < APR_WIN_CE_3 || apr_os_level >= APR_WIN_NT) {
+        if (flag & APR_XTHREAD) {
+            /* This win32 specific feature is required 
+             * to allow multiple threads to work with the file.
+             */
+            attributes |= FILE_FLAG_OVERLAPPED;
+        }
     }
 
 #if APR_HAS_UNICODE_FS
@@ -470,10 +486,28 @@
 #ifndef _WIN32_WCE
         if (MoveFileExW(wfrompath, wtopath, MOVEFILE_REPLACE_EXISTING |
                                             MOVEFILE_COPY_ALLOWED))
+            return APR_SUCCESS;
 #else
+        /* Windows CE does not support MoveFileEx, so we'll use
+         * the old MoveFile function.  However, MoveFile requires that
+         * the new file not already exist...so we have to delete that
+         * file if it does.  Perhaps we should back up the to-be-deleted
+         * file in case something happens?
+         */
+        do {
+            HANDLE handle = INVALID_HANDLE_VALUE;
+
+            if ((handle = CreateFileW(wtopath, GENERIC_WRITE, 0, 0,  
+                OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE )
+            {
+                CloseHandle(handle);
+                if (!DeleteFileW(wtopath))
+                    return apr_get_os_error();
+            }
+        } while (0);
         if (MoveFileW(wfrompath, wtopath))
+            return APR_SUCCESS;
 #endif
-            return APR_SUCCESS;
 #else
         if (MoveFileEx(frompath, topath, MOVEFILE_REPLACE_EXISTING |
                                          MOVEFILE_COPY_ALLOWED))
@@ -567,13 +601,14 @@
 
 APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile, apr_pool_t *pool)
 {
-#ifdef _WIN32_WCE
-    return APR_ENOTIMPL;
-#else
     apr_os_file_t file_handle;
 
     apr_set_os_error(APR_SUCCESS);
+#ifndef _WIN32_WCE
     file_handle = GetStdHandle(STD_ERROR_HANDLE);
+#else
+    file_handle = STDERR_FILENO;
+#endif
     if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
         apr_status_t rv = apr_get_os_error();
         if (rv == APR_SUCCESS) {
@@ -583,18 +618,18 @@
     }
 
     return apr_os_file_put(thefile, &file_handle, 0, pool);
-#endif
 }
 
 APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile, apr_pool_t *pool)
 {
-#ifdef _WIN32_WCE
-    return APR_ENOTIMPL;
-#else
     apr_os_file_t file_handle;
 
     apr_set_os_error(APR_SUCCESS);
+#ifndef _WIN32_WCE
     file_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+#else
+    file_handle = STDOUT_FILENO;
+#endif
     if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
         apr_status_t rv = apr_get_os_error();
         if (rv == APR_SUCCESS) {
@@ -604,18 +639,18 @@
     }
 
     return apr_os_file_put(thefile, &file_handle, 0, pool);
-#endif
 }
 
 APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile, apr_pool_t *pool)
 {
-#ifdef _WIN32_WCE
-    return APR_ENOTIMPL;
-#else
     apr_os_file_t file_handle;
 
     apr_set_os_error(APR_SUCCESS);
+#ifndef _WIN32_WCE
     file_handle = GetStdHandle(STD_INPUT_HANDLE);
+#else
+    file_handle = STDIN_FILENO;
+#endif
     if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
         apr_status_t rv = apr_get_os_error();
         if (rv == APR_SUCCESS) {
@@ -625,7 +660,6 @@
     }
 
     return apr_os_file_put(thefile, &file_handle, 0, pool);
-#endif
 }
 
 APR_POOL_IMPLEMENT_ACCESSOR(file);
Index: file_io/win32/readwrite.c
===================================================================
--- file_io/win32/readwrite.c	(revision 574284)
+++ file_io/win32/readwrite.c	(working copy)
@@ -40,6 +40,7 @@
          * If data is available, go ahead and read it.
          */
         if (file->pipe) {
+#ifndef _WIN32_WCE
             DWORD bytes;
             if (!PeekNamedPipe(file->filehand, NULL, 0, NULL, &bytes, NULL)) {
                 rv = apr_get_os_error();
@@ -58,6 +59,7 @@
                     len = bytes;
                 }
             }
+#endif
         }
         else {
             /* ToDo: Handle zero timeout non-blocking file i/o 
@@ -72,13 +74,20 @@
         file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
     }
 
+#ifndef _WIN32_WCE
     rv = ReadFile(file->filehand, buf, len, 
                   &bytesread, file->pOverlapped);
+#else
+    rv = ReadFile(file->filehand, buf, len, 
+                  &bytesread, NULL);
+#endif
     *nbytes = bytesread;
 
     if (!rv) {
         rv = apr_get_os_error();
-        if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
+        if (0) {}
+#ifndef _WIN32_WCE
+        else if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
             /* Wait for the pending i/o */
             if (file->timeout > 0) {
                 /* timeout in milliseconds... */
@@ -114,6 +123,7 @@
                 }
             }
         }
+#endif
         else if (rv == APR_FROM_OS_ERROR(ERROR_BROKEN_PIPE)) {
             /* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
             rv = APR_EOF;
@@ -144,6 +154,10 @@
         return APR_SUCCESS;
     }
 
+    /* CE doesn't support overlapped I/O, but "supports" thread-safe
+     * file access natively.
+     */
+#ifndef _WIN32_WCE
     /* If the file is open for xthread support, allocate and
      * initialize the overlapped and io completion event (hEvent). 
      * Threads should NOT share an apr_file_t or its hEvent.
@@ -157,6 +171,7 @@
             return rv;
         }
     }
+#endif
 
     /* Handle the ungetchar if there is one */
     if (thefile->ungetchar != -1) {
@@ -235,6 +250,10 @@
     apr_status_t rv;
     DWORD bwrote;
 
+    /* CE doesn't support overlapped I/O, but "supports" thread-safe
+     * file access natively.
+     */
+#ifndef _WIN32_WCE
     /* If the file is open for xthread support, allocate and
      * initialize the overlapped and io completion event (hEvent). 
      * Threads should NOT share an apr_file_t or its hEvent.
@@ -248,6 +267,7 @@
             return rv;
         }
     }
+#endif
 
     if (thefile->buffered) {
         char *pos = (char *)buf;
@@ -307,16 +327,37 @@
                 thefile->pOverlapped->Offset     = (DWORD)thefile->filePtr;
                 thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
             }
+#ifndef _WIN32_WCE
             rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
                            thefile->pOverlapped);
+#else
+            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
+                           NULL);
+            /* WriteFile() fails upon writing zero amount when "appending" to
+             * a file. Succeeds in writing zero amount in all other cases.
+             * Most likely has something to do with SetFilePointer() being
+             * called. Tried using SetEndOfFile(), but didn't help.
+             *
+             * Just pretend it succeeded in, essentially, not doing anything.
+             */
+            if (rv == 0 && *nbytes == 0) {
+                rv = 1;
+                bwrote = 0;
+            }
+#endif
             if (thefile->append) {
                 apr_file_unlock(thefile);
                 apr_thread_mutex_unlock(thefile->mutex);
             }
         }
         else {
+#ifndef _WIN32_WCE
             rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
                            thefile->pOverlapped);
+#else
+            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
+                           NULL);
+#endif
         }
         if (rv) {
             *nbytes = bwrote;
@@ -325,6 +366,7 @@
         else {
             (*nbytes) = 0;
             rv = apr_get_os_error();
+#ifndef _WIN32_WCE
             if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
  
                 DWORD timeout_ms;
@@ -361,6 +403,7 @@
                         CancelIo(thefile->filehand);
                 }
             }
+#endif
         }
         if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
             thefile->filePtr += *nbytes;
@@ -492,6 +535,10 @@
                 bytesleft -= written;
                 buffer += written;
 
+                if (!FlushFileBuffers(thefile->filehand)) {
+                  rc = apr_get_os_error();
+                  break;
+                }
             } while (bytesleft > 0);
 
             if (rc == 0)
Index: file_io/win32/seek.c
===================================================================
--- file_io/win32/seek.c	(revision 574284)
+++ file_io/win32/seek.c	(working copy)
@@ -16,7 +16,6 @@
 
 #include "win32/apr_arch_file_io.h"
 #include "apr_file_io.h"
-#include <errno.h>
 #include <string.h>
 
 static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
@@ -101,6 +100,10 @@
         *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
         return rc;
     }
+    /* CE doesn't support overlapped i/o, therefore, fallback to letting the
+     * OS handle the file pointer.
+     */
+#ifndef _WIN32_WCE
     /* A file opened with APR_XTHREAD has been opened for overlapped i/o. 
      * APR must explicitly track the file pointer in this case.
      */
@@ -126,6 +129,7 @@
         *offset = thefile->filePtr;
         return rc;
     }
+#endif
     else {
         DWORD howmove;
         DWORD offlo = (DWORD)*offset;
Index: include/apr.hw
===================================================================
--- include/apr.hw	(revision 574284)
+++ include/apr.hw	(working copy)
@@ -74,12 +74,6 @@
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
-#ifndef _WIN32_WINNT
-
-/* Restrict the server to a subset of Windows NT 4.0 header files by default
- */
-#define _WIN32_WINNT 0x0400
-#endif
 #ifndef NOUSER
 #define NOUSER
 #endif
@@ -96,13 +90,9 @@
  * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
  */
 #define SW_HIDE             0
-#ifndef _WIN32_WCE
 #include <winsock2.h>
 #include <mswsock.h>
 #include <ws2tcpip.h>
-#else
-#include <winsock.h>
-#endif
 #endif /* !_WINDOWS_ */
 
 /**
@@ -217,7 +207,7 @@
 #define APR_HAVE_IN_ADDR        1
 #define APR_HAVE_INET_ADDR      1
 #define APR_HAVE_INET_NETWORK   0
-#define APR_HAVE_IPV6           0
+#define APR_HAVE_IPV6           1
 #define APR_HAVE_MEMMOVE        1
 #define APR_HAVE_SETRLIMIT      0
 #define APR_HAVE_SIGACTION      0
@@ -231,14 +221,12 @@
 #define APR_HAVE_STRUCT_RLIMIT  0
 #define APR_HAVE_UNION_SEMUN    0
 #define APR_HAVE_SCTP           0
-
-#ifndef _WIN32_WCE
 #define APR_HAVE_STRICMP        1
 #define APR_HAVE_STRNICMP       1
+
+#ifndef _WIN32_WCE
 #define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 1
 #else
-#define APR_HAVE_STRICMP        0
-#define APR_HAVE_STRNICMP       0
 #define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
 #endif
 
@@ -503,7 +491,7 @@
 #define STDOUT_FILENO 1
 #define STDERR_FILENO 2
 
-#if APR_HAS_UNICODE_FS
+#if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)
 /* An arbitrary size that is digestable. True max is a bit less than 32000 */
 #define APR_PATH_MAX 8192
 #else /* !APR_HAS_UNICODE_FS */
Index: include/apr_errno.h
===================================================================
--- include/apr_errno.h	(revision 574284)
+++ include/apr_errno.h	(working copy)
@@ -329,9 +329,13 @@
  * APR was unable to open the dso object.  
  * For more information call apr_dso_error().
  */
-#if defined(WIN32)
+#if defined(_WIN32_WCE)
 #define APR_STATUS_IS_EDSOOPEN(s)       ((s) == APR_EDSOOPEN \
+                       || APR_TO_OS_ERROR(s) == ERROR_INVALID_PARAMETER \
                        || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND)
+#elif defined(WIN32)
+#define APR_STATUS_IS_EDSOOPEN(s)       ((s) == APR_EDSOOPEN \
+                       || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND)
 #else
 #define APR_STATUS_IS_EDSOOPEN(s)       ((s) == APR_EDSOOPEN)
 #endif
@@ -350,9 +354,13 @@
 /** Could not find the requested symbol.
  * For more information call apr_dso_error().
  */
-#if defined(WIN32)
+#if defined(_WIN32_WCE)
 #define APR_STATUS_IS_ESYMNOTFOUND(s)   ((s) == APR_ESYMNOTFOUND \
+                       || APR_TO_OS_ERROR(s) == ERROR_INVALID_HANDLE \
                        || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND)
+#elif defined(WIN32)
+#define APR_STATUS_IS_ESYMNOTFOUND(s)   ((s) == APR_ESYMNOTFOUND \
+                       || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND)
 #else
 #define APR_STATUS_IS_ESYMNOTFOUND(s)   ((s) == APR_ESYMNOTFOUND)
 #endif
Index: include/apr_general.h
===================================================================
--- include/apr_general.h	(revision 574284)
+++ include/apr_general.h	(working copy)
@@ -115,13 +115,21 @@
  * have it
  */
 #if (!APR_HAVE_STRCASECMP) && (APR_HAVE_STRICMP) 
+#ifdef _WIN32_WCE
+#define strcasecmp(s1, s2) _stricmp(s1, s2)
+#else
 #define strcasecmp(s1, s2) stricmp(s1, s2)
+#endif
 #elif (!APR_HAVE_STRCASECMP)
 int strcasecmp(const char *a, const char *b);
 #endif
 
 #if (!APR_HAVE_STRNCASECMP) && (APR_HAVE_STRNICMP)
+#ifdef _WIN32_WCE
+#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
+#else
 #define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
+#endif
 #elif (!APR_HAVE_STRNCASECMP)
 int strncasecmp(const char *a, const char *b, size_t n);
 #endif
Index: include/arch/win32/apr_arch_misc.h
===================================================================
--- include/arch/win32/apr_arch_misc.h	(revision 574284)
+++ include/arch/win32/apr_arch_misc.h	(working copy)
@@ -85,9 +85,12 @@
 	APR_WIN_UNICODE =  20, /* Prior versions support only narrow chars */
 
         APR_WIN_CE_3 =     23, /* CE is an odd beast, not supporting */
-                               /* some pre-NT features, such as the    */
-        APR_WIN_NT =       30, /* narrow charset APIs (fooA fns), while  */
-        APR_WIN_NT_3_5 =   35, /* not supporting some NT-family features.  */
+        APR_WIN_CE_4 =     24, /* some pre-NT features, such as the    */
+        APR_WIN_CE_5 =     25, /* narrow charset APIs (fooA fns), while  */
+        APR_WIN_CE_6 =     26, /* not supporting some NT-family features.  */
+
+        APR_WIN_NT =       30,
+        APR_WIN_NT_3_5 =   35,
         APR_WIN_NT_3_51 =  36,
 
         APR_WIN_NT_4 =     40,
@@ -138,6 +141,8 @@
 #define ELSE_WIN_OS_IS_ANSI
 #endif /* WINNT */
 
+#if !defined(_WIN32_WCE)
+
 typedef enum {
     DLL_WINBASEAPI = 0,    // kernel32 From WinBase.h
     DLL_WINADVAPI = 1,     // advapi32 From WinBase.h
@@ -159,8 +164,10 @@
     {   if (!apr_winapi_pfn_##fn) \
             apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
                                       apr_load_dll_func(lib, #fn, ord); \
-        return (*(apr_winapi_pfn_##fn)) names; }; \
+        return (*(apr_winapi_pfn_##fn)) names; };
 
+#endif /* !defined(_WIN32_WCE) */
+
 /* Provide late bound declarations of every API function missing from
  * one or more supported releases of the Win32 API
  *
Index: include/arch/win32/apr_arch_networkio.h
===================================================================
--- include/arch/win32/apr_arch_networkio.h	(revision 574284)
+++ include/arch/win32/apr_arch_networkio.h	(working copy)
@@ -50,13 +50,17 @@
      */
     OVERLAPPED         *overlapped;
 #endif
+#if _WIN32_WCE > 0x400
+    /* Needed in CE to implement blocking sockets that timeout. */
+    WSAOVERLAPPED      *wsaoverlapped;
+#endif
     sock_userdata_t    *userdata;
 
     /* if there is a timeout set, then this pollset is used */
     apr_pollset_t *pollset;
 };
 
-#ifdef _WIN32_WCE
+#if _WIN32_WCE < 0x500
 #ifndef WSABUF
 typedef struct _WSABUF {
     u_long      len;     /* the length of the buffer */
Index: include/arch/win32/apr_private.h
===================================================================
--- include/arch/win32/apr_private.h	(revision 574284)
+++ include/arch/win32/apr_private.h	(working copy)
@@ -134,7 +134,9 @@
 
 #if !APR_HAVE_ERRNO_H
 APR_DECLARE_DATA int errno;
-#define ENOSPC 1
+#define ENOSPC 28
+#define EINVAL 22
+#define ERANGE 34
 #endif
 
 #if APR_HAVE_IPV6
@@ -161,6 +163,10 @@
 #endif
 #endif
 
+#if defined(_WIN32_WCE) && !defined(BUFSIZ)
+#define BUFSIZ 512
+#endif
+
 /* used to check for DWORD overflow in 64bit compiles */
 #define APR_DWORD_MAX 0xFFFFFFFFUL
 
Index: misc/win32/internal.c
===================================================================
--- misc/win32/internal.c	(revision 574284)
+++ misc/win32/internal.c	(working copy)
@@ -18,7 +18,9 @@
 
 #include "apr_arch_misc.h"
 #include "apr_arch_file_io.h"
+#ifndef _WIN32_WCE
 #include <crtdbg.h>
+#endif
 #include <assert.h>
 
 /* This module is the source of -static- helper functions that are
@@ -52,8 +54,12 @@
             ;
     }
 
+#ifndef _WIN32_WCE
     newarr = _malloc_dbg((args + 1) * sizeof(char *),
                          _CRT_BLOCK, __FILE__, __LINE__);
+#else
+    newarr = malloc((args + 1) * sizeof(char *));
+#endif
 
     for (arg = 0; arg < args; ++arg) {
         newarr[arg] = (void*)(wcslen(arr[arg]) + 1);
@@ -66,8 +72,12 @@
      * 4 ucs bytes will hold a wchar_t pair value (20 bits)
      */
     elesize = elesize * 3 + 1;
+#ifndef _WIN32_WCE
     ele = elements = _malloc_dbg(elesize * sizeof(char), 
                                  _CRT_BLOCK, __FILE__, __LINE__);
+#else
+    ele = elements = malloc(elesize * sizeof(char));
+#endif
 
     for (arg = 0; arg < args; ++arg) {
         apr_size_t len = (apr_size_t)newarr[arg];
@@ -87,8 +97,12 @@
 
     /* Return to the free store if the heap realloc is the least bit optimized
      */
+#ifndef _WIN32_WCE
     ele = _realloc_dbg(elements, ele - elements, 
                        _CRT_BLOCK, __FILE__, __LINE__);
+#else
+    ele = realloc(elements, ele - elements);
+#endif
 
     if (ele != elements) {
         apr_size_t diff = ele - elements;
Index: misc/win32/misc.c
===================================================================
--- misc/win32/misc.c	(revision 574284)
+++ misc/win32/misc.c	(working copy)
@@ -16,7 +16,9 @@
 
 #include "apr_private.h"
 #include "apr_arch_misc.h"
+#ifndef _WIN32_WCE
 #include "crtdbg.h"
+#endif
 #include "apr_arch_file_io.h"
 #include "assert.h"
 #include "apr_lib.h"
@@ -31,8 +33,12 @@
         oslev.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
         GetVersionEx(&oslev);
 
-        if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT) 
+        if (0)
         {
+        }
+#ifdef WINNT
+        else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT) 
+        {
             static unsigned int servpack = 0;
             char *pservpack;
             if (pservpack = oslev.szCSDVersion) {
@@ -96,7 +102,7 @@
                 apr_os_level = APR_WIN_XP;
             }
         }
-#ifndef WINNT
+#elif !defined(WINNT) && !defined(_WIN32_WCE)
         else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
             char *prevision;
             if (prevision = oslev.szCSDVersion) {
@@ -122,16 +128,24 @@
                 apr_os_level = APR_WIN_ME;
             }
         }
-#endif
-#ifdef _WIN32_WCE
+#elif defined(_WIN32_WCE)
         else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_CE) 
         {
             if (oslev.dwMajorVersion < 3) {
                 apr_os_level = APR_WIN_UNSUP;
             }
-            else {
+            else if (oslev.dwMajorVersion < 4) {
                 apr_os_level = APR_WIN_CE_3;
             }
+            else if (oslev.dwMajorVersion < 5) {
+                apr_os_level = APR_WIN_CE_4;
+            }
+            else if (oslev.dwMajorVersion < 6) {
+                apr_os_level = APR_WIN_CE_5;
+            }
+            else {
+                apr_os_level = APR_WIN_CE_6;
+            }
         }
 #endif
         else {
@@ -148,7 +162,7 @@
     return APR_SUCCESS;
 }
 
-
+#if !defined(_WIN32_WCE)
 /* This is the helper code to resolve late bound entry points 
  * missing from one or more releases of the Win32 API
  */
@@ -170,6 +184,7 @@
     else
         return GetProcAddress(lateDllHandle[fnLib], fnName);
 }
+#endif
 
 /* Declared in include/arch/win32/apr_dbg_win32_handles.h
  */
@@ -196,11 +211,23 @@
         (TlsSetValue)(tlsid, sbuf);
         sbuf[1023] = '\0';
         if (!fh) {
+/* CE only has Unicode API. */
+#ifdef _WIN32_WCE
+            wchar_t *wsbuf = malloc(1024);
+            wsbuf[1023] = L'\0';
+            (GetModuleFileNameW)(NULL, wsbuf, 250);
+            swprintf(wcschr(wsbuf, L'\0'), L".%d",
+                    (GetCurrentProcessId)());
+            fh = (CreateFileW)(wsbuf, GENERIC_WRITE, 0, NULL, 
+                            CREATE_ALWAYS, 0, NULL);
+            free(wsbuf);
+#else
             (GetModuleFileName)(NULL, sbuf, 250);
             sprintf(strchr(sbuf, '\0'), ".%d",
                     (GetCurrentProcessId)());
             fh = (CreateFile)(sbuf, GENERIC_WRITE, 0, NULL, 
                             CREATE_ALWAYS, 0, NULL);
+#endif
             (InitializeCriticalSection)(&cs);
         }
     }
Index: misc/win32/rand.c
===================================================================
--- misc/win32/rand.c	(revision 574284)
+++ misc/win32/rand.c	(working copy)
@@ -20,8 +20,10 @@
 #include "apr_general.h"
 #include "apr_portable.h"
 #include "apr_arch_misc.h"
+#ifdef _WIN32_WCE
+#include <objbase.h>
+#endif
 
-
 APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf,
                                                     apr_size_t length)
 {
@@ -32,7 +34,12 @@
      * and will only work for Win2K and later.
      */
     DWORD flags = CRYPT_VERIFYCONTEXT
+#ifndef _WIN32_WCE
                 | ((apr_os_level >= APR_WIN_2000) ? 0x40 : 0);
+#else
+    /* CRYPT_SILENT works on CE from the beginning of CryptAcquireContext(). */
+                | CRYPT_SILENT;
+#endif
 
     if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, flags)) {
 	return apr_get_os_error();
@@ -61,7 +68,11 @@
      * Note that Win2000, XP and later no longer suffer from this problem,
      * a scrambling fix is only needed for (apr_os_level < APR_WIN_2000)
      */
+#ifndef _WIN32_WCE
     if (FAILED(UuidCreate((UUID *)uuid_data))) {
+#else
+    if (FAILED(CoCreateGuid((UUID *)uuid_data))) {
+#endif
         return APR_EGENERAL;
     }
     return APR_SUCCESS;
Index: misc/win32/start.c
===================================================================
--- misc/win32/start.c	(revision 574284)
+++ misc/win32/start.c	(working copy)
@@ -24,7 +24,9 @@
 #include "wchar.h"
 #include "apr_arch_file_io.h"    /* bring in unicode-ness */
 #include "apr_arch_threadproc.h" /* bring in apr_threadproc_init */
+#ifndef _WIN32_WCE
 #include "crtdbg.h"
+#endif
 #include "assert.h"
 
 /* This symbol is _private_, although it must be exported.
Index: mmap/win32/mmap.c
===================================================================
--- mmap/win32/mmap.c	(revision 574284)
+++ mmap/win32/mmap.c	(working copy)
@@ -75,6 +75,12 @@
     DWORD mvaccess = 0;
     DWORD offlo;
     DWORD offhi;
+#ifdef _WIN32_WCE
+    apr_wchar_t wfname[APR_PATH_MAX];
+    apr_status_t rv;
+    DWORD oflags = 0;
+    HANDLE fhandle;
+#endif
 
     if (size == 0)
         return APR_EINVAL;
@@ -104,13 +110,40 @@
     (*new)->pstart = (offset / memblock) * memblock;
     (*new)->poffset = offset - (*new)->pstart;
     (*new)->psize = (apr_size_t)((*new)->poffset) + size;
+#ifndef _WIN32_WCE
     /* The size of the CreateFileMapping object is the current size
      * of the size of the mmap object (e.g. file size), not the size 
      * of the mapped region!
      */
-
     (*new)->mhandle = CreateFileMapping(file->filehand, NULL, fmaccess,
                                         0, 0, NULL);
+#else
+    rv = utf8_to_unicode_path(wfname, APR_PATH_MAX, file->fname);
+    if (rv != APR_SUCCESS) {
+        *new = NULL;
+        return rv;
+    }
+    /* Need to use CreateFileForMapping() on CE to ensure MMap files work.
+     * CE ignores the sharemode parameter. Instead, it grants the same
+     * share mode as the desired access (open) flags.
+     */
+    if (flag & APR_MMAP_WRITE)
+        oflags = GENERIC_READ | GENERIC_WRITE;
+    else if (flag & APR_MMAP_READ)
+        oflags |= GENERIC_READ;
+    fhandle = CreateFileForMappingW(wfname, oflags, 0, NULL,
+                                    OPEN_EXISTING, 0, NULL);
+    if (!fhandle || fhandle == INVALID_HANDLE_VALUE) {
+        *new = NULL;
+        return apr_get_os_error();
+    }
+    /* The size of the CreateFileMapping object is the current size
+     * of the size of the mmap object (e.g. file size), not the size 
+     * of the mapped region!
+     */
+    (*new)->mhandle = CreateFileMapping(fhandle, NULL, fmaccess,
+                                        0, 0, NULL);
+#endif
     if (!(*new)->mhandle || (*new)->mhandle == INVALID_HANDLE_VALUE)
     {
         *new = NULL;
Index: network_io/unix/multicast.c
===================================================================
--- network_io/unix/multicast.c	(revision 574284)
+++ network_io/unix/multicast.c	(working copy)
@@ -185,7 +185,11 @@
 
             if (setsockopt(sock->socketdes, IPPROTO_IP, type,
                            (const void *) &mip4, sizeof(mip4)) == -1) {
+#ifndef _WIN32_WCE
                 rv = errno;
+#else
+                rv = apr_get_netos_error();
+#endif
             }
         }
 #if APR_HAVE_IPV6 && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
@@ -204,7 +208,11 @@
 
             if (setsockopt(sock->socketdes, IPPROTO_IPV6, type,
                            &mip6, sizeof(mip6)) == -1) {
+#ifndef _WIN32_WCE
                 rv = errno;
+#else
+                rv = apr_get_netos_error();
+#endif
             }
         }
 #endif
@@ -229,7 +237,11 @@
     if (sock_is_ipv4(sock)) {
         if (setsockopt(sock->socketdes, IPPROTO_IP, type,
                        (const void *) &value, sizeof(value)) == -1) {
+#ifndef _WIN32_WCE
             rv = errno;
+#else
+            rv = apr_get_netos_error();
+#endif
         }
     }
 #if APR_HAVE_IPV6
@@ -238,7 +250,11 @@
         type = IPV6_MULTICAST_LOOP;
         if (setsockopt(sock->socketdes, IPPROTO_IPV6, type,
                        &loopopt, sizeof(loopopt)) == -1) {
+#ifndef _WIN32_WCE
             rv = errno;
+#else
+            rv = apr_get_netos_error();
+#endif
         }
     }
     else if (sock_is_ipv6(sock)) {
@@ -251,7 +267,11 @@
 
         if (setsockopt(sock->socketdes, IPPROTO_IPV6, type,
                        &value, sizeof(value)) == -1) {
+#ifndef _WIN32_WCE
             rv = errno;
+#else
+            rv = apr_get_netos_error();
+#endif
         }
     }
 #endif
@@ -316,7 +336,11 @@
         if (setsockopt(sock->socketdes, IPPROTO_IP, IP_MULTICAST_IF,
                        (const void *) &iface->sa.sin.sin_addr,
                        sizeof(iface->sa.sin.sin_addr)) == -1) {
+#ifndef _WIN32_WCE
             rv = errno;
+#else
+            rv = apr_get_netos_error();
+#endif
         }
     }
 #if APR_HAVE_IPV6
@@ -324,7 +348,11 @@
         unsigned int idx = find_if_index(iface);
         if (setsockopt(sock->socketdes, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                        &idx, sizeof(idx)) == -1) {
+#ifndef _WIN32_WCE
             rv = errno;
+#else
+            rv = apr_get_netos_error();
+#endif
         }
     }
 #endif
Index: network_io/unix/sockaddr.c
===================================================================
--- network_io/unix/sockaddr.c	(revision 574284)
+++ network_io/unix/sockaddr.c	(working copy)
@@ -58,16 +58,6 @@
 #define GETHOSTBYNAME_BUFLEN 512
 #endif
 
-#ifdef _WIN32_WCE
-/* XXX: BS solution.  Need an HAVE_GETSERVBYNAME and actually
- * do something here, to provide the obvious proto mappings.
- */
-static void *getservbyname(const char *name, const char *proto)
-{
-    return NULL;
-}
-#endif
-
 static apr_status_t get_local_addr(apr_socket_t *sock)
 {
     sock->local_addr->salen = sizeof(sock->local_addr->sa);
@@ -706,7 +696,11 @@
         sockaddr->sa.sin.sin_port = se->s_port;
         return APR_SUCCESS;
     }
+#ifndef _WIN32_WCE
     return errno;
+#else
+    return apr_get_netos_error();
+#endif
 }
 
 #define V4MAPPED_EQUAL(a,b)                                   \
Index: network_io/win32/sendrecv.c
===================================================================
--- network_io/win32/sendrecv.c	(revision 574284)
+++ network_io/win32/sendrecv.c	(working copy)
@@ -41,22 +41,52 @@
 {
     apr_ssize_t rv;
     WSABUF wsaData;
-    int lasterror;
     DWORD dwBytes = 0;
+    apr_status_t wsarv;
 
     wsaData.len = (u_long)*len;
     wsaData.buf = (char*) buf;
 
 #ifndef _WIN32_WCE
     rv = WSASend(sock->socketdes, &wsaData, 1, &dwBytes, 0, NULL, NULL);
+#elif _WIN32_WCE > 0x400
+    rv = WSASend(sock->socketdes, &wsaData, 1, &dwBytes, 0,
+                 sock->wsaoverlapped, NULL);
+    if (rv == SOCKET_ERROR) {
+        wsarv = apr_get_netos_error();
+        if (wsarv == APR_FROM_OS_ERROR(WSA_IO_PENDING)) {
+            rv = WSAWaitForMultipleEvents(1, &sock->wsaoverlapped->hEvent,
+                                          FALSE, sock->timeout_ms >= 0
+                                                 ? sock->timeout_ms
+                                                 : WSA_INFINITE, FALSE);
+            if (rv == WSA_WAIT_EVENT_0) {
+                if (WSAResetEvent(sock->wsaoverlapped->hEvent)) {
+                    DWORD flags = 0;
+                    if (!WSAGetOverlappedResult(sock->socketdes,
+                        sock->wsaoverlapped, &dwBytes, FALSE, &flags)) {
+                        rv = SOCKET_ERROR;
+                    }
+                }
+                else {
+                    rv = SOCKET_ERROR;
+                }
+            }
+            else {
+                apr_set_netos_error(rv);
+                rv = SOCKET_ERROR;
+            }
+        }
+        else {
+            apr_set_netos_error(wsarv);
+        }
+    }
 #else
     rv = send(sock->socketdes, wsaData.buf, wsaData.len, 0);
     dwBytes = rv;
 #endif
     if (rv == SOCKET_ERROR) {
-        lasterror = apr_get_netos_error();
         *len = 0;
-        return lasterror;
+        return apr_get_netos_error();
     }
 
     *len = dwBytes;
@@ -70,23 +100,53 @@
 {
     apr_ssize_t rv;
     WSABUF wsaData;
-    int lasterror;
     DWORD dwBytes = 0;
     DWORD flags = 0;
+    apr_status_t wsarv;
 
     wsaData.len = (u_long)*len;
     wsaData.buf = (char*) buf;
 
 #ifndef _WIN32_WCE
     rv = WSARecv(sock->socketdes, &wsaData, 1, &dwBytes, &flags, NULL, NULL);
+#elif _WIN32_WCE > 0x400
+    rv = WSARecv(sock->socketdes, &wsaData, 1, &dwBytes, &flags,
+                 sock->wsaoverlapped, NULL);
+    if (rv == SOCKET_ERROR) {
+        wsarv = apr_get_netos_error();
+        if (wsarv == APR_FROM_OS_ERROR(WSA_IO_PENDING)) {
+            rv = WSAWaitForMultipleEvents(1, &sock->wsaoverlapped->hEvent,
+                                          FALSE, sock->timeout_ms >= 0
+                                                 ? sock->timeout_ms
+                                                 : WSA_INFINITE, FALSE);
+            if (rv == WSA_WAIT_EVENT_0) {
+                if (WSAResetEvent(sock->wsaoverlapped->hEvent)) {
+                    flags = 0;
+                    if (!WSAGetOverlappedResult(sock->socketdes,
+                        sock->wsaoverlapped, &dwBytes, FALSE, &flags)) {
+                        rv = SOCKET_ERROR;
+                    }
+                }
+                else {
+                    rv = SOCKET_ERROR;
+                }
+            }
+            else {
+                apr_set_netos_error(rv);
+                rv = SOCKET_ERROR;
+            }
+        }
+        else {
+            apr_set_netos_error(wsarv);
+        }
+    }
 #else
     rv = recv(sock->socketdes, wsaData.buf, wsaData.len, 0);
     dwBytes = rv;
 #endif
     if (rv == SOCKET_ERROR) {
-        lasterror = apr_get_netos_error();
         *len = 0;
-        return lasterror;
+        return apr_get_netos_error();
     }
 
     *len = dwBytes;
@@ -145,6 +205,34 @@
     if (rv == SOCKET_ERROR) {
         rc = apr_get_netos_error();
     }
+#elif _WIN32_WCE > 0x400
+    rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0,
+                 sock->wsaoverlapped, NULL);
+    rc = rv;
+    if (rv == SOCKET_ERROR) {
+        rc = apr_get_netos_error();
+        if (rc == APR_FROM_OS_ERROR(WSA_IO_PENDING)) {
+            rv = WSAWaitForMultipleEvents(1, &sock->wsaoverlapped->hEvent,
+                                          FALSE, sock->timeout_ms >= 0
+                                                 ? sock->timeout_ms
+                                                 : WSA_INFINITE, FALSE);
+            if (rv == WSA_WAIT_EVENT_0) {
+                if (WSAResetEvent(sock->wsaoverlapped->hEvent)) {
+                    DWORD flags = 0;
+                    if (!WSAGetOverlappedResult(sock->socketdes,
+                        sock->wsaoverlapped, &dwBytes, FALSE, &flags)) {
+                        rc = apr_get_netos_error();
+                    }
+                }
+                else {
+                    rc = apr_get_netos_error();
+                }
+            }
+            else {
+                rc = rv;
+            }
+        }
+    }
 #else
     for (i = 0; i < nvec; i++) {
         rv = send(sock->socketdes, pWsaBuf[i].buf, pWsaBuf[i].len, 0);
@@ -169,10 +257,52 @@
                                             apr_size_t *len)
 {
     apr_ssize_t rv;
+#if _WIN32_WCE > 0x400
+    apr_status_t wsarv;
+    WSABUF wsaData;
+    DWORD dwBytes = 0;
 
+    wsaData.len = (u_long)*len;
+    wsaData.buf = (char*) buf;
+
+    rv = WSASendTo(sock->socketdes, &wsaData, 1, &dwBytes, flags,
+                   (const struct sockaddr*)&where->sa, where->salen,
+                   sock->wsaoverlapped, NULL);
+    if (rv == SOCKET_ERROR) {
+        wsarv = apr_get_netos_error();
+        if (wsarv == APR_FROM_OS_ERROR(WSA_IO_PENDING)) {
+            rv = WSAWaitForMultipleEvents(1, &sock->wsaoverlapped->hEvent,
+                                          FALSE, sock->timeout_ms >= 0
+                                                 ? sock->timeout_ms
+                                                 : WSA_INFINITE, FALSE);
+            if (rv == WSA_WAIT_EVENT_0) {
+                if (WSAResetEvent(sock->wsaoverlapped->hEvent)) {
+                    if (WSAGetOverlappedResult(sock->socketdes,
+                        sock->wsaoverlapped, &dwBytes, FALSE, &flags)) {
+                        rv = dwBytes;
+                    }
+                    else {
+                        rv = SOCKET_ERROR;
+                    }
+                }
+                else {
+                    rv = SOCKET_ERROR;
+                }
+            }
+            else {
+                apr_set_netos_error(rv);
+                rv = SOCKET_ERROR;
+            }
+        }
+        else {
+            apr_set_netos_error(wsarv);
+        }
+    }
+#else
     rv = sendto(sock->socketdes, buf, (int)*len, flags, 
                 (const struct sockaddr*)&where->sa, 
                 where->salen);
+#endif
     if (rv == SOCKET_ERROR) {
         *len = 0;
         return apr_get_netos_error();
@@ -189,9 +319,54 @@
                                               char *buf, apr_size_t *len)
 {
     apr_ssize_t rv;
+#if _WIN32_WCE > 0x400
+    apr_status_t wsarv;
+    WSABUF wsaData;
+    DWORD dwBytes = 0;
 
+    wsaData.len = (u_long)*len;
+    wsaData.buf = (char*) buf;
+
+    rv = WSARecvFrom(sock->socketdes, &wsaData, 1, &dwBytes, &flags,
+                     (struct sockaddr*)&from->sa, &from->salen,
+                     sock->wsaoverlapped, NULL);
+    if (rv == SOCKET_ERROR) {
+        wsarv = apr_get_netos_error();
+        if (wsarv == APR_FROM_OS_ERROR(WSA_IO_PENDING)) {
+            rv = WSAWaitForMultipleEvents(1, &sock->wsaoverlapped->hEvent,
+                                          FALSE, sock->timeout_ms >= 0
+                                                 ? sock->timeout_ms
+                                                 : WSA_INFINITE, FALSE);
+            if (rv == WSA_WAIT_EVENT_0) {
+                if (WSAResetEvent(sock->wsaoverlapped->hEvent)) {
+                    if (WSAGetOverlappedResult(sock->socketdes,
+                        sock->wsaoverlapped, &dwBytes, FALSE, &flags)) {
+                        rv = dwBytes;
+                    }
+                    else {
+                        rv = SOCKET_ERROR;
+                    }
+                }
+                else {
+                    rv = SOCKET_ERROR;
+                }
+            }
+            else {
+                apr_set_netos_error(rv);
+                rv = SOCKET_ERROR;
+            }
+        }
+        else {
+            apr_set_netos_error(wsarv);
+        }
+    }
+    else {
+        rv = dwBytes;
+    }
+#else
     rv = recvfrom(sock->socketdes, buf, (int)*len, flags, 
                   (struct sockaddr*)&from->sa, &from->salen);
+#endif
     if (rv == SOCKET_ERROR) {
         (*len) = 0;
         return apr_get_netos_error();
Index: network_io/win32/sockets.c
===================================================================
--- network_io/win32/sockets.c	(revision 574284)
+++ network_io/win32/sockets.c	(working copy)
@@ -42,6 +42,12 @@
         thesocket->overlapped = NULL;
     }
 #endif
+#if _WIN32_WCE > 0x400
+    if (thesocket->wsaoverlapped) {
+        WSACloseEvent(thesocket->wsaoverlapped->hEvent);
+        thesocket->wsaoverlapped = NULL;
+    }
+#endif
     return APR_SUCCESS;
 }
 
@@ -92,11 +98,23 @@
     }
 
     alloc_socket(new, cont);
+#if _WIN32_WCE > 0x400
+    (*new)->wsaoverlapped = (WSAOVERLAPPED *)apr_pcalloc((*new)->pool,
+                                                         sizeof(WSAOVERLAPPED));
+    (*new)->wsaoverlapped->hEvent = WSACreateEvent();
+    if ((*new)->wsaoverlapped->hEvent == NULL) {
+        return apr_get_netos_error();
+    }
 
+    /* Need to use overlapped sockets to support blocking with timeout. */
+    (*new)->socketdes = WSASocket(family, type, protocol, NULL,
+                                  0, WSA_FLAG_OVERLAPPED);
+#else
     /* For right now, we are not using socket groups.  We may later.
      * No flags to use when creating a socket, so use 0 for that parameter as well.
      */
     (*new)->socketdes = socket(family, type, protocol);
+#endif
 #if APR_HAVE_IPV6
     if ((*new)->socketdes == INVALID_SOCKET && downgrade) {
         family = AF_INET;
@@ -177,12 +195,10 @@
             return APR_BADARG;
     }
 #endif
-    if (shutdown(thesocket->socketdes, winhow) == 0) {
-        return APR_SUCCESS;
-    }
-    else {
+    if (shutdown(thesocket->socketdes, winhow) != 0) {
         return apr_get_netos_error();
     }
+    return APR_SUCCESS;
 }
 
 APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket)
@@ -230,12 +246,24 @@
 
     /* Don't allocate the memory until after we call accept. This allows
        us to work with nonblocking sockets. */
+#if _WIN32_WCE > 0x400
+    s = WSAAccept(sock->socketdes, (struct sockaddr *)&sa, &salen, NULL, 0);
+#else
     s = accept(sock->socketdes, (struct sockaddr *)&sa, &salen);
+#endif
     if (s == INVALID_SOCKET) {
         return apr_get_netos_error();
     }
 
     alloc_socket(new, p);
+#if _WIN32_WCE > 0x400
+    (*new)->wsaoverlapped = (WSAOVERLAPPED *)apr_pcalloc((*new)->pool,
+                                                         sizeof(WSAOVERLAPPED));
+    (*new)->wsaoverlapped->hEvent = WSACreateEvent();
+    if ((*new)->wsaoverlapped->hEvent == NULL) {
+        return apr_get_netos_error();
+    }
+#endif
     set_socket_vars(*new, sock->local_addr->sa.sin.sin_family, SOCK_STREAM, 
                     sock->protocol);
 
@@ -306,9 +334,13 @@
     if ((sock->socketdes == INVALID_SOCKET) || (!sock->local_addr)) {
         return APR_ENOTSOCK;
     }
-
+#if _WIN32_WCE > 0x400
+    if (WSAConnect(sock->socketdes, (const struct sockaddr *)&sa->sa.sin,
+                   sa->salen, NULL, NULL, NULL, NULL) == SOCKET_ERROR) {
+#else
     if (connect(sock->socketdes, (const struct sockaddr *)&sa->sa.sin,
                 sa->salen) == SOCKET_ERROR) {
+#endif
         int rc;
         struct timeval tv, *tvptr;
         fd_set wfdset, efdset;
Index: network_io/win32/sockopt.c
===================================================================
--- network_io/win32/sockopt.c	(revision 574284)
+++ network_io/win32/sockopt.c	(working copy)
@@ -24,7 +24,12 @@
 {
     u_long zero = 0;
 
+#if _WIN32_WCE > 0x400
+    if (WSAIoctl(sd, FIONBIO, &zero, sizeof(zero),
+                 NULL, 0, NULL, NULL, NULL) == SOCKET_ERROR) {
+#else
     if (ioctlsocket(sd, FIONBIO, &zero) == SOCKET_ERROR) {
+#endif
         return apr_get_netos_error();
     }
     return APR_SUCCESS;
@@ -34,7 +39,12 @@
 {
     u_long one = 1;
 
+#if _WIN32_WCE > 0x400
+    if (WSAIoctl(sd, FIONBIO, &one, sizeof(one),
+                 NULL, 0, NULL, NULL, NULL) == SOCKET_ERROR) {
+#else
     if (ioctlsocket(sd, FIONBIO, &one) == SOCKET_ERROR) {
+#endif
         return apr_get_netos_error();
     }
     return APR_SUCCESS;
@@ -63,12 +73,14 @@
         {
             /* Win32 timeouts are in msec, represented as int */
             sock->timeout_ms = (int)apr_time_as_msec(t);
+#ifndef _WIN32_WCE
             setsockopt(sock->socketdes, SOL_SOCKET, SO_RCVTIMEO, 
                        (char *) &sock->timeout_ms, 
                        sizeof(sock->timeout_ms));
             setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDTIMEO, 
                        (char *) &sock->timeout_ms, 
                        sizeof(sock->timeout_ms));
+#endif
         }
     }
     else if (t < 0) {
@@ -76,10 +88,12 @@
         /* Set the socket to blocking with infinite timeouts */
         if ((stat = soblock(sock->socketdes)) != APR_SUCCESS)
             return stat;
+#ifndef _WIN32_WCE
         setsockopt(sock->socketdes, SOL_SOCKET, SO_RCVTIMEO, 
                    (char *) &zero, sizeof(zero));
         setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDTIMEO, 
                    (char *) &zero, sizeof(zero));
+#endif
     }
     sock->timeout = t;
     return APR_SUCCESS;
Index: shmem/win32/shm.c
===================================================================
--- shmem/win32/shm.c	(revision 574284)
+++ shmem/win32/shm.c	(working copy)
@@ -86,12 +86,11 @@
 
     if (!file) {
         /* Do Anonymous, which must be passed as a duplicated handle */
-#ifndef _WIN32_WCE
         hFile = INVALID_HANDLE_VALUE;
-#endif
         mapkey = NULL;
     }
     else {
+#ifndef _WIN32_WCE
         /* Do file backed, which is not an inherited handle 
          * While we could open APR_EXCL, it doesn't seem that Unix
          * ever did.  Ignore that error here, but fail later when
@@ -105,7 +104,24 @@
             return rv;
         }
         rv = apr_file_trunc(f, size);
+#else
+        apr_wchar_t wfname[APR_PATH_MAX];
 
+        rv = utf8_to_unicode_path(wfname, APR_PATH_MAX, file);
+        if (rv != APR_SUCCESS) {
+            return rv;
+        }
+        /* Need to use CreateFileForMapping() on CE to ensure MMap files
+         * work. CE ignores the sharemode parameter. Instead, it grants
+         * the same share mode as the desired access (open) flags.
+         */
+        hFile = CreateFileForMappingW(wfname, GENERIC_READ
+            | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
+        if (!hFile || hFile == INVALID_HANDLE_VALUE) {
+            return apr_get_os_error();
+        }
+#endif
+
         /* res_name_from_filename turns file into a pseudo-name
          * without slashes or backslashes, and prepends the \global
          * prefix on Win2K and later
@@ -129,9 +145,11 @@
 #endif
     err = apr_get_os_error();
 
+#ifndef _WIN32_WCE
     if (file) {
         apr_file_close(f);
     }
+#endif
 
     if (hMap && APR_STATUS_IS_EEXIST(err)) {
         CloseHandle(hMap);
Index: strings/apr_strings.c
===================================================================
--- strings/apr_strings.c	(revision 574284)
+++ strings/apr_strings.c	(working copy)
@@ -239,7 +239,13 @@
 {
     errno = 0;
     *offset = APR_OFF_T_STRFN(nptr, endptr, base);
+#ifndef _WIN32_WCE
     return APR_FROM_OS_ERROR(errno);
+#else
+    if (*offset == LONG_MAX || *offset == LONG_MIN)
+        return APR_FROM_OS_ERROR(ERROR_ARITHMETIC_OVERFLOW);
+    return APR_SUCCESS;
+#endif
 }
 
 APR_DECLARE(apr_int64_t) apr_strtoi64(const char *nptr, char **endptr, int base)
Index: threadproc/win32/proc.c
===================================================================
--- threadproc/win32/proc.c	(revision 574284)
+++ threadproc/win32/proc.c	(working copy)
@@ -613,9 +613,12 @@
              * complete file path.  That is; "c:\bin\aprtest.exe"
              * would succeed, but "c:\bin\aprtest" or "aprtest.exe"
              * can fail.
+             * Apparently, CE 5 already passes the program name as the first
+             * argument.
              */
-            cmdline = apr_pstrcat(pool, argv0, cmdline, NULL);
-
+            if (apr_os_level < APR_WIN_CE_5) {
+                cmdline = apr_pstrcat(pool, argv0, cmdline, NULL);
+            }
             if (attr->cmdtype == APR_PROGRAM_PATH) {
                 progname = NULL;
             }
@@ -647,7 +650,8 @@
         {
             apr_wchar_t *pNext;
             pEnvBlock = (char *)apr_palloc(pool, iEnvBlockLen * 2);
-            dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
+            if (apr_os_level >= APR_WIN_NT)
+                dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
 
             i = 0;
             pNext = (apr_wchar_t*)pEnvBlock;
Index: threadproc/win32/thread.c
===================================================================
--- threadproc/win32/thread.c	(revision 574284)
+++ threadproc/win32/thread.c	(working copy)
@@ -114,10 +114,12 @@
         return APR_FROM_OS_ERROR(_doserrno);
     }
 #else
-   if ((handle = CreateThread(NULL,
+    if ((handle = CreateThread(NULL,
                         attr && attr->stacksize > 0 ? attr->stacksize : 0,
                         (unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
-                        (*new), 0, &temp)) == 0) {
+                        (*new), attr && attr->stacksize > 0
+                        ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0,
+                        &temp)) == 0) {
         return apr_get_os_error();
     }
 #endif
Index: time/win32/time.c
===================================================================
--- time/win32/time.c	(revision 574284)
+++ time/win32/time.c	(working copy)
@@ -91,9 +91,7 @@
 #ifndef _WIN32_WCE
     GetSystemTimeAsFileTime(&time);
 #else
-    SYSTEMTIME st;
-    GetSystemTime(&st);
-    SystemTimeToFileTime(&st, &time);
+    GetCurrentFT(&time);
 #endif
     FileTimeToAprTime(&aprtime, &time);
     return aprtime;