persistentstorage/sql/SQLite/os_win.c
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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 ** $Id: os_win.c,v 1.132 2008/07/31 01:34:34 shane Exp $
       
    16 */
       
    17 #include "sqliteInt.h"
       
    18 #if SQLITE_OS_WIN               /* This file is used for windows only */
       
    19 
       
    20 
       
    21 /*
       
    22 ** A Note About Memory Allocation:
       
    23 **
       
    24 ** This driver uses malloc()/free() directly rather than going through
       
    25 ** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
       
    26 ** are designed for use on embedded systems where memory is scarce and
       
    27 ** malloc failures happen frequently.  Win32 does not typically run on
       
    28 ** embedded systems, and when it does the developers normally have bigger
       
    29 ** problems to worry about than running out of memory.  So there is not
       
    30 ** a compelling need to use the wrappers.
       
    31 **
       
    32 ** But there is a good reason to not use the wrappers.  If we use the
       
    33 ** wrappers then we will get simulated malloc() failures within this
       
    34 ** driver.  And that causes all kinds of problems for our tests.  We
       
    35 ** could enhance SQLite to deal with simulated malloc failures within
       
    36 ** the OS driver, but the code to deal with those failure would not
       
    37 ** be exercised on Linux (which does not need to malloc() in the driver)
       
    38 ** and so we would have difficulty writing coverage tests for that
       
    39 ** code.  Better to leave the code out, we think.
       
    40 **
       
    41 ** The point of this discussion is as follows:  When creating a new
       
    42 ** OS layer for an embedded system, if you use this file as an example,
       
    43 ** avoid the use of malloc()/free().  Those routines work ok on windows
       
    44 ** desktops but not so well in embedded systems.
       
    45 */
       
    46 
       
    47 #include <winbase.h>
       
    48 
       
    49 #ifdef __CYGWIN__
       
    50 # include <sys/cygwin.h>
       
    51 #endif
       
    52 
       
    53 /*
       
    54 ** Macros used to determine whether or not to use threads.
       
    55 */
       
    56 #if defined(THREADSAFE) && THREADSAFE
       
    57 # define SQLITE_W32_THREADS 1
       
    58 #endif
       
    59 
       
    60 /*
       
    61 ** Include code that is common to all os_*.c files
       
    62 */
       
    63 #include "os_common.h"
       
    64 
       
    65 /*
       
    66 ** Determine if we are dealing with WindowsCE - which has a much
       
    67 ** reduced API.
       
    68 */
       
    69 #if defined(SQLITE_OS_WINCE)
       
    70 # define AreFileApisANSI() 1
       
    71 #endif
       
    72 
       
    73 /*
       
    74 ** WinCE lacks native support for file locking so we have to fake it
       
    75 ** with some code of our own.
       
    76 */
       
    77 #if SQLITE_OS_WINCE
       
    78 typedef struct winceLock {
       
    79   int nReaders;       /* Number of reader locks obtained */
       
    80   BOOL bPending;      /* Indicates a pending lock has been obtained */
       
    81   BOOL bReserved;     /* Indicates a reserved lock has been obtained */
       
    82   BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
       
    83 } winceLock;
       
    84 #endif
       
    85 
       
    86 /*
       
    87 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
       
    88 ** portability layer.
       
    89 */
       
    90 typedef struct winFile winFile;
       
    91 struct winFile {
       
    92   const sqlite3_io_methods *pMethod;/* Must be first */
       
    93   HANDLE h;               /* Handle for accessing the file */
       
    94   unsigned char locktype; /* Type of lock currently held on this file */
       
    95   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
       
    96 #if SQLITE_OS_WINCE
       
    97   WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
       
    98   HANDLE hMutex;          /* Mutex used to control access to shared lock */  
       
    99   HANDLE hShared;         /* Shared memory segment used for locking */
       
   100   winceLock local;        /* Locks obtained by this instance of winFile */
       
   101   winceLock *shared;      /* Global shared lock memory for the file  */
       
   102 #endif
       
   103 };
       
   104 
       
   105 
       
   106 /*
       
   107 ** The following variable is (normally) set once and never changes
       
   108 ** thereafter.  It records whether the operating system is Win95
       
   109 ** or WinNT.
       
   110 **
       
   111 ** 0:   Operating system unknown.
       
   112 ** 1:   Operating system is Win95.
       
   113 ** 2:   Operating system is WinNT.
       
   114 **
       
   115 ** In order to facilitate testing on a WinNT system, the test fixture
       
   116 ** can manually set this value to 1 to emulate Win98 behavior.
       
   117 */
       
   118 #ifdef SQLITE_TEST
       
   119 int sqlite3_os_type = 0;
       
   120 #else
       
   121 static int sqlite3_os_type = 0;
       
   122 #endif
       
   123 
       
   124 /*
       
   125 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
       
   126 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
       
   127 **
       
   128 ** Here is an interesting observation:  Win95, Win98, and WinME lack
       
   129 ** the LockFileEx() API.  But we can still statically link against that
       
   130 ** API as long as we don't call it win running Win95/98/ME.  A call to
       
   131 ** this routine is used to determine if the host is Win95/98/ME or
       
   132 ** WinNT/2K/XP so that we will know whether or not we can safely call
       
   133 ** the LockFileEx() API.
       
   134 */
       
   135 #if SQLITE_OS_WINCE
       
   136 # define isNT()  (1)
       
   137 #else
       
   138   static int isNT(void){
       
   139     if( sqlite3_os_type==0 ){
       
   140       OSVERSIONINFO sInfo;
       
   141       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
       
   142       GetVersionEx(&sInfo);
       
   143       sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
       
   144     }
       
   145     return sqlite3_os_type==2;
       
   146   }
       
   147 #endif /* SQLITE_OS_WINCE */
       
   148 
       
   149 /*
       
   150 ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
       
   151 **
       
   152 ** Space to hold the returned string is obtained from malloc.
       
   153 */
       
   154 static WCHAR *utf8ToUnicode(const char *zFilename){
       
   155   int nChar;
       
   156   WCHAR *zWideFilename;
       
   157 
       
   158   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
       
   159   zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
       
   160   if( zWideFilename==0 ){
       
   161     return 0;
       
   162   }
       
   163   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
       
   164   if( nChar==0 ){
       
   165     free(zWideFilename);
       
   166     zWideFilename = 0;
       
   167   }
       
   168   return zWideFilename;
       
   169 }
       
   170 
       
   171 /*
       
   172 ** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
       
   173 ** obtained from malloc().
       
   174 */
       
   175 static char *unicodeToUtf8(const WCHAR *zWideFilename){
       
   176   int nByte;
       
   177   char *zFilename;
       
   178 
       
   179   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
       
   180   zFilename = malloc( nByte );
       
   181   if( zFilename==0 ){
       
   182     return 0;
       
   183   }
       
   184   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
       
   185                               0, 0);
       
   186   if( nByte == 0 ){
       
   187     free(zFilename);
       
   188     zFilename = 0;
       
   189   }
       
   190   return zFilename;
       
   191 }
       
   192 
       
   193 /*
       
   194 ** Convert an ansi string to microsoft unicode, based on the
       
   195 ** current codepage settings for file apis.
       
   196 ** 
       
   197 ** Space to hold the returned string is obtained
       
   198 ** from malloc.
       
   199 */
       
   200 static WCHAR *mbcsToUnicode(const char *zFilename){
       
   201   int nByte;
       
   202   WCHAR *zMbcsFilename;
       
   203   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
       
   204 
       
   205   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
       
   206   zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
       
   207   if( zMbcsFilename==0 ){
       
   208     return 0;
       
   209   }
       
   210   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
       
   211   if( nByte==0 ){
       
   212     free(zMbcsFilename);
       
   213     zMbcsFilename = 0;
       
   214   }
       
   215   return zMbcsFilename;
       
   216 }
       
   217 
       
   218 /*
       
   219 ** Convert microsoft unicode to multibyte character string, based on the
       
   220 ** user's Ansi codepage.
       
   221 **
       
   222 ** Space to hold the returned string is obtained from
       
   223 ** malloc().
       
   224 */
       
   225 static char *unicodeToMbcs(const WCHAR *zWideFilename){
       
   226   int nByte;
       
   227   char *zFilename;
       
   228   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
       
   229 
       
   230   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
       
   231   zFilename = malloc( nByte );
       
   232   if( zFilename==0 ){
       
   233     return 0;
       
   234   }
       
   235   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
       
   236                               0, 0);
       
   237   if( nByte == 0 ){
       
   238     free(zFilename);
       
   239     zFilename = 0;
       
   240   }
       
   241   return zFilename;
       
   242 }
       
   243 
       
   244 /*
       
   245 ** Convert multibyte character string to UTF-8.  Space to hold the
       
   246 ** returned string is obtained from malloc().
       
   247 */
       
   248 static char *mbcsToUtf8(const char *zFilename){
       
   249   char *zFilenameUtf8;
       
   250   WCHAR *zTmpWide;
       
   251 
       
   252   zTmpWide = mbcsToUnicode(zFilename);
       
   253   if( zTmpWide==0 ){
       
   254     return 0;
       
   255   }
       
   256   zFilenameUtf8 = unicodeToUtf8(zTmpWide);
       
   257   free(zTmpWide);
       
   258   return zFilenameUtf8;
       
   259 }
       
   260 
       
   261 /*
       
   262 ** Convert UTF-8 to multibyte character string.  Space to hold the 
       
   263 ** returned string is obtained from malloc().
       
   264 */
       
   265 static char *utf8ToMbcs(const char *zFilename){
       
   266   char *zFilenameMbcs;
       
   267   WCHAR *zTmpWide;
       
   268 
       
   269   zTmpWide = utf8ToUnicode(zFilename);
       
   270   if( zTmpWide==0 ){
       
   271     return 0;
       
   272   }
       
   273   zFilenameMbcs = unicodeToMbcs(zTmpWide);
       
   274   free(zTmpWide);
       
   275   return zFilenameMbcs;
       
   276 }
       
   277 
       
   278 #if SQLITE_OS_WINCE
       
   279 /*************************************************************************
       
   280 ** This section contains code for WinCE only.
       
   281 */
       
   282 /*
       
   283 ** WindowsCE does not have a localtime() function.  So create a
       
   284 ** substitute.
       
   285 */
       
   286 #include <time.h>
       
   287 struct tm *__cdecl localtime(const time_t *t)
       
   288 {
       
   289   static struct tm y;
       
   290   FILETIME uTm, lTm;
       
   291   SYSTEMTIME pTm;
       
   292   sqlite3_int64 t64;
       
   293   t64 = *t;
       
   294   t64 = (t64 + 11644473600)*10000000;
       
   295   uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
       
   296   uTm.dwHighDateTime= t64 >> 32;
       
   297   FileTimeToLocalFileTime(&uTm,&lTm);
       
   298   FileTimeToSystemTime(&lTm,&pTm);
       
   299   y.tm_year = pTm.wYear - 1900;
       
   300   y.tm_mon = pTm.wMonth - 1;
       
   301   y.tm_wday = pTm.wDayOfWeek;
       
   302   y.tm_mday = pTm.wDay;
       
   303   y.tm_hour = pTm.wHour;
       
   304   y.tm_min = pTm.wMinute;
       
   305   y.tm_sec = pTm.wSecond;
       
   306   return &y;
       
   307 }
       
   308 
       
   309 /* This will never be called, but defined to make the code compile */
       
   310 #define GetTempPathA(a,b)
       
   311 
       
   312 #define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
       
   313 #define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
       
   314 #define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
       
   315 
       
   316 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
       
   317 
       
   318 /*
       
   319 ** Acquire a lock on the handle h
       
   320 */
       
   321 static void winceMutexAcquire(HANDLE h){
       
   322    DWORD dwErr;
       
   323    do {
       
   324      dwErr = WaitForSingleObject(h, INFINITE);
       
   325    } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
       
   326 }
       
   327 /*
       
   328 ** Release a lock acquired by winceMutexAcquire()
       
   329 */
       
   330 #define winceMutexRelease(h) ReleaseMutex(h)
       
   331 
       
   332 /*
       
   333 ** Create the mutex and shared memory used for locking in the file
       
   334 ** descriptor pFile
       
   335 */
       
   336 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
       
   337   WCHAR *zTok;
       
   338   WCHAR *zName = utf8ToUnicode(zFilename);
       
   339   BOOL bInit = TRUE;
       
   340 
       
   341   /* Initialize the local lockdata */
       
   342   ZeroMemory(&pFile->local, sizeof(pFile->local));
       
   343 
       
   344   /* Replace the backslashes from the filename and lowercase it
       
   345   ** to derive a mutex name. */
       
   346   zTok = CharLowerW(zName);
       
   347   for (;*zTok;zTok++){
       
   348     if (*zTok == '\\') *zTok = '_';
       
   349   }
       
   350 
       
   351   /* Create/open the named mutex */
       
   352   pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
       
   353   if (!pFile->hMutex){
       
   354     free(zName);
       
   355     return FALSE;
       
   356   }
       
   357 
       
   358   /* Acquire the mutex before continuing */
       
   359   winceMutexAcquire(pFile->hMutex);
       
   360   
       
   361   /* Since the names of named mutexes, semaphores, file mappings etc are 
       
   362   ** case-sensitive, take advantage of that by uppercasing the mutex name
       
   363   ** and using that as the shared filemapping name.
       
   364   */
       
   365   CharUpperW(zName);
       
   366   pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
       
   367                                        PAGE_READWRITE, 0, sizeof(winceLock),
       
   368                                        zName);  
       
   369 
       
   370   /* Set a flag that indicates we're the first to create the memory so it 
       
   371   ** must be zero-initialized */
       
   372   if (GetLastError() == ERROR_ALREADY_EXISTS){
       
   373     bInit = FALSE;
       
   374   }
       
   375 
       
   376   free(zName);
       
   377 
       
   378   /* If we succeeded in making the shared memory handle, map it. */
       
   379   if (pFile->hShared){
       
   380     pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
       
   381              FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
       
   382     /* If mapping failed, close the shared memory handle and erase it */
       
   383     if (!pFile->shared){
       
   384       CloseHandle(pFile->hShared);
       
   385       pFile->hShared = NULL;
       
   386     }
       
   387   }
       
   388 
       
   389   /* If shared memory could not be created, then close the mutex and fail */
       
   390   if (pFile->hShared == NULL){
       
   391     winceMutexRelease(pFile->hMutex);
       
   392     CloseHandle(pFile->hMutex);
       
   393     pFile->hMutex = NULL;
       
   394     return FALSE;
       
   395   }
       
   396   
       
   397   /* Initialize the shared memory if we're supposed to */
       
   398   if (bInit) {
       
   399     ZeroMemory(pFile->shared, sizeof(winceLock));
       
   400   }
       
   401 
       
   402   winceMutexRelease(pFile->hMutex);
       
   403   return TRUE;
       
   404 }
       
   405 
       
   406 /*
       
   407 ** Destroy the part of winFile that deals with wince locks
       
   408 */
       
   409 static void winceDestroyLock(winFile *pFile){
       
   410   if (pFile->hMutex){
       
   411     /* Acquire the mutex */
       
   412     winceMutexAcquire(pFile->hMutex);
       
   413 
       
   414     /* The following blocks should probably assert in debug mode, but they
       
   415        are to cleanup in case any locks remained open */
       
   416     if (pFile->local.nReaders){
       
   417       pFile->shared->nReaders --;
       
   418     }
       
   419     if (pFile->local.bReserved){
       
   420       pFile->shared->bReserved = FALSE;
       
   421     }
       
   422     if (pFile->local.bPending){
       
   423       pFile->shared->bPending = FALSE;
       
   424     }
       
   425     if (pFile->local.bExclusive){
       
   426       pFile->shared->bExclusive = FALSE;
       
   427     }
       
   428 
       
   429     /* De-reference and close our copy of the shared memory handle */
       
   430     UnmapViewOfFile(pFile->shared);
       
   431     CloseHandle(pFile->hShared);
       
   432 
       
   433     /* Done with the mutex */
       
   434     winceMutexRelease(pFile->hMutex);    
       
   435     CloseHandle(pFile->hMutex);
       
   436     pFile->hMutex = NULL;
       
   437   }
       
   438 }
       
   439 
       
   440 /* 
       
   441 ** An implementation of the LockFile() API of windows for wince
       
   442 */
       
   443 static BOOL winceLockFile(
       
   444   HANDLE *phFile,
       
   445   DWORD dwFileOffsetLow,
       
   446   DWORD dwFileOffsetHigh,
       
   447   DWORD nNumberOfBytesToLockLow,
       
   448   DWORD nNumberOfBytesToLockHigh
       
   449 ){
       
   450   winFile *pFile = HANDLE_TO_WINFILE(phFile);
       
   451   BOOL bReturn = FALSE;
       
   452 
       
   453   if (!pFile->hMutex) return TRUE;
       
   454   winceMutexAcquire(pFile->hMutex);
       
   455 
       
   456   /* Wanting an exclusive lock? */
       
   457   if (dwFileOffsetLow == SHARED_FIRST
       
   458        && nNumberOfBytesToLockLow == SHARED_SIZE){
       
   459     if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
       
   460        pFile->shared->bExclusive = TRUE;
       
   461        pFile->local.bExclusive = TRUE;
       
   462        bReturn = TRUE;
       
   463     }
       
   464   }
       
   465 
       
   466   /* Want a read-only lock? */
       
   467   else if ((dwFileOffsetLow >= SHARED_FIRST &&
       
   468             dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
       
   469             nNumberOfBytesToLockLow == 1){
       
   470     if (pFile->shared->bExclusive == 0){
       
   471       pFile->local.nReaders ++;
       
   472       if (pFile->local.nReaders == 1){
       
   473         pFile->shared->nReaders ++;
       
   474       }
       
   475       bReturn = TRUE;
       
   476     }
       
   477   }
       
   478 
       
   479   /* Want a pending lock? */
       
   480   else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
       
   481     /* If no pending lock has been acquired, then acquire it */
       
   482     if (pFile->shared->bPending == 0) {
       
   483       pFile->shared->bPending = TRUE;
       
   484       pFile->local.bPending = TRUE;
       
   485       bReturn = TRUE;
       
   486     }
       
   487   }
       
   488   /* Want a reserved lock? */
       
   489   else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
       
   490     if (pFile->shared->bReserved == 0) {
       
   491       pFile->shared->bReserved = TRUE;
       
   492       pFile->local.bReserved = TRUE;
       
   493       bReturn = TRUE;
       
   494     }
       
   495   }
       
   496 
       
   497   winceMutexRelease(pFile->hMutex);
       
   498   return bReturn;
       
   499 }
       
   500 
       
   501 /*
       
   502 ** An implementation of the UnlockFile API of windows for wince
       
   503 */
       
   504 static BOOL winceUnlockFile(
       
   505   HANDLE *phFile,
       
   506   DWORD dwFileOffsetLow,
       
   507   DWORD dwFileOffsetHigh,
       
   508   DWORD nNumberOfBytesToUnlockLow,
       
   509   DWORD nNumberOfBytesToUnlockHigh
       
   510 ){
       
   511   winFile *pFile = HANDLE_TO_WINFILE(phFile);
       
   512   BOOL bReturn = FALSE;
       
   513 
       
   514   if (!pFile->hMutex) return TRUE;
       
   515   winceMutexAcquire(pFile->hMutex);
       
   516 
       
   517   /* Releasing a reader lock or an exclusive lock */
       
   518   if (dwFileOffsetLow >= SHARED_FIRST &&
       
   519        dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
       
   520     /* Did we have an exclusive lock? */
       
   521     if (pFile->local.bExclusive){
       
   522       pFile->local.bExclusive = FALSE;
       
   523       pFile->shared->bExclusive = FALSE;
       
   524       bReturn = TRUE;
       
   525     }
       
   526 
       
   527     /* Did we just have a reader lock? */
       
   528     else if (pFile->local.nReaders){
       
   529       pFile->local.nReaders --;
       
   530       if (pFile->local.nReaders == 0)
       
   531       {
       
   532         pFile->shared->nReaders --;
       
   533       }
       
   534       bReturn = TRUE;
       
   535     }
       
   536   }
       
   537 
       
   538   /* Releasing a pending lock */
       
   539   else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
       
   540     if (pFile->local.bPending){
       
   541       pFile->local.bPending = FALSE;
       
   542       pFile->shared->bPending = FALSE;
       
   543       bReturn = TRUE;
       
   544     }
       
   545   }
       
   546   /* Releasing a reserved lock */
       
   547   else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
       
   548     if (pFile->local.bReserved) {
       
   549       pFile->local.bReserved = FALSE;
       
   550       pFile->shared->bReserved = FALSE;
       
   551       bReturn = TRUE;
       
   552     }
       
   553   }
       
   554 
       
   555   winceMutexRelease(pFile->hMutex);
       
   556   return bReturn;
       
   557 }
       
   558 
       
   559 /*
       
   560 ** An implementation of the LockFileEx() API of windows for wince
       
   561 */
       
   562 static BOOL winceLockFileEx(
       
   563   HANDLE *phFile,
       
   564   DWORD dwFlags,
       
   565   DWORD dwReserved,
       
   566   DWORD nNumberOfBytesToLockLow,
       
   567   DWORD nNumberOfBytesToLockHigh,
       
   568   LPOVERLAPPED lpOverlapped
       
   569 ){
       
   570   /* If the caller wants a shared read lock, forward this call
       
   571   ** to winceLockFile */
       
   572   if (lpOverlapped->Offset == SHARED_FIRST &&
       
   573       dwFlags == 1 &&
       
   574       nNumberOfBytesToLockLow == SHARED_SIZE){
       
   575     return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
       
   576   }
       
   577   return FALSE;
       
   578 }
       
   579 /*
       
   580 ** End of the special code for wince
       
   581 *****************************************************************************/
       
   582 #endif /* SQLITE_OS_WINCE */
       
   583 
       
   584 /*****************************************************************************
       
   585 ** The next group of routines implement the I/O methods specified
       
   586 ** by the sqlite3_io_methods object.
       
   587 ******************************************************************************/
       
   588 
       
   589 /*
       
   590 ** Close a file.
       
   591 **
       
   592 ** It is reported that an attempt to close a handle might sometimes
       
   593 ** fail.  This is a very unreasonable result, but windows is notorious
       
   594 ** for being unreasonable so I do not doubt that it might happen.  If
       
   595 ** the close fails, we pause for 100 milliseconds and try again.  As
       
   596 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
       
   597 ** giving up and returning an error.
       
   598 */
       
   599 #define MX_CLOSE_ATTEMPT 3
       
   600 static int winClose(sqlite3_file *id){
       
   601   int rc, cnt = 0;
       
   602   winFile *pFile = (winFile*)id;
       
   603   OSTRACE2("CLOSE %d\n", pFile->h);
       
   604   do{
       
   605     rc = CloseHandle(pFile->h);
       
   606   }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
       
   607 #if SQLITE_OS_WINCE
       
   608 #define WINCE_DELETION_ATTEMPTS 3
       
   609   winceDestroyLock(pFile);
       
   610   if( pFile->zDeleteOnClose ){
       
   611     int cnt = 0;
       
   612     while(
       
   613            DeleteFileW(pFile->zDeleteOnClose)==0
       
   614         && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 
       
   615         && cnt++ < WINCE_DELETION_ATTEMPTS
       
   616     ){
       
   617        Sleep(100);  /* Wait a little before trying again */
       
   618     }
       
   619     free(pFile->zDeleteOnClose);
       
   620   }
       
   621 #endif
       
   622   OpenCounter(-1);
       
   623   return rc ? SQLITE_OK : SQLITE_IOERR;
       
   624 }
       
   625 
       
   626 /*
       
   627 ** Some microsoft compilers lack this definition.
       
   628 */
       
   629 #ifndef INVALID_SET_FILE_POINTER
       
   630 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
       
   631 #endif
       
   632 
       
   633 /*
       
   634 ** Read data from a file into a buffer.  Return SQLITE_OK if all
       
   635 ** bytes were read successfully and SQLITE_IOERR if anything goes
       
   636 ** wrong.
       
   637 */
       
   638 static int winRead(
       
   639   sqlite3_file *id,          /* File to read from */
       
   640   void *pBuf,                /* Write content into this buffer */
       
   641   int amt,                   /* Number of bytes to read */
       
   642   sqlite3_int64 offset       /* Begin reading at this offset */
       
   643 ){
       
   644   LONG upperBits = (offset>>32) & 0x7fffffff;
       
   645   LONG lowerBits = offset & 0xffffffff;
       
   646   DWORD rc;
       
   647   DWORD got;
       
   648   winFile *pFile = (winFile*)id;
       
   649   assert( id!=0 );
       
   650   SimulateIOError(return SQLITE_IOERR_READ);
       
   651   OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
       
   652   rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
       
   653   if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
       
   654     return SQLITE_FULL;
       
   655   }
       
   656   if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
       
   657     return SQLITE_IOERR_READ;
       
   658   }
       
   659   if( got==(DWORD)amt ){
       
   660     return SQLITE_OK;
       
   661   }else{
       
   662     memset(&((char*)pBuf)[got], 0, amt-got);
       
   663     return SQLITE_IOERR_SHORT_READ;
       
   664   }
       
   665 }
       
   666 
       
   667 /*
       
   668 ** Write data from a buffer into a file.  Return SQLITE_OK on success
       
   669 ** or some other error code on failure.
       
   670 */
       
   671 static int winWrite(
       
   672   sqlite3_file *id,         /* File to write into */
       
   673   const void *pBuf,         /* The bytes to be written */
       
   674   int amt,                  /* Number of bytes to write */
       
   675   sqlite3_int64 offset      /* Offset into the file to begin writing at */
       
   676 ){
       
   677   LONG upperBits = (offset>>32) & 0x7fffffff;
       
   678   LONG lowerBits = offset & 0xffffffff;
       
   679   DWORD rc;
       
   680   DWORD wrote;
       
   681   winFile *pFile = (winFile*)id;
       
   682   assert( id!=0 );
       
   683   SimulateIOError(return SQLITE_IOERR_WRITE);
       
   684   SimulateDiskfullError(return SQLITE_FULL);
       
   685   OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
       
   686   rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
       
   687   if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
       
   688     return SQLITE_FULL;
       
   689   }
       
   690   assert( amt>0 );
       
   691   while(
       
   692      amt>0
       
   693      && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
       
   694      && wrote>0
       
   695   ){
       
   696     amt -= wrote;
       
   697     pBuf = &((char*)pBuf)[wrote];
       
   698   }
       
   699   if( !rc || amt>(int)wrote ){
       
   700     return SQLITE_FULL;
       
   701   }
       
   702   return SQLITE_OK;
       
   703 }
       
   704 
       
   705 /*
       
   706 ** Truncate an open file to a specified size
       
   707 */
       
   708 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
       
   709   LONG upperBits = (nByte>>32) & 0x7fffffff;
       
   710   LONG lowerBits = nByte & 0xffffffff;
       
   711   winFile *pFile = (winFile*)id;
       
   712   OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
       
   713   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
       
   714   SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
       
   715   SetEndOfFile(pFile->h);
       
   716   return SQLITE_OK;
       
   717 }
       
   718 
       
   719 #ifdef SQLITE_TEST
       
   720 /*
       
   721 ** Count the number of fullsyncs and normal syncs.  This is used to test
       
   722 ** that syncs and fullsyncs are occuring at the right times.
       
   723 */
       
   724 int sqlite3_sync_count = 0;
       
   725 int sqlite3_fullsync_count = 0;
       
   726 #endif
       
   727 
       
   728 /*
       
   729 ** Make sure all writes to a particular file are committed to disk.
       
   730 */
       
   731 static int winSync(sqlite3_file *id, int flags){
       
   732   winFile *pFile = (winFile*)id;
       
   733   OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
       
   734 #ifdef SQLITE_TEST
       
   735   if( flags & SQLITE_SYNC_FULL ){
       
   736     sqlite3_fullsync_count++;
       
   737   }
       
   738   sqlite3_sync_count++;
       
   739 #endif
       
   740   if( FlushFileBuffers(pFile->h) ){
       
   741     return SQLITE_OK;
       
   742   }else{
       
   743     return SQLITE_IOERR;
       
   744   }
       
   745 }
       
   746 
       
   747 /*
       
   748 ** Determine the current size of a file in bytes
       
   749 */
       
   750 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
       
   751   winFile *pFile = (winFile*)id;
       
   752   DWORD upperBits, lowerBits;
       
   753   SimulateIOError(return SQLITE_IOERR_FSTAT);
       
   754   lowerBits = GetFileSize(pFile->h, &upperBits);
       
   755   *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
       
   756   return SQLITE_OK;
       
   757 }
       
   758 
       
   759 /*
       
   760 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
       
   761 */
       
   762 #ifndef LOCKFILE_FAIL_IMMEDIATELY
       
   763 # define LOCKFILE_FAIL_IMMEDIATELY 1
       
   764 #endif
       
   765 
       
   766 /*
       
   767 ** Acquire a reader lock.
       
   768 ** Different API routines are called depending on whether or not this
       
   769 ** is Win95 or WinNT.
       
   770 */
       
   771 static int getReadLock(winFile *pFile){
       
   772   int res;
       
   773   if( isNT() ){
       
   774     OVERLAPPED ovlp;
       
   775     ovlp.Offset = SHARED_FIRST;
       
   776     ovlp.OffsetHigh = 0;
       
   777     ovlp.hEvent = 0;
       
   778     res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
       
   779                      0, SHARED_SIZE, 0, &ovlp);
       
   780   }else{
       
   781     int lk;
       
   782     sqlite3_randomness(sizeof(lk), &lk);
       
   783     pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
       
   784     res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
       
   785   }
       
   786   return res;
       
   787 }
       
   788 
       
   789 /*
       
   790 ** Undo a readlock
       
   791 */
       
   792 static int unlockReadLock(winFile *pFile){
       
   793   int res;
       
   794   if( isNT() ){
       
   795     res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
       
   796   }else{
       
   797     res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
       
   798   }
       
   799   return res;
       
   800 }
       
   801 
       
   802 /*
       
   803 ** Lock the file with the lock specified by parameter locktype - one
       
   804 ** of the following:
       
   805 **
       
   806 **     (1) SHARED_LOCK
       
   807 **     (2) RESERVED_LOCK
       
   808 **     (3) PENDING_LOCK
       
   809 **     (4) EXCLUSIVE_LOCK
       
   810 **
       
   811 ** Sometimes when requesting one lock state, additional lock states
       
   812 ** are inserted in between.  The locking might fail on one of the later
       
   813 ** transitions leaving the lock state different from what it started but
       
   814 ** still short of its goal.  The following chart shows the allowed
       
   815 ** transitions and the inserted intermediate states:
       
   816 **
       
   817 **    UNLOCKED -> SHARED
       
   818 **    SHARED -> RESERVED
       
   819 **    SHARED -> (PENDING) -> EXCLUSIVE
       
   820 **    RESERVED -> (PENDING) -> EXCLUSIVE
       
   821 **    PENDING -> EXCLUSIVE
       
   822 **
       
   823 ** This routine will only increase a lock.  The winUnlock() routine
       
   824 ** erases all locks at once and returns us immediately to locking level 0.
       
   825 ** It is not possible to lower the locking level one step at a time.  You
       
   826 ** must go straight to locking level 0.
       
   827 */
       
   828 static int winLock(sqlite3_file *id, int locktype){
       
   829   int rc = SQLITE_OK;    /* Return code from subroutines */
       
   830   int res = 1;           /* Result of a windows lock call */
       
   831   int newLocktype;       /* Set pFile->locktype to this value before exiting */
       
   832   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
       
   833   winFile *pFile = (winFile*)id;
       
   834 
       
   835   assert( pFile!=0 );
       
   836   OSTRACE5("LOCK %d %d was %d(%d)\n",
       
   837           pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
       
   838 
       
   839   /* If there is already a lock of this type or more restrictive on the
       
   840   ** OsFile, do nothing. Don't use the end_lock: exit path, as
       
   841   ** sqlite3OsEnterMutex() hasn't been called yet.
       
   842   */
       
   843   if( pFile->locktype>=locktype ){
       
   844     return SQLITE_OK;
       
   845   }
       
   846 
       
   847   /* Make sure the locking sequence is correct
       
   848   */
       
   849   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
       
   850   assert( locktype!=PENDING_LOCK );
       
   851   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
       
   852 
       
   853   /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
       
   854   ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
       
   855   ** the PENDING_LOCK byte is temporary.
       
   856   */
       
   857   newLocktype = pFile->locktype;
       
   858   if( pFile->locktype==NO_LOCK
       
   859    || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
       
   860   ){
       
   861     int cnt = 3;
       
   862     while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
       
   863       /* Try 3 times to get the pending lock.  The pending lock might be
       
   864       ** held by another reader process who will release it momentarily.
       
   865       */
       
   866       OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
       
   867       Sleep(1);
       
   868     }
       
   869     gotPendingLock = res;
       
   870   }
       
   871 
       
   872   /* Acquire a shared lock
       
   873   */
       
   874   if( locktype==SHARED_LOCK && res ){
       
   875     assert( pFile->locktype==NO_LOCK );
       
   876     res = getReadLock(pFile);
       
   877     if( res ){
       
   878       newLocktype = SHARED_LOCK;
       
   879     }
       
   880   }
       
   881 
       
   882   /* Acquire a RESERVED lock
       
   883   */
       
   884   if( locktype==RESERVED_LOCK && res ){
       
   885     assert( pFile->locktype==SHARED_LOCK );
       
   886     res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
       
   887     if( res ){
       
   888       newLocktype = RESERVED_LOCK;
       
   889     }
       
   890   }
       
   891 
       
   892   /* Acquire a PENDING lock
       
   893   */
       
   894   if( locktype==EXCLUSIVE_LOCK && res ){
       
   895     newLocktype = PENDING_LOCK;
       
   896     gotPendingLock = 0;
       
   897   }
       
   898 
       
   899   /* Acquire an EXCLUSIVE lock
       
   900   */
       
   901   if( locktype==EXCLUSIVE_LOCK && res ){
       
   902     assert( pFile->locktype>=SHARED_LOCK );
       
   903     res = unlockReadLock(pFile);
       
   904     OSTRACE2("unreadlock = %d\n", res);
       
   905     res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
       
   906     if( res ){
       
   907       newLocktype = EXCLUSIVE_LOCK;
       
   908     }else{
       
   909       OSTRACE2("error-code = %d\n", GetLastError());
       
   910       getReadLock(pFile);
       
   911     }
       
   912   }
       
   913 
       
   914   /* If we are holding a PENDING lock that ought to be released, then
       
   915   ** release it now.
       
   916   */
       
   917   if( gotPendingLock && locktype==SHARED_LOCK ){
       
   918     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
       
   919   }
       
   920 
       
   921   /* Update the state of the lock has held in the file descriptor then
       
   922   ** return the appropriate result code.
       
   923   */
       
   924   if( res ){
       
   925     rc = SQLITE_OK;
       
   926   }else{
       
   927     OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
       
   928            locktype, newLocktype);
       
   929     rc = SQLITE_BUSY;
       
   930   }
       
   931   pFile->locktype = newLocktype;
       
   932   return rc;
       
   933 }
       
   934 
       
   935 /*
       
   936 ** This routine checks if there is a RESERVED lock held on the specified
       
   937 ** file by this or any other process. If such a lock is held, return
       
   938 ** non-zero, otherwise zero.
       
   939 */
       
   940 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
       
   941   int rc;
       
   942   winFile *pFile = (winFile*)id;
       
   943   assert( pFile!=0 );
       
   944   if( pFile->locktype>=RESERVED_LOCK ){
       
   945     rc = 1;
       
   946     OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
       
   947   }else{
       
   948     rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
       
   949     if( rc ){
       
   950       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
       
   951     }
       
   952     rc = !rc;
       
   953     OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
       
   954   }
       
   955   *pResOut = rc;
       
   956   return SQLITE_OK;
       
   957 }
       
   958 
       
   959 /*
       
   960 ** Lower the locking level on file descriptor id to locktype.  locktype
       
   961 ** must be either NO_LOCK or SHARED_LOCK.
       
   962 **
       
   963 ** If the locking level of the file descriptor is already at or below
       
   964 ** the requested locking level, this routine is a no-op.
       
   965 **
       
   966 ** It is not possible for this routine to fail if the second argument
       
   967 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
       
   968 ** might return SQLITE_IOERR;
       
   969 */
       
   970 static int winUnlock(sqlite3_file *id, int locktype){
       
   971   int type;
       
   972   winFile *pFile = (winFile*)id;
       
   973   int rc = SQLITE_OK;
       
   974   assert( pFile!=0 );
       
   975   assert( locktype<=SHARED_LOCK );
       
   976   OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
       
   977           pFile->locktype, pFile->sharedLockByte);
       
   978   type = pFile->locktype;
       
   979   if( type>=EXCLUSIVE_LOCK ){
       
   980     UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
       
   981     if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
       
   982       /* This should never happen.  We should always be able to
       
   983       ** reacquire the read lock */
       
   984       rc = SQLITE_IOERR_UNLOCK;
       
   985     }
       
   986   }
       
   987   if( type>=RESERVED_LOCK ){
       
   988     UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
       
   989   }
       
   990   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
       
   991     unlockReadLock(pFile);
       
   992   }
       
   993   if( type>=PENDING_LOCK ){
       
   994     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
       
   995   }
       
   996   pFile->locktype = locktype;
       
   997   return rc;
       
   998 }
       
   999 
       
  1000 /*
       
  1001 ** Control and query of the open file handle.
       
  1002 */
       
  1003 static int winFileControl(sqlite3_file *id, int op, void *pArg){
       
  1004   switch( op ){
       
  1005     case SQLITE_FCNTL_LOCKSTATE: {
       
  1006       *(int*)pArg = ((winFile*)id)->locktype;
       
  1007       return SQLITE_OK;
       
  1008     }
       
  1009   }
       
  1010   return SQLITE_ERROR;
       
  1011 }
       
  1012 
       
  1013 /*
       
  1014 ** Return the sector size in bytes of the underlying block device for
       
  1015 ** the specified file. This is almost always 512 bytes, but may be
       
  1016 ** larger for some devices.
       
  1017 **
       
  1018 ** SQLite code assumes this function cannot fail. It also assumes that
       
  1019 ** if two files are created in the same file-system directory (i.e.
       
  1020 ** a database and its journal file) that the sector size will be the
       
  1021 ** same for both.
       
  1022 */
       
  1023 static int winSectorSize(sqlite3_file *id){
       
  1024   return SQLITE_DEFAULT_SECTOR_SIZE;
       
  1025 }
       
  1026 
       
  1027 /*
       
  1028 ** Return a vector of device characteristics.
       
  1029 */
       
  1030 static int winDeviceCharacteristics(sqlite3_file *id){
       
  1031   return 0;
       
  1032 }
       
  1033 
       
  1034 /*
       
  1035 ** This vector defines all the methods that can operate on an
       
  1036 ** sqlite3_file for win32.
       
  1037 */
       
  1038 static const sqlite3_io_methods winIoMethod = {
       
  1039   1,                        /* iVersion */
       
  1040   winClose,
       
  1041   winRead,
       
  1042   winWrite,
       
  1043   winTruncate,
       
  1044   winSync,
       
  1045   winFileSize,
       
  1046   winLock,
       
  1047   winUnlock,
       
  1048   winCheckReservedLock,
       
  1049   winFileControl,
       
  1050   winSectorSize,
       
  1051   winDeviceCharacteristics
       
  1052 };
       
  1053 
       
  1054 /***************************************************************************
       
  1055 ** Here ends the I/O methods that form the sqlite3_io_methods object.
       
  1056 **
       
  1057 ** The next block of code implements the VFS methods.
       
  1058 ****************************************************************************/
       
  1059 
       
  1060 /*
       
  1061 ** Convert a UTF-8 filename into whatever form the underlying
       
  1062 ** operating system wants filenames in.  Space to hold the result
       
  1063 ** is obtained from malloc and must be freed by the calling
       
  1064 ** function.
       
  1065 */
       
  1066 static void *convertUtf8Filename(const char *zFilename){
       
  1067   void *zConverted = 0;
       
  1068   if( isNT() ){
       
  1069     zConverted = utf8ToUnicode(zFilename);
       
  1070   }else{
       
  1071     zConverted = utf8ToMbcs(zFilename);
       
  1072   }
       
  1073   /* caller will handle out of memory */
       
  1074   return zConverted;
       
  1075 }
       
  1076 
       
  1077 /*
       
  1078 ** Create a temporary file name in zBuf.  zBuf must be big enough to
       
  1079 ** hold at pVfs->mxPathname characters.
       
  1080 */
       
  1081 static int getTempname(int nBuf, char *zBuf){
       
  1082   static char zChars[] =
       
  1083     "abcdefghijklmnopqrstuvwxyz"
       
  1084     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
       
  1085     "0123456789";
       
  1086   size_t i, j;
       
  1087   char zTempPath[MAX_PATH+1];
       
  1088   if( sqlite3_temp_directory ){
       
  1089     sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
       
  1090   }else if( isNT() ){
       
  1091     char *zMulti;
       
  1092     WCHAR zWidePath[MAX_PATH];
       
  1093     GetTempPathW(MAX_PATH-30, zWidePath);
       
  1094     zMulti = unicodeToUtf8(zWidePath);
       
  1095     if( zMulti ){
       
  1096       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
       
  1097       free(zMulti);
       
  1098     }else{
       
  1099       return SQLITE_NOMEM;
       
  1100     }
       
  1101   }else{
       
  1102     char *zUtf8;
       
  1103     char zMbcsPath[MAX_PATH];
       
  1104     GetTempPathA(MAX_PATH-30, zMbcsPath);
       
  1105     zUtf8 = mbcsToUtf8(zMbcsPath);
       
  1106     if( zUtf8 ){
       
  1107       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
       
  1108       free(zUtf8);
       
  1109     }else{
       
  1110       return SQLITE_NOMEM;
       
  1111     }
       
  1112   }
       
  1113   for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
       
  1114   zTempPath[i] = 0;
       
  1115   sqlite3_snprintf(nBuf-30, zBuf,
       
  1116                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
       
  1117   j = strlen(zBuf);
       
  1118   sqlite3_randomness(20, &zBuf[j]);
       
  1119   for(i=0; i<20; i++, j++){
       
  1120     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
       
  1121   }
       
  1122   zBuf[j] = 0;
       
  1123   OSTRACE2("TEMP FILENAME: %s\n", zBuf);
       
  1124   return SQLITE_OK; 
       
  1125 }
       
  1126 
       
  1127 /*
       
  1128 ** The return value of getLastErrorMsg
       
  1129 ** is zero if the error message fits in the buffer, or non-zero
       
  1130 ** otherwise (if the message was truncated).
       
  1131 */
       
  1132 static int getLastErrorMsg(int nBuf, char *zBuf){
       
  1133   DWORD error = GetLastError();
       
  1134 
       
  1135 #if SQLITE_OS_WINCE
       
  1136   sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
       
  1137 #else
       
  1138   /* FormatMessage returns 0 on failure.  Otherwise it
       
  1139   ** returns the number of TCHARs written to the output
       
  1140   ** buffer, excluding the terminating null char.
       
  1141   */
       
  1142   if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
       
  1143                       NULL,
       
  1144                       error,
       
  1145                       0,
       
  1146                       zBuf,
       
  1147                       nBuf-1,
       
  1148                       0))
       
  1149   {
       
  1150     sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
       
  1151   }
       
  1152 #endif
       
  1153 
       
  1154   return 0;
       
  1155 }
       
  1156 
       
  1157 
       
  1158 /*
       
  1159 ** Open a file.
       
  1160 */
       
  1161 static int winOpen(
       
  1162   sqlite3_vfs *pVfs,        /* Not used */
       
  1163   const char *zName,        /* Name of the file (UTF-8) */
       
  1164   sqlite3_file *id,         /* Write the SQLite file handle here */
       
  1165   int flags,                /* Open mode flags */
       
  1166   int *pOutFlags            /* Status return flags */
       
  1167 ){
       
  1168   HANDLE h;
       
  1169   DWORD dwDesiredAccess;
       
  1170   DWORD dwShareMode;
       
  1171   DWORD dwCreationDisposition;
       
  1172   DWORD dwFlagsAndAttributes = 0;
       
  1173   int isTemp;
       
  1174   winFile *pFile = (winFile*)id;
       
  1175   void *zConverted;                 /* Filename in OS encoding */
       
  1176   const char *zUtf8Name = zName;    /* Filename in UTF-8 encoding */
       
  1177   char zTmpname[MAX_PATH+1];        /* Buffer used to create temp filename */
       
  1178 
       
  1179   /* If the second argument to this function is NULL, generate a 
       
  1180   ** temporary file name to use 
       
  1181   */
       
  1182   if( !zUtf8Name ){
       
  1183     int rc = getTempname(MAX_PATH+1, zTmpname);
       
  1184     if( rc!=SQLITE_OK ){
       
  1185       return rc;
       
  1186     }
       
  1187     zUtf8Name = zTmpname;
       
  1188   }
       
  1189 
       
  1190   /* Convert the filename to the system encoding. */
       
  1191   zConverted = convertUtf8Filename(zUtf8Name);
       
  1192   if( zConverted==0 ){
       
  1193     return SQLITE_NOMEM;
       
  1194   }
       
  1195 
       
  1196   if( flags & SQLITE_OPEN_READWRITE ){
       
  1197     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
       
  1198   }else{
       
  1199     dwDesiredAccess = GENERIC_READ;
       
  1200   }
       
  1201   if( flags & SQLITE_OPEN_CREATE ){
       
  1202     dwCreationDisposition = OPEN_ALWAYS;
       
  1203   }else{
       
  1204     dwCreationDisposition = OPEN_EXISTING;
       
  1205   }
       
  1206   if( flags & SQLITE_OPEN_MAIN_DB ){
       
  1207     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
       
  1208   }else{
       
  1209     dwShareMode = 0;
       
  1210   }
       
  1211   if( flags & SQLITE_OPEN_DELETEONCLOSE ){
       
  1212 #if SQLITE_OS_WINCE
       
  1213     dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
       
  1214 #else
       
  1215     dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
       
  1216                                | FILE_ATTRIBUTE_HIDDEN
       
  1217                                | FILE_FLAG_DELETE_ON_CLOSE;
       
  1218 #endif
       
  1219     isTemp = 1;
       
  1220   }else{
       
  1221     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
       
  1222     isTemp = 0;
       
  1223   }
       
  1224   /* Reports from the internet are that performance is always
       
  1225   ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
       
  1226   dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
       
  1227   if( isNT() ){
       
  1228     h = CreateFileW((WCHAR*)zConverted,
       
  1229        dwDesiredAccess,
       
  1230        dwShareMode,
       
  1231        NULL,
       
  1232        dwCreationDisposition,
       
  1233        dwFlagsAndAttributes,
       
  1234        NULL
       
  1235     );
       
  1236   }else{
       
  1237     h = CreateFileA((char*)zConverted,
       
  1238        dwDesiredAccess,
       
  1239        dwShareMode,
       
  1240        NULL,
       
  1241        dwCreationDisposition,
       
  1242        dwFlagsAndAttributes,
       
  1243        NULL
       
  1244     );
       
  1245   }
       
  1246   if( h==INVALID_HANDLE_VALUE ){
       
  1247     free(zConverted);
       
  1248     if( flags & SQLITE_OPEN_READWRITE ){
       
  1249       return winOpen(0, zName, id, 
       
  1250              ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
       
  1251     }else{
       
  1252       return SQLITE_CANTOPEN;
       
  1253     }
       
  1254   }
       
  1255   if( pOutFlags ){
       
  1256     if( flags & SQLITE_OPEN_READWRITE ){
       
  1257       *pOutFlags = SQLITE_OPEN_READWRITE;
       
  1258     }else{
       
  1259       *pOutFlags = SQLITE_OPEN_READONLY;
       
  1260     }
       
  1261   }
       
  1262   memset(pFile, 0, sizeof(*pFile));
       
  1263   pFile->pMethod = &winIoMethod;
       
  1264   pFile->h = h;
       
  1265 #if SQLITE_OS_WINCE
       
  1266   if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
       
  1267                (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
       
  1268        && !winceCreateLock(zName, pFile)
       
  1269   ){
       
  1270     CloseHandle(h);
       
  1271     free(zConverted);
       
  1272     return SQLITE_CANTOPEN;
       
  1273   }
       
  1274   if( isTemp ){
       
  1275     pFile->zDeleteOnClose = zConverted;
       
  1276   }else
       
  1277 #endif
       
  1278   {
       
  1279     free(zConverted);
       
  1280   }
       
  1281   OpenCounter(+1);
       
  1282   return SQLITE_OK;
       
  1283 }
       
  1284 
       
  1285 /*
       
  1286 ** Delete the named file.
       
  1287 **
       
  1288 ** Note that windows does not allow a file to be deleted if some other
       
  1289 ** process has it open.  Sometimes a virus scanner or indexing program
       
  1290 ** will open a journal file shortly after it is created in order to do
       
  1291 ** whatever it does.  While this other process is holding the
       
  1292 ** file open, we will be unable to delete it.  To work around this
       
  1293 ** problem, we delay 100 milliseconds and try to delete again.  Up
       
  1294 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
       
  1295 ** up and returning an error.
       
  1296 */
       
  1297 #define MX_DELETION_ATTEMPTS 5
       
  1298 static int winDelete(
       
  1299   sqlite3_vfs *pVfs,          /* Not used on win32 */
       
  1300   const char *zFilename,      /* Name of file to delete */
       
  1301   int syncDir                 /* Not used on win32 */
       
  1302 ){
       
  1303   int cnt = 0;
       
  1304   int rc;
       
  1305   DWORD error;
       
  1306   void *zConverted = convertUtf8Filename(zFilename);
       
  1307   if( zConverted==0 ){
       
  1308     return SQLITE_NOMEM;
       
  1309   }
       
  1310   SimulateIOError(return SQLITE_IOERR_DELETE);
       
  1311   if( isNT() ){
       
  1312     do{
       
  1313       DeleteFileW(zConverted);
       
  1314     }while(   (   ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
       
  1315                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
       
  1316            && (cnt++ < MX_DELETION_ATTEMPTS)
       
  1317            && (Sleep(100), 1) );
       
  1318   }else{
       
  1319     do{
       
  1320       DeleteFileA(zConverted);
       
  1321     }while(   (   ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
       
  1322                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
       
  1323            && (cnt++ < MX_DELETION_ATTEMPTS)
       
  1324            && (Sleep(100), 1) );
       
  1325   }
       
  1326   free(zConverted);
       
  1327   OSTRACE2("DELETE \"%s\"\n", zFilename);
       
  1328   return (   (rc==INVALID_FILE_ATTRIBUTES) 
       
  1329           && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
       
  1330 }
       
  1331 
       
  1332 /*
       
  1333 ** Check the existance and status of a file.
       
  1334 */
       
  1335 static int winAccess(
       
  1336   sqlite3_vfs *pVfs,         /* Not used on win32 */
       
  1337   const char *zFilename,     /* Name of file to check */
       
  1338   int flags,                 /* Type of test to make on this file */
       
  1339   int *pResOut               /* OUT: Result */
       
  1340 ){
       
  1341   DWORD attr;
       
  1342   int rc;
       
  1343   void *zConverted = convertUtf8Filename(zFilename);
       
  1344   if( zConverted==0 ){
       
  1345     return SQLITE_NOMEM;
       
  1346   }
       
  1347   if( isNT() ){
       
  1348     attr = GetFileAttributesW((WCHAR*)zConverted);
       
  1349   }else{
       
  1350     attr = GetFileAttributesA((char*)zConverted);
       
  1351   }
       
  1352   free(zConverted);
       
  1353   switch( flags ){
       
  1354     case SQLITE_ACCESS_READ:
       
  1355     case SQLITE_ACCESS_EXISTS:
       
  1356       rc = attr!=INVALID_FILE_ATTRIBUTES;
       
  1357       break;
       
  1358     case SQLITE_ACCESS_READWRITE:
       
  1359       rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
       
  1360       break;
       
  1361     default:
       
  1362       assert(!"Invalid flags argument");
       
  1363   }
       
  1364   *pResOut = rc;
       
  1365   return SQLITE_OK;
       
  1366 }
       
  1367 
       
  1368 
       
  1369 /*
       
  1370 ** Turn a relative pathname into a full pathname.  Write the full
       
  1371 ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
       
  1372 ** bytes in size.
       
  1373 */
       
  1374 static int winFullPathname(
       
  1375   sqlite3_vfs *pVfs,            /* Pointer to vfs object */
       
  1376   const char *zRelative,        /* Possibly relative input path */
       
  1377   int nFull,                    /* Size of output buffer in bytes */
       
  1378   char *zFull                   /* Output buffer */
       
  1379 ){
       
  1380 
       
  1381 #if defined(__CYGWIN__)
       
  1382   cygwin_conv_to_full_win32_path(zRelative, zFull);
       
  1383   return SQLITE_OK;
       
  1384 #endif
       
  1385 
       
  1386 #if SQLITE_OS_WINCE
       
  1387   /* WinCE has no concept of a relative pathname, or so I am told. */
       
  1388   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
       
  1389   return SQLITE_OK;
       
  1390 #endif
       
  1391 
       
  1392 #if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
       
  1393   int nByte;
       
  1394   void *zConverted;
       
  1395   char *zOut;
       
  1396   zConverted = convertUtf8Filename(zRelative);
       
  1397   if( isNT() ){
       
  1398     WCHAR *zTemp;
       
  1399     nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
       
  1400     zTemp = malloc( nByte*sizeof(zTemp[0]) );
       
  1401     if( zTemp==0 ){
       
  1402       free(zConverted);
       
  1403       return SQLITE_NOMEM;
       
  1404     }
       
  1405     GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
       
  1406     free(zConverted);
       
  1407     zOut = unicodeToUtf8(zTemp);
       
  1408     free(zTemp);
       
  1409   }else{
       
  1410     char *zTemp;
       
  1411     nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
       
  1412     zTemp = malloc( nByte*sizeof(zTemp[0]) );
       
  1413     if( zTemp==0 ){
       
  1414       free(zConverted);
       
  1415       return SQLITE_NOMEM;
       
  1416     }
       
  1417     GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
       
  1418     free(zConverted);
       
  1419     zOut = mbcsToUtf8(zTemp);
       
  1420     free(zTemp);
       
  1421   }
       
  1422   if( zOut ){
       
  1423     sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
       
  1424     free(zOut);
       
  1425     return SQLITE_OK;
       
  1426   }else{
       
  1427     return SQLITE_NOMEM;
       
  1428   }
       
  1429 #endif
       
  1430 }
       
  1431 
       
  1432 #ifndef SQLITE_OMIT_LOAD_EXTENSION
       
  1433 /*
       
  1434 ** Interfaces for opening a shared library, finding entry points
       
  1435 ** within the shared library, and closing the shared library.
       
  1436 */
       
  1437 /*
       
  1438 ** Interfaces for opening a shared library, finding entry points
       
  1439 ** within the shared library, and closing the shared library.
       
  1440 */
       
  1441 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
       
  1442   HANDLE h;
       
  1443   void *zConverted = convertUtf8Filename(zFilename);
       
  1444   if( zConverted==0 ){
       
  1445     return 0;
       
  1446   }
       
  1447   if( isNT() ){
       
  1448     h = LoadLibraryW((WCHAR*)zConverted);
       
  1449   }else{
       
  1450     h = LoadLibraryA((char*)zConverted);
       
  1451   }
       
  1452   free(zConverted);
       
  1453   return (void*)h;
       
  1454 }
       
  1455 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
       
  1456   getLastErrorMsg(nBuf, zBufOut);
       
  1457 }
       
  1458 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
       
  1459 #if SQLITE_OS_WINCE
       
  1460   /* The GetProcAddressA() routine is only available on wince. */
       
  1461   return GetProcAddressA((HANDLE)pHandle, zSymbol);
       
  1462 #else
       
  1463   /* All other windows platforms expect GetProcAddress() to take
       
  1464   ** an Ansi string regardless of the _UNICODE setting */
       
  1465   return GetProcAddress((HANDLE)pHandle, zSymbol);
       
  1466 #endif
       
  1467 }
       
  1468 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
       
  1469   FreeLibrary((HANDLE)pHandle);
       
  1470 }
       
  1471 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
       
  1472   #define winDlOpen  0
       
  1473   #define winDlError 0
       
  1474   #define winDlSym   0
       
  1475   #define winDlClose 0
       
  1476 #endif
       
  1477 
       
  1478 
       
  1479 /*
       
  1480 ** Write up to nBuf bytes of randomness into zBuf.
       
  1481 */
       
  1482 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
       
  1483   int n = 0;
       
  1484   if( sizeof(SYSTEMTIME)<=nBuf-n ){
       
  1485     SYSTEMTIME x;
       
  1486     GetSystemTime(&x);
       
  1487     memcpy(&zBuf[n], &x, sizeof(x));
       
  1488     n += sizeof(x);
       
  1489   }
       
  1490   if( sizeof(DWORD)<=nBuf-n ){
       
  1491     DWORD pid = GetCurrentProcessId();
       
  1492     memcpy(&zBuf[n], &pid, sizeof(pid));
       
  1493     n += sizeof(pid);
       
  1494   }
       
  1495   if( sizeof(DWORD)<=nBuf-n ){
       
  1496     DWORD cnt = GetTickCount();
       
  1497     memcpy(&zBuf[n], &cnt, sizeof(cnt));
       
  1498     n += sizeof(cnt);
       
  1499   }
       
  1500   if( sizeof(LARGE_INTEGER)<=nBuf-n ){
       
  1501     LARGE_INTEGER i;
       
  1502     QueryPerformanceCounter(&i);
       
  1503     memcpy(&zBuf[n], &i, sizeof(i));
       
  1504     n += sizeof(i);
       
  1505   }
       
  1506   return n;
       
  1507 }
       
  1508 
       
  1509 
       
  1510 /*
       
  1511 ** Sleep for a little while.  Return the amount of time slept.
       
  1512 */
       
  1513 static int winSleep(sqlite3_vfs *pVfs, int microsec){
       
  1514   Sleep((microsec+999)/1000);
       
  1515   return ((microsec+999)/1000)*1000;
       
  1516 }
       
  1517 
       
  1518 /*
       
  1519 ** The following variable, if set to a non-zero value, becomes the result
       
  1520 ** returned from sqlite3OsCurrentTime().  This is used for testing.
       
  1521 */
       
  1522 #ifdef SQLITE_TEST
       
  1523 int sqlite3_current_time = 0;
       
  1524 #endif
       
  1525 
       
  1526 /*
       
  1527 ** Find the current time (in Universal Coordinated Time).  Write the
       
  1528 ** current time and date as a Julian Day number into *prNow and
       
  1529 ** return 0.  Return 1 if the time and date cannot be found.
       
  1530 */
       
  1531 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
       
  1532   FILETIME ft;
       
  1533   /* FILETIME structure is a 64-bit value representing the number of 
       
  1534      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
       
  1535   */
       
  1536   double now;
       
  1537 #if SQLITE_OS_WINCE
       
  1538   SYSTEMTIME time;
       
  1539   GetSystemTime(&time);
       
  1540   /* if SystemTimeToFileTime() fails, it returns zero. */
       
  1541   if (!SystemTimeToFileTime(&time,&ft)){
       
  1542     return 1;
       
  1543   }
       
  1544 #else
       
  1545   GetSystemTimeAsFileTime( &ft );
       
  1546 #endif
       
  1547   now = ((double)ft.dwHighDateTime) * 4294967296.0; 
       
  1548   *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
       
  1549 #ifdef SQLITE_TEST
       
  1550   if( sqlite3_current_time ){
       
  1551     *prNow = sqlite3_current_time/86400.0 + 2440587.5;
       
  1552   }
       
  1553 #endif
       
  1554   return 0;
       
  1555 }
       
  1556 
       
  1557 /*
       
  1558 ** The idea is that this function works like a combination of
       
  1559 ** GetLastError() and FormatMessage() on windows (or errno and
       
  1560 ** strerror_r() on unix). After an error is returned by an OS
       
  1561 ** function, SQLite calls this function with zBuf pointing to
       
  1562 ** a buffer of nBuf bytes. The OS layer should populate the
       
  1563 ** buffer with a nul-terminated UTF-8 encoded error message
       
  1564 ** describing the last IO error to have occured within the calling
       
  1565 ** thread.
       
  1566 **
       
  1567 ** If the error message is too large for the supplied buffer,
       
  1568 ** it should be truncated. The return value of xGetLastError
       
  1569 ** is zero if the error message fits in the buffer, or non-zero
       
  1570 ** otherwise (if the message was truncated). If non-zero is returned,
       
  1571 ** then it is not necessary to include the nul-terminator character
       
  1572 ** in the output buffer.
       
  1573 **
       
  1574 ** Not supplying an error message will have no adverse effect
       
  1575 ** on SQLite. It is fine to have an implementation that never
       
  1576 ** returns an error message:
       
  1577 **
       
  1578 **   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
       
  1579 **     assert(zBuf[0]=='\0');
       
  1580 **     return 0;
       
  1581 **   }
       
  1582 **
       
  1583 ** However if an error message is supplied, it will be incorporated
       
  1584 ** by sqlite into the error message available to the user using
       
  1585 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
       
  1586 */
       
  1587 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
       
  1588   return getLastErrorMsg(nBuf, zBuf);
       
  1589 }
       
  1590 
       
  1591 /*
       
  1592 ** Initialize and deinitialize the operating system interface.
       
  1593 */
       
  1594 int sqlite3_os_init(void){
       
  1595   static sqlite3_vfs winVfs = {
       
  1596     1,                 /* iVersion */
       
  1597     sizeof(winFile),   /* szOsFile */
       
  1598     MAX_PATH,          /* mxPathname */
       
  1599     0,                 /* pNext */
       
  1600     "win32",           /* zName */
       
  1601     0,                 /* pAppData */
       
  1602  
       
  1603     winOpen,           /* xOpen */
       
  1604     winDelete,         /* xDelete */
       
  1605     winAccess,         /* xAccess */
       
  1606     winFullPathname,   /* xFullPathname */
       
  1607     winDlOpen,         /* xDlOpen */
       
  1608     winDlError,        /* xDlError */
       
  1609     winDlSym,          /* xDlSym */
       
  1610     winDlClose,        /* xDlClose */
       
  1611     winRandomness,     /* xRandomness */
       
  1612     winSleep,          /* xSleep */
       
  1613     winCurrentTime,    /* xCurrentTime */
       
  1614     winGetLastError    /* xGetLastError */
       
  1615   };
       
  1616   sqlite3_vfs_register(&winVfs, 1);
       
  1617   return SQLITE_OK; 
       
  1618 }
       
  1619 int sqlite3_os_end(void){ 
       
  1620   return SQLITE_OK;
       
  1621 }
       
  1622 
       
  1623 #endif /* SQLITE_OS_WIN */