• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SQLITE_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 ** Some microsoft compilers lack this definition.
65 */
66 #ifndef INVALID_FILE_ATTRIBUTES
67 # define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
68 #endif
69 
70 /*
71 ** Determine if we are dealing with WindowsCE - which has a much
72 ** reduced API.
73 */
74 #if SQLITE_OS_WINCE
75 # define AreFileApisANSI() 1
76 # define FormatMessageW(a,b,c,d,e,f,g) 0
77 #endif
78 
79 /* Forward references */
80 typedef struct winShm winShm;           /* A connection to shared-memory */
81 typedef struct winShmNode winShmNode;   /* A region of shared-memory */
82 
83 /*
84 ** WinCE lacks native support for file locking so we have to fake it
85 ** with some code of our own.
86 */
87 #if SQLITE_OS_WINCE
88 typedef struct winceLock {
89   int nReaders;       /* Number of reader locks obtained */
90   BOOL bPending;      /* Indicates a pending lock has been obtained */
91   BOOL bReserved;     /* Indicates a reserved lock has been obtained */
92   BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
93 } winceLock;
94 #endif
95 
96 /*
97 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
98 ** portability layer.
99 */
100 typedef struct winFile winFile;
101 struct winFile {
102   const sqlite3_io_methods *pMethod; /*** Must be first ***/
103   sqlite3_vfs *pVfs;      /* The VFS used to open this file */
104   HANDLE h;               /* Handle for accessing the file */
105   unsigned char locktype; /* Type of lock currently held on this file */
106   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
107   DWORD lastErrno;        /* The Windows errno from the last I/O error */
108   DWORD sectorSize;       /* Sector size of the device file is on */
109   winShm *pShm;           /* Instance of shared memory on this file */
110   const char *zPath;      /* Full pathname of this file */
111   int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
112 #if SQLITE_OS_WINCE
113   WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
114   HANDLE hMutex;          /* Mutex used to control access to shared lock */
115   HANDLE hShared;         /* Shared memory segment used for locking */
116   winceLock local;        /* Locks obtained by this instance of winFile */
117   winceLock *shared;      /* Global shared lock memory for the file  */
118 #endif
119 };
120 
121 /*
122 ** Forward prototypes.
123 */
124 static int getSectorSize(
125     sqlite3_vfs *pVfs,
126     const char *zRelative     /* UTF-8 file name */
127 );
128 
129 /*
130 ** The following variable is (normally) set once and never changes
131 ** thereafter.  It records whether the operating system is Win95
132 ** or WinNT.
133 **
134 ** 0:   Operating system unknown.
135 ** 1:   Operating system is Win95.
136 ** 2:   Operating system is WinNT.
137 **
138 ** In order to facilitate testing on a WinNT system, the test fixture
139 ** can manually set this value to 1 to emulate Win98 behavior.
140 */
141 #ifdef SQLITE_TEST
142 int sqlite3_os_type = 0;
143 #else
144 static int sqlite3_os_type = 0;
145 #endif
146 
147 /*
148 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
149 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
150 **
151 ** Here is an interesting observation:  Win95, Win98, and WinME lack
152 ** the LockFileEx() API.  But we can still statically link against that
153 ** API as long as we don't call it when running Win95/98/ME.  A call to
154 ** this routine is used to determine if the host is Win95/98/ME or
155 ** WinNT/2K/XP so that we will know whether or not we can safely call
156 ** the LockFileEx() API.
157 */
158 #if SQLITE_OS_WINCE
159 # define isNT()  (1)
160 #else
isNT(void)161   static int isNT(void){
162     if( sqlite3_os_type==0 ){
163       OSVERSIONINFO sInfo;
164       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
165       GetVersionEx(&sInfo);
166       sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
167     }
168     return sqlite3_os_type==2;
169   }
170 #endif /* SQLITE_OS_WINCE */
171 
172 /*
173 ** Convert a UTF-8 string to microsoft unicode (UTF-16?).
174 **
175 ** Space to hold the returned string is obtained from malloc.
176 */
utf8ToUnicode(const char * zFilename)177 static WCHAR *utf8ToUnicode(const char *zFilename){
178   int nChar;
179   WCHAR *zWideFilename;
180 
181   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
182   zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
183   if( zWideFilename==0 ){
184     return 0;
185   }
186   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
187   if( nChar==0 ){
188     free(zWideFilename);
189     zWideFilename = 0;
190   }
191   return zWideFilename;
192 }
193 
194 /*
195 ** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
196 ** obtained from malloc().
197 */
unicodeToUtf8(const WCHAR * zWideFilename)198 static char *unicodeToUtf8(const WCHAR *zWideFilename){
199   int nByte;
200   char *zFilename;
201 
202   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
203   zFilename = malloc( nByte );
204   if( zFilename==0 ){
205     return 0;
206   }
207   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
208                               0, 0);
209   if( nByte == 0 ){
210     free(zFilename);
211     zFilename = 0;
212   }
213   return zFilename;
214 }
215 
216 /*
217 ** Convert an ansi string to microsoft unicode, based on the
218 ** current codepage settings for file apis.
219 **
220 ** Space to hold the returned string is obtained
221 ** from malloc.
222 */
mbcsToUnicode(const char * zFilename)223 static WCHAR *mbcsToUnicode(const char *zFilename){
224   int nByte;
225   WCHAR *zMbcsFilename;
226   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
227 
228   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
229   zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
230   if( zMbcsFilename==0 ){
231     return 0;
232   }
233   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
234   if( nByte==0 ){
235     free(zMbcsFilename);
236     zMbcsFilename = 0;
237   }
238   return zMbcsFilename;
239 }
240 
241 /*
242 ** Convert microsoft unicode to multibyte character string, based on the
243 ** user's Ansi codepage.
244 **
245 ** Space to hold the returned string is obtained from
246 ** malloc().
247 */
unicodeToMbcs(const WCHAR * zWideFilename)248 static char *unicodeToMbcs(const WCHAR *zWideFilename){
249   int nByte;
250   char *zFilename;
251   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
252 
253   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
254   zFilename = malloc( nByte );
255   if( zFilename==0 ){
256     return 0;
257   }
258   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
259                               0, 0);
260   if( nByte == 0 ){
261     free(zFilename);
262     zFilename = 0;
263   }
264   return zFilename;
265 }
266 
267 /*
268 ** Convert multibyte character string to UTF-8.  Space to hold the
269 ** returned string is obtained from malloc().
270 */
sqlite3_win32_mbcs_to_utf8(const char * zFilename)271 char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
272   char *zFilenameUtf8;
273   WCHAR *zTmpWide;
274 
275   zTmpWide = mbcsToUnicode(zFilename);
276   if( zTmpWide==0 ){
277     return 0;
278   }
279   zFilenameUtf8 = unicodeToUtf8(zTmpWide);
280   free(zTmpWide);
281   return zFilenameUtf8;
282 }
283 
284 /*
285 ** Convert UTF-8 to multibyte character string.  Space to hold the
286 ** returned string is obtained from malloc().
287 */
utf8ToMbcs(const char * zFilename)288 static char *utf8ToMbcs(const char *zFilename){
289   char *zFilenameMbcs;
290   WCHAR *zTmpWide;
291 
292   zTmpWide = utf8ToUnicode(zFilename);
293   if( zTmpWide==0 ){
294     return 0;
295   }
296   zFilenameMbcs = unicodeToMbcs(zTmpWide);
297   free(zTmpWide);
298   return zFilenameMbcs;
299 }
300 
301 #if SQLITE_OS_WINCE
302 /*************************************************************************
303 ** This section contains code for WinCE only.
304 */
305 /*
306 ** WindowsCE does not have a localtime() function.  So create a
307 ** substitute.
308 */
309 #include <time.h>
localtime(const time_t * t)310 struct tm *__cdecl localtime(const time_t *t)
311 {
312   static struct tm y;
313   FILETIME uTm, lTm;
314   SYSTEMTIME pTm;
315   sqlite3_int64 t64;
316   t64 = *t;
317   t64 = (t64 + 11644473600)*10000000;
318   uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
319   uTm.dwHighDateTime= (DWORD)(t64 >> 32);
320   FileTimeToLocalFileTime(&uTm,&lTm);
321   FileTimeToSystemTime(&lTm,&pTm);
322   y.tm_year = pTm.wYear - 1900;
323   y.tm_mon = pTm.wMonth - 1;
324   y.tm_wday = pTm.wDayOfWeek;
325   y.tm_mday = pTm.wDay;
326   y.tm_hour = pTm.wHour;
327   y.tm_min = pTm.wMinute;
328   y.tm_sec = pTm.wSecond;
329   return &y;
330 }
331 
332 /* This will never be called, but defined to make the code compile */
333 #define GetTempPathA(a,b)
334 
335 #define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
336 #define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
337 #define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
338 
339 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
340 
341 /*
342 ** Acquire a lock on the handle h
343 */
winceMutexAcquire(HANDLE h)344 static void winceMutexAcquire(HANDLE h){
345    DWORD dwErr;
346    do {
347      dwErr = WaitForSingleObject(h, INFINITE);
348    } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
349 }
350 /*
351 ** Release a lock acquired by winceMutexAcquire()
352 */
353 #define winceMutexRelease(h) ReleaseMutex(h)
354 
355 /*
356 ** Create the mutex and shared memory used for locking in the file
357 ** descriptor pFile
358 */
winceCreateLock(const char * zFilename,winFile * pFile)359 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
360   WCHAR *zTok;
361   WCHAR *zName = utf8ToUnicode(zFilename);
362   BOOL bInit = TRUE;
363 
364   /* Initialize the local lockdata */
365   ZeroMemory(&pFile->local, sizeof(pFile->local));
366 
367   /* Replace the backslashes from the filename and lowercase it
368   ** to derive a mutex name. */
369   zTok = CharLowerW(zName);
370   for (;*zTok;zTok++){
371     if (*zTok == '\\') *zTok = '_';
372   }
373 
374   /* Create/open the named mutex */
375   pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
376   if (!pFile->hMutex){
377     pFile->lastErrno = GetLastError();
378     free(zName);
379     return FALSE;
380   }
381 
382   /* Acquire the mutex before continuing */
383   winceMutexAcquire(pFile->hMutex);
384 
385   /* Since the names of named mutexes, semaphores, file mappings etc are
386   ** case-sensitive, take advantage of that by uppercasing the mutex name
387   ** and using that as the shared filemapping name.
388   */
389   CharUpperW(zName);
390   pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
391                                        PAGE_READWRITE, 0, sizeof(winceLock),
392                                        zName);
393 
394   /* Set a flag that indicates we're the first to create the memory so it
395   ** must be zero-initialized */
396   if (GetLastError() == ERROR_ALREADY_EXISTS){
397     bInit = FALSE;
398   }
399 
400   free(zName);
401 
402   /* If we succeeded in making the shared memory handle, map it. */
403   if (pFile->hShared){
404     pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
405              FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
406     /* If mapping failed, close the shared memory handle and erase it */
407     if (!pFile->shared){
408       pFile->lastErrno = GetLastError();
409       CloseHandle(pFile->hShared);
410       pFile->hShared = NULL;
411     }
412   }
413 
414   /* If shared memory could not be created, then close the mutex and fail */
415   if (pFile->hShared == NULL){
416     winceMutexRelease(pFile->hMutex);
417     CloseHandle(pFile->hMutex);
418     pFile->hMutex = NULL;
419     return FALSE;
420   }
421 
422   /* Initialize the shared memory if we're supposed to */
423   if (bInit) {
424     ZeroMemory(pFile->shared, sizeof(winceLock));
425   }
426 
427   winceMutexRelease(pFile->hMutex);
428   return TRUE;
429 }
430 
431 /*
432 ** Destroy the part of winFile that deals with wince locks
433 */
winceDestroyLock(winFile * pFile)434 static void winceDestroyLock(winFile *pFile){
435   if (pFile->hMutex){
436     /* Acquire the mutex */
437     winceMutexAcquire(pFile->hMutex);
438 
439     /* The following blocks should probably assert in debug mode, but they
440        are to cleanup in case any locks remained open */
441     if (pFile->local.nReaders){
442       pFile->shared->nReaders --;
443     }
444     if (pFile->local.bReserved){
445       pFile->shared->bReserved = FALSE;
446     }
447     if (pFile->local.bPending){
448       pFile->shared->bPending = FALSE;
449     }
450     if (pFile->local.bExclusive){
451       pFile->shared->bExclusive = FALSE;
452     }
453 
454     /* De-reference and close our copy of the shared memory handle */
455     UnmapViewOfFile(pFile->shared);
456     CloseHandle(pFile->hShared);
457 
458     /* Done with the mutex */
459     winceMutexRelease(pFile->hMutex);
460     CloseHandle(pFile->hMutex);
461     pFile->hMutex = NULL;
462   }
463 }
464 
465 /*
466 ** An implementation of the LockFile() API of windows for wince
467 */
winceLockFile(HANDLE * phFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh)468 static BOOL winceLockFile(
469   HANDLE *phFile,
470   DWORD dwFileOffsetLow,
471   DWORD dwFileOffsetHigh,
472   DWORD nNumberOfBytesToLockLow,
473   DWORD nNumberOfBytesToLockHigh
474 ){
475   winFile *pFile = HANDLE_TO_WINFILE(phFile);
476   BOOL bReturn = FALSE;
477 
478   UNUSED_PARAMETER(dwFileOffsetHigh);
479   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
480 
481   if (!pFile->hMutex) return TRUE;
482   winceMutexAcquire(pFile->hMutex);
483 
484   /* Wanting an exclusive lock? */
485   if (dwFileOffsetLow == (DWORD)SHARED_FIRST
486        && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
487     if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
488        pFile->shared->bExclusive = TRUE;
489        pFile->local.bExclusive = TRUE;
490        bReturn = TRUE;
491     }
492   }
493 
494   /* Want a read-only lock? */
495   else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
496            nNumberOfBytesToLockLow == 1){
497     if (pFile->shared->bExclusive == 0){
498       pFile->local.nReaders ++;
499       if (pFile->local.nReaders == 1){
500         pFile->shared->nReaders ++;
501       }
502       bReturn = TRUE;
503     }
504   }
505 
506   /* Want a pending lock? */
507   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
508     /* If no pending lock has been acquired, then acquire it */
509     if (pFile->shared->bPending == 0) {
510       pFile->shared->bPending = TRUE;
511       pFile->local.bPending = TRUE;
512       bReturn = TRUE;
513     }
514   }
515 
516   /* Want a reserved lock? */
517   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
518     if (pFile->shared->bReserved == 0) {
519       pFile->shared->bReserved = TRUE;
520       pFile->local.bReserved = TRUE;
521       bReturn = TRUE;
522     }
523   }
524 
525   winceMutexRelease(pFile->hMutex);
526   return bReturn;
527 }
528 
529 /*
530 ** An implementation of the UnlockFile API of windows for wince
531 */
winceUnlockFile(HANDLE * phFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh)532 static BOOL winceUnlockFile(
533   HANDLE *phFile,
534   DWORD dwFileOffsetLow,
535   DWORD dwFileOffsetHigh,
536   DWORD nNumberOfBytesToUnlockLow,
537   DWORD nNumberOfBytesToUnlockHigh
538 ){
539   winFile *pFile = HANDLE_TO_WINFILE(phFile);
540   BOOL bReturn = FALSE;
541 
542   UNUSED_PARAMETER(dwFileOffsetHigh);
543   UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
544 
545   if (!pFile->hMutex) return TRUE;
546   winceMutexAcquire(pFile->hMutex);
547 
548   /* Releasing a reader lock or an exclusive lock */
549   if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
550     /* Did we have an exclusive lock? */
551     if (pFile->local.bExclusive){
552       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
553       pFile->local.bExclusive = FALSE;
554       pFile->shared->bExclusive = FALSE;
555       bReturn = TRUE;
556     }
557 
558     /* Did we just have a reader lock? */
559     else if (pFile->local.nReaders){
560       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
561       pFile->local.nReaders --;
562       if (pFile->local.nReaders == 0)
563       {
564         pFile->shared->nReaders --;
565       }
566       bReturn = TRUE;
567     }
568   }
569 
570   /* Releasing a pending lock */
571   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
572     if (pFile->local.bPending){
573       pFile->local.bPending = FALSE;
574       pFile->shared->bPending = FALSE;
575       bReturn = TRUE;
576     }
577   }
578   /* Releasing a reserved lock */
579   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
580     if (pFile->local.bReserved) {
581       pFile->local.bReserved = FALSE;
582       pFile->shared->bReserved = FALSE;
583       bReturn = TRUE;
584     }
585   }
586 
587   winceMutexRelease(pFile->hMutex);
588   return bReturn;
589 }
590 
591 /*
592 ** An implementation of the LockFileEx() API of windows for wince
593 */
winceLockFileEx(HANDLE * phFile,DWORD dwFlags,DWORD dwReserved,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh,LPOVERLAPPED lpOverlapped)594 static BOOL winceLockFileEx(
595   HANDLE *phFile,
596   DWORD dwFlags,
597   DWORD dwReserved,
598   DWORD nNumberOfBytesToLockLow,
599   DWORD nNumberOfBytesToLockHigh,
600   LPOVERLAPPED lpOverlapped
601 ){
602   UNUSED_PARAMETER(dwReserved);
603   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
604 
605   /* If the caller wants a shared read lock, forward this call
606   ** to winceLockFile */
607   if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
608       dwFlags == 1 &&
609       nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
610     return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
611   }
612   return FALSE;
613 }
614 /*
615 ** End of the special code for wince
616 *****************************************************************************/
617 #endif /* SQLITE_OS_WINCE */
618 
619 /*****************************************************************************
620 ** The next group of routines implement the I/O methods specified
621 ** by the sqlite3_io_methods object.
622 ******************************************************************************/
623 
624 /*
625 ** Some microsoft compilers lack this definition.
626 */
627 #ifndef INVALID_SET_FILE_POINTER
628 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
629 #endif
630 
631 /*
632 ** Move the current position of the file handle passed as the first
633 ** argument to offset iOffset within the file. If successful, return 0.
634 ** Otherwise, set pFile->lastErrno and return non-zero.
635 */
seekWinFile(winFile * pFile,sqlite3_int64 iOffset)636 static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
637   LONG upperBits;                 /* Most sig. 32 bits of new offset */
638   LONG lowerBits;                 /* Least sig. 32 bits of new offset */
639   DWORD dwRet;                    /* Value returned by SetFilePointer() */
640 
641   upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
642   lowerBits = (LONG)(iOffset & 0xffffffff);
643 
644   /* API oddity: If successful, SetFilePointer() returns a dword
645   ** containing the lower 32-bits of the new file-offset. Or, if it fails,
646   ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
647   ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
648   ** whether an error has actually occured, it is also necessary to call
649   ** GetLastError().
650   */
651   dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
652   if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
653     pFile->lastErrno = GetLastError();
654     return 1;
655   }
656 
657   return 0;
658 }
659 
660 /*
661 ** Close a file.
662 **
663 ** It is reported that an attempt to close a handle might sometimes
664 ** fail.  This is a very unreasonable result, but windows is notorious
665 ** for being unreasonable so I do not doubt that it might happen.  If
666 ** the close fails, we pause for 100 milliseconds and try again.  As
667 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
668 ** giving up and returning an error.
669 */
670 #define MX_CLOSE_ATTEMPT 3
winClose(sqlite3_file * id)671 static int winClose(sqlite3_file *id){
672   int rc, cnt = 0;
673   winFile *pFile = (winFile*)id;
674 
675   assert( id!=0 );
676   assert( pFile->pShm==0 );
677   OSTRACE(("CLOSE %d\n", pFile->h));
678   do{
679     rc = CloseHandle(pFile->h);
680     /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
681   }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
682 #if SQLITE_OS_WINCE
683 #define WINCE_DELETION_ATTEMPTS 3
684   winceDestroyLock(pFile);
685   if( pFile->zDeleteOnClose ){
686     int cnt = 0;
687     while(
688            DeleteFileW(pFile->zDeleteOnClose)==0
689         && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
690         && cnt++ < WINCE_DELETION_ATTEMPTS
691     ){
692        Sleep(100);  /* Wait a little before trying again */
693     }
694     free(pFile->zDeleteOnClose);
695   }
696 #endif
697   OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
698   OpenCounter(-1);
699   return rc ? SQLITE_OK : SQLITE_IOERR;
700 }
701 
702 /*
703 ** Read data from a file into a buffer.  Return SQLITE_OK if all
704 ** bytes were read successfully and SQLITE_IOERR if anything goes
705 ** wrong.
706 */
winRead(sqlite3_file * id,void * pBuf,int amt,sqlite3_int64 offset)707 static int winRead(
708   sqlite3_file *id,          /* File to read from */
709   void *pBuf,                /* Write content into this buffer */
710   int amt,                   /* Number of bytes to read */
711   sqlite3_int64 offset       /* Begin reading at this offset */
712 ){
713   winFile *pFile = (winFile*)id;  /* file handle */
714   DWORD nRead;                    /* Number of bytes actually read from file */
715 
716   assert( id!=0 );
717   SimulateIOError(return SQLITE_IOERR_READ);
718   OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
719 
720   if( seekWinFile(pFile, offset) ){
721     return SQLITE_FULL;
722   }
723   if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
724     pFile->lastErrno = GetLastError();
725     return SQLITE_IOERR_READ;
726   }
727   if( nRead<(DWORD)amt ){
728     /* Unread parts of the buffer must be zero-filled */
729     memset(&((char*)pBuf)[nRead], 0, amt-nRead);
730     return SQLITE_IOERR_SHORT_READ;
731   }
732 
733   return SQLITE_OK;
734 }
735 
736 /*
737 ** Write data from a buffer into a file.  Return SQLITE_OK on success
738 ** or some other error code on failure.
739 */
winWrite(sqlite3_file * id,const void * pBuf,int amt,sqlite3_int64 offset)740 static int winWrite(
741   sqlite3_file *id,               /* File to write into */
742   const void *pBuf,               /* The bytes to be written */
743   int amt,                        /* Number of bytes to write */
744   sqlite3_int64 offset            /* Offset into the file to begin writing at */
745 ){
746   int rc;                         /* True if error has occured, else false */
747   winFile *pFile = (winFile*)id;  /* File handle */
748 
749   assert( amt>0 );
750   assert( pFile );
751   SimulateIOError(return SQLITE_IOERR_WRITE);
752   SimulateDiskfullError(return SQLITE_FULL);
753 
754   OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
755 
756   rc = seekWinFile(pFile, offset);
757   if( rc==0 ){
758     u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
759     int nRem = amt;               /* Number of bytes yet to be written */
760     DWORD nWrite;                 /* Bytes written by each WriteFile() call */
761 
762     while( nRem>0 && WriteFile(pFile->h, aRem, nRem, &nWrite, 0) && nWrite>0 ){
763       aRem += nWrite;
764       nRem -= nWrite;
765     }
766     if( nRem>0 ){
767       pFile->lastErrno = GetLastError();
768       rc = 1;
769     }
770   }
771 
772   if( rc ){
773     if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
774       return SQLITE_FULL;
775     }
776     return SQLITE_IOERR_WRITE;
777   }
778   return SQLITE_OK;
779 }
780 
781 /*
782 ** Truncate an open file to a specified size
783 */
winTruncate(sqlite3_file * id,sqlite3_int64 nByte)784 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
785   winFile *pFile = (winFile*)id;  /* File handle object */
786   int rc = SQLITE_OK;             /* Return code for this function */
787 
788   assert( pFile );
789 
790   OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
791   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
792 
793   /* If the user has configured a chunk-size for this file, truncate the
794   ** file so that it consists of an integer number of chunks (i.e. the
795   ** actual file size after the operation may be larger than the requested
796   ** size).
797   */
798   if( pFile->szChunk ){
799     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
800   }
801 
802   /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
803   if( seekWinFile(pFile, nByte) ){
804     rc = SQLITE_IOERR_TRUNCATE;
805   }else if( 0==SetEndOfFile(pFile->h) ){
806     pFile->lastErrno = GetLastError();
807     rc = SQLITE_IOERR_TRUNCATE;
808   }
809 
810   OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
811   return rc;
812 }
813 
814 #ifdef SQLITE_TEST
815 /*
816 ** Count the number of fullsyncs and normal syncs.  This is used to test
817 ** that syncs and fullsyncs are occuring at the right times.
818 */
819 int sqlite3_sync_count = 0;
820 int sqlite3_fullsync_count = 0;
821 #endif
822 
823 /*
824 ** Make sure all writes to a particular file are committed to disk.
825 */
winSync(sqlite3_file * id,int flags)826 static int winSync(sqlite3_file *id, int flags){
827 #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG)
828   winFile *pFile = (winFile*)id;
829 #else
830   UNUSED_PARAMETER(id);
831 #endif
832 
833   assert( pFile );
834   /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
835   assert((flags&0x0F)==SQLITE_SYNC_NORMAL
836       || (flags&0x0F)==SQLITE_SYNC_FULL
837   );
838 
839   OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
840 
841 #ifndef SQLITE_TEST
842   UNUSED_PARAMETER(flags);
843 #else
844   if( flags & SQLITE_SYNC_FULL ){
845     sqlite3_fullsync_count++;
846   }
847   sqlite3_sync_count++;
848 #endif
849 
850   /* Unix cannot, but some systems may return SQLITE_FULL from here. This
851   ** line is to test that doing so does not cause any problems.
852   */
853   SimulateDiskfullError( return SQLITE_FULL );
854   SimulateIOError( return SQLITE_IOERR; );
855 
856   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
857   ** no-op
858   */
859 #ifdef SQLITE_NO_SYNC
860   return SQLITE_OK;
861 #else
862   if( FlushFileBuffers(pFile->h) ){
863     return SQLITE_OK;
864   }else{
865     pFile->lastErrno = GetLastError();
866     return SQLITE_IOERR;
867   }
868 #endif
869 }
870 
871 /*
872 ** Determine the current size of a file in bytes
873 */
winFileSize(sqlite3_file * id,sqlite3_int64 * pSize)874 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
875   DWORD upperBits;
876   DWORD lowerBits;
877   winFile *pFile = (winFile*)id;
878   DWORD error;
879 
880   assert( id!=0 );
881   SimulateIOError(return SQLITE_IOERR_FSTAT);
882   lowerBits = GetFileSize(pFile->h, &upperBits);
883   if(   (lowerBits == INVALID_FILE_SIZE)
884      && ((error = GetLastError()) != NO_ERROR) )
885   {
886     pFile->lastErrno = error;
887     return SQLITE_IOERR_FSTAT;
888   }
889   *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
890   return SQLITE_OK;
891 }
892 
893 /*
894 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
895 */
896 #ifndef LOCKFILE_FAIL_IMMEDIATELY
897 # define LOCKFILE_FAIL_IMMEDIATELY 1
898 #endif
899 
900 /*
901 ** Acquire a reader lock.
902 ** Different API routines are called depending on whether or not this
903 ** is Win95 or WinNT.
904 */
getReadLock(winFile * pFile)905 static int getReadLock(winFile *pFile){
906   int res;
907   if( isNT() ){
908     OVERLAPPED ovlp;
909     ovlp.Offset = SHARED_FIRST;
910     ovlp.OffsetHigh = 0;
911     ovlp.hEvent = 0;
912     res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
913                      0, SHARED_SIZE, 0, &ovlp);
914 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
915 */
916 #if SQLITE_OS_WINCE==0
917   }else{
918     int lk;
919     sqlite3_randomness(sizeof(lk), &lk);
920     pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
921     res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
922 #endif
923   }
924   if( res == 0 ){
925     pFile->lastErrno = GetLastError();
926   }
927   return res;
928 }
929 
930 /*
931 ** Undo a readlock
932 */
unlockReadLock(winFile * pFile)933 static int unlockReadLock(winFile *pFile){
934   int res;
935   if( isNT() ){
936     res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
937 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
938 */
939 #if SQLITE_OS_WINCE==0
940   }else{
941     res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
942 #endif
943   }
944   if( res == 0 ){
945     pFile->lastErrno = GetLastError();
946   }
947   return res;
948 }
949 
950 /*
951 ** Lock the file with the lock specified by parameter locktype - one
952 ** of the following:
953 **
954 **     (1) SHARED_LOCK
955 **     (2) RESERVED_LOCK
956 **     (3) PENDING_LOCK
957 **     (4) EXCLUSIVE_LOCK
958 **
959 ** Sometimes when requesting one lock state, additional lock states
960 ** are inserted in between.  The locking might fail on one of the later
961 ** transitions leaving the lock state different from what it started but
962 ** still short of its goal.  The following chart shows the allowed
963 ** transitions and the inserted intermediate states:
964 **
965 **    UNLOCKED -> SHARED
966 **    SHARED -> RESERVED
967 **    SHARED -> (PENDING) -> EXCLUSIVE
968 **    RESERVED -> (PENDING) -> EXCLUSIVE
969 **    PENDING -> EXCLUSIVE
970 **
971 ** This routine will only increase a lock.  The winUnlock() routine
972 ** erases all locks at once and returns us immediately to locking level 0.
973 ** It is not possible to lower the locking level one step at a time.  You
974 ** must go straight to locking level 0.
975 */
winLock(sqlite3_file * id,int locktype)976 static int winLock(sqlite3_file *id, int locktype){
977   int rc = SQLITE_OK;    /* Return code from subroutines */
978   int res = 1;           /* Result of a windows lock call */
979   int newLocktype;       /* Set pFile->locktype to this value before exiting */
980   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
981   winFile *pFile = (winFile*)id;
982   DWORD error = NO_ERROR;
983 
984   assert( id!=0 );
985   OSTRACE(("LOCK %d %d was %d(%d)\n",
986            pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
987 
988   /* If there is already a lock of this type or more restrictive on the
989   ** OsFile, do nothing. Don't use the end_lock: exit path, as
990   ** sqlite3OsEnterMutex() hasn't been called yet.
991   */
992   if( pFile->locktype>=locktype ){
993     return SQLITE_OK;
994   }
995 
996   /* Make sure the locking sequence is correct
997   */
998   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
999   assert( locktype!=PENDING_LOCK );
1000   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
1001 
1002   /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
1003   ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
1004   ** the PENDING_LOCK byte is temporary.
1005   */
1006   newLocktype = pFile->locktype;
1007   if(   (pFile->locktype==NO_LOCK)
1008      || (   (locktype==EXCLUSIVE_LOCK)
1009          && (pFile->locktype==RESERVED_LOCK))
1010   ){
1011     int cnt = 3;
1012     while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
1013       /* Try 3 times to get the pending lock.  The pending lock might be
1014       ** held by another reader process who will release it momentarily.
1015       */
1016       OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
1017       Sleep(1);
1018     }
1019     gotPendingLock = res;
1020     if( !res ){
1021       error = GetLastError();
1022     }
1023   }
1024 
1025   /* Acquire a shared lock
1026   */
1027   if( locktype==SHARED_LOCK && res ){
1028     assert( pFile->locktype==NO_LOCK );
1029     res = getReadLock(pFile);
1030     if( res ){
1031       newLocktype = SHARED_LOCK;
1032     }else{
1033       error = GetLastError();
1034     }
1035   }
1036 
1037   /* Acquire a RESERVED lock
1038   */
1039   if( locktype==RESERVED_LOCK && res ){
1040     assert( pFile->locktype==SHARED_LOCK );
1041     res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1042     if( res ){
1043       newLocktype = RESERVED_LOCK;
1044     }else{
1045       error = GetLastError();
1046     }
1047   }
1048 
1049   /* Acquire a PENDING lock
1050   */
1051   if( locktype==EXCLUSIVE_LOCK && res ){
1052     newLocktype = PENDING_LOCK;
1053     gotPendingLock = 0;
1054   }
1055 
1056   /* Acquire an EXCLUSIVE lock
1057   */
1058   if( locktype==EXCLUSIVE_LOCK && res ){
1059     assert( pFile->locktype>=SHARED_LOCK );
1060     res = unlockReadLock(pFile);
1061     OSTRACE(("unreadlock = %d\n", res));
1062     res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1063     if( res ){
1064       newLocktype = EXCLUSIVE_LOCK;
1065     }else{
1066       error = GetLastError();
1067       OSTRACE(("error-code = %d\n", error));
1068       getReadLock(pFile);
1069     }
1070   }
1071 
1072   /* If we are holding a PENDING lock that ought to be released, then
1073   ** release it now.
1074   */
1075   if( gotPendingLock && locktype==SHARED_LOCK ){
1076     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
1077   }
1078 
1079   /* Update the state of the lock has held in the file descriptor then
1080   ** return the appropriate result code.
1081   */
1082   if( res ){
1083     rc = SQLITE_OK;
1084   }else{
1085     OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
1086            locktype, newLocktype));
1087     pFile->lastErrno = error;
1088     rc = SQLITE_BUSY;
1089   }
1090   pFile->locktype = (u8)newLocktype;
1091   return rc;
1092 }
1093 
1094 /*
1095 ** This routine checks if there is a RESERVED lock held on the specified
1096 ** file by this or any other process. If such a lock is held, return
1097 ** non-zero, otherwise zero.
1098 */
winCheckReservedLock(sqlite3_file * id,int * pResOut)1099 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
1100   int rc;
1101   winFile *pFile = (winFile*)id;
1102 
1103   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
1104 
1105   assert( id!=0 );
1106   if( pFile->locktype>=RESERVED_LOCK ){
1107     rc = 1;
1108     OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
1109   }else{
1110     rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1111     if( rc ){
1112       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1113     }
1114     rc = !rc;
1115     OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
1116   }
1117   *pResOut = rc;
1118   return SQLITE_OK;
1119 }
1120 
1121 /*
1122 ** Lower the locking level on file descriptor id to locktype.  locktype
1123 ** must be either NO_LOCK or SHARED_LOCK.
1124 **
1125 ** If the locking level of the file descriptor is already at or below
1126 ** the requested locking level, this routine is a no-op.
1127 **
1128 ** It is not possible for this routine to fail if the second argument
1129 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
1130 ** might return SQLITE_IOERR;
1131 */
winUnlock(sqlite3_file * id,int locktype)1132 static int winUnlock(sqlite3_file *id, int locktype){
1133   int type;
1134   winFile *pFile = (winFile*)id;
1135   int rc = SQLITE_OK;
1136   assert( pFile!=0 );
1137   assert( locktype<=SHARED_LOCK );
1138   OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
1139           pFile->locktype, pFile->sharedLockByte));
1140   type = pFile->locktype;
1141   if( type>=EXCLUSIVE_LOCK ){
1142     UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1143     if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
1144       /* This should never happen.  We should always be able to
1145       ** reacquire the read lock */
1146       rc = SQLITE_IOERR_UNLOCK;
1147     }
1148   }
1149   if( type>=RESERVED_LOCK ){
1150     UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1151   }
1152   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
1153     unlockReadLock(pFile);
1154   }
1155   if( type>=PENDING_LOCK ){
1156     UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
1157   }
1158   pFile->locktype = (u8)locktype;
1159   return rc;
1160 }
1161 
1162 /*
1163 ** Control and query of the open file handle.
1164 */
winFileControl(sqlite3_file * id,int op,void * pArg)1165 static int winFileControl(sqlite3_file *id, int op, void *pArg){
1166   switch( op ){
1167     case SQLITE_FCNTL_LOCKSTATE: {
1168       *(int*)pArg = ((winFile*)id)->locktype;
1169       return SQLITE_OK;
1170     }
1171     case SQLITE_LAST_ERRNO: {
1172       *(int*)pArg = (int)((winFile*)id)->lastErrno;
1173       return SQLITE_OK;
1174     }
1175     case SQLITE_FCNTL_CHUNK_SIZE: {
1176       ((winFile*)id)->szChunk = *(int *)pArg;
1177       return SQLITE_OK;
1178     }
1179     case SQLITE_FCNTL_SIZE_HINT: {
1180       sqlite3_int64 sz = *(sqlite3_int64*)pArg;
1181       SimulateIOErrorBenign(1);
1182       winTruncate(id, sz);
1183       SimulateIOErrorBenign(0);
1184       return SQLITE_OK;
1185     }
1186     case SQLITE_FCNTL_SYNC_OMITTED: {
1187       return SQLITE_OK;
1188     }
1189   }
1190   return SQLITE_NOTFOUND;
1191 }
1192 
1193 /*
1194 ** Return the sector size in bytes of the underlying block device for
1195 ** the specified file. This is almost always 512 bytes, but may be
1196 ** larger for some devices.
1197 **
1198 ** SQLite code assumes this function cannot fail. It also assumes that
1199 ** if two files are created in the same file-system directory (i.e.
1200 ** a database and its journal file) that the sector size will be the
1201 ** same for both.
1202 */
winSectorSize(sqlite3_file * id)1203 static int winSectorSize(sqlite3_file *id){
1204   assert( id!=0 );
1205   return (int)(((winFile*)id)->sectorSize);
1206 }
1207 
1208 /*
1209 ** Return a vector of device characteristics.
1210 */
winDeviceCharacteristics(sqlite3_file * id)1211 static int winDeviceCharacteristics(sqlite3_file *id){
1212   UNUSED_PARAMETER(id);
1213   return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
1214 }
1215 
1216 #ifndef SQLITE_OMIT_WAL
1217 
1218 /*
1219 ** Windows will only let you create file view mappings
1220 ** on allocation size granularity boundaries.
1221 ** During sqlite3_os_init() we do a GetSystemInfo()
1222 ** to get the granularity size.
1223 */
1224 SYSTEM_INFO winSysInfo;
1225 
1226 /*
1227 ** Helper functions to obtain and relinquish the global mutex. The
1228 ** global mutex is used to protect the winLockInfo objects used by
1229 ** this file, all of which may be shared by multiple threads.
1230 **
1231 ** Function winShmMutexHeld() is used to assert() that the global mutex
1232 ** is held when required. This function is only used as part of assert()
1233 ** statements. e.g.
1234 **
1235 **   winShmEnterMutex()
1236 **     assert( winShmMutexHeld() );
1237 **   winShmLeaveMutex()
1238 */
winShmEnterMutex(void)1239 static void winShmEnterMutex(void){
1240   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1241 }
winShmLeaveMutex(void)1242 static void winShmLeaveMutex(void){
1243   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1244 }
1245 #ifdef SQLITE_DEBUG
winShmMutexHeld(void)1246 static int winShmMutexHeld(void) {
1247   return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1248 }
1249 #endif
1250 
1251 /*
1252 ** Object used to represent a single file opened and mmapped to provide
1253 ** shared memory.  When multiple threads all reference the same
1254 ** log-summary, each thread has its own winFile object, but they all
1255 ** point to a single instance of this object.  In other words, each
1256 ** log-summary is opened only once per process.
1257 **
1258 ** winShmMutexHeld() must be true when creating or destroying
1259 ** this object or while reading or writing the following fields:
1260 **
1261 **      nRef
1262 **      pNext
1263 **
1264 ** The following fields are read-only after the object is created:
1265 **
1266 **      fid
1267 **      zFilename
1268 **
1269 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
1270 ** winShmMutexHeld() is true when reading or writing any other field
1271 ** in this structure.
1272 **
1273 */
1274 struct winShmNode {
1275   sqlite3_mutex *mutex;      /* Mutex to access this object */
1276   char *zFilename;           /* Name of the file */
1277   winFile hFile;             /* File handle from winOpen */
1278 
1279   int szRegion;              /* Size of shared-memory regions */
1280   int nRegion;               /* Size of array apRegion */
1281   struct ShmRegion {
1282     HANDLE hMap;             /* File handle from CreateFileMapping */
1283     void *pMap;
1284   } *aRegion;
1285   DWORD lastErrno;           /* The Windows errno from the last I/O error */
1286 
1287   int nRef;                  /* Number of winShm objects pointing to this */
1288   winShm *pFirst;            /* All winShm objects pointing to this */
1289   winShmNode *pNext;         /* Next in list of all winShmNode objects */
1290 #ifdef SQLITE_DEBUG
1291   u8 nextShmId;              /* Next available winShm.id value */
1292 #endif
1293 };
1294 
1295 /*
1296 ** A global array of all winShmNode objects.
1297 **
1298 ** The winShmMutexHeld() must be true while reading or writing this list.
1299 */
1300 static winShmNode *winShmNodeList = 0;
1301 
1302 /*
1303 ** Structure used internally by this VFS to record the state of an
1304 ** open shared memory connection.
1305 **
1306 ** The following fields are initialized when this object is created and
1307 ** are read-only thereafter:
1308 **
1309 **    winShm.pShmNode
1310 **    winShm.id
1311 **
1312 ** All other fields are read/write.  The winShm.pShmNode->mutex must be held
1313 ** while accessing any read/write fields.
1314 */
1315 struct winShm {
1316   winShmNode *pShmNode;      /* The underlying winShmNode object */
1317   winShm *pNext;             /* Next winShm with the same winShmNode */
1318   u8 hasMutex;               /* True if holding the winShmNode mutex */
1319   u16 sharedMask;            /* Mask of shared locks held */
1320   u16 exclMask;              /* Mask of exclusive locks held */
1321 #ifdef SQLITE_DEBUG
1322   u8 id;                     /* Id of this connection with its winShmNode */
1323 #endif
1324 };
1325 
1326 /*
1327 ** Constants used for locking
1328 */
1329 #define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
1330 #define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
1331 
1332 /*
1333 ** Apply advisory locks for all n bytes beginning at ofst.
1334 */
1335 #define _SHM_UNLCK  1
1336 #define _SHM_RDLCK  2
1337 #define _SHM_WRLCK  3
winShmSystemLock(winShmNode * pFile,int lockType,int ofst,int nByte)1338 static int winShmSystemLock(
1339   winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
1340   int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
1341   int ofst,             /* Offset to first byte to be locked/unlocked */
1342   int nByte             /* Number of bytes to lock or unlock */
1343 ){
1344   OVERLAPPED ovlp;
1345   DWORD dwFlags;
1346   int rc = 0;           /* Result code form Lock/UnlockFileEx() */
1347 
1348   /* Access to the winShmNode object is serialized by the caller */
1349   assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
1350 
1351   /* Initialize the locking parameters */
1352   dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
1353   if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
1354 
1355   memset(&ovlp, 0, sizeof(OVERLAPPED));
1356   ovlp.Offset = ofst;
1357 
1358   /* Release/Acquire the system-level lock */
1359   if( lockType==_SHM_UNLCK ){
1360     rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
1361   }else{
1362     rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
1363   }
1364 
1365   if( rc!= 0 ){
1366     rc = SQLITE_OK;
1367   }else{
1368     pFile->lastErrno =  GetLastError();
1369     rc = SQLITE_BUSY;
1370   }
1371 
1372   OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n",
1373            pFile->hFile.h,
1374            rc==SQLITE_OK ? "ok" : "failed",
1375            lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
1376            pFile->lastErrno));
1377 
1378   return rc;
1379 }
1380 
1381 /* Forward references to VFS methods */
1382 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
1383 static int winDelete(sqlite3_vfs *,const char*,int);
1384 
1385 /*
1386 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
1387 **
1388 ** This is not a VFS shared-memory method; it is a utility function called
1389 ** by VFS shared-memory methods.
1390 */
winShmPurge(sqlite3_vfs * pVfs,int deleteFlag)1391 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
1392   winShmNode **pp;
1393   winShmNode *p;
1394   BOOL bRc;
1395   assert( winShmMutexHeld() );
1396   pp = &winShmNodeList;
1397   while( (p = *pp)!=0 ){
1398     if( p->nRef==0 ){
1399       int i;
1400       if( p->mutex ) sqlite3_mutex_free(p->mutex);
1401       for(i=0; i<p->nRegion; i++){
1402         bRc = UnmapViewOfFile(p->aRegion[i].pMap);
1403         OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
1404                  (int)GetCurrentProcessId(), i,
1405                  bRc ? "ok" : "failed"));
1406         bRc = CloseHandle(p->aRegion[i].hMap);
1407         OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
1408                  (int)GetCurrentProcessId(), i,
1409                  bRc ? "ok" : "failed"));
1410       }
1411       if( p->hFile.h != INVALID_HANDLE_VALUE ){
1412         SimulateIOErrorBenign(1);
1413         winClose((sqlite3_file *)&p->hFile);
1414         SimulateIOErrorBenign(0);
1415       }
1416       if( deleteFlag ){
1417         SimulateIOErrorBenign(1);
1418         winDelete(pVfs, p->zFilename, 0);
1419         SimulateIOErrorBenign(0);
1420       }
1421       *pp = p->pNext;
1422       sqlite3_free(p->aRegion);
1423       sqlite3_free(p);
1424     }else{
1425       pp = &p->pNext;
1426     }
1427   }
1428 }
1429 
1430 /*
1431 ** Open the shared-memory area associated with database file pDbFd.
1432 **
1433 ** When opening a new shared-memory file, if no other instances of that
1434 ** file are currently open, in this process or in other processes, then
1435 ** the file must be truncated to zero length or have its header cleared.
1436 */
winOpenSharedMemory(winFile * pDbFd)1437 static int winOpenSharedMemory(winFile *pDbFd){
1438   struct winShm *p;                  /* The connection to be opened */
1439   struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
1440   int rc;                            /* Result code */
1441   struct winShmNode *pNew;           /* Newly allocated winShmNode */
1442   int nName;                         /* Size of zName in bytes */
1443 
1444   assert( pDbFd->pShm==0 );    /* Not previously opened */
1445 
1446   /* Allocate space for the new sqlite3_shm object.  Also speculatively
1447   ** allocate space for a new winShmNode and filename.
1448   */
1449   p = sqlite3_malloc( sizeof(*p) );
1450   if( p==0 ) return SQLITE_NOMEM;
1451   memset(p, 0, sizeof(*p));
1452   nName = sqlite3Strlen30(pDbFd->zPath);
1453   pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 );
1454   if( pNew==0 ){
1455     sqlite3_free(p);
1456     return SQLITE_NOMEM;
1457   }
1458   memset(pNew, 0, sizeof(*pNew));
1459   pNew->zFilename = (char*)&pNew[1];
1460   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
1461 
1462   /* Look to see if there is an existing winShmNode that can be used.
1463   ** If no matching winShmNode currently exists, create a new one.
1464   */
1465   winShmEnterMutex();
1466   for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
1467     /* TBD need to come up with better match here.  Perhaps
1468     ** use FILE_ID_BOTH_DIR_INFO Structure.
1469     */
1470     if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
1471   }
1472   if( pShmNode ){
1473     sqlite3_free(pNew);
1474   }else{
1475     pShmNode = pNew;
1476     pNew = 0;
1477     ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
1478     pShmNode->pNext = winShmNodeList;
1479     winShmNodeList = pShmNode;
1480 
1481     pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1482     if( pShmNode->mutex==0 ){
1483       rc = SQLITE_NOMEM;
1484       goto shm_open_err;
1485     }
1486 
1487     rc = winOpen(pDbFd->pVfs,
1488                  pShmNode->zFilename,             /* Name of the file (UTF-8) */
1489                  (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
1490                  SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
1491                  0);
1492     if( SQLITE_OK!=rc ){
1493       rc = SQLITE_CANTOPEN_BKPT;
1494       goto shm_open_err;
1495     }
1496 
1497     /* Check to see if another process is holding the dead-man switch.
1498     ** If not, truncate the file to zero length.
1499     */
1500     if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
1501       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
1502       if( rc!=SQLITE_OK ){
1503         rc = SQLITE_IOERR_SHMOPEN;
1504       }
1505     }
1506     if( rc==SQLITE_OK ){
1507       winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
1508       rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
1509     }
1510     if( rc ) goto shm_open_err;
1511   }
1512 
1513   /* Make the new connection a child of the winShmNode */
1514   p->pShmNode = pShmNode;
1515 #ifdef SQLITE_DEBUG
1516   p->id = pShmNode->nextShmId++;
1517 #endif
1518   pShmNode->nRef++;
1519   pDbFd->pShm = p;
1520   winShmLeaveMutex();
1521 
1522   /* The reference count on pShmNode has already been incremented under
1523   ** the cover of the winShmEnterMutex() mutex and the pointer from the
1524   ** new (struct winShm) object to the pShmNode has been set. All that is
1525   ** left to do is to link the new object into the linked list starting
1526   ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
1527   ** mutex.
1528   */
1529   sqlite3_mutex_enter(pShmNode->mutex);
1530   p->pNext = pShmNode->pFirst;
1531   pShmNode->pFirst = p;
1532   sqlite3_mutex_leave(pShmNode->mutex);
1533   return SQLITE_OK;
1534 
1535   /* Jump here on any error */
1536 shm_open_err:
1537   winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
1538   winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
1539   sqlite3_free(p);
1540   sqlite3_free(pNew);
1541   winShmLeaveMutex();
1542   return rc;
1543 }
1544 
1545 /*
1546 ** Close a connection to shared-memory.  Delete the underlying
1547 ** storage if deleteFlag is true.
1548 */
winShmUnmap(sqlite3_file * fd,int deleteFlag)1549 static int winShmUnmap(
1550   sqlite3_file *fd,          /* Database holding shared memory */
1551   int deleteFlag             /* Delete after closing if true */
1552 ){
1553   winFile *pDbFd;       /* Database holding shared-memory */
1554   winShm *p;            /* The connection to be closed */
1555   winShmNode *pShmNode; /* The underlying shared-memory file */
1556   winShm **pp;          /* For looping over sibling connections */
1557 
1558   pDbFd = (winFile*)fd;
1559   p = pDbFd->pShm;
1560   if( p==0 ) return SQLITE_OK;
1561   pShmNode = p->pShmNode;
1562 
1563   /* Remove connection p from the set of connections associated
1564   ** with pShmNode */
1565   sqlite3_mutex_enter(pShmNode->mutex);
1566   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
1567   *pp = p->pNext;
1568 
1569   /* Free the connection p */
1570   sqlite3_free(p);
1571   pDbFd->pShm = 0;
1572   sqlite3_mutex_leave(pShmNode->mutex);
1573 
1574   /* If pShmNode->nRef has reached 0, then close the underlying
1575   ** shared-memory file, too */
1576   winShmEnterMutex();
1577   assert( pShmNode->nRef>0 );
1578   pShmNode->nRef--;
1579   if( pShmNode->nRef==0 ){
1580     winShmPurge(pDbFd->pVfs, deleteFlag);
1581   }
1582   winShmLeaveMutex();
1583 
1584   return SQLITE_OK;
1585 }
1586 
1587 /*
1588 ** Change the lock state for a shared-memory segment.
1589 */
winShmLock(sqlite3_file * fd,int ofst,int n,int flags)1590 static int winShmLock(
1591   sqlite3_file *fd,          /* Database file holding the shared memory */
1592   int ofst,                  /* First lock to acquire or release */
1593   int n,                     /* Number of locks to acquire or release */
1594   int flags                  /* What to do with the lock */
1595 ){
1596   winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
1597   winShm *p = pDbFd->pShm;              /* The shared memory being locked */
1598   winShm *pX;                           /* For looping over all siblings */
1599   winShmNode *pShmNode = p->pShmNode;
1600   int rc = SQLITE_OK;                   /* Result code */
1601   u16 mask;                             /* Mask of locks to take or release */
1602 
1603   assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
1604   assert( n>=1 );
1605   assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
1606        || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
1607        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
1608        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
1609   assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
1610 
1611   mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
1612   assert( n>1 || mask==(1<<ofst) );
1613   sqlite3_mutex_enter(pShmNode->mutex);
1614   if( flags & SQLITE_SHM_UNLOCK ){
1615     u16 allMask = 0; /* Mask of locks held by siblings */
1616 
1617     /* See if any siblings hold this same lock */
1618     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
1619       if( pX==p ) continue;
1620       assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
1621       allMask |= pX->sharedMask;
1622     }
1623 
1624     /* Unlock the system-level locks */
1625     if( (mask & allMask)==0 ){
1626       rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
1627     }else{
1628       rc = SQLITE_OK;
1629     }
1630 
1631     /* Undo the local locks */
1632     if( rc==SQLITE_OK ){
1633       p->exclMask &= ~mask;
1634       p->sharedMask &= ~mask;
1635     }
1636   }else if( flags & SQLITE_SHM_SHARED ){
1637     u16 allShared = 0;  /* Union of locks held by connections other than "p" */
1638 
1639     /* Find out which shared locks are already held by sibling connections.
1640     ** If any sibling already holds an exclusive lock, go ahead and return
1641     ** SQLITE_BUSY.
1642     */
1643     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
1644       if( (pX->exclMask & mask)!=0 ){
1645         rc = SQLITE_BUSY;
1646         break;
1647       }
1648       allShared |= pX->sharedMask;
1649     }
1650 
1651     /* Get shared locks at the system level, if necessary */
1652     if( rc==SQLITE_OK ){
1653       if( (allShared & mask)==0 ){
1654         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
1655       }else{
1656         rc = SQLITE_OK;
1657       }
1658     }
1659 
1660     /* Get the local shared locks */
1661     if( rc==SQLITE_OK ){
1662       p->sharedMask |= mask;
1663     }
1664   }else{
1665     /* Make sure no sibling connections hold locks that will block this
1666     ** lock.  If any do, return SQLITE_BUSY right away.
1667     */
1668     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
1669       if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
1670         rc = SQLITE_BUSY;
1671         break;
1672       }
1673     }
1674 
1675     /* Get the exclusive locks at the system level.  Then if successful
1676     ** also mark the local connection as being locked.
1677     */
1678     if( rc==SQLITE_OK ){
1679       rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
1680       if( rc==SQLITE_OK ){
1681         assert( (p->sharedMask & mask)==0 );
1682         p->exclMask |= mask;
1683       }
1684     }
1685   }
1686   sqlite3_mutex_leave(pShmNode->mutex);
1687   OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
1688            p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
1689            rc ? "failed" : "ok"));
1690   return rc;
1691 }
1692 
1693 /*
1694 ** Implement a memory barrier or memory fence on shared memory.
1695 **
1696 ** All loads and stores begun before the barrier must complete before
1697 ** any load or store begun after the barrier.
1698 */
winShmBarrier(sqlite3_file * fd)1699 static void winShmBarrier(
1700   sqlite3_file *fd          /* Database holding the shared memory */
1701 ){
1702   UNUSED_PARAMETER(fd);
1703   /* MemoryBarrier(); // does not work -- do not know why not */
1704   winShmEnterMutex();
1705   winShmLeaveMutex();
1706 }
1707 
1708 /*
1709 ** This function is called to obtain a pointer to region iRegion of the
1710 ** shared-memory associated with the database file fd. Shared-memory regions
1711 ** are numbered starting from zero. Each shared-memory region is szRegion
1712 ** bytes in size.
1713 **
1714 ** If an error occurs, an error code is returned and *pp is set to NULL.
1715 **
1716 ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
1717 ** region has not been allocated (by any client, including one running in a
1718 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If
1719 ** isWrite is non-zero and the requested shared-memory region has not yet
1720 ** been allocated, it is allocated by this function.
1721 **
1722 ** If the shared-memory region has already been allocated or is allocated by
1723 ** this call as described above, then it is mapped into this processes
1724 ** address space (if it is not already), *pp is set to point to the mapped
1725 ** memory and SQLITE_OK returned.
1726 */
winShmMap(sqlite3_file * fd,int iRegion,int szRegion,int isWrite,void volatile ** pp)1727 static int winShmMap(
1728   sqlite3_file *fd,               /* Handle open on database file */
1729   int iRegion,                    /* Region to retrieve */
1730   int szRegion,                   /* Size of regions */
1731   int isWrite,                    /* True to extend file if necessary */
1732   void volatile **pp              /* OUT: Mapped memory */
1733 ){
1734   winFile *pDbFd = (winFile*)fd;
1735   winShm *p = pDbFd->pShm;
1736   winShmNode *pShmNode;
1737   int rc = SQLITE_OK;
1738 
1739   if( !p ){
1740     rc = winOpenSharedMemory(pDbFd);
1741     if( rc!=SQLITE_OK ) return rc;
1742     p = pDbFd->pShm;
1743   }
1744   pShmNode = p->pShmNode;
1745 
1746   sqlite3_mutex_enter(pShmNode->mutex);
1747   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
1748 
1749   if( pShmNode->nRegion<=iRegion ){
1750     struct ShmRegion *apNew;           /* New aRegion[] array */
1751     int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
1752     sqlite3_int64 sz;                  /* Current size of wal-index file */
1753 
1754     pShmNode->szRegion = szRegion;
1755 
1756     /* The requested region is not mapped into this processes address space.
1757     ** Check to see if it has been allocated (i.e. if the wal-index file is
1758     ** large enough to contain the requested region).
1759     */
1760     rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
1761     if( rc!=SQLITE_OK ){
1762       rc = SQLITE_IOERR_SHMSIZE;
1763       goto shmpage_out;
1764     }
1765 
1766     if( sz<nByte ){
1767       /* The requested memory region does not exist. If isWrite is set to
1768       ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
1769       **
1770       ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
1771       ** the requested memory region.
1772       */
1773       if( !isWrite ) goto shmpage_out;
1774       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
1775       if( rc!=SQLITE_OK ){
1776         rc = SQLITE_IOERR_SHMSIZE;
1777         goto shmpage_out;
1778       }
1779     }
1780 
1781     /* Map the requested memory region into this processes address space. */
1782     apNew = (struct ShmRegion *)sqlite3_realloc(
1783         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
1784     );
1785     if( !apNew ){
1786       rc = SQLITE_IOERR_NOMEM;
1787       goto shmpage_out;
1788     }
1789     pShmNode->aRegion = apNew;
1790 
1791     while( pShmNode->nRegion<=iRegion ){
1792       HANDLE hMap;                /* file-mapping handle */
1793       void *pMap = 0;             /* Mapped memory region */
1794 
1795       hMap = CreateFileMapping(pShmNode->hFile.h,
1796           NULL, PAGE_READWRITE, 0, nByte, NULL
1797       );
1798       OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
1799                (int)GetCurrentProcessId(), pShmNode->nRegion, nByte,
1800                hMap ? "ok" : "failed"));
1801       if( hMap ){
1802         int iOffset = pShmNode->nRegion*szRegion;
1803         int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
1804         pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
1805             0, iOffset - iOffsetShift, szRegion + iOffsetShift
1806         );
1807         OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
1808                  (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
1809                  pMap ? "ok" : "failed"));
1810       }
1811       if( !pMap ){
1812         pShmNode->lastErrno = GetLastError();
1813         rc = SQLITE_IOERR;
1814         if( hMap ) CloseHandle(hMap);
1815         goto shmpage_out;
1816       }
1817 
1818       pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
1819       pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
1820       pShmNode->nRegion++;
1821     }
1822   }
1823 
1824 shmpage_out:
1825   if( pShmNode->nRegion>iRegion ){
1826     int iOffset = iRegion*szRegion;
1827     int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
1828     char *p = (char *)pShmNode->aRegion[iRegion].pMap;
1829     *pp = (void *)&p[iOffsetShift];
1830   }else{
1831     *pp = 0;
1832   }
1833   sqlite3_mutex_leave(pShmNode->mutex);
1834   return rc;
1835 }
1836 
1837 #else
1838 # define winShmMap     0
1839 # define winShmLock    0
1840 # define winShmBarrier 0
1841 # define winShmUnmap   0
1842 #endif /* #ifndef SQLITE_OMIT_WAL */
1843 
1844 /*
1845 ** Here ends the implementation of all sqlite3_file methods.
1846 **
1847 ********************** End sqlite3_file Methods *******************************
1848 ******************************************************************************/
1849 
1850 /*
1851 ** This vector defines all the methods that can operate on an
1852 ** sqlite3_file for win32.
1853 */
1854 static const sqlite3_io_methods winIoMethod = {
1855   2,                              /* iVersion */
1856   winClose,                       /* xClose */
1857   winRead,                        /* xRead */
1858   winWrite,                       /* xWrite */
1859   winTruncate,                    /* xTruncate */
1860   winSync,                        /* xSync */
1861   winFileSize,                    /* xFileSize */
1862   winLock,                        /* xLock */
1863   winUnlock,                      /* xUnlock */
1864   winCheckReservedLock,           /* xCheckReservedLock */
1865   winFileControl,                 /* xFileControl */
1866   winSectorSize,                  /* xSectorSize */
1867   winDeviceCharacteristics,       /* xDeviceCharacteristics */
1868   winShmMap,                      /* xShmMap */
1869   winShmLock,                     /* xShmLock */
1870   winShmBarrier,                  /* xShmBarrier */
1871   winShmUnmap                     /* xShmUnmap */
1872 };
1873 
1874 /****************************************************************************
1875 **************************** sqlite3_vfs methods ****************************
1876 **
1877 ** This division contains the implementation of methods on the
1878 ** sqlite3_vfs object.
1879 */
1880 
1881 /*
1882 ** Convert a UTF-8 filename into whatever form the underlying
1883 ** operating system wants filenames in.  Space to hold the result
1884 ** is obtained from malloc and must be freed by the calling
1885 ** function.
1886 */
convertUtf8Filename(const char * zFilename)1887 static void *convertUtf8Filename(const char *zFilename){
1888   void *zConverted = 0;
1889   if( isNT() ){
1890     zConverted = utf8ToUnicode(zFilename);
1891 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1892 */
1893 #if SQLITE_OS_WINCE==0
1894   }else{
1895     zConverted = utf8ToMbcs(zFilename);
1896 #endif
1897   }
1898   /* caller will handle out of memory */
1899   return zConverted;
1900 }
1901 
1902 /*
1903 ** Create a temporary file name in zBuf.  zBuf must be big enough to
1904 ** hold at pVfs->mxPathname characters.
1905 */
getTempname(int nBuf,char * zBuf)1906 static int getTempname(int nBuf, char *zBuf){
1907   static char zChars[] =
1908     "abcdefghijklmnopqrstuvwxyz"
1909     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1910     "0123456789";
1911   size_t i, j;
1912   char zTempPath[MAX_PATH+1];
1913 
1914   /* It's odd to simulate an io-error here, but really this is just
1915   ** using the io-error infrastructure to test that SQLite handles this
1916   ** function failing.
1917   */
1918   SimulateIOError( return SQLITE_IOERR );
1919 
1920   if( sqlite3_temp_directory ){
1921     sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1922   }else if( isNT() ){
1923     char *zMulti;
1924     WCHAR zWidePath[MAX_PATH];
1925     GetTempPathW(MAX_PATH-30, zWidePath);
1926     zMulti = unicodeToUtf8(zWidePath);
1927     if( zMulti ){
1928       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1929       free(zMulti);
1930     }else{
1931       return SQLITE_NOMEM;
1932     }
1933 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1934 ** Since the ASCII version of these Windows API do not exist for WINCE,
1935 ** it's important to not reference them for WINCE builds.
1936 */
1937 #if SQLITE_OS_WINCE==0
1938   }else{
1939     char *zUtf8;
1940     char zMbcsPath[MAX_PATH];
1941     GetTempPathA(MAX_PATH-30, zMbcsPath);
1942     zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
1943     if( zUtf8 ){
1944       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1945       free(zUtf8);
1946     }else{
1947       return SQLITE_NOMEM;
1948     }
1949 #endif
1950   }
1951 
1952   /* Check that the output buffer is large enough for the temporary file
1953   ** name. If it is not, return SQLITE_ERROR.
1954   */
1955   if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
1956     return SQLITE_ERROR;
1957   }
1958 
1959   for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
1960   zTempPath[i] = 0;
1961 
1962   sqlite3_snprintf(nBuf-17, zBuf,
1963                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
1964   j = sqlite3Strlen30(zBuf);
1965   sqlite3_randomness(15, &zBuf[j]);
1966   for(i=0; i<15; i++, j++){
1967     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1968   }
1969   zBuf[j] = 0;
1970 
1971   OSTRACE(("TEMP FILENAME: %s\n", zBuf));
1972   return SQLITE_OK;
1973 }
1974 
1975 /*
1976 ** The return value of getLastErrorMsg
1977 ** is zero if the error message fits in the buffer, or non-zero
1978 ** otherwise (if the message was truncated).
1979 */
getLastErrorMsg(int nBuf,char * zBuf)1980 static int getLastErrorMsg(int nBuf, char *zBuf){
1981   /* FormatMessage returns 0 on failure.  Otherwise it
1982   ** returns the number of TCHARs written to the output
1983   ** buffer, excluding the terminating null char.
1984   */
1985   DWORD error = GetLastError();
1986   DWORD dwLen = 0;
1987   char *zOut = 0;
1988 
1989   if( isNT() ){
1990     WCHAR *zTempWide = NULL;
1991     dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1992                            NULL,
1993                            error,
1994                            0,
1995                            (LPWSTR) &zTempWide,
1996                            0,
1997                            0);
1998     if( dwLen > 0 ){
1999       /* allocate a buffer and convert to UTF8 */
2000       zOut = unicodeToUtf8(zTempWide);
2001       /* free the system buffer allocated by FormatMessage */
2002       LocalFree(zTempWide);
2003     }
2004 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2005 ** Since the ASCII version of these Windows API do not exist for WINCE,
2006 ** it's important to not reference them for WINCE builds.
2007 */
2008 #if SQLITE_OS_WINCE==0
2009   }else{
2010     char *zTemp = NULL;
2011     dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
2012                            NULL,
2013                            error,
2014                            0,
2015                            (LPSTR) &zTemp,
2016                            0,
2017                            0);
2018     if( dwLen > 0 ){
2019       /* allocate a buffer and convert to UTF8 */
2020       zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
2021       /* free the system buffer allocated by FormatMessage */
2022       LocalFree(zTemp);
2023     }
2024 #endif
2025   }
2026   if( 0 == dwLen ){
2027     sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
2028   }else{
2029     /* copy a maximum of nBuf chars to output buffer */
2030     sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
2031     /* free the UTF8 buffer */
2032     free(zOut);
2033   }
2034   return 0;
2035 }
2036 
2037 /*
2038 ** Open a file.
2039 */
winOpen(sqlite3_vfs * pVfs,const char * zName,sqlite3_file * id,int flags,int * pOutFlags)2040 static int winOpen(
2041   sqlite3_vfs *pVfs,        /* Not used */
2042   const char *zName,        /* Name of the file (UTF-8) */
2043   sqlite3_file *id,         /* Write the SQLite file handle here */
2044   int flags,                /* Open mode flags */
2045   int *pOutFlags            /* Status return flags */
2046 ){
2047   HANDLE h;
2048   DWORD dwDesiredAccess;
2049   DWORD dwShareMode;
2050   DWORD dwCreationDisposition;
2051   DWORD dwFlagsAndAttributes = 0;
2052 #if SQLITE_OS_WINCE
2053   int isTemp = 0;
2054 #endif
2055   winFile *pFile = (winFile*)id;
2056   void *zConverted;              /* Filename in OS encoding */
2057   const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
2058 
2059   /* If argument zPath is a NULL pointer, this function is required to open
2060   ** a temporary file. Use this buffer to store the file name in.
2061   */
2062   char zTmpname[MAX_PATH+1];     /* Buffer used to create temp filename */
2063 
2064   int rc = SQLITE_OK;            /* Function Return Code */
2065 #if !defined(NDEBUG) || SQLITE_OS_WINCE
2066   int eType = flags&0xFFFFFF00;  /* Type of file to open */
2067 #endif
2068 
2069   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
2070   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
2071   int isCreate     = (flags & SQLITE_OPEN_CREATE);
2072 #ifndef NDEBUG
2073   int isReadonly   = (flags & SQLITE_OPEN_READONLY);
2074 #endif
2075   int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
2076 
2077 #ifndef NDEBUG
2078   int isOpenJournal = (isCreate && (
2079         eType==SQLITE_OPEN_MASTER_JOURNAL
2080      || eType==SQLITE_OPEN_MAIN_JOURNAL
2081      || eType==SQLITE_OPEN_WAL
2082   ));
2083 #endif
2084 
2085   /* Check the following statements are true:
2086   **
2087   **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
2088   **   (b) if CREATE is set, then READWRITE must also be set, and
2089   **   (c) if EXCLUSIVE is set, then CREATE must also be set.
2090   **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
2091   */
2092   assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
2093   assert(isCreate==0 || isReadWrite);
2094   assert(isExclusive==0 || isCreate);
2095   assert(isDelete==0 || isCreate);
2096 
2097   /* The main DB, main journal, WAL file and master journal are never
2098   ** automatically deleted. Nor are they ever temporary files.  */
2099   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
2100   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
2101   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
2102   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
2103 
2104   /* Assert that the upper layer has set one of the "file-type" flags. */
2105   assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
2106        || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
2107        || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
2108        || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
2109   );
2110 
2111   assert( id!=0 );
2112   UNUSED_PARAMETER(pVfs);
2113 
2114   pFile->h = INVALID_HANDLE_VALUE;
2115 
2116   /* If the second argument to this function is NULL, generate a
2117   ** temporary file name to use
2118   */
2119   if( !zUtf8Name ){
2120     assert(isDelete && !isOpenJournal);
2121     rc = getTempname(MAX_PATH+1, zTmpname);
2122     if( rc!=SQLITE_OK ){
2123       return rc;
2124     }
2125     zUtf8Name = zTmpname;
2126   }
2127 
2128   /* Convert the filename to the system encoding. */
2129   zConverted = convertUtf8Filename(zUtf8Name);
2130   if( zConverted==0 ){
2131     return SQLITE_NOMEM;
2132   }
2133 
2134   if( isReadWrite ){
2135     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
2136   }else{
2137     dwDesiredAccess = GENERIC_READ;
2138   }
2139 
2140   /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
2141   ** created. SQLite doesn't use it to indicate "exclusive access"
2142   ** as it is usually understood.
2143   */
2144   if( isExclusive ){
2145     /* Creates a new file, only if it does not already exist. */
2146     /* If the file exists, it fails. */
2147     dwCreationDisposition = CREATE_NEW;
2148   }else if( isCreate ){
2149     /* Open existing file, or create if it doesn't exist */
2150     dwCreationDisposition = OPEN_ALWAYS;
2151   }else{
2152     /* Opens a file, only if it exists. */
2153     dwCreationDisposition = OPEN_EXISTING;
2154   }
2155 
2156   dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
2157 
2158   if( isDelete ){
2159 #if SQLITE_OS_WINCE
2160     dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
2161     isTemp = 1;
2162 #else
2163     dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
2164                                | FILE_ATTRIBUTE_HIDDEN
2165                                | FILE_FLAG_DELETE_ON_CLOSE;
2166 #endif
2167   }else{
2168     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
2169   }
2170   /* Reports from the internet are that performance is always
2171   ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
2172 #if SQLITE_OS_WINCE
2173   dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
2174 #endif
2175 
2176   if( isNT() ){
2177     h = CreateFileW((WCHAR*)zConverted,
2178        dwDesiredAccess,
2179        dwShareMode,
2180        NULL,
2181        dwCreationDisposition,
2182        dwFlagsAndAttributes,
2183        NULL
2184     );
2185 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2186 ** Since the ASCII version of these Windows API do not exist for WINCE,
2187 ** it's important to not reference them for WINCE builds.
2188 */
2189 #if SQLITE_OS_WINCE==0
2190   }else{
2191     h = CreateFileA((char*)zConverted,
2192        dwDesiredAccess,
2193        dwShareMode,
2194        NULL,
2195        dwCreationDisposition,
2196        dwFlagsAndAttributes,
2197        NULL
2198     );
2199 #endif
2200   }
2201 
2202   OSTRACE(("OPEN %d %s 0x%lx %s\n",
2203            h, zName, dwDesiredAccess,
2204            h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
2205 
2206   if( h==INVALID_HANDLE_VALUE ){
2207     pFile->lastErrno = GetLastError();
2208     free(zConverted);
2209     if( isReadWrite ){
2210       return winOpen(pVfs, zName, id,
2211              ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
2212     }else{
2213       return SQLITE_CANTOPEN_BKPT;
2214     }
2215   }
2216 
2217   if( pOutFlags ){
2218     if( isReadWrite ){
2219       *pOutFlags = SQLITE_OPEN_READWRITE;
2220     }else{
2221       *pOutFlags = SQLITE_OPEN_READONLY;
2222     }
2223   }
2224 
2225   memset(pFile, 0, sizeof(*pFile));
2226   pFile->pMethod = &winIoMethod;
2227   pFile->h = h;
2228   pFile->lastErrno = NO_ERROR;
2229   pFile->pVfs = pVfs;
2230   pFile->pShm = 0;
2231   pFile->zPath = zName;
2232   pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
2233 
2234 #if SQLITE_OS_WINCE
2235   if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
2236        && !winceCreateLock(zName, pFile)
2237   ){
2238     CloseHandle(h);
2239     free(zConverted);
2240     return SQLITE_CANTOPEN_BKPT;
2241   }
2242   if( isTemp ){
2243     pFile->zDeleteOnClose = zConverted;
2244   }else
2245 #endif
2246   {
2247     free(zConverted);
2248   }
2249 
2250   OpenCounter(+1);
2251   return rc;
2252 }
2253 
2254 /*
2255 ** Delete the named file.
2256 **
2257 ** Note that windows does not allow a file to be deleted if some other
2258 ** process has it open.  Sometimes a virus scanner or indexing program
2259 ** will open a journal file shortly after it is created in order to do
2260 ** whatever it does.  While this other process is holding the
2261 ** file open, we will be unable to delete it.  To work around this
2262 ** problem, we delay 100 milliseconds and try to delete again.  Up
2263 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
2264 ** up and returning an error.
2265 */
2266 #define MX_DELETION_ATTEMPTS 5
winDelete(sqlite3_vfs * pVfs,const char * zFilename,int syncDir)2267 static int winDelete(
2268   sqlite3_vfs *pVfs,          /* Not used on win32 */
2269   const char *zFilename,      /* Name of file to delete */
2270   int syncDir                 /* Not used on win32 */
2271 ){
2272   int cnt = 0;
2273   DWORD rc;
2274   DWORD error = 0;
2275   void *zConverted;
2276   UNUSED_PARAMETER(pVfs);
2277   UNUSED_PARAMETER(syncDir);
2278 
2279   SimulateIOError(return SQLITE_IOERR_DELETE);
2280   zConverted = convertUtf8Filename(zFilename);
2281   if( zConverted==0 ){
2282     return SQLITE_NOMEM;
2283   }
2284   if( isNT() ){
2285     do{
2286       DeleteFileW(zConverted);
2287     }while(   (   ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
2288                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
2289            && (++cnt < MX_DELETION_ATTEMPTS)
2290            && (Sleep(100), 1) );
2291 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2292 ** Since the ASCII version of these Windows API do not exist for WINCE,
2293 ** it's important to not reference them for WINCE builds.
2294 */
2295 #if SQLITE_OS_WINCE==0
2296   }else{
2297     do{
2298       DeleteFileA(zConverted);
2299     }while(   (   ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
2300                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
2301            && (++cnt < MX_DELETION_ATTEMPTS)
2302            && (Sleep(100), 1) );
2303 #endif
2304   }
2305   free(zConverted);
2306   OSTRACE(("DELETE \"%s\" %s\n", zFilename,
2307        ( (rc==INVALID_FILE_ATTRIBUTES) && (error==ERROR_FILE_NOT_FOUND)) ?
2308          "ok" : "failed" ));
2309 
2310   return (   (rc == INVALID_FILE_ATTRIBUTES)
2311           && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
2312 }
2313 
2314 /*
2315 ** Check the existance and status of a file.
2316 */
winAccess(sqlite3_vfs * pVfs,const char * zFilename,int flags,int * pResOut)2317 static int winAccess(
2318   sqlite3_vfs *pVfs,         /* Not used on win32 */
2319   const char *zFilename,     /* Name of file to check */
2320   int flags,                 /* Type of test to make on this file */
2321   int *pResOut               /* OUT: Result */
2322 ){
2323   DWORD attr;
2324   int rc = 0;
2325   void *zConverted;
2326   UNUSED_PARAMETER(pVfs);
2327 
2328   SimulateIOError( return SQLITE_IOERR_ACCESS; );
2329   zConverted = convertUtf8Filename(zFilename);
2330   if( zConverted==0 ){
2331     return SQLITE_NOMEM;
2332   }
2333   if( isNT() ){
2334     WIN32_FILE_ATTRIBUTE_DATA sAttrData;
2335     memset(&sAttrData, 0, sizeof(sAttrData));
2336     if( GetFileAttributesExW((WCHAR*)zConverted,
2337                              GetFileExInfoStandard,
2338                              &sAttrData) ){
2339       /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
2340       ** as if it does not exist.
2341       */
2342       if(    flags==SQLITE_ACCESS_EXISTS
2343           && sAttrData.nFileSizeHigh==0
2344           && sAttrData.nFileSizeLow==0 ){
2345         attr = INVALID_FILE_ATTRIBUTES;
2346       }else{
2347         attr = sAttrData.dwFileAttributes;
2348       }
2349     }else{
2350       if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
2351         free(zConverted);
2352         return SQLITE_IOERR_ACCESS;
2353       }else{
2354         attr = INVALID_FILE_ATTRIBUTES;
2355       }
2356     }
2357 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2358 ** Since the ASCII version of these Windows API do not exist for WINCE,
2359 ** it's important to not reference them for WINCE builds.
2360 */
2361 #if SQLITE_OS_WINCE==0
2362   }else{
2363     attr = GetFileAttributesA((char*)zConverted);
2364 #endif
2365   }
2366   free(zConverted);
2367   switch( flags ){
2368     case SQLITE_ACCESS_READ:
2369     case SQLITE_ACCESS_EXISTS:
2370       rc = attr!=INVALID_FILE_ATTRIBUTES;
2371       break;
2372     case SQLITE_ACCESS_READWRITE:
2373       rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
2374       break;
2375     default:
2376       assert(!"Invalid flags argument");
2377   }
2378   *pResOut = rc;
2379   return SQLITE_OK;
2380 }
2381 
2382 
2383 /*
2384 ** Turn a relative pathname into a full pathname.  Write the full
2385 ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
2386 ** bytes in size.
2387 */
winFullPathname(sqlite3_vfs * pVfs,const char * zRelative,int nFull,char * zFull)2388 static int winFullPathname(
2389   sqlite3_vfs *pVfs,            /* Pointer to vfs object */
2390   const char *zRelative,        /* Possibly relative input path */
2391   int nFull,                    /* Size of output buffer in bytes */
2392   char *zFull                   /* Output buffer */
2393 ){
2394 
2395 #if defined(__CYGWIN__)
2396   SimulateIOError( return SQLITE_ERROR );
2397   UNUSED_PARAMETER(nFull);
2398   cygwin_conv_to_full_win32_path(zRelative, zFull);
2399   return SQLITE_OK;
2400 #endif
2401 
2402 #if SQLITE_OS_WINCE
2403   SimulateIOError( return SQLITE_ERROR );
2404   UNUSED_PARAMETER(nFull);
2405   /* WinCE has no concept of a relative pathname, or so I am told. */
2406   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
2407   return SQLITE_OK;
2408 #endif
2409 
2410 #if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
2411   int nByte;
2412   void *zConverted;
2413   char *zOut;
2414 
2415   /* It's odd to simulate an io-error here, but really this is just
2416   ** using the io-error infrastructure to test that SQLite handles this
2417   ** function failing. This function could fail if, for example, the
2418   ** current working directory has been unlinked.
2419   */
2420   SimulateIOError( return SQLITE_ERROR );
2421   UNUSED_PARAMETER(nFull);
2422   zConverted = convertUtf8Filename(zRelative);
2423   if( isNT() ){
2424     WCHAR *zTemp;
2425     nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
2426     zTemp = malloc( nByte*sizeof(zTemp[0]) );
2427     if( zTemp==0 ){
2428       free(zConverted);
2429       return SQLITE_NOMEM;
2430     }
2431     GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
2432     free(zConverted);
2433     zOut = unicodeToUtf8(zTemp);
2434     free(zTemp);
2435 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2436 ** Since the ASCII version of these Windows API do not exist for WINCE,
2437 ** it's important to not reference them for WINCE builds.
2438 */
2439 #if SQLITE_OS_WINCE==0
2440   }else{
2441     char *zTemp;
2442     nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
2443     zTemp = malloc( nByte*sizeof(zTemp[0]) );
2444     if( zTemp==0 ){
2445       free(zConverted);
2446       return SQLITE_NOMEM;
2447     }
2448     GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
2449     free(zConverted);
2450     zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
2451     free(zTemp);
2452 #endif
2453   }
2454   if( zOut ){
2455     sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
2456     free(zOut);
2457     return SQLITE_OK;
2458   }else{
2459     return SQLITE_NOMEM;
2460   }
2461 #endif
2462 }
2463 
2464 /*
2465 ** Get the sector size of the device used to store
2466 ** file.
2467 */
getSectorSize(sqlite3_vfs * pVfs,const char * zRelative)2468 static int getSectorSize(
2469     sqlite3_vfs *pVfs,
2470     const char *zRelative     /* UTF-8 file name */
2471 ){
2472   DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
2473   /* GetDiskFreeSpace is not supported under WINCE */
2474 #if SQLITE_OS_WINCE
2475   UNUSED_PARAMETER(pVfs);
2476   UNUSED_PARAMETER(zRelative);
2477 #else
2478   char zFullpath[MAX_PATH+1];
2479   int rc;
2480   DWORD dwRet = 0;
2481   DWORD dwDummy;
2482 
2483   /*
2484   ** We need to get the full path name of the file
2485   ** to get the drive letter to look up the sector
2486   ** size.
2487   */
2488   SimulateIOErrorBenign(1);
2489   rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
2490   SimulateIOErrorBenign(0);
2491   if( rc == SQLITE_OK )
2492   {
2493     void *zConverted = convertUtf8Filename(zFullpath);
2494     if( zConverted ){
2495       if( isNT() ){
2496         /* trim path to just drive reference */
2497         WCHAR *p = zConverted;
2498         for(;*p;p++){
2499           if( *p == '\\' ){
2500             *p = '\0';
2501             break;
2502           }
2503         }
2504         dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
2505                                   &dwDummy,
2506                                   &bytesPerSector,
2507                                   &dwDummy,
2508                                   &dwDummy);
2509       }else{
2510         /* trim path to just drive reference */
2511         char *p = (char *)zConverted;
2512         for(;*p;p++){
2513           if( *p == '\\' ){
2514             *p = '\0';
2515             break;
2516           }
2517         }
2518         dwRet = GetDiskFreeSpaceA((char*)zConverted,
2519                                   &dwDummy,
2520                                   &bytesPerSector,
2521                                   &dwDummy,
2522                                   &dwDummy);
2523       }
2524       free(zConverted);
2525     }
2526     if( !dwRet ){
2527       bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
2528     }
2529   }
2530 #endif
2531   return (int) bytesPerSector;
2532 }
2533 
2534 #ifndef SQLITE_OMIT_LOAD_EXTENSION
2535 /*
2536 ** Interfaces for opening a shared library, finding entry points
2537 ** within the shared library, and closing the shared library.
2538 */
2539 /*
2540 ** Interfaces for opening a shared library, finding entry points
2541 ** within the shared library, and closing the shared library.
2542 */
winDlOpen(sqlite3_vfs * pVfs,const char * zFilename)2543 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
2544   HANDLE h;
2545   void *zConverted = convertUtf8Filename(zFilename);
2546   UNUSED_PARAMETER(pVfs);
2547   if( zConverted==0 ){
2548     return 0;
2549   }
2550   if( isNT() ){
2551     h = LoadLibraryW((WCHAR*)zConverted);
2552 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2553 ** Since the ASCII version of these Windows API do not exist for WINCE,
2554 ** it's important to not reference them for WINCE builds.
2555 */
2556 #if SQLITE_OS_WINCE==0
2557   }else{
2558     h = LoadLibraryA((char*)zConverted);
2559 #endif
2560   }
2561   free(zConverted);
2562   return (void*)h;
2563 }
winDlError(sqlite3_vfs * pVfs,int nBuf,char * zBufOut)2564 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
2565   UNUSED_PARAMETER(pVfs);
2566   getLastErrorMsg(nBuf, zBufOut);
2567 }
winDlSym(sqlite3_vfs * pVfs,void * pHandle,const char * zSymbol)2568 void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
2569   UNUSED_PARAMETER(pVfs);
2570 #if SQLITE_OS_WINCE
2571   /* The GetProcAddressA() routine is only available on wince. */
2572   return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
2573 #else
2574   /* All other windows platforms expect GetProcAddress() to take
2575   ** an Ansi string regardless of the _UNICODE setting */
2576   return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
2577 #endif
2578 }
winDlClose(sqlite3_vfs * pVfs,void * pHandle)2579 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
2580   UNUSED_PARAMETER(pVfs);
2581   FreeLibrary((HANDLE)pHandle);
2582 }
2583 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
2584   #define winDlOpen  0
2585   #define winDlError 0
2586   #define winDlSym   0
2587   #define winDlClose 0
2588 #endif
2589 
2590 
2591 /*
2592 ** Write up to nBuf bytes of randomness into zBuf.
2593 */
winRandomness(sqlite3_vfs * pVfs,int nBuf,char * zBuf)2594 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
2595   int n = 0;
2596   UNUSED_PARAMETER(pVfs);
2597 #if defined(SQLITE_TEST)
2598   n = nBuf;
2599   memset(zBuf, 0, nBuf);
2600 #else
2601   if( sizeof(SYSTEMTIME)<=nBuf-n ){
2602     SYSTEMTIME x;
2603     GetSystemTime(&x);
2604     memcpy(&zBuf[n], &x, sizeof(x));
2605     n += sizeof(x);
2606   }
2607   if( sizeof(DWORD)<=nBuf-n ){
2608     DWORD pid = GetCurrentProcessId();
2609     memcpy(&zBuf[n], &pid, sizeof(pid));
2610     n += sizeof(pid);
2611   }
2612   if( sizeof(DWORD)<=nBuf-n ){
2613     DWORD cnt = GetTickCount();
2614     memcpy(&zBuf[n], &cnt, sizeof(cnt));
2615     n += sizeof(cnt);
2616   }
2617   if( sizeof(LARGE_INTEGER)<=nBuf-n ){
2618     LARGE_INTEGER i;
2619     QueryPerformanceCounter(&i);
2620     memcpy(&zBuf[n], &i, sizeof(i));
2621     n += sizeof(i);
2622   }
2623 #endif
2624   return n;
2625 }
2626 
2627 
2628 /*
2629 ** Sleep for a little while.  Return the amount of time slept.
2630 */
winSleep(sqlite3_vfs * pVfs,int microsec)2631 static int winSleep(sqlite3_vfs *pVfs, int microsec){
2632   Sleep((microsec+999)/1000);
2633   UNUSED_PARAMETER(pVfs);
2634   return ((microsec+999)/1000)*1000;
2635 }
2636 
2637 /*
2638 ** The following variable, if set to a non-zero value, is interpreted as
2639 ** the number of seconds since 1970 and is used to set the result of
2640 ** sqlite3OsCurrentTime() during testing.
2641 */
2642 #ifdef SQLITE_TEST
2643 int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
2644 #endif
2645 
2646 /*
2647 ** Find the current time (in Universal Coordinated Time).  Write into *piNow
2648 ** the current time and date as a Julian Day number times 86_400_000.  In
2649 ** other words, write into *piNow the number of milliseconds since the Julian
2650 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
2651 ** proleptic Gregorian calendar.
2652 **
2653 ** On success, return 0.  Return 1 if the time and date cannot be found.
2654 */
winCurrentTimeInt64(sqlite3_vfs * pVfs,sqlite3_int64 * piNow)2655 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
2656   /* FILETIME structure is a 64-bit value representing the number of
2657      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
2658   */
2659   FILETIME ft;
2660   static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
2661 #ifdef SQLITE_TEST
2662   static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
2663 #endif
2664   /* 2^32 - to avoid use of LL and warnings in gcc */
2665   static const sqlite3_int64 max32BitValue =
2666       (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
2667 
2668 #if SQLITE_OS_WINCE
2669   SYSTEMTIME time;
2670   GetSystemTime(&time);
2671   /* if SystemTimeToFileTime() fails, it returns zero. */
2672   if (!SystemTimeToFileTime(&time,&ft)){
2673     return 1;
2674   }
2675 #else
2676   GetSystemTimeAsFileTime( &ft );
2677 #endif
2678 
2679   *piNow = winFiletimeEpoch +
2680             ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
2681                (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
2682 
2683 #ifdef SQLITE_TEST
2684   if( sqlite3_current_time ){
2685     *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
2686   }
2687 #endif
2688   UNUSED_PARAMETER(pVfs);
2689   return 0;
2690 }
2691 
2692 /*
2693 ** Find the current time (in Universal Coordinated Time).  Write the
2694 ** current time and date as a Julian Day number into *prNow and
2695 ** return 0.  Return 1 if the time and date cannot be found.
2696 */
winCurrentTime(sqlite3_vfs * pVfs,double * prNow)2697 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
2698   int rc;
2699   sqlite3_int64 i;
2700   rc = winCurrentTimeInt64(pVfs, &i);
2701   if( !rc ){
2702     *prNow = i/86400000.0;
2703   }
2704   return rc;
2705 }
2706 
2707 /*
2708 ** The idea is that this function works like a combination of
2709 ** GetLastError() and FormatMessage() on windows (or errno and
2710 ** strerror_r() on unix). After an error is returned by an OS
2711 ** function, SQLite calls this function with zBuf pointing to
2712 ** a buffer of nBuf bytes. The OS layer should populate the
2713 ** buffer with a nul-terminated UTF-8 encoded error message
2714 ** describing the last IO error to have occurred within the calling
2715 ** thread.
2716 **
2717 ** If the error message is too large for the supplied buffer,
2718 ** it should be truncated. The return value of xGetLastError
2719 ** is zero if the error message fits in the buffer, or non-zero
2720 ** otherwise (if the message was truncated). If non-zero is returned,
2721 ** then it is not necessary to include the nul-terminator character
2722 ** in the output buffer.
2723 **
2724 ** Not supplying an error message will have no adverse effect
2725 ** on SQLite. It is fine to have an implementation that never
2726 ** returns an error message:
2727 **
2728 **   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
2729 **     assert(zBuf[0]=='\0');
2730 **     return 0;
2731 **   }
2732 **
2733 ** However if an error message is supplied, it will be incorporated
2734 ** by sqlite into the error message available to the user using
2735 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
2736 */
winGetLastError(sqlite3_vfs * pVfs,int nBuf,char * zBuf)2737 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
2738   UNUSED_PARAMETER(pVfs);
2739   return getLastErrorMsg(nBuf, zBuf);
2740 }
2741 
2742 
2743 
2744 /*
2745 ** Initialize and deinitialize the operating system interface.
2746 */
sqlite3_os_init(void)2747 int sqlite3_os_init(void){
2748   static sqlite3_vfs winVfs = {
2749     3,                   /* iVersion */
2750     sizeof(winFile),     /* szOsFile */
2751     MAX_PATH,            /* mxPathname */
2752     0,                   /* pNext */
2753     "win32",             /* zName */
2754     0,                   /* pAppData */
2755     winOpen,             /* xOpen */
2756     winDelete,           /* xDelete */
2757     winAccess,           /* xAccess */
2758     winFullPathname,     /* xFullPathname */
2759     winDlOpen,           /* xDlOpen */
2760     winDlError,          /* xDlError */
2761     winDlSym,            /* xDlSym */
2762     winDlClose,          /* xDlClose */
2763     winRandomness,       /* xRandomness */
2764     winSleep,            /* xSleep */
2765     winCurrentTime,      /* xCurrentTime */
2766     winGetLastError,     /* xGetLastError */
2767     winCurrentTimeInt64, /* xCurrentTimeInt64 */
2768     0,                   /* xSetSystemCall */
2769     0,                   /* xGetSystemCall */
2770     0,                   /* xNextSystemCall */
2771   };
2772 
2773 #ifndef SQLITE_OMIT_WAL
2774   /* get memory map allocation granularity */
2775   memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
2776   GetSystemInfo(&winSysInfo);
2777   assert(winSysInfo.dwAllocationGranularity > 0);
2778 #endif
2779 
2780   sqlite3_vfs_register(&winVfs, 1);
2781   return SQLITE_OK;
2782 }
sqlite3_os_end(void)2783 int sqlite3_os_end(void){
2784   return SQLITE_OK;
2785 }
2786 
chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file * file,HANDLE handle)2787 void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) {
2788   winFile* winSQLite3File = (winFile*)file;
2789   memset(file, 0, sizeof(*file));
2790   winSQLite3File->pMethod = &winIoMethod;
2791   winSQLite3File->h = handle;
2792 }
2793 
2794 #endif /* SQLITE_OS_WIN */
2795