4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 ******************************************************************************
13 ** This file contains code that is specific to windows.
15 #include "sqliteInt.h"
16 #if OS_WIN /* This file is used for windows only */
20 ** A Note About Memory Allocation:
22 ** This driver uses malloc()/free() directly rather than going through
23 ** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers
24 ** are designed for use on embedded systems where memory is scarce and
25 ** malloc failures happen frequently. Win32 does not typically run on
26 ** embedded systems, and when it does the developers normally have bigger
27 ** problems to worry about than running out of memory. So there is not
28 ** a compelling need to use the wrappers.
30 ** But there is a good reason to not use the wrappers. If we use the
31 ** wrappers then we will get simulated malloc() failures within this
32 ** driver. And that causes all kinds of problems for our tests. We
33 ** could enhance SQLite to deal with simulated malloc failures within
34 ** the OS driver, but the code to deal with those failure would not
35 ** be exercised on Linux (which does not need to malloc() in the driver)
36 ** and so we would have difficulty writing coverage tests for that
37 ** code. Better to leave the code out, we think.
39 ** The point of this discussion is as follows: When creating a new
40 ** OS layer for an embedded system, if you use this file as an example,
41 ** avoid the use of malloc()/free(). Those routines work ok on windows
42 ** desktops but not so well in embedded systems.
48 # include <sys/cygwin.h>
52 ** Macros used to determine whether or not to use threads.
54 #if defined(THREADSAFE) && THREADSAFE
55 # define SQLITE_W32_THREADS 1
59 ** Include code that is common to all os_*.c files
61 #include "os_common.h"
64 ** Determine if we are dealing with WindowsCE - which has a much
67 #if defined(_WIN32_WCE)
69 # define AreFileApisANSI() 1
75 ** WinCE lacks native support for file locking so we have to fake it
76 ** with some code of our own.
79 typedef struct winceLock {
80 int nReaders; /* Number of reader locks obtained */
81 BOOL bPending; /* Indicates a pending lock has been obtained */
82 BOOL bReserved; /* Indicates a reserved lock has been obtained */
83 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
88 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
91 typedef struct winFile winFile;
93 const sqlite3_io_methods *pMethod;/* Must be first */
94 HANDLE h; /* Handle for accessing the file */
95 unsigned char locktype; /* Type of lock currently held on this file */
96 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
98 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
99 HANDLE hMutex; /* Mutex used to control access to shared lock */
100 HANDLE hShared; /* Shared memory segment used for locking */
101 winceLock local; /* Locks obtained by this instance of winFile */
102 winceLock *shared; /* Global shared lock memory for the file */
108 ** The following variable is (normally) set once and never changes
109 ** thereafter. It records whether the operating system is Win95
112 ** 0: Operating system unknown.
113 ** 1: Operating system is Win95.
114 ** 2: Operating system is WinNT.
116 ** In order to facilitate testing on a WinNT system, the test fixture
117 ** can manually set this value to 1 to emulate Win98 behavior.
120 int sqlite3_os_type = 0;
122 static int sqlite3_os_type = 0;
126 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
127 ** or WinCE. Return false (zero) for Win95, Win98, or WinME.
129 ** Here is an interesting observation: Win95, Win98, and WinME lack
130 ** the LockFileEx() API. But we can still statically link against that
131 ** API as long as we don't call it win running Win95/98/ME. A call to
132 ** this routine is used to determine if the host is Win95/98/ME or
133 ** WinNT/2K/XP so that we will know whether or not we can safely call
134 ** the LockFileEx() API.
139 static int isNT(void){
140 if( sqlite3_os_type==0 ){
142 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
143 GetVersionEx(&sInfo);
144 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
146 return sqlite3_os_type==2;
148 #endif /* OS_WINCE */
151 ** Convert a UTF-8 string to microsoft unicode (UTF-16?).
153 ** Space to hold the returned string is obtained from malloc.
155 static WCHAR *utf8ToUnicode(const char *zFilename){
157 WCHAR *zWideFilename;
159 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
160 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
161 if( zWideFilename==0 ){
164 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
169 return zWideFilename;
173 ** Convert microsoft unicode to UTF-8. Space to hold the returned string is
174 ** obtained from malloc().
176 static char *unicodeToUtf8(const WCHAR *zWideFilename){
180 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
181 zFilename = malloc( nByte );
185 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
195 ** Convert an ansi string to microsoft unicode, based on the
196 ** current codepage settings for file apis.
198 ** Space to hold the returned string is obtained
201 static WCHAR *mbcsToUnicode(const char *zFilename){
203 WCHAR *zMbcsFilename;
204 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
206 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
207 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
208 if( zMbcsFilename==0 ){
211 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
216 return zMbcsFilename;
220 ** Convert microsoft unicode to multibyte character string, based on the
221 ** user's Ansi codepage.
223 ** Space to hold the returned string is obtained from
226 static char *unicodeToMbcs(const WCHAR *zWideFilename){
229 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
231 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
232 zFilename = malloc( nByte );
236 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
246 ** Convert multibyte character string to UTF-8. Space to hold the
247 ** returned string is obtained from malloc().
249 static char *mbcsToUtf8(const char *zFilename){
253 zTmpWide = mbcsToUnicode(zFilename);
257 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
259 return zFilenameUtf8;
263 ** Convert UTF-8 to multibyte character string. Space to hold the
264 ** returned string is obtained from malloc().
266 static char *utf8ToMbcs(const char *zFilename){
270 zTmpWide = utf8ToUnicode(zFilename);
274 zFilenameMbcs = unicodeToMbcs(zTmpWide);
276 return zFilenameMbcs;
280 /*************************************************************************
281 ** This section contains code for WinCE only.
284 ** WindowsCE does not have a localtime() function. So create a
288 struct tm *__cdecl localtime(const time_t *t)
295 t64 = (t64 + 11644473600)*10000000;
296 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
297 uTm.dwHighDateTime= t64 >> 32;
298 FileTimeToLocalFileTime(&uTm,&lTm);
299 FileTimeToSystemTime(&lTm,&pTm);
300 y.tm_year = pTm.wYear - 1900;
301 y.tm_mon = pTm.wMonth - 1;
302 y.tm_wday = pTm.wDayOfWeek;
303 y.tm_mday = pTm.wDay;
304 y.tm_hour = pTm.wHour;
305 y.tm_min = pTm.wMinute;
306 y.tm_sec = pTm.wSecond;
310 /* This will never be called, but defined to make the code compile */
311 #define GetTempPathA(a,b)
313 #define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
314 #define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
315 #define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
317 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
320 ** Acquire a lock on the handle h
322 static void winceMutexAcquire(HANDLE h){
325 dwErr = WaitForSingleObject(h, INFINITE);
326 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
329 ** Release a lock acquired by winceMutexAcquire()
331 #define winceMutexRelease(h) ReleaseMutex(h)
334 ** Create the mutex and shared memory used for locking in the file
337 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
339 WCHAR *zName = utf8ToUnicode(zFilename);
342 /* Initialize the local lockdata */
343 ZeroMemory(&pFile->local, sizeof(pFile->local));
345 /* Replace the backslashes from the filename and lowercase it
346 ** to derive a mutex name. */
347 zTok = CharLowerW(zName);
349 if (*zTok == '\\') *zTok = '_';
352 /* Create/open the named mutex */
353 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
359 /* Acquire the mutex before continuing */
360 winceMutexAcquire(pFile->hMutex);
362 /* Since the names of named mutexes, semaphores, file mappings etc are
363 ** case-sensitive, take advantage of that by uppercasing the mutex name
364 ** and using that as the shared filemapping name.
367 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
368 PAGE_READWRITE, 0, sizeof(winceLock),
371 /* Set a flag that indicates we're the first to create the memory so it
372 ** must be zero-initialized */
373 if (GetLastError() == ERROR_ALREADY_EXISTS){
379 /* If we succeeded in making the shared memory handle, map it. */
381 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
382 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
383 /* If mapping failed, close the shared memory handle and erase it */
385 CloseHandle(pFile->hShared);
386 pFile->hShared = NULL;
390 /* If shared memory could not be created, then close the mutex and fail */
391 if (pFile->hShared == NULL){
392 winceMutexRelease(pFile->hMutex);
393 CloseHandle(pFile->hMutex);
394 pFile->hMutex = NULL;
398 /* Initialize the shared memory if we're supposed to */
400 ZeroMemory(pFile->shared, sizeof(winceLock));
403 winceMutexRelease(pFile->hMutex);
408 ** Destroy the part of winFile that deals with wince locks
410 static void winceDestroyLock(winFile *pFile){
412 /* Acquire the mutex */
413 winceMutexAcquire(pFile->hMutex);
415 /* The following blocks should probably assert in debug mode, but they
416 are to cleanup in case any locks remained open */
417 if (pFile->local.nReaders){
418 pFile->shared->nReaders --;
420 if (pFile->local.bReserved){
421 pFile->shared->bReserved = FALSE;
423 if (pFile->local.bPending){
424 pFile->shared->bPending = FALSE;
426 if (pFile->local.bExclusive){
427 pFile->shared->bExclusive = FALSE;
430 /* De-reference and close our copy of the shared memory handle */
431 UnmapViewOfFile(pFile->shared);
432 CloseHandle(pFile->hShared);
434 if( pFile->zDeleteOnClose ){
435 DeleteFileW(pFile->zDeleteOnClose);
436 free(pFile->zDeleteOnClose);
437 pFile->zDeleteOnClose = 0;
440 /* Done with the mutex */
441 winceMutexRelease(pFile->hMutex);
442 CloseHandle(pFile->hMutex);
443 pFile->hMutex = NULL;
448 ** An implementation of the LockFile() API of windows for wince
450 static BOOL winceLockFile(
452 DWORD dwFileOffsetLow,
453 DWORD dwFileOffsetHigh,
454 DWORD nNumberOfBytesToLockLow,
455 DWORD nNumberOfBytesToLockHigh
457 winFile *pFile = HANDLE_TO_WINFILE(phFile);
458 BOOL bReturn = FALSE;
460 if (!pFile->hMutex) return TRUE;
461 winceMutexAcquire(pFile->hMutex);
463 /* Wanting an exclusive lock? */
464 if (dwFileOffsetLow == SHARED_FIRST
465 && nNumberOfBytesToLockLow == SHARED_SIZE){
466 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
467 pFile->shared->bExclusive = TRUE;
468 pFile->local.bExclusive = TRUE;
473 /* Want a read-only lock? */
474 else if ((dwFileOffsetLow >= SHARED_FIRST &&
475 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
476 nNumberOfBytesToLockLow == 1){
477 if (pFile->shared->bExclusive == 0){
478 pFile->local.nReaders ++;
479 if (pFile->local.nReaders == 1){
480 pFile->shared->nReaders ++;
486 /* Want a pending lock? */
487 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
488 /* If no pending lock has been acquired, then acquire it */
489 if (pFile->shared->bPending == 0) {
490 pFile->shared->bPending = TRUE;
491 pFile->local.bPending = TRUE;
495 /* Want a reserved lock? */
496 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
497 if (pFile->shared->bReserved == 0) {
498 pFile->shared->bReserved = TRUE;
499 pFile->local.bReserved = TRUE;
504 winceMutexRelease(pFile->hMutex);
509 ** An implementation of the UnlockFile API of windows for wince
511 static BOOL winceUnlockFile(
513 DWORD dwFileOffsetLow,
514 DWORD dwFileOffsetHigh,
515 DWORD nNumberOfBytesToUnlockLow,
516 DWORD nNumberOfBytesToUnlockHigh
518 winFile *pFile = HANDLE_TO_WINFILE(phFile);
519 BOOL bReturn = FALSE;
521 if (!pFile->hMutex) return TRUE;
522 winceMutexAcquire(pFile->hMutex);
524 /* Releasing a reader lock or an exclusive lock */
525 if (dwFileOffsetLow >= SHARED_FIRST &&
526 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
527 /* Did we have an exclusive lock? */
528 if (pFile->local.bExclusive){
529 pFile->local.bExclusive = FALSE;
530 pFile->shared->bExclusive = FALSE;
534 /* Did we just have a reader lock? */
535 else if (pFile->local.nReaders){
536 pFile->local.nReaders --;
537 if (pFile->local.nReaders == 0)
539 pFile->shared->nReaders --;
545 /* Releasing a pending lock */
546 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
547 if (pFile->local.bPending){
548 pFile->local.bPending = FALSE;
549 pFile->shared->bPending = FALSE;
553 /* Releasing a reserved lock */
554 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
555 if (pFile->local.bReserved) {
556 pFile->local.bReserved = FALSE;
557 pFile->shared->bReserved = FALSE;
562 winceMutexRelease(pFile->hMutex);
567 ** An implementation of the LockFileEx() API of windows for wince
569 static BOOL winceLockFileEx(
573 DWORD nNumberOfBytesToLockLow,
574 DWORD nNumberOfBytesToLockHigh,
575 LPOVERLAPPED lpOverlapped
577 /* If the caller wants a shared read lock, forward this call
578 ** to winceLockFile */
579 if (lpOverlapped->Offset == SHARED_FIRST &&
581 nNumberOfBytesToLockLow == SHARED_SIZE){
582 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
587 ** End of the special code for wince
588 *****************************************************************************/
589 #endif /* OS_WINCE */
591 /*****************************************************************************
592 ** The next group of routines implement the I/O methods specified
593 ** by the sqlite3_io_methods object.
594 ******************************************************************************/
599 ** It is reported that an attempt to close a handle might sometimes
600 ** fail. This is a very unreasonable result, but windows is notorious
601 ** for being unreasonable so I do not doubt that it might happen. If
602 ** the close fails, we pause for 100 milliseconds and try again. As
603 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
604 ** giving up and returning an error.
606 #define MX_CLOSE_ATTEMPT 3
607 static int winClose(sqlite3_file *id){
609 winFile *pFile = (winFile*)id;
610 OSTRACE2("CLOSE %d\n", pFile->h);
612 rc = CloseHandle(pFile->h);
613 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
615 winceDestroyLock(pFile);
618 return rc ? SQLITE_OK : SQLITE_IOERR;
622 ** Some microsoft compilers lack this definition.
624 #ifndef INVALID_SET_FILE_POINTER
625 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
629 ** Read data from a file into a buffer. Return SQLITE_OK if all
630 ** bytes were read successfully and SQLITE_IOERR if anything goes
634 sqlite3_file *id, /* File to read from */
635 void *pBuf, /* Write content into this buffer */
636 int amt, /* Number of bytes to read */
637 sqlite3_int64 offset /* Begin reading at this offset */
639 LONG upperBits = (offset>>32) & 0x7fffffff;
640 LONG lowerBits = offset & 0xffffffff;
643 winFile *pFile = (winFile*)id;
645 SimulateIOError(return SQLITE_IOERR_READ);
646 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
647 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
648 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
651 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
652 return SQLITE_IOERR_READ;
654 if( got==(DWORD)amt ){
657 memset(&((char*)pBuf)[got], 0, amt-got);
658 return SQLITE_IOERR_SHORT_READ;
663 ** Write data from a buffer into a file. Return SQLITE_OK on success
664 ** or some other error code on failure.
667 sqlite3_file *id, /* File to write into */
668 const void *pBuf, /* The bytes to be written */
669 int amt, /* Number of bytes to write */
670 sqlite3_int64 offset /* Offset into the file to begin writing at */
672 LONG upperBits = (offset>>32) & 0x7fffffff;
673 LONG lowerBits = offset & 0xffffffff;
676 winFile *pFile = (winFile*)id;
678 SimulateIOError(return SQLITE_IOERR_WRITE);
679 SimulateDiskfullError(return SQLITE_FULL);
680 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
681 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
682 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
688 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
692 pBuf = &((char*)pBuf)[wrote];
694 if( !rc || amt>(int)wrote ){
701 ** Truncate an open file to a specified size
703 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
704 LONG upperBits = (nByte>>32) & 0x7fffffff;
705 LONG lowerBits = nByte & 0xffffffff;
706 winFile *pFile = (winFile*)id;
707 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
708 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
709 SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
710 SetEndOfFile(pFile->h);
716 ** Count the number of fullsyncs and normal syncs. This is used to test
717 ** that syncs and fullsyncs are occuring at the right times.
719 int sqlite3_sync_count = 0;
720 int sqlite3_fullsync_count = 0;
724 ** Make sure all writes to a particular file are committed to disk.
726 static int winSync(sqlite3_file *id, int flags){
727 winFile *pFile = (winFile*)id;
728 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
730 if( flags & SQLITE_SYNC_FULL ){
731 sqlite3_fullsync_count++;
733 sqlite3_sync_count++;
735 if( FlushFileBuffers(pFile->h) ){
743 ** Determine the current size of a file in bytes
745 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
746 winFile *pFile = (winFile*)id;
747 DWORD upperBits, lowerBits;
748 SimulateIOError(return SQLITE_IOERR_FSTAT);
749 lowerBits = GetFileSize(pFile->h, &upperBits);
750 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
755 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
757 #ifndef LOCKFILE_FAIL_IMMEDIATELY
758 # define LOCKFILE_FAIL_IMMEDIATELY 1
762 ** Acquire a reader lock.
763 ** Different API routines are called depending on whether or not this
764 ** is Win95 or WinNT.
766 static int getReadLock(winFile *pFile){
770 ovlp.Offset = SHARED_FIRST;
773 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
774 0, SHARED_SIZE, 0, &ovlp);
777 sqlite3Randomness(sizeof(lk), &lk);
778 pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
779 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
787 static int unlockReadLock(winFile *pFile){
790 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
792 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
798 ** Lock the file with the lock specified by parameter locktype - one
804 ** (4) EXCLUSIVE_LOCK
806 ** Sometimes when requesting one lock state, additional lock states
807 ** are inserted in between. The locking might fail on one of the later
808 ** transitions leaving the lock state different from what it started but
809 ** still short of its goal. The following chart shows the allowed
810 ** transitions and the inserted intermediate states:
812 ** UNLOCKED -> SHARED
813 ** SHARED -> RESERVED
814 ** SHARED -> (PENDING) -> EXCLUSIVE
815 ** RESERVED -> (PENDING) -> EXCLUSIVE
816 ** PENDING -> EXCLUSIVE
818 ** This routine will only increase a lock. The winUnlock() routine
819 ** erases all locks at once and returns us immediately to locking level 0.
820 ** It is not possible to lower the locking level one step at a time. You
821 ** must go straight to locking level 0.
823 static int winLock(sqlite3_file *id, int locktype){
824 int rc = SQLITE_OK; /* Return code from subroutines */
825 int res = 1; /* Result of a windows lock call */
826 int newLocktype; /* Set pFile->locktype to this value before exiting */
827 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
828 winFile *pFile = (winFile*)id;
831 OSTRACE5("LOCK %d %d was %d(%d)\n",
832 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
834 /* If there is already a lock of this type or more restrictive on the
835 ** OsFile, do nothing. Don't use the end_lock: exit path, as
836 ** sqlite3OsEnterMutex() hasn't been called yet.
838 if( pFile->locktype>=locktype ){
842 /* Make sure the locking sequence is correct
844 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
845 assert( locktype!=PENDING_LOCK );
846 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
848 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
849 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
850 ** the PENDING_LOCK byte is temporary.
852 newLocktype = pFile->locktype;
853 if( pFile->locktype==NO_LOCK
854 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
857 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
858 /* Try 3 times to get the pending lock. The pending lock might be
859 ** held by another reader process who will release it momentarily.
861 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
864 gotPendingLock = res;
867 /* Acquire a shared lock
869 if( locktype==SHARED_LOCK && res ){
870 assert( pFile->locktype==NO_LOCK );
871 res = getReadLock(pFile);
873 newLocktype = SHARED_LOCK;
877 /* Acquire a RESERVED lock
879 if( locktype==RESERVED_LOCK && res ){
880 assert( pFile->locktype==SHARED_LOCK );
881 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
883 newLocktype = RESERVED_LOCK;
887 /* Acquire a PENDING lock
889 if( locktype==EXCLUSIVE_LOCK && res ){
890 newLocktype = PENDING_LOCK;
894 /* Acquire an EXCLUSIVE lock
896 if( locktype==EXCLUSIVE_LOCK && res ){
897 assert( pFile->locktype>=SHARED_LOCK );
898 res = unlockReadLock(pFile);
899 OSTRACE2("unreadlock = %d\n", res);
900 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
902 newLocktype = EXCLUSIVE_LOCK;
904 OSTRACE2("error-code = %d\n", GetLastError());
909 /* If we are holding a PENDING lock that ought to be released, then
912 if( gotPendingLock && locktype==SHARED_LOCK ){
913 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
916 /* Update the state of the lock has held in the file descriptor then
917 ** return the appropriate result code.
922 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
923 locktype, newLocktype);
926 pFile->locktype = newLocktype;
931 ** This routine checks if there is a RESERVED lock held on the specified
932 ** file by this or any other process. If such a lock is held, return
933 ** non-zero, otherwise zero.
935 static int winCheckReservedLock(sqlite3_file *id){
937 winFile *pFile = (winFile*)id;
939 if( pFile->locktype>=RESERVED_LOCK ){
941 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
943 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
945 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
948 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
954 ** Lower the locking level on file descriptor id to locktype. locktype
955 ** must be either NO_LOCK or SHARED_LOCK.
957 ** If the locking level of the file descriptor is already at or below
958 ** the requested locking level, this routine is a no-op.
960 ** It is not possible for this routine to fail if the second argument
961 ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
962 ** might return SQLITE_IOERR;
964 static int winUnlock(sqlite3_file *id, int locktype){
966 winFile *pFile = (winFile*)id;
969 assert( locktype<=SHARED_LOCK );
970 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
971 pFile->locktype, pFile->sharedLockByte);
972 type = pFile->locktype;
973 if( type>=EXCLUSIVE_LOCK ){
974 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
975 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
976 /* This should never happen. We should always be able to
977 ** reacquire the read lock */
978 rc = SQLITE_IOERR_UNLOCK;
981 if( type>=RESERVED_LOCK ){
982 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
984 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
985 unlockReadLock(pFile);
987 if( type>=PENDING_LOCK ){
988 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
990 pFile->locktype = locktype;
995 ** Control and query of the open file handle.
997 static int winFileControl(sqlite3_file *id, int op, void *pArg){
999 case SQLITE_FCNTL_LOCKSTATE: {
1000 *(int*)pArg = ((winFile*)id)->locktype;
1004 return SQLITE_ERROR;
1008 ** Return the sector size in bytes of the underlying block device for
1009 ** the specified file. This is almost always 512 bytes, but may be
1010 ** larger for some devices.
1012 ** SQLite code assumes this function cannot fail. It also assumes that
1013 ** if two files are created in the same file-system directory (i.e.
1014 ** a database and it's journal file) that the sector size will be the
1017 static int winSectorSize(sqlite3_file *id){
1018 return SQLITE_DEFAULT_SECTOR_SIZE;
1022 ** Return a vector of device characteristics.
1024 static int winDeviceCharacteristics(sqlite3_file *id){
1029 ** This vector defines all the methods that can operate on an
1030 ** sqlite3_file for win32.
1032 static const sqlite3_io_methods winIoMethod = {
1042 winCheckReservedLock,
1045 winDeviceCharacteristics
1048 /***************************************************************************
1049 ** Here ends the I/O methods that form the sqlite3_io_methods object.
1051 ** The next block of code implements the VFS methods.
1052 ****************************************************************************/
1055 ** Convert a UTF-8 filename into whatever form the underlying
1056 ** operating system wants filenames in. Space to hold the result
1057 ** is obtained from malloc and must be freed by the calling
1060 static void *convertUtf8Filename(const char *zFilename){
1061 void *zConverted = 0;
1063 zConverted = utf8ToUnicode(zFilename);
1065 zConverted = utf8ToMbcs(zFilename);
1067 /* caller will handle out of memory */
1075 sqlite3_vfs *pVfs, /* Not used */
1076 const char *zName, /* Name of the file (UTF-8) */
1077 sqlite3_file *id, /* Write the SQLite file handle here */
1078 int flags, /* Open mode flags */
1079 int *pOutFlags /* Status return flags */
1082 DWORD dwDesiredAccess;
1084 DWORD dwCreationDisposition;
1085 DWORD dwFlagsAndAttributes = 0;
1086 winFile *pFile = (winFile*)id;
1087 void *zConverted = convertUtf8Filename(zName);
1088 if( zConverted==0 ){
1089 return SQLITE_NOMEM;
1092 if( flags & SQLITE_OPEN_READWRITE ){
1093 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1095 dwDesiredAccess = GENERIC_READ;
1097 if( flags & SQLITE_OPEN_CREATE ){
1098 dwCreationDisposition = OPEN_ALWAYS;
1100 dwCreationDisposition = OPEN_EXISTING;
1102 if( flags & SQLITE_OPEN_MAIN_DB ){
1103 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1107 if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL
1108 | SQLITE_OPEN_SUBJOURNAL) ){
1109 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1110 | FILE_ATTRIBUTE_HIDDEN
1111 | FILE_FLAG_DELETE_ON_CLOSE;
1113 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1115 if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){
1116 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
1118 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
1121 h = CreateFileW((WCHAR*)zConverted,
1125 dwCreationDisposition,
1126 dwFlagsAndAttributes,
1131 return SQLITE_NOMEM;
1133 h = CreateFileA((char*)zConverted,
1137 dwCreationDisposition,
1138 dwFlagsAndAttributes,
1143 if( h==INVALID_HANDLE_VALUE ){
1145 if( flags & SQLITE_OPEN_READWRITE ){
1146 return winOpen(0, zName, id,
1147 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1149 return SQLITE_CANTOPEN;
1153 if( flags & SQLITE_OPEN_READWRITE ){
1154 *pOutFlags = SQLITE_OPEN_READWRITE;
1156 *pOutFlags = SQLITE_OPEN_READONLY;
1159 memset(pFile, 0, sizeof(*pFile));
1160 pFile->pMethod = &winIoMethod;
1163 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1164 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
1165 && !winceCreateLock(zFilename, pFile)
1169 return SQLITE_CANTOPEN;
1171 if( dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE ){
1172 pFile->zDeleteOnClose = zConverted;
1183 ** Delete the named file.
1185 ** Note that windows does not allow a file to be deleted if some other
1186 ** process has it open. Sometimes a virus scanner or indexing program
1187 ** will open a journal file shortly after it is created in order to do
1188 ** whatever it is it does. While this other process is holding the
1189 ** file open, we will be unable to delete it. To work around this
1190 ** problem, we delay 100 milliseconds and try to delete again. Up
1191 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
1192 ** up and returning an error.
1194 #define MX_DELETION_ATTEMPTS 3
1195 static int winDelete(
1196 sqlite3_vfs *pVfs, /* Not used on win32 */
1197 const char *zFilename, /* Name of file to delete */
1198 int syncDir /* Not used on win32 */
1202 void *zConverted = convertUtf8Filename(zFilename);
1203 if( zConverted==0 ){
1204 return SQLITE_NOMEM;
1206 SimulateIOError(return SQLITE_IOERR_DELETE);
1209 rc = DeleteFileW(zConverted);
1210 }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
1211 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
1214 return SQLITE_NOMEM;
1217 rc = DeleteFileA(zConverted);
1218 }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
1219 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
1223 OSTRACE2("DELETE \"%s\"\n", zFilename);
1224 return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
1228 ** Check the existance and status of a file.
1230 static int winAccess(
1231 sqlite3_vfs *pVfs, /* Not used on win32 */
1232 const char *zFilename, /* Name of file to check */
1233 int flags /* Type of test to make on this file */
1237 void *zConverted = convertUtf8Filename(zFilename);
1238 if( zConverted==0 ){
1239 return SQLITE_NOMEM;
1242 attr = GetFileAttributesW((WCHAR*)zConverted);
1245 return SQLITE_NOMEM;
1247 attr = GetFileAttributesA((char*)zConverted);
1252 case SQLITE_ACCESS_READ:
1253 case SQLITE_ACCESS_EXISTS:
1254 rc = attr!=0xffffffff;
1256 case SQLITE_ACCESS_READWRITE:
1257 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
1260 assert(!"Invalid flags argument");
1267 ** Create a temporary file name in zBuf. zBuf must be big enough to
1268 ** hold at pVfs->mxPathname characters.
1270 static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
1271 static char zChars[] =
1272 "abcdefghijklmnopqrstuvwxyz"
1273 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1276 char zTempPath[MAX_PATH+1];
1277 if( sqlite3_temp_directory ){
1278 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1281 WCHAR zWidePath[MAX_PATH];
1282 GetTempPathW(MAX_PATH-30, zWidePath);
1283 zMulti = unicodeToUtf8(zWidePath);
1285 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1288 return SQLITE_NOMEM;
1292 char zMbcsPath[MAX_PATH];
1293 GetTempPathA(MAX_PATH-30, zMbcsPath);
1294 zUtf8 = mbcsToUtf8(zMbcsPath);
1296 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1299 return SQLITE_NOMEM;
1302 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
1304 sqlite3_snprintf(pVfs->mxPathname-30, zBuf,
1305 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
1307 sqlite3Randomness(20, &zBuf[j]);
1308 for(i=0; i<20; i++, j++){
1309 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1312 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
1317 ** Turn a relative pathname into a full pathname. Write the full
1318 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
1321 static int winFullPathname(
1322 sqlite3_vfs *pVfs, /* Pointer to vfs object */
1323 const char *zRelative, /* Possibly relative input path */
1324 int nFull, /* Size of output buffer in bytes */
1325 char *zFull /* Output buffer */
1328 #if defined(__CYGWIN__)
1329 cygwin_conv_to_full_win32_path(zRelative, zFull);
1334 /* WinCE has no concept of a relative pathname, or so I am told. */
1335 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
1338 #if !OS_WINCE && !defined(__CYGWIN__)
1342 zConverted = convertUtf8Filename(zRelative);
1345 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
1346 zTemp = malloc( nByte*sizeof(zTemp[0]) );
1349 return SQLITE_NOMEM;
1351 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
1353 zOut = unicodeToUtf8(zTemp);
1357 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
1358 zTemp = malloc( nByte*sizeof(zTemp[0]) );
1361 return SQLITE_NOMEM;
1363 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
1365 zOut = mbcsToUtf8(zTemp);
1369 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
1373 return SQLITE_NOMEM;
1378 #ifndef SQLITE_OMIT_LOAD_EXTENSION
1380 ** Interfaces for opening a shared library, finding entry points
1381 ** within the shared library, and closing the shared library.
1384 ** Interfaces for opening a shared library, finding entry points
1385 ** within the shared library, and closing the shared library.
1387 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
1389 void *zConverted = convertUtf8Filename(zFilename);
1390 if( zConverted==0 ){
1394 h = LoadLibraryW((WCHAR*)zConverted);
1399 h = LoadLibraryA((char*)zConverted);
1405 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
1407 FORMAT_MESSAGE_FROM_SYSTEM,
1416 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
1418 /* The GetProcAddressA() routine is only available on wince. */
1419 return GetProcAddressA((HANDLE)pHandle, zSymbol);
1421 /* All other windows platforms expect GetProcAddress() to take
1422 ** an Ansi string regardless of the _UNICODE setting */
1423 return GetProcAddress((HANDLE)pHandle, zSymbol);
1426 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
1427 FreeLibrary((HANDLE)pHandle);
1429 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
1431 #define winDlError 0
1433 #define winDlClose 0
1438 ** Write up to nBuf bytes of randomness into zBuf.
1440 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
1442 if( sizeof(SYSTEMTIME)<=nBuf-n ){
1445 memcpy(&zBuf[n], &x, sizeof(x));
1448 if( sizeof(DWORD)<=nBuf-n ){
1449 DWORD pid = GetCurrentProcessId();
1450 memcpy(&zBuf[n], &pid, sizeof(pid));
1453 if( sizeof(DWORD)<=nBuf-n ){
1454 DWORD cnt = GetTickCount();
1455 memcpy(&zBuf[n], &cnt, sizeof(cnt));
1458 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
1460 QueryPerformanceCounter(&i);
1461 memcpy(&zBuf[n], &i, sizeof(i));
1469 ** Sleep for a little while. Return the amount of time slept.
1471 static int winSleep(sqlite3_vfs *pVfs, int microsec){
1472 Sleep((microsec+999)/1000);
1473 return ((microsec+999)/1000)*1000;
1477 ** The following variable, if set to a non-zero value, becomes the result
1478 ** returned from sqlite3OsCurrentTime(). This is used for testing.
1481 int sqlite3_current_time = 0;
1485 ** Find the current time (in Universal Coordinated Time). Write the
1486 ** current time and date as a Julian Day number into *prNow and
1487 ** return 0. Return 1 if the time and date cannot be found.
1489 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
1491 /* FILETIME structure is a 64-bit value representing the number of
1492 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1497 GetSystemTime(&time);
1498 SystemTimeToFileTime(&time,&ft);
1500 GetSystemTimeAsFileTime( &ft );
1502 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1503 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1505 if( sqlite3_current_time ){
1506 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1514 ** Return a pointer to the sqlite3DefaultVfs structure. We use
1515 ** a function rather than give the structure global scope because
1516 ** some compilers (MSVC) do not allow forward declarations of
1517 ** initialized structures.
1519 sqlite3_vfs *sqlite3OsDefaultVfs(void){
1520 static sqlite3_vfs winVfs = {
1522 sizeof(winFile), /* szOsFile */
1523 MAX_PATH, /* mxPathname */
1525 "win32", /* zName */
1528 winOpen, /* xOpen */
1529 winDelete, /* xDelete */
1530 winAccess, /* xAccess */
1531 winGetTempname, /* xGetTempName */
1532 winFullPathname, /* xFullPathname */
1533 winDlOpen, /* xDlOpen */
1534 winDlError, /* xDlError */
1535 winDlSym, /* xDlSym */
1536 winDlClose, /* xDlClose */
1537 winRandomness, /* xRandomness */
1538 winSleep, /* xSleep */
1539 winCurrentTime /* xCurrentTime */