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