From cc78fea4b973437cafbf820266dd9d30e1caff72 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Jan 2006 16:17:05 +0000 Subject: [PATCH] A first attempt at adding native support for WinCE. (CVS 2874) FossilOrigin-Name: 434405678778e7ce6e0bdec02fa7049a1ca68d27 --- manifest | 14 +++--- manifest.uuid | 2 +- src/os_win.c | 137 ++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 129 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index aec563a7b4..746a053396 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\scaused\sby\sadding\sa\strigger\sto\sa\sshared-schema\sand\sthen\sdeleting\sit\nusing\sa\sdifferent\sconnection.\s(CVS\s2873) -D 2006-01-06T15:03:48 +C A\sfirst\sattempt\sat\sadding\snative\ssupport\sfor\sWinCE.\s(CVS\s2874) +D 2006-01-06T16:17:05 F Makefile.in c79fbdaa264c6afcd435f2fb492551de5a8cf80d F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -57,7 +57,7 @@ F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 F src/os_unix.c 1ade7cd84c6f18dd2ceb98000ea1e9bdcac256ff F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e -F src/os_win.c 3239b124d2400ed30d213053df43dc29405d018f +F src/os_win.c 60da6aa3cf5b78d866360f04a379c20df0b17cf7 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c f06b85eb1e43bb2e6a7a5108ac8346576b4b78fa F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f @@ -335,7 +335,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 373b56f0048fd6a1946a97acfcca40fd12f7d572 -R f298cefe96bf8aa08947c68d7cf6500d -U danielk1977 -Z 0630f893c341afffaad594ffa4fb7ae6 +P 19f93e135f1ff4f987d14afe74b955e119904017 +R 53948b3fa243d1793437a5e4c87ad2b8 +U drh +Z 9819db2ea9674432e7be1ad7f011900f diff --git a/manifest.uuid b/manifest.uuid index a14f6ccbe2..51fdd92fe9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19f93e135f1ff4f987d14afe74b955e119904017 \ No newline at end of file +434405678778e7ce6e0bdec02fa7049a1ca68d27 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 4f969e4234..fd2f75bca0 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -34,6 +34,16 @@ */ #include "os_common.h" +/* +** Determine if we are dealing with WindowsCE - which has a much +** reduced API. +*/ +#if defined(_WIN32_WCE) +# define OS_WINCE 1 +#else +# define OS_WINCE 0 +#endif + /* ** The winFile structure is a subclass of OsFile specific to the win32 ** portability layer. @@ -44,6 +54,9 @@ struct winFile { HANDLE h; /* Handle for accessing the file */ unsigned char locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ +#if OS_WINCE + char *zDeleteOnClose; /* Name of file to delete when closing */ +#endif }; @@ -69,8 +82,8 @@ struct winFile { int sqlite3_os_type = 0; /* -** Return true (non-zero) if we are running under WinNT, Win2K or WinXP. -** Return false (zero) for Win95, Win98, or WinME. +** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, +** or WinCE. Return false (zero) for Win95, Win98, or WinME. ** ** Here is an interesting observation: Win95, Win98, and WinME lack ** the LockFileEx() API. But we can still statically link against that @@ -79,15 +92,61 @@ int sqlite3_os_type = 0; ** WinNT/2K/XP so that we will know whether or not we can safely call ** the LockFileEx() API. */ -static int isNT(void){ - if( sqlite3_os_type==0 ){ - OSVERSIONINFO sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - GetVersionEx(&sInfo); - sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; +#if OS_WINCE +# define isNT() (1) +#else + static int isNT(void){ + 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; +#endif /* OS_WINCE */ + +#if OS_WINCE +/* +** WindowsCE does not have a localtime() function. So create a +** substitute. +*/ +#include +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + i64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = t64 & 0xFFFFFFFF; + uTm.dwHighDateTime= t64 >> 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; } +#endif + +/* +** Compile with -DSQLITE_OMIT_WIN_LOCKS to disable file locking on +** windows. If you do this and two or more connections attempt to +** write the database at the same time, the database file will be +** corrupted. But some versions of WindowsCE do not support locking, +** in which case compiling with this option is required just to get +** it to work at all. +*/ +#ifdef SQLITE_OMIT_WIN_LOCKS +# define LockFileEx(a,b,c,d,e,f) (1) +# define UnlockFileEx(a,b,c,d,e) (1) +#endif /* ** Convert a UTF-8 string to UTF-32. Space to hold the returned string @@ -145,7 +204,11 @@ int sqlite3WinDelete(const char *zFilename){ DeleteFileW(zWide); sqliteFree(zWide); }else{ +#if OS_WINCE + return SQLITE_NOMEM; +#else DeleteFileA(zFilename); +#endif } TRACE2("DELETE \"%s\"\n", zFilename); return SQLITE_OK; @@ -161,7 +224,11 @@ int sqlite3WinFileExists(const char *zFilename){ exists = GetFileAttributesW(zWide) != 0xffffffff; sqliteFree(zWide); }else{ +#if OS_WINCE + return SQLITE_NOMEM; +#else exists = GetFileAttributesA(zFilename) != 0xffffffff; +#endif } return exists; } @@ -219,6 +286,9 @@ int sqlite3WinOpenReadWrite( } sqliteFree(zWide); }else{ +#if OS_WINCE + return SQLITE_NOMEM; +#else h = CreateFileA(zFilename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -243,6 +313,7 @@ int sqlite3WinOpenReadWrite( }else{ *pReadonly = 0; } +#endif /* OS_WINCE */ } f.h = h; f.locktype = NO_LOCK; @@ -272,12 +343,12 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int fileflags; WCHAR *zWide = utf8ToUnicode(zFilename); assert( *pId == 0 ); + fileflags = FILE_FLAG_RANDOM_ACCESS; +#if !OS_WINCE if( delFlag ){ - fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS - | FILE_FLAG_DELETE_ON_CLOSE; - }else{ - fileflags = FILE_FLAG_RANDOM_ACCESS; + fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; } +#endif if( zWide ){ h = CreateFileW(zWide, GENERIC_READ | GENERIC_WRITE, @@ -289,6 +360,9 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ ); sqliteFree(zWide); }else{ +#if OS_WINCE + return SQLITE_NOMEM; +#else h = CreateFileA(zFilename, GENERIC_READ | GENERIC_WRITE, 0, @@ -297,6 +371,7 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ fileflags, NULL ); +#endif /* OS_WINCE */ } if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; @@ -304,6 +379,9 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ f.h = h; f.locktype = NO_LOCK; f.sharedLockByte = 0; +#if OS_WINCE + f.zDeleteOnClose = delFlag ? sqlite3StrDup(zFilename) : 0; +#endif TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); return allocateWinFile(&f, pId); } @@ -331,6 +409,9 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ ); sqliteFree(zWide); }else{ +#if OS_WINCE + return SQLITE_NOMEM; +#else h = CreateFileA(zFilename, GENERIC_READ, 0, @@ -339,6 +420,7 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); +#endif } if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; @@ -431,6 +513,12 @@ static int winClose(OsFile **pId){ if( pId && (pFile = (winFile*)*pId)!=0 ){ TRACE2("CLOSE %d\n", pFile->h); CloseHandle(pFile->h); +#if OS_WINCE + if( pFile->zDeleteOnClose ){ + DeleteFileW((WCHAR*)pFile->zDeleteOnClose); + sqliteFree(pFile->zDeleteOnClose); + } +#endif OpenCounter(-1); sqliteFree(pFile); *pId = 0; @@ -605,7 +693,11 @@ int sqlite3WinIsDirWritable(char *zDirname){ fileAttr = GetFileAttributesW(zWide); sqliteFree(zWide); }else{ +#if OS_WINCE + return 0; +#else fileAttr = GetFileAttributesA(zDirname); +#endif } if( fileAttr == 0xffffffff ) return 0; if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ @@ -818,16 +910,20 @@ static int winUnlock(OsFile *id, int locktype){ ** is no longer needed. */ char *sqlite3WinFullPathname(const char *zRelative){ - char *zNotUsed; char *zFull; - WCHAR *zWide; +#if defined(__CYGWIN__) int nByte; -#ifdef __CYGWIN__ nByte = strlen(zRelative) + MAX_PATH + 1001; zFull = sqliteMalloc( nByte ); if( zFull==0 ) return 0; if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0; +#elif OS_WINCE + /* WinCE has no concept of a relative pathname, or so I am told. */ + zFull = sqlite3StrDup(zRelative); #else + char *zNotUsed; + WCHAR *zWide; + int nByte; zWide = utf8ToUnicode(zRelative); if( zWide ){ WCHAR *zTemp, *zNotUsedW; @@ -901,6 +997,9 @@ int allocateWinFile(winFile *pInit, OsFile **pId){ pNew = sqliteMalloc( sizeof(*pNew) ); if( pNew==0 ){ CloseHandle(pInit->h); +#if OS_WINCE + sqliteFree(pInit->zDeleteOnClose); +#endif *pId = 0; return SQLITE_NOMEM; }else{ @@ -1020,7 +1119,13 @@ int sqlite3WinCurrentTime(double *prNow){ 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ double now; +#if OS_WINCE + 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 -- 2.47.2