Hi,

I do not now if you found it but there is another port of sqlite to
WinCE. You can find it at http://sqlite-wince.sourceforge.net/. 

Would it be possible if your port and the sf port could be merged
together in main line src tree?

Regards Simon

On sre, 2006-01-04 at 10:13 -1000, Steve Lhomme wrote:
> Hi everyone,
> 
> I'm a happy user of SQlite for a project I just started to make a 
> multimedia database (a bit like the DB in iTunes). The idea is to make 
> it as cross-platform as possible and free.
> 
> I tried to make it work under Windows CE but run into a few problems 
> when compiling with Embedded Visual C++ 4. Although WinCE has a very 
> similar API to Windows, it lacks some of the features.
> 
> - only the unicode API is present, so I disabled all the xxxA() API calls
> 
> - localtime() is defined but doesn't exist, so I coded one with the 
> existing API
> 
> - LockFile(Ex) and UnlockFile(Ex) are not supported, only the Ex API is 
> available on WinCE 5 but I need bigger support so I just made the code 
> blank on WinCE. Is there any drawback to that ?
> 
> - FILE_ATTRIBUTE_TEMPORARY and FILE_FLAG_DELETE_ON_CLOSE are not 
> supported for CreateFile. So I removed the flags for WinCE. But that 
> means I have to delete the auto-deleting files on close. I modified the 
> API to do that when calling sqlite3OsClose(). I realise changing the API 
> is not so good, so calling sqlite3OsDelete() where the close is called 
> could be a better option.
> 
> All of the changes are included in the following patch.
> 
> Steve
> 
> priloga plain text document (WinCE.patch)
> Index: os.h
> ===================================================================
> --- os.h      (revision 1)
> +++ os.h      (working copy)
> @@ -182,7 +182,7 @@
>  int sqlite3OsSyncDirectory(const char*);
>  int sqlite3OsTempFileName(char*);
>  int sqlite3OsIsDirWritable(char*);
> -int sqlite3OsClose(OsFile*);
> +int sqlite3OsClose(OsFile*, const char*);
>  int sqlite3OsRead(OsFile*, void*, int amt);
>  int sqlite3OsWrite(OsFile*, const void*, int amt);
>  int sqlite3OsSeek(OsFile*, i64 offset);
> Index: os_unix.c
> ===================================================================
> --- os_unix.c (revision 1)
> +++ os_unix.c (working copy)
> @@ -1278,7 +1278,7 @@
>  /*
>  ** Close a file.
>  */
> -int sqlite3OsClose(OsFile *id){
> +int sqlite3OsClose(OsFile *id, const char*){
>    if( !id->isOpen ) return SQLITE_OK;
>    if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
>    sqlite3OsUnlock(id, NO_LOCK);
> Index: os_win.c
> ===================================================================
> --- os_win.c  (revision 1)
> +++ os_win.c  (working copy)
> @@ -33,6 +33,64 @@
>  ** Include code that is common to all os_*.c files
>  */
>  #include "os_common.h"
> +
> +#if defined(_WIN32_WCE)
> +#include <time.h>
> +struct tm * __cdecl localtime(const time_t *t)
> +{
> +  static struct tm y;
> +  FILETIME uTm, lTm;
> +  SYSTEMTIME pTm;
> +  uTm.dwLowDateTime = *t & 0xFFFFFFFF;
> +  uTm.dwHighDateTime= *t >> 32;
> +  FileTimeToLocalFileTime(&uTm,&lTm);
> +  FileTimeToSystemTime(&lTm,&pTm);
> +  y.tm_year = pTm.wYear - 1900;
> +  y.tm_mon = pTm.wMonth - 1;
> +  y.tm_wday = pTm.wDayOfWeek;
> +  y.tm_mday = pTm.wDay;
> +  y.tm_hour = pTm.wHour;
> +  y.tm_min = pTm.wMinute;
> +  y.tm_sec = pTm.wSecond;
> +  return &y;
> +}
> +
> +#ifndef LOCKFILE_EXCLUSIVE_LOCK
> +#define LockFileEx(a,b,c,d,e,f) (1)
> +#define UnlockFileEx(a,b,c,d,e) (1)
> +#endif
> +
> +BOOL LockFile(
> +  HANDLE hFile,
> +  DWORD dwFileOffsetLow,
> +  DWORD dwFileOffsetHigh,
> +  DWORD nNumberOfBytesToLockLow,
> +  DWORD nNumberOfBytesToLockHigh
> +)
> +{
> +  OVERLAPPED ovlp;
> +  ovlp.Offset = dwFileOffsetLow;
> +  ovlp.OffsetHigh = dwFileOffsetHigh;
> +  ovlp.hEvent = 0;
> +  return LockFileEx(hFile, 
> LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0, 
> nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &ovlp);
> +}
> +
> +
> +BOOL UnlockFile(
> +  HANDLE hFile,
> +  DWORD dwFileOffsetLow,
> +  DWORD dwFileOffsetHigh,
> +  DWORD nNumberOfBytesToUnlockLow,
> +  DWORD nNumberOfBytesToUnlockHigh
> +)
> +{
> +  OVERLAPPED ovlp;
> +  ovlp.Offset = dwFileOffsetLow;
> +  ovlp.OffsetHigh = dwFileOffsetHigh;
> +  ovlp.hEvent = 0;
> +  return UnlockFileEx(hFile, 0, nNumberOfBytesToUnlockLow, 
> nNumberOfBytesToUnlockHigh, &ovlp);
> +}
> +#endif
>  
>  /*
>  ** Do not include any of the File I/O interface procedures if the
> @@ -66,14 +124,18 @@
>  ** WinNT/2K/XP so that we will know whether or not we can safely call
>  ** the LockFileEx() API.
>  */
> -static int isNT(void){
> +static int isNT(void){
> +#if !defined(_WIN32_WCE)
>    if( sqlite3_os_type==0 ){
>      OSVERSIONINFO sInfo;
>      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
>      GetVersionEx(&sInfo);
>      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
>    }
> -  return sqlite3_os_type==2;
> +  return sqlite3_os_type==2;
> +#else
> +  return 1;
> +#endif
>  }
>  
>  /*
> @@ -131,9 +193,11 @@
>    if( zWide ){
>      DeleteFileW(zWide);
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
>      DeleteFileA(zFilename);
> -  }
> +#endif
> +  }
>    TRACE2("DELETE \"%s\"\n", zFilename);
>    return SQLITE_OK;
>  }
> @@ -147,8 +211,10 @@
>    if( zWide ){
>      exists = GetFileAttributesW(zWide) != 0xffffffff;
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
> -    exists = GetFileAttributesA(zFilename) != 0xffffffff;
> +    exists = GetFileAttributesA(zFilename) != 0xffffffff;
> +#endif
>    }
>    return exists;
>  }
> @@ -201,6 +267,7 @@
>        *pReadonly = 0;
>      }
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
>      h = CreateFileA(zFilename,
>         GENERIC_READ | GENERIC_WRITE,
> @@ -225,7 +292,8 @@
>        *pReadonly = 1;
>      }else{
>        *pReadonly = 0;
> -    }
> +    }
> +#endif
>    }
>    id->h = h;
>    id->locktype = NO_LOCK;
> @@ -257,8 +325,12 @@
>    WCHAR *zWide = utf8ToUnicode(zFilename);
>    assert( !id->isOpen );
>    if( delFlag ){
> -    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
> -                     | FILE_FLAG_DELETE_ON_CLOSE;
> +#if defined(_WIN32_WCE)
> +    fileflags = FILE_FLAG_RANDOM_ACCESS;
> +#else
> +    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
> +                     | FILE_FLAG_DELETE_ON_CLOSE;
> +#endif
>    }else{
>      fileflags = FILE_FLAG_RANDOM_ACCESS;
>    }
> @@ -271,7 +343,11 @@
>         fileflags,
>         NULL
>      );
> +#if defined(_WIN32_WCE)
> +  SetFileAttributes(zWide, FILE_ATTRIBUTE_TEMPORARY);
> +#endif
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
>      h = CreateFileA(zFilename,
>         GENERIC_READ | GENERIC_WRITE,
> @@ -280,9 +356,10 @@
>         CREATE_ALWAYS,
>         fileflags,
>         NULL
> -    );
> +    );
> +#endif
>    }
> -  if( h==INVALID_HANDLE_VALUE ){
> +  if( h==INVALID_HANDLE_VALUE ){
>      return SQLITE_CANTOPEN;
>    }
>    id->h = h;
> @@ -315,6 +392,7 @@
>         NULL
>      );
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
>      h = CreateFileA(zFilename,
>         GENERIC_READ,
> @@ -323,7 +401,8 @@
>         OPEN_EXISTING,
>         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
>         NULL
> -    );
> +    );
> +#endif
>    }
>    if( h==INVALID_HANDLE_VALUE ){
>      return SQLITE_CANTOPEN;
> @@ -381,7 +460,11 @@
>    if( sqlite3_temp_directory ){
>      strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
>      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
> -  }else if( isNT() ){
> +#if !defined(_WIN32_WCE)
> +  }else if( !isNT() ){
> +    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
> +#endif
> +  }else{
>      char *zMulti;
>      WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
>      GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
> @@ -391,8 +474,6 @@
>        zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
>        sqliteFree(zMulti);
>      }
> -  }else{
> -    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
>    }
>    for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
>    zTempPath[i] = 0;
> @@ -413,11 +494,18 @@
>  /*
>  ** Close a file.
>  */
> -int sqlite3OsClose(OsFile *id){
> +int sqlite3OsClose(OsFile *id, const char *FilePath){
>    if( id->isOpen ){
>      TRACE2("CLOSE %d\n", id->h);
>      CloseHandle(id->h);
> -    OpenCounter(-1);
> +    OpenCounter(-1);
> +#if defined(_WIN32_WCE)
> +     {
> +             WCHAR *path = utf8ToUnicode(FilePath);
> +             DeleteFile(path);
> +             sqliteFree(path);
> +     }
> +#endif
>      id->isOpen = 0;
>    }
>    return SQLITE_OK;
> @@ -556,7 +644,7 @@
>      int lk;
>      sqlite3Randomness(sizeof(lk), &lk);
>      id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
> -    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
> +    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
>    }
>    return res;
>  }
> @@ -565,12 +653,12 @@
>  ** Undo a readlock
>  */
>  static int unlockReadLock(OsFile *id){
> -  int res;
> +  int res;
>    if( isNT() ){
>      res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
>    }else{
>      res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
> -  }
> +  }
>    return res;
>  }
>  
> @@ -588,8 +676,10 @@
>    if( zWide ){
>      fileAttr = GetFileAttributesW(zWide);
>      sqliteFree(zWide);
> +#if !defined(_WIN32_WCE)
>    }else{
> -    fileAttr = GetFileAttributesA(zDirname);
> +    fileAttr = GetFileAttributesA(zDirname);
> +#endif
>    }
>    if( fileAttr == 0xffffffff ) return 0;
>    if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
> @@ -800,7 +890,7 @@
>  */
>  char *sqlite3OsFullPathname(const char *zRelative){
>    char *zNotUsed;
> -  char *zFull;
> +  char *zFull=0;
>    WCHAR *zWide;
>    int nByte;
>  #ifdef __CYGWIN__
> @@ -808,7 +898,7 @@
>    zFull = sqliteMalloc( nByte );
>    if( zFull==0 ) return 0;
>    if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
> -#else
> +#elif !defined(_WIN32_WCE)
>    zWide = utf8ToUnicode(zRelative);
>    if( zWide ){
>      WCHAR *zTemp, *zNotUsedW;
> @@ -823,8 +913,13 @@
>      nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
>      zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
>      if( zFull==0 ) return 0;
> -    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
> +    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
>    }
> +#else
> +  nByte = strlen(zRelative)+1;
> +  zFull = sqliteMalloc(nByte);
> +  if (zFull)
> +       memcpy(zFull,zRelative,nByte);
>  #endif
>    return zFull;
>  }
> @@ -919,14 +1014,20 @@
>  ** Find the current time (in Universal Coordinated Time).  Write the
>  ** current time and date as a Julian Day number into *prNow and
>  ** return 0.  Return 1 if the time and date cannot be found.
> -*/
> +*/
>  int sqlite3OsCurrentTime(double *prNow){
>    FILETIME ft;
>    /* FILETIME structure is a 64-bit value representing the number of 
>       100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
>    */
>    double now;
> -  GetSystemTimeAsFileTime( &ft );
> +#if defined(_WIN32_WCE)
> +  SYSTEMTIME time;
> +  GetSystemTime(&time);
> +  SystemTimeToFileTime(&time,&ft);
> +#else
> +  GetSystemTimeAsFileTime( &ft );
> +#endif
>    now = ((double)ft.dwHighDateTime) * 4294967296.0; 
>    *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
>  #ifdef SQLITE_TEST
> @@ -935,6 +1036,6 @@
>    }
>  #endif
>    return 0;
> -}
> +}
>  
>  #endif /* OS_WIN */
> Index: pager.c
> ===================================================================
> --- pager.c   (revision 1)
> +++ pager.c   (working copy)
> @@ -907,11 +907,11 @@
>    }
>    sqlite3pager_stmt_commit(pPager);
>    if( pPager->stmtOpen ){
> -    sqlite3OsClose(&pPager->stfd);
> +    sqlite3OsClose(&pPager->stfd, pPager->zFilename);
>      pPager->stmtOpen = 0;
>    }
>    if( pPager->journalOpen ){
> -    sqlite3OsClose(&pPager->jfd);
> +       sqlite3OsClose(&pPager->jfd, pPager->tempFile?pPager->zFilename:NULL);
>      pPager->journalOpen = 0;
>      sqlite3OsDelete(pPager->zJournal);
>      sqliteFree( pPager->aInJournal );
> @@ -1128,7 +1128,7 @@
>          }
>  
>          rc = readMasterJournal(&journal, &zMasterPtr);
> -        sqlite3OsClose(&journal);
> +        sqlite3OsClose(&journal, NULL);
>          if( rc!=SQLITE_OK ){
>            goto delmaster_out;
>          }
> @@ -1151,7 +1151,7 @@
>      sqliteFree(zMasterJournal);
>    }  
>    if( master_open ){
> -    sqlite3OsClose(&master);
> +    sqlite3OsClose(&master, NULL);
>    }
>    return rc;
>  }
> @@ -1633,18 +1633,18 @@
>      }
>    }
>    if( !zFullPathname ){
> -    sqlite3OsClose(&fd);
> +    sqlite3OsClose(&fd, zFilename);
>      return SQLITE_NOMEM;
>    }
>    if( rc!=SQLITE_OK ){
> -    sqlite3OsClose(&fd);
> +    sqlite3OsClose(&fd, zFilename);
>      sqliteFree(zFullPathname);
>      return rc;
>    }
>    nameLen = strlen(zFullPathname);
>    pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
>    if( pPager==0 ){
> -    sqlite3OsClose(&fd);
> +    sqlite3OsClose(&fd, zFilename);
>      sqliteFree(zFullPathname);
>      return SQLITE_NOMEM;
>    }
> @@ -2002,13 +2002,13 @@
>    TRACE2("CLOSE %d\n", PAGERID(pPager));
>    assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) 
> );
>    if( pPager->journalOpen ){
> -    sqlite3OsClose(&pPager->jfd);
> +       sqlite3OsClose(&pPager->jfd, pPager->tempFile?pPager->zJournal:NULL);
>    }
>    sqliteFree(pPager->aInJournal);
>    if( pPager->stmtOpen ){
> -    sqlite3OsClose(&pPager->stfd);
> +    sqlite3OsClose(&pPager->stfd, pPager->zFilename);
>    }
> -  sqlite3OsClose(&pPager->fd);
> +  sqlite3OsClose(&pPager->fd, NULL);
>    /* Temp files are automatically deleted by the OS
>    ** if( pPager->tempFile ){
>    **   sqlite3OsDelete(pPager->zFilename);
> Index: vdbeaux.c
> ===================================================================
> --- vdbeaux.c (revision 1)
> +++ vdbeaux.c (working copy)
> @@ -1003,7 +1003,7 @@
>          }
>          rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
>          if( rc!=SQLITE_OK ){
> -          sqlite3OsClose(&master);
> +          sqlite3OsClose(&master, 0);
>            sqlite3OsDelete(zMaster);
>            sqliteFree(zMaster);
>            return rc;
> @@ -1019,7 +1019,7 @@
>      rc = sqlite3OsOpenDirectory(zMainFile, &master);
>      if( rc!=SQLITE_OK ||
>            (needSync && (rc=sqlite3OsSync(&master,0))!=SQLITE_OK) ){
> -      sqlite3OsClose(&master);
> +      sqlite3OsClose(&master, 0);
>        sqlite3OsDelete(zMaster);
>        sqliteFree(zMaster);
>        return rc;
> @@ -1040,13 +1040,13 @@
>        if( pBt && sqlite3BtreeIsInTrans(pBt) ){
>          rc = sqlite3BtreeSync(pBt, zMaster);
>          if( rc!=SQLITE_OK ){
> -          sqlite3OsClose(&master);
> +          sqlite3OsClose(&master, 0);
>            sqliteFree(zMaster);
>            return rc;
>          }
>        }
>      }
> -    sqlite3OsClose(&master);
> +    sqlite3OsClose(&master, 0);
>  
>      /* Delete the master journal file. This commits the transaction. After
>      ** doing this the directory is synced again before any individual

Reply via email to