From 8bb20b81abcf4080f03cf6b00980e65e37d23e47 Mon Sep 17 00:00:00 2001
From: Geoffroy Couprie <geo.couprie@gmail.com>
Date: Thu, 4 Sep 2008 13:37:00 +0200
Subject: [PATCH] WinCE:File and directory access rework

---
 include/vlc_charset.h      |    6 +++++
 include/vlc_fixups.h       |   50 +++++++++++++++++++++++++++++++++++++++++++-
 modules/access/directory.c |    4 +++
 modules/access/file.c      |   24 +++++++++++++++------
 src/misc/block.c           |   11 +++++++++
 src/text/unicode.c         |   48 ++++++++++++++++++++++++++++++++++++------
 6 files changed, 128 insertions(+), 15 deletions(-)

diff --git a/include/vlc_charset.h b/include/vlc_charset.h
index 5bd3faa..55f0cea 100644
--- a/include/vlc_charset.h
+++ b/include/vlc_charset.h
@@ -32,6 +32,10 @@
 
 #include <stdarg.h>
 #include <sys/types.h>
+#ifdef UNDER_CE
+# include <sys/stat.h>
+#endif
+
 #include <dirent.h>
 
 VLC_EXPORT( void, LocaleFree, ( const char * ) );
@@ -51,7 +55,9 @@ VLC_EXPORT( int, utf8_mkdir, ( const char *filename, mode_t mode ) );
 VLC_EXPORT( int, utf8_unlink, ( const char *filename ) );
 
 #ifdef WIN32
+# ifndef UNDER_CE
 # define stat _stati64
+# endif
 #endif
 
 VLC_EXPORT( int, utf8_stat, ( const char *filename, struct stat *buf ) );
diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h
index 11e279f..d43bb7a 100644
--- a/include/vlc_fixups.h
+++ b/include/vlc_fixups.h
@@ -26,6 +26,11 @@
 #ifndef LIBVLC_FIXUPS_H
 # define LIBVLC_FIXUPS_H 1
 
+#ifdef UNDER_CE
+#include <windows.h>
+#include <winbase.h>
+#endif
+
 #ifndef HAVE_STRDUP
 # include <string.h>
 # include <stdlib.h>
@@ -44,12 +49,55 @@ static inline char *strdup (const char *str)
 # include <stdarg.h>
 static inline int vasprintf (char **strp, const char *fmt, va_list ap)
 {
+# ifndef UNDER_CE
     int len = vsnprintf (NULL, 0, fmt, ap) + 1;
     char *res = (char *)malloc (len);
     if (res == NULL)
         return -1;
     *strp = res;
     return vsprintf (res, fmt, ap);
+# else
+
+/* HACK: vsnprintf in the win32 API behaves like
+ * the one in glibc 2.0 and doesn't return the number of characters
+ * it needed to copy the string.
+ * cf http://msdn.microsoft.com/en-us/library/1kt27hek.aspx
+ * and cf the man page of vsnprintf
+ *
+ Guess we need no more than 50 bytes. */
+    int n, size = 50;
+    char *res, *np;
+
+    if ((res = (char *) malloc (size)) == NULL)
+        return -1;
+
+    while (1)
+    {
+        n = vsnprintf (res, size, fmt, ap);
+
+        /* If that worked, return the string. */
+        if (n > -1 && n < size)
+        {
+            *strp = res;
+            return n;
+        }
+
+        /* Else try again with more space. */
+        if (n == -1)
+            size *= 2;  /* twice the old size */
+
+        if ((np = (char *) realloc (res, size)) == NULL)
+        {
+            free(res);
+            return -1;
+        }
+        else
+        {
+            res = np;
+        }
+
+    }
+# endif
 }
 #endif
 
@@ -135,7 +183,7 @@ static inline lldiv_t lldiv (long long numer, long long denom)
 #endif
 
 #ifndef HAVE_GETENV
-static inline getenv (const char *name)
+static inline char *getenv (const char *name)
 {
     (void)name;
     return NULL;
diff --git a/modules/access/directory.c b/modules/access/directory.c
index b5a38af..3c5deac 100644
--- a/modules/access/directory.c
+++ b/modules/access/directory.c
@@ -360,7 +360,11 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
 
 static int Sort (const char **a, const char **b)
 {
+#ifndef UNDER_CE
     return strcoll (*a, *b);
+#else
+    return wcscmp (*a, *b);
+#endif
 }
 
 struct stat_list_t
diff --git a/modules/access/file.c b/modules/access/file.c
index cdf51ac..4c2ee71 100644
--- a/modules/access/file.c
+++ b/modules/access/file.c
@@ -52,8 +52,10 @@
 #   include <io.h>
 #   include <ctype.h>
 #else
+# ifdef UNDER_CE
 #   include <unistd.h>
-#   include <poll.h>
+#   include <ctype.h>
+# endif
 #endif
 
 #if defined( WIN32 ) && !defined( UNDER_CE )
@@ -62,15 +64,16 @@
 #   endif
 #   define lseek _lseeki64
 #elif defined( UNDER_CE )
+/*
 #   ifdef read
 #      undef read
 #   endif
-#   define read(a,b,c) fread(b,1,c,a)
+#   define read(a,b,c) fread(b,c,1,a)
 #   define close(a) fclose(a)
 #   ifdef lseek
 #      undef lseek
 #   endif
-#   define lseek fseek
+#   define lseek fseek*/
 #endif
 
 #include <vlc_charset.h>
@@ -152,7 +155,13 @@ static int Open( vlc_object_t *p_this )
     msg_Dbg (p_access, "opening file `%s'", p_access->psz_path);
 
     if (b_stdin)
+# ifndef UNDER_CE
         fd = dup (0);
+# else
+    {
+        fd = -1;
+    }
+# endif
     else
         fd = open_file (p_access, p_access->psz_path);
 
@@ -357,13 +366,14 @@ static int open_file (access_t *p_access, const char *path)
 #endif
 
 #ifdef UNDER_CE
-    p_sys->fd = utf8_fopen( path, "rb" );
-    if ( !p_sys->fd )
+/*There is no non-blocking I/O on Windows CE*/
+    int fd = utf8_open (path, O_RDONLY, 0666);
+    if ( !fd )
     {
         msg_Err( p_access, "cannot open file %s", path );
         intf_UserFatal( p_access, false, _("File reading failed"),
                         _("VLC could not open the file \"%s\"."), path );
-        return VLC_EGENERIC;
+        return -1;
     }
 
     fseek( p_sys->fd, 0, SEEK_END );
@@ -379,6 +389,7 @@ static int open_file (access_t *p_access, const char *path)
                         _("VLC could not open the file \"%s\"."), path);
         return -1;
     }
+#endif
 
 # if defined(HAVE_FCNTL_H) && defined(F_FDAHEAD) && defined(F_NOCACHE)
     /* We'd rather use any available memory for reading ahead
@@ -386,7 +397,6 @@ static int open_file (access_t *p_access, const char *path)
     fcntl (fd, F_RDAHEAD, 1);
     fcntl (fd, F_NOCACHE, 1);
 # endif
-#endif
 
     return fd;
 }
diff --git a/src/misc/block.c b/src/misc/block.c
index 8c37bcf..e6fd3cd 100644
--- a/src/misc/block.c
+++ b/src/misc/block.c
@@ -29,6 +29,8 @@
 #endif
 
 #include <vlc_common.h>
+#include <vlc/vlc.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include "vlc_block.h"
 
@@ -246,6 +248,10 @@ block_t *block_mmap_Alloc (void *addr, size_t length)
 static
 ssize_t pread (int fd, void *buf, size_t count, off_t offset)
 {
+#ifdef UNDER_CE
+#define FILDES
+#define _get_osfhandle(FILDES) ((long) (FILDES))
+#endif
     HANDLE handle = (HANDLE)(intptr_t)_get_osfhandle (fd);
     if (handle == INVALID_HANDLE_VALUE)
         return -1;
@@ -274,6 +280,11 @@ ssize_t pread (int fd, void *buf, size_t count, off_t offset)
 block_t *block_File (int fd)
 {
     size_t length;
+
+#ifdef UNDER_CE
+# define stat _stat
+#endif
+
     struct stat st;
 
     /* First, get the file size */
diff --git a/src/text/unicode.c b/src/text/unicode.c
index 036027c..735236a 100644
--- a/src/text/unicode.c
+++ b/src/text/unicode.c
@@ -44,6 +44,8 @@
 #endif
 #ifdef UNDER_CE
 #  include <tchar.h>
+#  include <winbase.h>
+#  include <winnt.h>
 #endif
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
@@ -262,8 +264,15 @@ char *ToLocaleDup (const char *utf8)
  */
 int utf8_open (const char *filename, int flags, mode_t mode)
 {
-#if defined (WIN32) || defined (UNDER_CE)
-    if (GetVersion() < 0x80000000)
+#if defined (WIN32)
+    OSVERSIONINFO osinf;
+
+    ZeroMemory(&osinf, sizeof(OSVERSIONINFO));
+    osinf.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+    GetVersionEx(&osinf);
+	/* Check for version >= NT (aka NT, XP, Vista, Windows CE...)*/
+    if(osinf.dwPlatformId>1)
     {
         /* for Windows NT and above */
         wchar_t wpath[MAX_PATH + 1];
@@ -275,11 +284,15 @@ int utf8_open (const char *filename, int flags, mode_t mode)
         }
         wpath[MAX_PATH] = L'\0';
 
+# ifdef UNDER_CE
+        return _open (filename, flags, mode);
+# elif
         /*
          * open() cannot open files with non-“ANSI” characters on Windows.
          * We use _wopen() instead. Same thing for mkdir() and stat().
          */
         return _wopen (wpath, flags, mode);
+# endif
     }
 #endif
     const char *local_name = ToLocale (filename);
@@ -573,9 +586,15 @@ int utf8_scandir( const char *dirname, char ***namelist,
 static int utf8_statEx( const char *filename, struct stat *buf,
                         bool deref )
 {
-#if defined (WIN32) || defined (UNDER_CE)
-    /* retrieve Windows OS version */
-    if( GetVersion() < 0x80000000 )
+#if defined (WIN32)
+    OSVERSIONINFO osinf;
+
+    ZeroMemory(&osinf, sizeof(OSVERSIONINFO));
+    osinf.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+    GetVersionEx(&osinf);
+
+    if(osinf.dwPlatformId >1)
     {
         /* for Windows NT and above */
         wchar_t wpath[MAX_PATH + 1];
@@ -587,7 +606,11 @@ static int utf8_statEx( const char *filename, struct stat *buf,
         }
         wpath[MAX_PATH] = L'\0';
 
+# ifdef UNDER_CE
+        return GetFileAttributesEx ( wpath,  GetFileExInfoStandard, buf);
+# elif
         return _wstati64( wpath, buf );
+# endif
     }
 #endif
 #ifdef HAVE_SYS_STAT_H
@@ -636,8 +659,15 @@ int utf8_lstat( const char *filename, struct stat *buf)
  */
 int utf8_unlink( const char *filename )
 {
-#if defined (WIN32) || defined (UNDER_CE)
-    if( GetVersion() < 0x80000000 )
+#if defined (WIN32)
+    OSVERSIONINFO osinf;
+
+    ZeroMemory(&osinf, sizeof(OSVERSIONINFO));
+    osinf.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+    GetVersionEx(&osinf);
+
+    if(osinf.dwPlatformId >1)
     {
         /* for Windows NT and above */
         wchar_t wpath[MAX_PATH + 1];
@@ -649,11 +679,15 @@ int utf8_unlink( const char *filename )
         }
         wpath[MAX_PATH] = L'\0';
 
+# ifdef UNDER_CE
+        return _unlink(filename);
+# elif
         /*
          * unlink() cannot open files with non-“ANSI” characters on Windows.
          * We use _wunlink() instead.
          */
         return _wunlink( wpath );
+# endif
     }
 #endif
     const char *local_name = ToLocale( filename );
-- 
1.5.4.3

