extensions/sqlite/sqlite-source/os_win.c
author Scott Ehlert <ds@alliedmods.net>
Sun Sep 14 02:58:58 2008 -0500 (2008-09-14)
changeset 2287 017a725c9d17
parent 1952 b7aa2b626807
permissions -rw-r--r--
Eliminated head for dead branch: sourcemod-1.1.0
     1 /*
     2 ** 2004 May 22
     3 **
     4 ** The author disclaims copyright to this source code.  In place of
     5 ** a legal notice, here is a blessing:
     6 **
     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.
    10 **
    11 ******************************************************************************
    12 **
    13 ** This file contains code that is specific to windows.
    14 */
    15 #include "sqliteInt.h"
    16 #if OS_WIN               /* This file is used for windows only */
    17 
    18 
    19 /*
    20 ** A Note About Memory Allocation:
    21 **
    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.
    29 **
    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.
    38 **
    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.
    43 */
    44 
    45 #include <winbase.h>
    46 
    47 #ifdef __CYGWIN__
    48 # include <sys/cygwin.h>
    49 #endif
    50 
    51 /*
    52 ** Macros used to determine whether or not to use threads.
    53 */
    54 #if defined(THREADSAFE) && THREADSAFE
    55 # define SQLITE_W32_THREADS 1
    56 #endif
    57 
    58 /*
    59 ** Include code that is common to all os_*.c files
    60 */
    61 #include "os_common.h"
    62 
    63 /*
    64 ** Determine if we are dealing with WindowsCE - which has a much
    65 ** reduced API.
    66 */
    67 #if defined(_WIN32_WCE)
    68 # define OS_WINCE 1
    69 # define AreFileApisANSI() 1
    70 #else
    71 # define OS_WINCE 0
    72 #endif
    73 
    74 /*
    75 ** WinCE lacks native support for file locking so we have to fake it
    76 ** with some code of our own.
    77 */
    78 #if OS_WINCE
    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 */
    84 } winceLock;
    85 #endif
    86 
    87 /*
    88 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
    89 ** portability layer.
    90 */
    91 typedef struct winFile winFile;
    92 struct 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 */
    97 #if OS_WINCE
    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  */
   103 #endif
   104 };
   105 
   106 
   107 /*
   108 ** The following variable is (normally) set once and never changes
   109 ** thereafter.  It records whether the operating system is Win95
   110 ** or WinNT.
   111 **
   112 ** 0:   Operating system unknown.
   113 ** 1:   Operating system is Win95.
   114 ** 2:   Operating system is WinNT.
   115 **
   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.
   118 */
   119 #ifdef SQLITE_TEST
   120 int sqlite3_os_type = 0;
   121 #else
   122 static int sqlite3_os_type = 0;
   123 #endif
   124 
   125 /*
   126 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
   127 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
   128 **
   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.
   135 */
   136 #if OS_WINCE
   137 # define isNT()  (1)
   138 #else
   139   static int isNT(void){
   140     if( sqlite3_os_type==0 ){
   141       OSVERSIONINFO sInfo;
   142       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
   143       GetVersionEx(&sInfo);
   144       sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
   145     }
   146     return sqlite3_os_type==2;
   147   }
   148 #endif /* OS_WINCE */
   149 
   150 /*
   151 ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
   152 **
   153 ** Space to hold the returned string is obtained from malloc.
   154 */
   155 static WCHAR *utf8ToUnicode(const char *zFilename){
   156   int nChar;
   157   WCHAR *zWideFilename;
   158 
   159   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
   160   zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
   161   if( zWideFilename==0 ){
   162     return 0;
   163   }
   164   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
   165   if( nChar==0 ){
   166     free(zWideFilename);
   167     zWideFilename = 0;
   168   }
   169   return zWideFilename;
   170 }
   171 
   172 /*
   173 ** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
   174 ** obtained from malloc().
   175 */
   176 static char *unicodeToUtf8(const WCHAR *zWideFilename){
   177   int nByte;
   178   char *zFilename;
   179 
   180   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
   181   zFilename = malloc( nByte );
   182   if( zFilename==0 ){
   183     return 0;
   184   }
   185   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
   186                               0, 0);
   187   if( nByte == 0 ){
   188     free(zFilename);
   189     zFilename = 0;
   190   }
   191   return zFilename;
   192 }
   193 
   194 /*
   195 ** Convert an ansi string to microsoft unicode, based on the
   196 ** current codepage settings for file apis.
   197 ** 
   198 ** Space to hold the returned string is obtained
   199 ** from malloc.
   200 */
   201 static WCHAR *mbcsToUnicode(const char *zFilename){
   202   int nByte;
   203   WCHAR *zMbcsFilename;
   204   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
   205 
   206   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
   207   zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
   208   if( zMbcsFilename==0 ){
   209     return 0;
   210   }
   211   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
   212   if( nByte==0 ){
   213     free(zMbcsFilename);
   214     zMbcsFilename = 0;
   215   }
   216   return zMbcsFilename;
   217 }
   218 
   219 /*
   220 ** Convert microsoft unicode to multibyte character string, based on the
   221 ** user's Ansi codepage.
   222 **
   223 ** Space to hold the returned string is obtained from
   224 ** malloc().
   225 */
   226 static char *unicodeToMbcs(const WCHAR *zWideFilename){
   227   int nByte;
   228   char *zFilename;
   229   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
   230 
   231   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
   232   zFilename = malloc( nByte );
   233   if( zFilename==0 ){
   234     return 0;
   235   }
   236   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
   237                               0, 0);
   238   if( nByte == 0 ){
   239     free(zFilename);
   240     zFilename = 0;
   241   }
   242   return zFilename;
   243 }
   244 
   245 /*
   246 ** Convert multibyte character string to UTF-8.  Space to hold the
   247 ** returned string is obtained from malloc().
   248 */
   249 static char *mbcsToUtf8(const char *zFilename){
   250   char *zFilenameUtf8;
   251   WCHAR *zTmpWide;
   252 
   253   zTmpWide = mbcsToUnicode(zFilename);
   254   if( zTmpWide==0 ){
   255     return 0;
   256   }
   257   zFilenameUtf8 = unicodeToUtf8(zTmpWide);
   258   free(zTmpWide);
   259   return zFilenameUtf8;
   260 }
   261 
   262 /*
   263 ** Convert UTF-8 to multibyte character string.  Space to hold the 
   264 ** returned string is obtained from malloc().
   265 */
   266 static char *utf8ToMbcs(const char *zFilename){
   267   char *zFilenameMbcs;
   268   WCHAR *zTmpWide;
   269 
   270   zTmpWide = utf8ToUnicode(zFilename);
   271   if( zTmpWide==0 ){
   272     return 0;
   273   }
   274   zFilenameMbcs = unicodeToMbcs(zTmpWide);
   275   free(zTmpWide);
   276   return zFilenameMbcs;
   277 }
   278 
   279 #if OS_WINCE
   280 /*************************************************************************
   281 ** This section contains code for WinCE only.
   282 */
   283 /*
   284 ** WindowsCE does not have a localtime() function.  So create a
   285 ** substitute.
   286 */
   287 #include <time.h>
   288 struct tm *__cdecl localtime(const time_t *t)
   289 {
   290   static struct tm y;
   291   FILETIME uTm, lTm;
   292   SYSTEMTIME pTm;
   293   sqlite3_int64 t64;
   294   t64 = *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;
   307   return &y;
   308 }
   309 
   310 /* This will never be called, but defined to make the code compile */
   311 #define GetTempPathA(a,b)
   312 
   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)
   316 
   317 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
   318 
   319 /*
   320 ** Acquire a lock on the handle h
   321 */
   322 static void winceMutexAcquire(HANDLE h){
   323    DWORD dwErr;
   324    do {
   325      dwErr = WaitForSingleObject(h, INFINITE);
   326    } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
   327 }
   328 /*
   329 ** Release a lock acquired by winceMutexAcquire()
   330 */
   331 #define winceMutexRelease(h) ReleaseMutex(h)
   332 
   333 /*
   334 ** Create the mutex and shared memory used for locking in the file
   335 ** descriptor pFile
   336 */
   337 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
   338   WCHAR *zTok;
   339   WCHAR *zName = utf8ToUnicode(zFilename);
   340   BOOL bInit = TRUE;
   341 
   342   /* Initialize the local lockdata */
   343   ZeroMemory(&pFile->local, sizeof(pFile->local));
   344 
   345   /* Replace the backslashes from the filename and lowercase it
   346   ** to derive a mutex name. */
   347   zTok = CharLowerW(zName);
   348   for (;*zTok;zTok++){
   349     if (*zTok == '\\') *zTok = '_';
   350   }
   351 
   352   /* Create/open the named mutex */
   353   pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
   354   if (!pFile->hMutex){
   355     free(zName);
   356     return FALSE;
   357   }
   358 
   359   /* Acquire the mutex before continuing */
   360   winceMutexAcquire(pFile->hMutex);
   361   
   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.
   365   */
   366   CharUpperW(zName);
   367   pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
   368                                        PAGE_READWRITE, 0, sizeof(winceLock),
   369                                        zName);  
   370 
   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){
   374     bInit = FALSE;
   375   }
   376 
   377   free(zName);
   378 
   379   /* If we succeeded in making the shared memory handle, map it. */
   380   if (pFile->hShared){
   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 */
   384     if (!pFile->shared){
   385       CloseHandle(pFile->hShared);
   386       pFile->hShared = NULL;
   387     }
   388   }
   389 
   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;
   395     return FALSE;
   396   }
   397   
   398   /* Initialize the shared memory if we're supposed to */
   399   if (bInit) {
   400     ZeroMemory(pFile->shared, sizeof(winceLock));
   401   }
   402 
   403   winceMutexRelease(pFile->hMutex);
   404   return TRUE;
   405 }
   406 
   407 /*
   408 ** Destroy the part of winFile that deals with wince locks
   409 */
   410 static void winceDestroyLock(winFile *pFile){
   411   if (pFile->hMutex){
   412     /* Acquire the mutex */
   413     winceMutexAcquire(pFile->hMutex);
   414 
   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 --;
   419     }
   420     if (pFile->local.bReserved){
   421       pFile->shared->bReserved = FALSE;
   422     }
   423     if (pFile->local.bPending){
   424       pFile->shared->bPending = FALSE;
   425     }
   426     if (pFile->local.bExclusive){
   427       pFile->shared->bExclusive = FALSE;
   428     }
   429 
   430     /* De-reference and close our copy of the shared memory handle */
   431     UnmapViewOfFile(pFile->shared);
   432     CloseHandle(pFile->hShared);
   433 
   434     if( pFile->zDeleteOnClose ){
   435       DeleteFileW(pFile->zDeleteOnClose);
   436       free(pFile->zDeleteOnClose);
   437       pFile->zDeleteOnClose = 0;
   438     }
   439 
   440     /* Done with the mutex */
   441     winceMutexRelease(pFile->hMutex);    
   442     CloseHandle(pFile->hMutex);
   443     pFile->hMutex = NULL;
   444   }
   445 }
   446 
   447 /* 
   448 ** An implementation of the LockFile() API of windows for wince
   449 */
   450 static BOOL winceLockFile(
   451   HANDLE *phFile,
   452   DWORD dwFileOffsetLow,
   453   DWORD dwFileOffsetHigh,
   454   DWORD nNumberOfBytesToLockLow,
   455   DWORD nNumberOfBytesToLockHigh
   456 ){
   457   winFile *pFile = HANDLE_TO_WINFILE(phFile);
   458   BOOL bReturn = FALSE;
   459 
   460   if (!pFile->hMutex) return TRUE;
   461   winceMutexAcquire(pFile->hMutex);
   462 
   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;
   469        bReturn = TRUE;
   470     }
   471   }
   472 
   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 ++;
   481       }
   482       bReturn = TRUE;
   483     }
   484   }
   485 
   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;
   492       bReturn = TRUE;
   493     }
   494   }
   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;
   500       bReturn = TRUE;
   501     }
   502   }
   503 
   504   winceMutexRelease(pFile->hMutex);
   505   return bReturn;
   506 }
   507 
   508 /*
   509 ** An implementation of the UnlockFile API of windows for wince
   510 */
   511 static BOOL winceUnlockFile(
   512   HANDLE *phFile,
   513   DWORD dwFileOffsetLow,
   514   DWORD dwFileOffsetHigh,
   515   DWORD nNumberOfBytesToUnlockLow,
   516   DWORD nNumberOfBytesToUnlockHigh
   517 ){
   518   winFile *pFile = HANDLE_TO_WINFILE(phFile);
   519   BOOL bReturn = FALSE;
   520 
   521   if (!pFile->hMutex) return TRUE;
   522   winceMutexAcquire(pFile->hMutex);
   523 
   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;
   531       bReturn = TRUE;
   532     }
   533 
   534     /* Did we just have a reader lock? */
   535     else if (pFile->local.nReaders){
   536       pFile->local.nReaders --;
   537       if (pFile->local.nReaders == 0)
   538       {
   539         pFile->shared->nReaders --;
   540       }
   541       bReturn = TRUE;
   542     }
   543   }
   544 
   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;
   550       bReturn = TRUE;
   551     }
   552   }
   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;
   558       bReturn = TRUE;
   559     }
   560   }
   561 
   562   winceMutexRelease(pFile->hMutex);
   563   return bReturn;
   564 }
   565 
   566 /*
   567 ** An implementation of the LockFileEx() API of windows for wince
   568 */
   569 static BOOL winceLockFileEx(
   570   HANDLE *phFile,
   571   DWORD dwFlags,
   572   DWORD dwReserved,
   573   DWORD nNumberOfBytesToLockLow,
   574   DWORD nNumberOfBytesToLockHigh,
   575   LPOVERLAPPED lpOverlapped
   576 ){
   577   /* If the caller wants a shared read lock, forward this call
   578   ** to winceLockFile */
   579   if (lpOverlapped->Offset == SHARED_FIRST &&
   580       dwFlags == 1 &&
   581       nNumberOfBytesToLockLow == SHARED_SIZE){
   582     return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
   583   }
   584   return FALSE;
   585 }
   586 /*
   587 ** End of the special code for wince
   588 *****************************************************************************/
   589 #endif /* OS_WINCE */
   590 
   591 /*****************************************************************************
   592 ** The next group of routines implement the I/O methods specified
   593 ** by the sqlite3_io_methods object.
   594 ******************************************************************************/
   595 
   596 /*
   597 ** Close a file.
   598 **
   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.
   605 */
   606 #define MX_CLOSE_ATTEMPT 3
   607 static int winClose(sqlite3_file *id){
   608   int rc, cnt = 0;
   609   winFile *pFile = (winFile*)id;
   610   OSTRACE2("CLOSE %d\n", pFile->h);
   611   do{
   612     rc = CloseHandle(pFile->h);
   613   }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
   614 #if OS_WINCE
   615   winceDestroyLock(pFile);
   616 #endif
   617   OpenCounter(-1);
   618   return rc ? SQLITE_OK : SQLITE_IOERR;
   619 }
   620 
   621 /*
   622 ** Some microsoft compilers lack this definition.
   623 */
   624 #ifndef INVALID_SET_FILE_POINTER
   625 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
   626 #endif
   627 
   628 /*
   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
   631 ** wrong.
   632 */
   633 static int winRead(
   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 */
   638 ){
   639   LONG upperBits = (offset>>32) & 0x7fffffff;
   640   LONG lowerBits = offset & 0xffffffff;
   641   DWORD rc;
   642   DWORD got;
   643   winFile *pFile = (winFile*)id;
   644   assert( id!=0 );
   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 ){
   649     return SQLITE_FULL;
   650   }
   651   if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
   652     return SQLITE_IOERR_READ;
   653   }
   654   if( got==(DWORD)amt ){
   655     return SQLITE_OK;
   656   }else{
   657     memset(&((char*)pBuf)[got], 0, amt-got);
   658     return SQLITE_IOERR_SHORT_READ;
   659   }
   660 }
   661 
   662 /*
   663 ** Write data from a buffer into a file.  Return SQLITE_OK on success
   664 ** or some other error code on failure.
   665 */
   666 static int winWrite(
   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 */
   671 ){
   672   LONG upperBits = (offset>>32) & 0x7fffffff;
   673   LONG lowerBits = offset & 0xffffffff;
   674   DWORD rc;
   675   DWORD wrote;
   676   winFile *pFile = (winFile*)id;
   677   assert( id!=0 );
   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 ){
   683     return SQLITE_FULL;
   684   }
   685   assert( amt>0 );
   686   while(
   687      amt>0
   688      && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
   689      && wrote>0
   690   ){
   691     amt -= wrote;
   692     pBuf = &((char*)pBuf)[wrote];
   693   }
   694   if( !rc || amt>(int)wrote ){
   695     return SQLITE_FULL;
   696   }
   697   return SQLITE_OK;
   698 }
   699 
   700 /*
   701 ** Truncate an open file to a specified size
   702 */
   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);
   711   return SQLITE_OK;
   712 }
   713 
   714 #ifdef SQLITE_TEST
   715 /*
   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.
   718 */
   719 int sqlite3_sync_count = 0;
   720 int sqlite3_fullsync_count = 0;
   721 #endif
   722 
   723 /*
   724 ** Make sure all writes to a particular file are committed to disk.
   725 */
   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);
   729 #ifdef SQLITE_TEST
   730   if( flags & SQLITE_SYNC_FULL ){
   731     sqlite3_fullsync_count++;
   732   }
   733   sqlite3_sync_count++;
   734 #endif
   735   if( FlushFileBuffers(pFile->h) ){
   736     return SQLITE_OK;
   737   }else{
   738     return SQLITE_IOERR;
   739   }
   740 }
   741 
   742 /*
   743 ** Determine the current size of a file in bytes
   744 */
   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;
   751   return SQLITE_OK;
   752 }
   753 
   754 /*
   755 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
   756 */
   757 #ifndef LOCKFILE_FAIL_IMMEDIATELY
   758 # define LOCKFILE_FAIL_IMMEDIATELY 1
   759 #endif
   760 
   761 /*
   762 ** Acquire a reader lock.
   763 ** Different API routines are called depending on whether or not this
   764 ** is Win95 or WinNT.
   765 */
   766 static int getReadLock(winFile *pFile){
   767   int res;
   768   if( isNT() ){
   769     OVERLAPPED ovlp;
   770     ovlp.Offset = SHARED_FIRST;
   771     ovlp.OffsetHigh = 0;
   772     ovlp.hEvent = 0;
   773     res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
   774                      0, SHARED_SIZE, 0, &ovlp);
   775   }else{
   776     int lk;
   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);
   780   }
   781   return res;
   782 }
   783 
   784 /*
   785 ** Undo a readlock
   786 */
   787 static int unlockReadLock(winFile *pFile){
   788   int res;
   789   if( isNT() ){
   790     res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
   791   }else{
   792     res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
   793   }
   794   return res;
   795 }
   796 
   797 /*
   798 ** Lock the file with the lock specified by parameter locktype - one
   799 ** of the following:
   800 **
   801 **     (1) SHARED_LOCK
   802 **     (2) RESERVED_LOCK
   803 **     (3) PENDING_LOCK
   804 **     (4) EXCLUSIVE_LOCK
   805 **
   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:
   811 **
   812 **    UNLOCKED -> SHARED
   813 **    SHARED -> RESERVED
   814 **    SHARED -> (PENDING) -> EXCLUSIVE
   815 **    RESERVED -> (PENDING) -> EXCLUSIVE
   816 **    PENDING -> EXCLUSIVE
   817 **
   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.
   822 */
   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;
   829 
   830   assert( pFile!=0 );
   831   OSTRACE5("LOCK %d %d was %d(%d)\n",
   832           pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
   833 
   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.
   837   */
   838   if( pFile->locktype>=locktype ){
   839     return SQLITE_OK;
   840   }
   841 
   842   /* Make sure the locking sequence is correct
   843   */
   844   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
   845   assert( locktype!=PENDING_LOCK );
   846   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
   847 
   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.
   851   */
   852   newLocktype = pFile->locktype;
   853   if( pFile->locktype==NO_LOCK
   854    || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
   855   ){
   856     int cnt = 3;
   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.
   860       */
   861       OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
   862       Sleep(1);
   863     }
   864     gotPendingLock = res;
   865   }
   866 
   867   /* Acquire a shared lock
   868   */
   869   if( locktype==SHARED_LOCK && res ){
   870     assert( pFile->locktype==NO_LOCK );
   871     res = getReadLock(pFile);
   872     if( res ){
   873       newLocktype = SHARED_LOCK;
   874     }
   875   }
   876 
   877   /* Acquire a RESERVED lock
   878   */
   879   if( locktype==RESERVED_LOCK && res ){
   880     assert( pFile->locktype==SHARED_LOCK );
   881     res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
   882     if( res ){
   883       newLocktype = RESERVED_LOCK;
   884     }
   885   }
   886 
   887   /* Acquire a PENDING lock
   888   */
   889   if( locktype==EXCLUSIVE_LOCK && res ){
   890     newLocktype = PENDING_LOCK;
   891     gotPendingLock = 0;
   892   }
   893 
   894   /* Acquire an EXCLUSIVE lock
   895   */
   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);
   901     if( res ){
   902       newLocktype = EXCLUSIVE_LOCK;
   903     }else{
   904       OSTRACE2("error-code = %d\n", GetLastError());
   905       getReadLock(pFile);
   906     }
   907   }
   908 
   909   /* If we are holding a PENDING lock that ought to be released, then
   910   ** release it now.
   911   */
   912   if( gotPendingLock && locktype==SHARED_LOCK ){
   913     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
   914   }
   915 
   916   /* Update the state of the lock has held in the file descriptor then
   917   ** return the appropriate result code.
   918   */
   919   if( res ){
   920     rc = SQLITE_OK;
   921   }else{
   922     OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
   923            locktype, newLocktype);
   924     rc = SQLITE_BUSY;
   925   }
   926   pFile->locktype = newLocktype;
   927   return rc;
   928 }
   929 
   930 /*
   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.
   934 */
   935 static int winCheckReservedLock(sqlite3_file *id){
   936   int rc;
   937   winFile *pFile = (winFile*)id;
   938   assert( pFile!=0 );
   939   if( pFile->locktype>=RESERVED_LOCK ){
   940     rc = 1;
   941     OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
   942   }else{
   943     rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
   944     if( rc ){
   945       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
   946     }
   947     rc = !rc;
   948     OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
   949   }
   950   return rc;
   951 }
   952 
   953 /*
   954 ** Lower the locking level on file descriptor id to locktype.  locktype
   955 ** must be either NO_LOCK or SHARED_LOCK.
   956 **
   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.
   959 **
   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;
   963 */
   964 static int winUnlock(sqlite3_file *id, int locktype){
   965   int type;
   966   winFile *pFile = (winFile*)id;
   967   int rc = SQLITE_OK;
   968   assert( pFile!=0 );
   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;
   979     }
   980   }
   981   if( type>=RESERVED_LOCK ){
   982     UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
   983   }
   984   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
   985     unlockReadLock(pFile);
   986   }
   987   if( type>=PENDING_LOCK ){
   988     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
   989   }
   990   pFile->locktype = locktype;
   991   return rc;
   992 }
   993 
   994 /*
   995 ** Control and query of the open file handle.
   996 */
   997 static int winFileControl(sqlite3_file *id, int op, void *pArg){
   998   switch( op ){
   999     case SQLITE_FCNTL_LOCKSTATE: {
  1000       *(int*)pArg = ((winFile*)id)->locktype;
  1001       return SQLITE_OK;
  1002     }
  1003   }
  1004   return SQLITE_ERROR;
  1005 }
  1006 
  1007 /*
  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.
  1011 **
  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
  1015 ** same for both.
  1016 */
  1017 static int winSectorSize(sqlite3_file *id){
  1018   return SQLITE_DEFAULT_SECTOR_SIZE;
  1019 }
  1020 
  1021 /*
  1022 ** Return a vector of device characteristics.
  1023 */
  1024 static int winDeviceCharacteristics(sqlite3_file *id){
  1025   return 0;
  1026 }
  1027 
  1028 /*
  1029 ** This vector defines all the methods that can operate on an
  1030 ** sqlite3_file for win32.
  1031 */
  1032 static const sqlite3_io_methods winIoMethod = {
  1033   1,                        /* iVersion */
  1034   winClose,
  1035   winRead,
  1036   winWrite,
  1037   winTruncate,
  1038   winSync,
  1039   winFileSize,
  1040   winLock,
  1041   winUnlock,
  1042   winCheckReservedLock,
  1043   winFileControl,
  1044   winSectorSize,
  1045   winDeviceCharacteristics
  1046 };
  1047 
  1048 /***************************************************************************
  1049 ** Here ends the I/O methods that form the sqlite3_io_methods object.
  1050 **
  1051 ** The next block of code implements the VFS methods.
  1052 ****************************************************************************/
  1053 
  1054 /*
  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
  1058 ** function.
  1059 */
  1060 static void *convertUtf8Filename(const char *zFilename){
  1061   void *zConverted = 0;
  1062   if( isNT() ){
  1063     zConverted = utf8ToUnicode(zFilename);
  1064   }else{
  1065     zConverted = utf8ToMbcs(zFilename);
  1066   }
  1067   /* caller will handle out of memory */
  1068   return zConverted;
  1069 }
  1070 
  1071 /*
  1072 ** Open a file.
  1073 */
  1074 static int winOpen(
  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 */
  1080 ){
  1081   HANDLE h;
  1082   DWORD dwDesiredAccess;
  1083   DWORD dwShareMode;
  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;
  1090   }
  1091 
  1092   if( flags & SQLITE_OPEN_READWRITE ){
  1093     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
  1094   }else{
  1095     dwDesiredAccess = GENERIC_READ;
  1096   }
  1097   if( flags & SQLITE_OPEN_CREATE ){
  1098     dwCreationDisposition = OPEN_ALWAYS;
  1099   }else{
  1100     dwCreationDisposition = OPEN_EXISTING;
  1101   }
  1102   if( flags & SQLITE_OPEN_MAIN_DB ){
  1103     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  1104   }else{
  1105     dwShareMode = 0;
  1106   }
  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;
  1112   }else{
  1113     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
  1114   }
  1115   if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){
  1116     dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
  1117   }else{
  1118     dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
  1119   }
  1120   if( isNT() ){
  1121     h = CreateFileW((WCHAR*)zConverted,
  1122        dwDesiredAccess,
  1123        dwShareMode,
  1124        NULL,
  1125        dwCreationDisposition,
  1126        dwFlagsAndAttributes,
  1127        NULL
  1128     );
  1129   }else{
  1130 #if OS_WINCE
  1131     return SQLITE_NOMEM;
  1132 #else
  1133     h = CreateFileA((char*)zConverted,
  1134        dwDesiredAccess,
  1135        dwShareMode,
  1136        NULL,
  1137        dwCreationDisposition,
  1138        dwFlagsAndAttributes,
  1139        NULL
  1140     );
  1141 #endif
  1142   }
  1143   if( h==INVALID_HANDLE_VALUE ){
  1144     free(zConverted);
  1145     if( flags & SQLITE_OPEN_READWRITE ){
  1146       return winOpen(0, zName, id, 
  1147              ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
  1148     }else{
  1149       return SQLITE_CANTOPEN;
  1150     }
  1151   }
  1152   if( pOutFlags ){
  1153     if( flags & SQLITE_OPEN_READWRITE ){
  1154       *pOutFlags = SQLITE_OPEN_READWRITE;
  1155     }else{
  1156       *pOutFlags = SQLITE_OPEN_READONLY;
  1157     }
  1158   }
  1159   memset(pFile, 0, sizeof(*pFile));
  1160   pFile->pMethod = &winIoMethod;
  1161   pFile->h = h;
  1162 #if OS_WINCE
  1163   if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
  1164                (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
  1165        && !winceCreateLock(zFilename, pFile)
  1166   ){
  1167     CloseHandle(h);
  1168     free(zConverted);
  1169     return SQLITE_CANTOPEN;
  1170   }
  1171   if( dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE ){
  1172     pFile->zDeleteOnClose = zConverted;
  1173   }else
  1174 #endif
  1175   {
  1176     free(zConverted);
  1177   }
  1178   OpenCounter(+1);
  1179   return SQLITE_OK;
  1180 }
  1181 
  1182 /*
  1183 ** Delete the named file.
  1184 **
  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.
  1193 */
  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 */
  1199 ){
  1200   int cnt = 0;
  1201   int rc;
  1202   void *zConverted = convertUtf8Filename(zFilename);
  1203   if( zConverted==0 ){
  1204     return SQLITE_NOMEM;
  1205   }
  1206   SimulateIOError(return SQLITE_IOERR_DELETE);
  1207   if( isNT() ){
  1208     do{
  1209       rc = DeleteFileW(zConverted);
  1210     }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff 
  1211             && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
  1212   }else{
  1213 #if OS_WINCE
  1214     return SQLITE_NOMEM;
  1215 #else
  1216     do{
  1217       rc = DeleteFileA(zConverted);
  1218     }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
  1219             && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
  1220 #endif
  1221   }
  1222   free(zConverted);
  1223   OSTRACE2("DELETE \"%s\"\n", zFilename);
  1224   return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
  1225 }
  1226 
  1227 /*
  1228 ** Check the existance and status of a file.
  1229 */
  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 */
  1234 ){
  1235   DWORD attr;
  1236   int rc;
  1237   void *zConverted = convertUtf8Filename(zFilename);
  1238   if( zConverted==0 ){
  1239     return SQLITE_NOMEM;
  1240   }
  1241   if( isNT() ){
  1242     attr = GetFileAttributesW((WCHAR*)zConverted);
  1243   }else{
  1244 #if OS_WINCE
  1245     return SQLITE_NOMEM;
  1246 #else
  1247     attr = GetFileAttributesA((char*)zConverted);
  1248 #endif
  1249   }
  1250   free(zConverted);
  1251   switch( flags ){
  1252     case SQLITE_ACCESS_READ:
  1253     case SQLITE_ACCESS_EXISTS:
  1254       rc = attr!=0xffffffff;
  1255       break;
  1256     case SQLITE_ACCESS_READWRITE:
  1257       rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
  1258       break;
  1259     default:
  1260       assert(!"Invalid flags argument");
  1261   }
  1262   return rc;
  1263 }
  1264 
  1265 
  1266 /*
  1267 ** Create a temporary file name in zBuf.  zBuf must be big enough to
  1268 ** hold at pVfs->mxPathname characters.
  1269 */
  1270 static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  1271   static char zChars[] =
  1272     "abcdefghijklmnopqrstuvwxyz"
  1273     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  1274     "0123456789";
  1275   int i, j;
  1276   char zTempPath[MAX_PATH+1];
  1277   if( sqlite3_temp_directory ){
  1278     sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
  1279   }else if( isNT() ){
  1280     char *zMulti;
  1281     WCHAR zWidePath[MAX_PATH];
  1282     GetTempPathW(MAX_PATH-30, zWidePath);
  1283     zMulti = unicodeToUtf8(zWidePath);
  1284     if( zMulti ){
  1285       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
  1286       free(zMulti);
  1287     }else{
  1288       return SQLITE_NOMEM;
  1289     }
  1290   }else{
  1291     char *zUtf8;
  1292     char zMbcsPath[MAX_PATH];
  1293     GetTempPathA(MAX_PATH-30, zMbcsPath);
  1294     zUtf8 = mbcsToUtf8(zMbcsPath);
  1295     if( zUtf8 ){
  1296       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
  1297       free(zUtf8);
  1298     }else{
  1299       return SQLITE_NOMEM;
  1300     }
  1301   }
  1302   for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  1303   zTempPath[i] = 0;
  1304   sqlite3_snprintf(pVfs->mxPathname-30, zBuf,
  1305                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
  1306   j = strlen(zBuf);
  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) ];
  1310   }
  1311   zBuf[j] = 0;
  1312   OSTRACE2("TEMP FILENAME: %s\n", zBuf);
  1313   return SQLITE_OK; 
  1314 }
  1315 
  1316 /*
  1317 ** Turn a relative pathname into a full pathname.  Write the full
  1318 ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
  1319 ** bytes in size.
  1320 */
  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 */
  1326 ){
  1327 
  1328 #if defined(__CYGWIN__)
  1329   cygwin_conv_to_full_win32_path(zRelative, zFull);
  1330   return SQLITE_OK;
  1331 #endif
  1332 
  1333 #if OS_WINCE
  1334   /* WinCE has no concept of a relative pathname, or so I am told. */
  1335   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
  1336 #endif
  1337 
  1338 #if !OS_WINCE && !defined(__CYGWIN__)
  1339   int nByte;
  1340   void *zConverted;
  1341   char *zOut;
  1342   zConverted = convertUtf8Filename(zRelative);
  1343   if( isNT() ){
  1344     WCHAR *zTemp;
  1345     nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
  1346     zTemp = malloc( nByte*sizeof(zTemp[0]) );
  1347     if( zTemp==0 ){
  1348       free(zConverted);
  1349       return SQLITE_NOMEM;
  1350     }
  1351     GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
  1352     free(zConverted);
  1353     zOut = unicodeToUtf8(zTemp);
  1354     free(zTemp);
  1355   }else{
  1356     char *zTemp;
  1357     nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
  1358     zTemp = malloc( nByte*sizeof(zTemp[0]) );
  1359     if( zTemp==0 ){
  1360       free(zConverted);
  1361       return SQLITE_NOMEM;
  1362     }
  1363     GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
  1364     free(zConverted);
  1365     zOut = mbcsToUtf8(zTemp);
  1366     free(zTemp);
  1367   }
  1368   if( zOut ){
  1369     sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
  1370     free(zOut);
  1371     return SQLITE_OK;
  1372   }else{
  1373     return SQLITE_NOMEM;
  1374   }
  1375 #endif
  1376 }
  1377 
  1378 #ifndef SQLITE_OMIT_LOAD_EXTENSION
  1379 /*
  1380 ** Interfaces for opening a shared library, finding entry points
  1381 ** within the shared library, and closing the shared library.
  1382 */
  1383 /*
  1384 ** Interfaces for opening a shared library, finding entry points
  1385 ** within the shared library, and closing the shared library.
  1386 */
  1387 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
  1388   HANDLE h;
  1389   void *zConverted = convertUtf8Filename(zFilename);
  1390   if( zConverted==0 ){
  1391     return 0;
  1392   }
  1393   if( isNT() ){
  1394     h = LoadLibraryW((WCHAR*)zConverted);
  1395   }else{
  1396 #if OS_WINCE
  1397     return 0;
  1398 #else
  1399     h = LoadLibraryA((char*)zConverted);
  1400 #endif
  1401   }
  1402   free(zConverted);
  1403   return (void*)h;
  1404 }
  1405 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  1406   FormatMessage(
  1407     FORMAT_MESSAGE_FROM_SYSTEM,
  1408     NULL,
  1409     GetLastError(),
  1410     0,
  1411     zBufOut,
  1412     nBuf-1,
  1413     0
  1414   );
  1415 }
  1416 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
  1417 #if OS_WINCE
  1418   /* The GetProcAddressA() routine is only available on wince. */
  1419   return GetProcAddressA((HANDLE)pHandle, zSymbol);
  1420 #else
  1421   /* All other windows platforms expect GetProcAddress() to take
  1422   ** an Ansi string regardless of the _UNICODE setting */
  1423   return GetProcAddress((HANDLE)pHandle, zSymbol);
  1424 #endif
  1425 }
  1426 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
  1427   FreeLibrary((HANDLE)pHandle);
  1428 }
  1429 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
  1430   #define winDlOpen  0
  1431   #define winDlError 0
  1432   #define winDlSym   0
  1433   #define winDlClose 0
  1434 #endif
  1435 
  1436 
  1437 /*
  1438 ** Write up to nBuf bytes of randomness into zBuf.
  1439 */
  1440 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  1441   int n = 0;
  1442   if( sizeof(SYSTEMTIME)<=nBuf-n ){
  1443     SYSTEMTIME x;
  1444     GetSystemTime(&x);
  1445     memcpy(&zBuf[n], &x, sizeof(x));
  1446     n += sizeof(x);
  1447   }
  1448   if( sizeof(DWORD)<=nBuf-n ){
  1449     DWORD pid = GetCurrentProcessId();
  1450     memcpy(&zBuf[n], &pid, sizeof(pid));
  1451     n += sizeof(pid);
  1452   }
  1453   if( sizeof(DWORD)<=nBuf-n ){
  1454     DWORD cnt = GetTickCount();
  1455     memcpy(&zBuf[n], &cnt, sizeof(cnt));
  1456     n += sizeof(cnt);
  1457   }
  1458   if( sizeof(LARGE_INTEGER)<=nBuf-n ){
  1459     LARGE_INTEGER i;
  1460     QueryPerformanceCounter(&i);
  1461     memcpy(&zBuf[n], &i, sizeof(i));
  1462     n += sizeof(i);
  1463   }
  1464   return n;
  1465 }
  1466 
  1467 
  1468 /*
  1469 ** Sleep for a little while.  Return the amount of time slept.
  1470 */
  1471 static int winSleep(sqlite3_vfs *pVfs, int microsec){
  1472   Sleep((microsec+999)/1000);
  1473   return ((microsec+999)/1000)*1000;
  1474 }
  1475 
  1476 /*
  1477 ** The following variable, if set to a non-zero value, becomes the result
  1478 ** returned from sqlite3OsCurrentTime().  This is used for testing.
  1479 */
  1480 #ifdef SQLITE_TEST
  1481 int sqlite3_current_time = 0;
  1482 #endif
  1483 
  1484 /*
  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.
  1488 */
  1489 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
  1490   FILETIME ft;
  1491   /* FILETIME structure is a 64-bit value representing the number of 
  1492      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  1493   */
  1494   double now;
  1495 #if OS_WINCE
  1496   SYSTEMTIME time;
  1497   GetSystemTime(&time);
  1498   SystemTimeToFileTime(&time,&ft);
  1499 #else
  1500   GetSystemTimeAsFileTime( &ft );
  1501 #endif
  1502   now = ((double)ft.dwHighDateTime) * 4294967296.0; 
  1503   *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
  1504 #ifdef SQLITE_TEST
  1505   if( sqlite3_current_time ){
  1506     *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  1507   }
  1508 #endif
  1509   return 0;
  1510 }
  1511 
  1512 
  1513 /*
  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.
  1518 */
  1519 sqlite3_vfs *sqlite3OsDefaultVfs(void){
  1520   static sqlite3_vfs winVfs = {
  1521     1,                 /* iVersion */
  1522     sizeof(winFile),   /* szOsFile */
  1523     MAX_PATH,          /* mxPathname */
  1524     0,                 /* pNext */
  1525     "win32",           /* zName */
  1526     0,                 /* pAppData */
  1527   
  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 */
  1540   };
  1541   
  1542   return &winVfs;
  1543 }
  1544 
  1545 #endif /* OS_WIN */