Initial, quick and dirty WinCE port with EVC4

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@125 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjlib/src/pj/compat/unicode_win32.c b/pjlib/src/pj/compat/unicode_win32.c
new file mode 100644
index 0000000..4727210
--- /dev/null
+++ b/pjlib/src/pj/compat/unicode_win32.c
@@ -0,0 +1,38 @@
+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 
+ */
+#include <pj/compat/unicode.h>
+#include <pj/assert.h>
+#include <pj/string.h>
+#include <windows.h>
+
+
+PJ_DEF(wchar_t*) pj_ansi_to_unicode(const char *s, wchar_t *buf,
+				    pj_size_t buf_count)
+{
+    int len;
+
+    PJ_ASSERT_RETURN(s, NULL);
+
+    len = MultiByteToWideChar(CP_ACP, 0, s, strlen(s), 
+			      buf, buf_count);
+    if (!len)
+	return NULL;
+
+    return buf;
+}
diff --git a/pjlib/src/pj/file_access_win32.c b/pjlib/src/pj/file_access_win32.c
index 79eb1f8..9c6d83c 100644
--- a/pjlib/src/pj/file_access_win32.c
+++ b/pjlib/src/pj/file_access_win32.c
@@ -17,8 +17,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 #include <pj/file_access.h>
+#include <pj/compat/unicode.h>
 #include <pj/assert.h>
 #include <pj/errno.h>
+#include <pj/string.h>
+#include <pj/os.h>
 #include <windows.h>
 #include <time.h>
 
@@ -28,10 +31,12 @@
 PJ_DEF(pj_bool_t) pj_file_exists(const char *filename)
 {
     HANDLE hFile;
+    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256);
 
     PJ_ASSERT_RETURN(filename != NULL, 0);
 
-    hFile = CreateFile(filename, READ_CONTROL, FILE_SHARE_READ, NULL,
+    hFile = CreateFile(PJ_NATIVE_STRING(filename,wfilename), READ_CONTROL, 
+		       FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
         return 0;
@@ -49,10 +54,11 @@
     HANDLE hFile;
     DWORD sizeLo, sizeHi;
     pj_off_t size;
+    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256);
 
     PJ_ASSERT_RETURN(filename != NULL, -1);
 
-    hFile = CreateFile(filename, READ_CONTROL, 
+    hFile = CreateFile(PJ_NATIVE_STRING(filename, wfilename), READ_CONTROL, 
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
@@ -80,9 +86,11 @@
  */
 PJ_DEF(pj_status_t) pj_file_delete(const char *filename)
 {
+    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256);
+
     PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);
 
-    if (DeleteFile(filename) == FALSE)
+    if (DeleteFile(PJ_NATIVE_STRING(filename,wfilename)) == FALSE)
         return PJ_RETURN_OS_ERROR(GetLastError());
 
     return PJ_SUCCESS;
@@ -95,14 +103,18 @@
 PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)
 {
     BOOL rc;
+    PJ_DECL_UNICODE_TEMP_BUF(woldname,256);
+    PJ_DECL_UNICODE_TEMP_BUF(wnewname,256);
 
     PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL);
 
 #if PJ_WIN32_WINNT >= 0x0400
-    rc = MoveFileEx(oldname, newname, 
+    rc = MoveFileEx(PJ_NATIVE_STRING(oldname,woldname), 
+		    PJ_NATIVE_STRING(newname,wnewname), 
                     MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);
 #else
-    rc = MoveFile(oldname, newname);
+    rc = MoveFile(PJ_NATIVE_STRING(oldname, woldname), 
+		  PJ_NATIVE_STRING(newname, wnewname));
 #endif
 
     if (!rc)
@@ -115,31 +127,31 @@
 static pj_status_t file_time_to_time_val(const FILETIME *file_time,
                                          pj_time_val *time_val)
 {
-    SYSTEMTIME systemTime, localTime;
-    struct tm tm;
+    FILETIME local_file_time;
+    SYSTEMTIME localTime;
+    pj_parsed_time pt;
 
-    if (!FileTimeToSystemTime(file_time, &systemTime))
-        return -1;
+    if (!FileTimeToLocalFileTime(file_time, &local_file_time))
+	return PJ_RETURN_OS_ERROR(GetLastError());
 
-    if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))
-        return -1;
+    if (!FileTimeToSystemTime(file_time, &localTime))
+        return PJ_RETURN_OS_ERROR(GetLastError());
 
-    memset(&tm, 0, sizeof(struct tm));
-    tm.tm_year = localTime.wYear - 1900;
-    tm.tm_mon = localTime.wMonth - 1;
-    tm.tm_mday = localTime.wDay;
-    tm.tm_hour = localTime.wHour;
-    tm.tm_min = localTime.wMinute;
-    tm.tm_sec = localTime.wSecond;
-    tm.tm_isdst = 0;
+    //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))
+    //    return PJ_RETURN_OS_ERROR(GetLastError());
 
-    time_val->sec = mktime(&tm);
-    if (time_val->sec == (time_t)-1)
-        return -1;
+    pj_memset(&pt, 0, sizeof(pt));
+    pt.year = localTime.wYear;
+    pt.mon = localTime.wMonth-1;
+    pt.day = localTime.wDay;
+    pt.wday = localTime.wDayOfWeek;
 
-    time_val->msec = localTime.wMilliseconds;
+    pt.hour = localTime.wHour;
+    pt.min = localTime.wMinute;
+    pt.sec = localTime.wSecond;
+    pt.msec = localTime.wMilliseconds;
 
-    return PJ_SUCCESS;
+    return pj_time_encode(&pt, time_val);
 }
 
 /*
@@ -150,10 +162,12 @@
     HANDLE hFile;
     DWORD sizeLo, sizeHi;
     FILETIME creationTime, accessTime, writeTime;
+    PJ_DECL_UNICODE_TEMP_BUF(wfilename,256);
 
     PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);
 
-    hFile = CreateFile(filename, READ_CONTROL, FILE_SHARE_READ, NULL,
+    hFile = CreateFile(PJ_NATIVE_STRING(filename,wfilename), READ_CONTROL, 
+		       FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
         return PJ_RETURN_OS_ERROR(GetLastError());
diff --git a/pjlib/src/pj/file_io_win32.c b/pjlib/src/pj/file_io_win32.c
index f7a4f16..bf8e11f 100644
--- a/pjlib/src/pj/file_io_win32.c
+++ b/pjlib/src/pj/file_io_win32.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 #include <pj/file_io.h>
+#include <pj/compat/unicode.h>
 #include <pj/errno.h>
 #include <pj/assert.h>
 
@@ -43,6 +44,7 @@
                                   unsigned flags,
                                   pj_oshandle_t *fd)
 {
+    PJ_DECL_UNICODE_TEMP_BUF(wpathname,256);
     HANDLE hFile;
     DWORD dwDesiredAccess = 0;
     DWORD dwShareMode = 0;
@@ -76,7 +78,8 @@
     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
 
-    hFile = CreateFile(pathname, dwDesiredAccess, dwShareMode, NULL,
+    hFile = CreateFile(PJ_NATIVE_STRING(pathname,wpathname), 
+		       dwDesiredAccess, dwShareMode, NULL,
                        dwCreationDisposition, dwFlagsAndAttributes, NULL);
     if (hFile == INVALID_HANDLE_VALUE) {
         *fd = 0;
diff --git a/pjlib/src/pj/ioqueue_common_abs.c b/pjlib/src/pj/ioqueue_common_abs.c
index 285aefc..9b59657 100644
--- a/pjlib/src/pj/ioqueue_common_abs.c
+++ b/pjlib/src/pj/ioqueue_common_abs.c
@@ -215,12 +215,14 @@
 	 * the right errno through error slippage. This is a combination
 	 * of suggestions from Douglas C. Schmidt and Ken Keys.
 	 */
-	int gp_rc;
-	struct sockaddr_in addr;
-	socklen_t addrlen = sizeof(addr);
+	{
+	    int gp_rc;
+	    struct sockaddr_in addr;
+	    socklen_t addrlen = sizeof(addr);
 
-	gp_rc = getpeername(h->fd, (struct sockaddr*)&addr, &addrlen);
-	bytes_transfered = gp_rc;
+	    gp_rc = getpeername(h->fd, (struct sockaddr*)&addr, &addrlen);
+	    bytes_transfered = gp_rc;
+	}
 #endif
 
 	/* Call callback. */
@@ -399,7 +401,8 @@
              * read(). That's why we only specify PJ_LINUX here so
              * that error is easier to catch.
              */
-#	    if defined(PJ_WIN32) && PJ_WIN32 != 0
+#	    if defined(PJ_WIN32) && PJ_WIN32 != 0 || \
+	       defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0
                 rc = pj_sock_recv(h->fd, read_op->buf, &bytes_read, 0);
                 //rc = ReadFile((HANDLE)h->fd, read_op->buf, read_op->size,
                 //              &bytes_read, NULL);
diff --git a/pjlib/src/pj/ioqueue_select.c b/pjlib/src/pj/ioqueue_select.c
index df08d0c..1dfcb11 100644
--- a/pjlib/src/pj/ioqueue_select.c
+++ b/pjlib/src/pj/ioqueue_select.c
@@ -221,7 +221,8 @@
 
     /* Set socket to nonblocking. */
     value = 1;
-#ifdef PJ_WIN32
+#if defined(PJ_WIN32) && PJ_WIN32!=0 || \
+    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
     if (ioctlsocket(sock, FIONBIO, (u_long*)&value)) {
 #else
     if (ioctl(sock, FIONBIO, &value)) {
diff --git a/pjlib/src/pj/log.c b/pjlib/src/pj/log.c
index 2077fc9..442ee94 100644
--- a/pjlib/src/pj/log.c
+++ b/pjlib/src/pj/log.c
@@ -138,13 +138,19 @@
 
     /* Print the whole message to the string log_buffer. */
     len = len + vsnprintf(pre, sizeof(log_buffer)-len, format, marker);
-    if (len > 0 && len < sizeof(log_buffer)-1) {
+    if (len > 0 && len < sizeof(log_buffer)-2) {
+	if (log_decor & PJ_LOG_HAS_CR) {
+	    log_buffer[len++] = '\r';
+	}
 	if (log_decor & PJ_LOG_HAS_NEWLINE) {
 	    log_buffer[len++] = '\n';
 	}
 	log_buffer[len++] = '\0';
     } else {
 	len = sizeof(log_buffer)-1;
+	if (log_decor & PJ_LOG_HAS_CR) {
+	    log_buffer[sizeof(log_buffer)-3] = '\r';
+	}
 	if (log_decor & PJ_LOG_HAS_NEWLINE) {
 	    log_buffer[sizeof(log_buffer)-2] = '\n';
 	}
diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c
index 7633e7b..94c438f 100644
--- a/pjlib/src/pj/os_core_win32.c
+++ b/pjlib/src/pj/os_core_win32.c
@@ -536,7 +536,7 @@
 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
     return InterlockedIncrement(&atomic_var->value);
 #else
-#   error Fix Me
+    return InterlockedIncrement(&atomic_var->value);
 #endif
 }
 
@@ -558,7 +558,7 @@
 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
     return InterlockedDecrement(&atomic_var->value);
 #else
-#   error Fix me
+    return InterlockedDecrement(&atomic_var->value);
 #endif
 }
 
@@ -579,7 +579,7 @@
 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
     InterlockedExchangeAdd( &atomic_var->value, value );
 #else
-#   error Fix me
+    InterlockedExchangeAdd( &atomic_var->value, value );
 #endif
 }
 
@@ -593,7 +593,8 @@
     long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);
     return oldValue + value;
 #else
-#   error Fix me
+    long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);
+    return oldValue + value;
 #endif
 }
 
diff --git a/pjlib/src/pj/os_time_ansi.c b/pjlib/src/pj/os_time_ansi.c
index 21a117a..c0cb9f5 100644
--- a/pjlib/src/pj/os_time_ansi.c
+++ b/pjlib/src/pj/os_time_ansi.c
@@ -48,7 +48,6 @@
     pt->min = local_time->tm_min;
     pt->sec = local_time->tm_sec;
     pt->wday = local_time->tm_wday;
-    pt->yday = local_time->tm_yday;
     pt->msec = tv->msec;
 
     return PJ_SUCCESS;
@@ -57,7 +56,23 @@
 /**
  * Encode parsed time to time value.
  */
-PJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
+PJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv)
+{
+    struct tm local_time;
+
+    local_time.tm_year = pt->year-1900;
+    local_time.tm_mon = pt->mon;
+    local_time.tm_mday = pt->day;
+    local_time.tm_hour = pt->hour;
+    local_time.tm_min = pt->min;
+    local_time.tm_sec = pt->sec;
+    local_time.tm_isdst = 0;
+    
+    tv->sec = mktime(&local_time);
+    tv->msec = pt->msec;
+
+    return PJ_SUCCESS;
+}
 
 /**
  * Convert local time to GMT.
diff --git a/pjlib/src/pj/os_time_win32.c b/pjlib/src/pj/os_time_win32.c
new file mode 100644
index 0000000..f979931
--- /dev/null
+++ b/pjlib/src/pj/os_time_win32.c
@@ -0,0 +1,137 @@
+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 
+ */
+#include <pj/os.h>
+#include <pj/string.h>
+#include <windows.h>
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define SECS_TO_FT_MULT 10000000
+
+static LARGE_INTEGER base_time;
+
+// Find 1st Jan 1970 as a FILETIME 
+static void get_base_time(void)
+{
+    SYSTEMTIME st;
+    FILETIME ft;
+
+    memset(&st,0,sizeof(st));
+    st.wYear=1970;
+    st.wMonth=1;
+    st.wDay=1;
+    SystemTimeToFileTime(&st, &ft);
+    
+    base_time.LowPart = ft.dwLowDateTime;
+    base_time.HighPart = ft.dwHighDateTime;
+    base_time.QuadPart /= SECS_TO_FT_MULT;
+}
+
+PJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *tv)
+{
+    SYSTEMTIME st;
+    FILETIME ft;
+    LARGE_INTEGER li;
+
+    if (base_time.QuadPart == 0)
+	get_base_time();
+
+    GetLocalTime(&st);
+    SystemTimeToFileTime(&st, &ft);
+
+    li.LowPart = ft.dwLowDateTime;
+    li.HighPart = ft.dwHighDateTime;
+    li.QuadPart /= SECS_TO_FT_MULT;
+    li.QuadPart -= base_time.QuadPart;
+
+    tv->sec = li.LowPart;
+    tv->msec = st.wMilliseconds;
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)
+{
+    LARGE_INTEGER li;
+    FILETIME ft;
+    SYSTEMTIME st;
+
+    li.QuadPart = tv->sec;
+    li.QuadPart += base_time.QuadPart;
+    li.QuadPart *= SECS_TO_FT_MULT;
+
+    ft.dwLowDateTime = li.LowPart;
+    ft.dwHighDateTime = li.HighPart;
+    FileTimeToSystemTime(&ft, &st);
+
+    pt->year = st.wYear;
+    pt->mon = st.wMonth-1;
+    pt->day = st.wDay;
+    pt->wday = st.wDayOfWeek;
+
+    pt->hour = st.wHour;
+    pt->min = st.wMinute;
+    pt->sec = st.wSecond;
+    pt->msec = tv->msec;
+
+    return PJ_SUCCESS;
+}
+
+/**
+ * Encode parsed time to time value.
+ */
+PJ_DEF(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv)
+{
+    SYSTEMTIME st;
+    FILETIME ft;
+    LARGE_INTEGER li;
+
+    pj_memset(&st, 0, sizeof(st));
+    st.wYear = pt->year;
+    st.wMonth = pt->mon + 1;
+    st.wDay = pt->day;
+    st.wHour = pt->hour;
+    st.wMinute = pt->min;
+    st.wSecond = pt->sec;
+    st.wMilliseconds = pt->msec;
+    
+    SystemTimeToFileTime(&st, &ft);
+
+    li.LowPart = ft.dwLowDateTime;
+    li.HighPart = ft.dwHighDateTime;
+    li.QuadPart /= SECS_TO_FT_MULT;
+    li.QuadPart -= base_time.QuadPart;
+
+    tv->sec = li.LowPart;
+    tv->msec = st.wMilliseconds;
+
+    return PJ_SUCCESS;
+}
+
+/**
+ * Convert local time to GMT.
+ */
+PJ_DEF(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
+
+/**
+ * Convert GMT to local time.
+ */
+PJ_DEF(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
+
+
diff --git a/pjlib/src/pj/os_timestamp_win32.c b/pjlib/src/pj/os_timestamp_win32.c
index 5b63529..7cd391e 100644
--- a/pjlib/src/pj/os_timestamp_win32.c
+++ b/pjlib/src/pj/os_timestamp_win32.c
@@ -24,6 +24,7 @@
     defined(PJ_M_I386) && PJ_M_I386 != 0 && \
     defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \
     defined(_MSC_VER)
+
 /*
  * Use rdtsc to get the OS timestamp.
  */
@@ -36,9 +37,16 @@
     LONG rc;
     DWORD size;
 
+#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+		      L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
+		      0, 0, &key);
+#else
     rc = RegOpenKey( HKEY_LOCAL_MACHINE,
 		     "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
 		     &key);
+#endif
+
     if (rc != ERROR_SUCCESS)
 	return PJ_RETURN_OS_ERROR(rc);
 
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
index 3ded3a5..cdb8ca8 100644
--- a/pjlib/src/pj/sock_bsd.c
+++ b/pjlib/src/pj/sock_bsd.c
@@ -362,7 +362,8 @@
     int rc;
 
     PJ_CHECK_STACK();
-#if defined(PJ_WIN32) && PJ_WIN32==1
+#if defined(PJ_WIN32) && PJ_WIN32!=0 || \
+    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
     rc = closesocket(sock);
 #else
     rc = close(sock);