xref: /sqlite-3.40.0/src/os_win.c (revision dfe4e6bb)
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 ** Include code that is common to all os_*.c files
20 */
21 #include "os_common.h"
22 
23 /*
24 ** Include the header file for the Windows VFS.
25 */
26 #include "os_win.h"
27 
28 /*
29 ** Compiling and using WAL mode requires several APIs that are only
30 ** available in Windows platforms based on the NT kernel.
31 */
32 #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
33 #  error "WAL mode requires support from the Windows NT kernel, compile\
34  with SQLITE_OMIT_WAL."
35 #endif
36 
37 #if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
38 #  error "Memory mapped files require support from the Windows NT kernel,\
39  compile with SQLITE_MAX_MMAP_SIZE=0."
40 #endif
41 
42 /*
43 ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
44 ** based on the sub-platform)?
45 */
46 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
47 #  define SQLITE_WIN32_HAS_ANSI
48 #endif
49 
50 /*
51 ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
52 ** based on the sub-platform)?
53 */
54 #if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
55     !defined(SQLITE_WIN32_NO_WIDE)
56 #  define SQLITE_WIN32_HAS_WIDE
57 #endif
58 
59 /*
60 ** Make sure at least one set of Win32 APIs is available.
61 */
62 #if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
63 #  error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
64  must be defined."
65 #endif
66 
67 /*
68 ** Define the required Windows SDK version constants if they are not
69 ** already available.
70 */
71 #ifndef NTDDI_WIN8
72 #  define NTDDI_WIN8                        0x06020000
73 #endif
74 
75 #ifndef NTDDI_WINBLUE
76 #  define NTDDI_WINBLUE                     0x06030000
77 #endif
78 
79 #ifndef NTDDI_WINTHRESHOLD
80 #  define NTDDI_WINTHRESHOLD                0x06040000
81 #endif
82 
83 /*
84 ** Check to see if the GetVersionEx[AW] functions are deprecated on the
85 ** target system.  GetVersionEx was first deprecated in Win8.1.
86 */
87 #ifndef SQLITE_WIN32_GETVERSIONEX
88 #  if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
89 #    define SQLITE_WIN32_GETVERSIONEX   0   /* GetVersionEx() is deprecated */
90 #  else
91 #    define SQLITE_WIN32_GETVERSIONEX   1   /* GetVersionEx() is current */
92 #  endif
93 #endif
94 
95 /*
96 ** Check to see if the CreateFileMappingA function is supported on the
97 ** target system.  It is unavailable when using "mincore.lib" on Win10.
98 ** When compiling for Windows 10, always assume "mincore.lib" is in use.
99 */
100 #ifndef SQLITE_WIN32_CREATEFILEMAPPINGA
101 #  if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD
102 #    define SQLITE_WIN32_CREATEFILEMAPPINGA   0
103 #  else
104 #    define SQLITE_WIN32_CREATEFILEMAPPINGA   1
105 #  endif
106 #endif
107 
108 /*
109 ** This constant should already be defined (in the "WinDef.h" SDK file).
110 */
111 #ifndef MAX_PATH
112 #  define MAX_PATH                      (260)
113 #endif
114 
115 /*
116 ** Maximum pathname length (in chars) for Win32.  This should normally be
117 ** MAX_PATH.
118 */
119 #ifndef SQLITE_WIN32_MAX_PATH_CHARS
120 #  define SQLITE_WIN32_MAX_PATH_CHARS   (MAX_PATH)
121 #endif
122 
123 /*
124 ** This constant should already be defined (in the "WinNT.h" SDK file).
125 */
126 #ifndef UNICODE_STRING_MAX_CHARS
127 #  define UNICODE_STRING_MAX_CHARS      (32767)
128 #endif
129 
130 /*
131 ** Maximum pathname length (in chars) for WinNT.  This should normally be
132 ** UNICODE_STRING_MAX_CHARS.
133 */
134 #ifndef SQLITE_WINNT_MAX_PATH_CHARS
135 #  define SQLITE_WINNT_MAX_PATH_CHARS   (UNICODE_STRING_MAX_CHARS)
136 #endif
137 
138 /*
139 ** Maximum pathname length (in bytes) for Win32.  The MAX_PATH macro is in
140 ** characters, so we allocate 4 bytes per character assuming worst-case of
141 ** 4-bytes-per-character for UTF8.
142 */
143 #ifndef SQLITE_WIN32_MAX_PATH_BYTES
144 #  define SQLITE_WIN32_MAX_PATH_BYTES   (SQLITE_WIN32_MAX_PATH_CHARS*4)
145 #endif
146 
147 /*
148 ** Maximum pathname length (in bytes) for WinNT.  This should normally be
149 ** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
150 */
151 #ifndef SQLITE_WINNT_MAX_PATH_BYTES
152 #  define SQLITE_WINNT_MAX_PATH_BYTES   \
153                             (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
154 #endif
155 
156 /*
157 ** Maximum error message length (in chars) for WinRT.
158 */
159 #ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS
160 #  define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024)
161 #endif
162 
163 /*
164 ** Returns non-zero if the character should be treated as a directory
165 ** separator.
166 */
167 #ifndef winIsDirSep
168 #  define winIsDirSep(a)                (((a) == '/') || ((a) == '\\'))
169 #endif
170 
171 /*
172 ** This macro is used when a local variable is set to a value that is
173 ** [sometimes] not used by the code (e.g. via conditional compilation).
174 */
175 #ifndef UNUSED_VARIABLE_VALUE
176 #  define UNUSED_VARIABLE_VALUE(x)      (void)(x)
177 #endif
178 
179 /*
180 ** Returns the character that should be used as the directory separator.
181 */
182 #ifndef winGetDirSep
183 #  define winGetDirSep()                '\\'
184 #endif
185 
186 /*
187 ** Do we need to manually define the Win32 file mapping APIs for use with WAL
188 ** mode or memory mapped files (e.g. these APIs are available in the Windows
189 ** CE SDK; however, they are not present in the header file)?
190 */
191 #if SQLITE_WIN32_FILEMAPPING_API && \
192         (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
193 /*
194 ** Two of the file mapping APIs are different under WinRT.  Figure out which
195 ** set we need.
196 */
197 #if SQLITE_OS_WINRT
198 WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
199         LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
200 
201 WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
202 #else
203 #if defined(SQLITE_WIN32_HAS_ANSI)
204 WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
205         DWORD, DWORD, DWORD, LPCSTR);
206 #endif /* defined(SQLITE_WIN32_HAS_ANSI) */
207 
208 #if defined(SQLITE_WIN32_HAS_WIDE)
209 WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
210         DWORD, DWORD, DWORD, LPCWSTR);
211 #endif /* defined(SQLITE_WIN32_HAS_WIDE) */
212 
213 WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
214 #endif /* SQLITE_OS_WINRT */
215 
216 /*
217 ** These file mapping APIs are common to both Win32 and WinRT.
218 */
219 
220 WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T);
221 WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
222 #endif /* SQLITE_WIN32_FILEMAPPING_API */
223 
224 /*
225 ** Some Microsoft compilers lack this definition.
226 */
227 #ifndef INVALID_FILE_ATTRIBUTES
228 # define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
229 #endif
230 
231 #ifndef FILE_FLAG_MASK
232 # define FILE_FLAG_MASK          (0xFF3C0000)
233 #endif
234 
235 #ifndef FILE_ATTRIBUTE_MASK
236 # define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
237 #endif
238 
239 #ifndef SQLITE_OMIT_WAL
240 /* Forward references to structures used for WAL */
241 typedef struct winShm winShm;           /* A connection to shared-memory */
242 typedef struct winShmNode winShmNode;   /* A region of shared-memory */
243 #endif
244 
245 /*
246 ** WinCE lacks native support for file locking so we have to fake it
247 ** with some code of our own.
248 */
249 #if SQLITE_OS_WINCE
250 typedef struct winceLock {
251   int nReaders;       /* Number of reader locks obtained */
252   BOOL bPending;      /* Indicates a pending lock has been obtained */
253   BOOL bReserved;     /* Indicates a reserved lock has been obtained */
254   BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
255 } winceLock;
256 #endif
257 
258 /*
259 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
260 ** portability layer.
261 */
262 typedef struct winFile winFile;
263 struct winFile {
264   const sqlite3_io_methods *pMethod; /*** Must be first ***/
265   sqlite3_vfs *pVfs;      /* The VFS used to open this file */
266   HANDLE h;               /* Handle for accessing the file */
267   u8 locktype;            /* Type of lock currently held on this file */
268   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
269   u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
270   DWORD lastErrno;        /* The Windows errno from the last I/O error */
271 #ifndef SQLITE_OMIT_WAL
272   winShm *pShm;           /* Instance of shared memory on this file */
273 #endif
274   const char *zPath;      /* Full pathname of this file */
275   int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
276 #if SQLITE_OS_WINCE
277   LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
278   HANDLE hMutex;          /* Mutex used to control access to shared lock */
279   HANDLE hShared;         /* Shared memory segment used for locking */
280   winceLock local;        /* Locks obtained by this instance of winFile */
281   winceLock *shared;      /* Global shared lock memory for the file  */
282 #endif
283 #if SQLITE_MAX_MMAP_SIZE>0
284   int nFetchOut;                /* Number of outstanding xFetch references */
285   HANDLE hMap;                  /* Handle for accessing memory mapping */
286   void *pMapRegion;             /* Area memory mapped */
287   sqlite3_int64 mmapSize;       /* Usable size of mapped region */
288   sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
289   sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
290 #endif
291 };
292 
293 /*
294 ** The winVfsAppData structure is used for the pAppData member for all of the
295 ** Win32 VFS variants.
296 */
297 typedef struct winVfsAppData winVfsAppData;
298 struct winVfsAppData {
299   const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
300   void *pAppData;                    /* The extra pAppData, if any. */
301   BOOL bNoLock;                      /* Non-zero if locking is disabled. */
302 };
303 
304 /*
305 ** Allowed values for winFile.ctrlFlags
306 */
307 #define WINFILE_RDONLY          0x02   /* Connection is read only */
308 #define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
309 #define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
310 
311 /*
312  * The size of the buffer used by sqlite3_win32_write_debug().
313  */
314 #ifndef SQLITE_WIN32_DBG_BUF_SIZE
315 #  define SQLITE_WIN32_DBG_BUF_SIZE   ((int)(4096-sizeof(DWORD)))
316 #endif
317 
318 /*
319  * The value used with sqlite3_win32_set_directory() to specify that
320  * the data directory should be changed.
321  */
322 #ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
323 #  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
324 #endif
325 
326 /*
327  * The value used with sqlite3_win32_set_directory() to specify that
328  * the temporary directory should be changed.
329  */
330 #ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
331 #  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
332 #endif
333 
334 /*
335  * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
336  * various Win32 API heap functions instead of our own.
337  */
338 #ifdef SQLITE_WIN32_MALLOC
339 
340 /*
341  * If this is non-zero, an isolated heap will be created by the native Win32
342  * allocator subsystem; otherwise, the default process heap will be used.  This
343  * setting has no effect when compiling for WinRT.  By default, this is enabled
344  * and an isolated heap will be created to store all allocated data.
345  *
346  ******************************************************************************
347  * WARNING: It is important to note that when this setting is non-zero and the
348  *          winMemShutdown function is called (e.g. by the sqlite3_shutdown
349  *          function), all data that was allocated using the isolated heap will
350  *          be freed immediately and any attempt to access any of that freed
351  *          data will almost certainly result in an immediate access violation.
352  ******************************************************************************
353  */
354 #ifndef SQLITE_WIN32_HEAP_CREATE
355 #  define SQLITE_WIN32_HEAP_CREATE    (TRUE)
356 #endif
357 
358 /*
359  * This is cache size used in the calculation of the initial size of the
360  * Win32-specific heap.  It cannot be negative.
361  */
362 #ifndef SQLITE_WIN32_CACHE_SIZE
363 #  if SQLITE_DEFAULT_CACHE_SIZE>=0
364 #    define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
365 #  else
366 #    define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
367 #  endif
368 #endif
369 
370 /*
371  * The initial size of the Win32-specific heap.  This value may be zero.
372  */
373 #ifndef SQLITE_WIN32_HEAP_INIT_SIZE
374 #  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
375                                        (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
376 #endif
377 
378 /*
379  * The maximum size of the Win32-specific heap.  This value may be zero.
380  */
381 #ifndef SQLITE_WIN32_HEAP_MAX_SIZE
382 #  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
383 #endif
384 
385 /*
386  * The extra flags to use in calls to the Win32 heap APIs.  This value may be
387  * zero for the default behavior.
388  */
389 #ifndef SQLITE_WIN32_HEAP_FLAGS
390 #  define SQLITE_WIN32_HEAP_FLAGS     (0)
391 #endif
392 
393 
394 /*
395 ** The winMemData structure stores information required by the Win32-specific
396 ** sqlite3_mem_methods implementation.
397 */
398 typedef struct winMemData winMemData;
399 struct winMemData {
400 #ifndef NDEBUG
401   u32 magic1;   /* Magic number to detect structure corruption. */
402 #endif
403   HANDLE hHeap; /* The handle to our heap. */
404   BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
405 #ifndef NDEBUG
406   u32 magic2;   /* Magic number to detect structure corruption. */
407 #endif
408 };
409 
410 #ifndef NDEBUG
411 #define WINMEM_MAGIC1     0x42b2830b
412 #define WINMEM_MAGIC2     0xbd4d7cf4
413 #endif
414 
415 static struct winMemData win_mem_data = {
416 #ifndef NDEBUG
417   WINMEM_MAGIC1,
418 #endif
419   NULL, FALSE
420 #ifndef NDEBUG
421   ,WINMEM_MAGIC2
422 #endif
423 };
424 
425 #ifndef NDEBUG
426 #define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
427 #define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
428 #define winMemAssertMagic()  winMemAssertMagic1(); winMemAssertMagic2();
429 #else
430 #define winMemAssertMagic()
431 #endif
432 
433 #define winMemGetDataPtr()  &win_mem_data
434 #define winMemGetHeap()     win_mem_data.hHeap
435 #define winMemGetOwned()    win_mem_data.bOwned
436 
437 static void *winMemMalloc(int nBytes);
438 static void winMemFree(void *pPrior);
439 static void *winMemRealloc(void *pPrior, int nBytes);
440 static int winMemSize(void *p);
441 static int winMemRoundup(int n);
442 static int winMemInit(void *pAppData);
443 static void winMemShutdown(void *pAppData);
444 
445 const sqlite3_mem_methods *sqlite3MemGetWin32(void);
446 #endif /* SQLITE_WIN32_MALLOC */
447 
448 /*
449 ** The following variable is (normally) set once and never changes
450 ** thereafter.  It records whether the operating system is Win9x
451 ** or WinNT.
452 **
453 ** 0:   Operating system unknown.
454 ** 1:   Operating system is Win9x.
455 ** 2:   Operating system is WinNT.
456 **
457 ** In order to facilitate testing on a WinNT system, the test fixture
458 ** can manually set this value to 1 to emulate Win98 behavior.
459 */
460 #ifdef SQLITE_TEST
461 LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
462 #else
463 static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
464 #endif
465 
466 #ifndef SYSCALL
467 #  define SYSCALL sqlite3_syscall_ptr
468 #endif
469 
470 /*
471 ** This function is not available on Windows CE or WinRT.
472  */
473 
474 #if SQLITE_OS_WINCE || SQLITE_OS_WINRT
475 #  define osAreFileApisANSI()       1
476 #endif
477 
478 /*
479 ** Many system calls are accessed through pointer-to-functions so that
480 ** they may be overridden at runtime to facilitate fault injection during
481 ** testing and sandboxing.  The following array holds the names and pointers
482 ** to all overrideable system calls.
483 */
484 static struct win_syscall {
485   const char *zName;            /* Name of the system call */
486   sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
487   sqlite3_syscall_ptr pDefault; /* Default value */
488 } aSyscall[] = {
489 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
490   { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
491 #else
492   { "AreFileApisANSI",         (SYSCALL)0,                       0 },
493 #endif
494 
495 #ifndef osAreFileApisANSI
496 #define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
497 #endif
498 
499 #if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
500   { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
501 #else
502   { "CharLowerW",              (SYSCALL)0,                       0 },
503 #endif
504 
505 #define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
506 
507 #if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
508   { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
509 #else
510   { "CharUpperW",              (SYSCALL)0,                       0 },
511 #endif
512 
513 #define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
514 
515   { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
516 
517 #define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
518 
519 #if defined(SQLITE_WIN32_HAS_ANSI)
520   { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
521 #else
522   { "CreateFileA",             (SYSCALL)0,                       0 },
523 #endif
524 
525 #define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
526         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
527 
528 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
529   { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
530 #else
531   { "CreateFileW",             (SYSCALL)0,                       0 },
532 #endif
533 
534 #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
535         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
536 
537 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
538         (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \
539         SQLITE_WIN32_CREATEFILEMAPPINGA
540   { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
541 #else
542   { "CreateFileMappingA",      (SYSCALL)0,                       0 },
543 #endif
544 
545 #define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
546         DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
547 
548 #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
549         (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
550   { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
551 #else
552   { "CreateFileMappingW",      (SYSCALL)0,                       0 },
553 #endif
554 
555 #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
556         DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
557 
558 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
559   { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
560 #else
561   { "CreateMutexW",            (SYSCALL)0,                       0 },
562 #endif
563 
564 #define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
565         LPCWSTR))aSyscall[8].pCurrent)
566 
567 #if defined(SQLITE_WIN32_HAS_ANSI)
568   { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
569 #else
570   { "DeleteFileA",             (SYSCALL)0,                       0 },
571 #endif
572 
573 #define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
574 
575 #if defined(SQLITE_WIN32_HAS_WIDE)
576   { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
577 #else
578   { "DeleteFileW",             (SYSCALL)0,                       0 },
579 #endif
580 
581 #define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
582 
583 #if SQLITE_OS_WINCE
584   { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
585 #else
586   { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
587 #endif
588 
589 #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
590         LPFILETIME))aSyscall[11].pCurrent)
591 
592 #if SQLITE_OS_WINCE
593   { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
594 #else
595   { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
596 #endif
597 
598 #define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
599         LPSYSTEMTIME))aSyscall[12].pCurrent)
600 
601   { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
602 
603 #define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
604 
605 #if defined(SQLITE_WIN32_HAS_ANSI)
606   { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
607 #else
608   { "FormatMessageA",          (SYSCALL)0,                       0 },
609 #endif
610 
611 #define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
612         DWORD,va_list*))aSyscall[14].pCurrent)
613 
614 #if defined(SQLITE_WIN32_HAS_WIDE)
615   { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
616 #else
617   { "FormatMessageW",          (SYSCALL)0,                       0 },
618 #endif
619 
620 #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
621         DWORD,va_list*))aSyscall[15].pCurrent)
622 
623 #if !defined(SQLITE_OMIT_LOAD_EXTENSION)
624   { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
625 #else
626   { "FreeLibrary",             (SYSCALL)0,                       0 },
627 #endif
628 
629 #define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
630 
631   { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
632 
633 #define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
634 
635 #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
636   { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
637 #else
638   { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
639 #endif
640 
641 #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
642         LPDWORD))aSyscall[18].pCurrent)
643 
644 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
645   { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
646 #else
647   { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
648 #endif
649 
650 #define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
651         LPDWORD))aSyscall[19].pCurrent)
652 
653 #if defined(SQLITE_WIN32_HAS_ANSI)
654   { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
655 #else
656   { "GetFileAttributesA",      (SYSCALL)0,                       0 },
657 #endif
658 
659 #define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
660 
661 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
662   { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
663 #else
664   { "GetFileAttributesW",      (SYSCALL)0,                       0 },
665 #endif
666 
667 #define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
668 
669 #if defined(SQLITE_WIN32_HAS_WIDE)
670   { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
671 #else
672   { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
673 #endif
674 
675 #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
676         LPVOID))aSyscall[22].pCurrent)
677 
678 #if !SQLITE_OS_WINRT
679   { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
680 #else
681   { "GetFileSize",             (SYSCALL)0,                       0 },
682 #endif
683 
684 #define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
685 
686 #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
687   { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
688 #else
689   { "GetFullPathNameA",        (SYSCALL)0,                       0 },
690 #endif
691 
692 #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
693         LPSTR*))aSyscall[24].pCurrent)
694 
695 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
696   { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
697 #else
698   { "GetFullPathNameW",        (SYSCALL)0,                       0 },
699 #endif
700 
701 #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
702         LPWSTR*))aSyscall[25].pCurrent)
703 
704   { "GetLastError",            (SYSCALL)GetLastError,            0 },
705 
706 #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
707 
708 #if !defined(SQLITE_OMIT_LOAD_EXTENSION)
709 #if SQLITE_OS_WINCE
710   /* The GetProcAddressA() routine is only available on Windows CE. */
711   { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
712 #else
713   /* All other Windows platforms expect GetProcAddress() to take
714   ** an ANSI string regardless of the _UNICODE setting */
715   { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
716 #endif
717 #else
718   { "GetProcAddressA",         (SYSCALL)0,                       0 },
719 #endif
720 
721 #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
722         LPCSTR))aSyscall[27].pCurrent)
723 
724 #if !SQLITE_OS_WINRT
725   { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
726 #else
727   { "GetSystemInfo",           (SYSCALL)0,                       0 },
728 #endif
729 
730 #define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
731 
732   { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
733 
734 #define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
735 
736 #if !SQLITE_OS_WINCE
737   { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
738 #else
739   { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
740 #endif
741 
742 #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
743         LPFILETIME))aSyscall[30].pCurrent)
744 
745 #if defined(SQLITE_WIN32_HAS_ANSI)
746   { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
747 #else
748   { "GetTempPathA",            (SYSCALL)0,                       0 },
749 #endif
750 
751 #define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
752 
753 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
754   { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
755 #else
756   { "GetTempPathW",            (SYSCALL)0,                       0 },
757 #endif
758 
759 #define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
760 
761 #if !SQLITE_OS_WINRT
762   { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
763 #else
764   { "GetTickCount",            (SYSCALL)0,                       0 },
765 #endif
766 
767 #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
768 
769 #if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX
770   { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
771 #else
772   { "GetVersionExA",           (SYSCALL)0,                       0 },
773 #endif
774 
775 #define osGetVersionExA ((BOOL(WINAPI*)( \
776         LPOSVERSIONINFOA))aSyscall[34].pCurrent)
777 
778 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
779         SQLITE_WIN32_GETVERSIONEX
780   { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
781 #else
782   { "GetVersionExW",           (SYSCALL)0,                       0 },
783 #endif
784 
785 #define osGetVersionExW ((BOOL(WINAPI*)( \
786         LPOSVERSIONINFOW))aSyscall[35].pCurrent)
787 
788   { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
789 
790 #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
791         SIZE_T))aSyscall[36].pCurrent)
792 
793 #if !SQLITE_OS_WINRT
794   { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
795 #else
796   { "HeapCreate",              (SYSCALL)0,                       0 },
797 #endif
798 
799 #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
800         SIZE_T))aSyscall[37].pCurrent)
801 
802 #if !SQLITE_OS_WINRT
803   { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
804 #else
805   { "HeapDestroy",             (SYSCALL)0,                       0 },
806 #endif
807 
808 #define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
809 
810   { "HeapFree",                (SYSCALL)HeapFree,                0 },
811 
812 #define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
813 
814   { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
815 
816 #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
817         SIZE_T))aSyscall[40].pCurrent)
818 
819   { "HeapSize",                (SYSCALL)HeapSize,                0 },
820 
821 #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
822         LPCVOID))aSyscall[41].pCurrent)
823 
824 #if !SQLITE_OS_WINRT
825   { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
826 #else
827   { "HeapValidate",            (SYSCALL)0,                       0 },
828 #endif
829 
830 #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
831         LPCVOID))aSyscall[42].pCurrent)
832 
833 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
834   { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
835 #else
836   { "HeapCompact",             (SYSCALL)0,                       0 },
837 #endif
838 
839 #define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
840 
841 #if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
842   { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
843 #else
844   { "LoadLibraryA",            (SYSCALL)0,                       0 },
845 #endif
846 
847 #define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
848 
849 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
850         !defined(SQLITE_OMIT_LOAD_EXTENSION)
851   { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
852 #else
853   { "LoadLibraryW",            (SYSCALL)0,                       0 },
854 #endif
855 
856 #define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
857 
858 #if !SQLITE_OS_WINRT
859   { "LocalFree",               (SYSCALL)LocalFree,               0 },
860 #else
861   { "LocalFree",               (SYSCALL)0,                       0 },
862 #endif
863 
864 #define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
865 
866 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
867   { "LockFile",                (SYSCALL)LockFile,                0 },
868 #else
869   { "LockFile",                (SYSCALL)0,                       0 },
870 #endif
871 
872 #ifndef osLockFile
873 #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
874         DWORD))aSyscall[47].pCurrent)
875 #endif
876 
877 #if !SQLITE_OS_WINCE
878   { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
879 #else
880   { "LockFileEx",              (SYSCALL)0,                       0 },
881 #endif
882 
883 #ifndef osLockFileEx
884 #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
885         LPOVERLAPPED))aSyscall[48].pCurrent)
886 #endif
887 
888 #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
889         (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
890   { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
891 #else
892   { "MapViewOfFile",           (SYSCALL)0,                       0 },
893 #endif
894 
895 #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
896         SIZE_T))aSyscall[49].pCurrent)
897 
898   { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
899 
900 #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
901         int))aSyscall[50].pCurrent)
902 
903   { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
904 
905 #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
906         LARGE_INTEGER*))aSyscall[51].pCurrent)
907 
908   { "ReadFile",                (SYSCALL)ReadFile,                0 },
909 
910 #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
911         LPOVERLAPPED))aSyscall[52].pCurrent)
912 
913   { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
914 
915 #define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
916 
917 #if !SQLITE_OS_WINRT
918   { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
919 #else
920   { "SetFilePointer",          (SYSCALL)0,                       0 },
921 #endif
922 
923 #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
924         DWORD))aSyscall[54].pCurrent)
925 
926 #if !SQLITE_OS_WINRT
927   { "Sleep",                   (SYSCALL)Sleep,                   0 },
928 #else
929   { "Sleep",                   (SYSCALL)0,                       0 },
930 #endif
931 
932 #define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
933 
934   { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
935 
936 #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
937         LPFILETIME))aSyscall[56].pCurrent)
938 
939 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
940   { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
941 #else
942   { "UnlockFile",              (SYSCALL)0,                       0 },
943 #endif
944 
945 #ifndef osUnlockFile
946 #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
947         DWORD))aSyscall[57].pCurrent)
948 #endif
949 
950 #if !SQLITE_OS_WINCE
951   { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
952 #else
953   { "UnlockFileEx",            (SYSCALL)0,                       0 },
954 #endif
955 
956 #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
957         LPOVERLAPPED))aSyscall[58].pCurrent)
958 
959 #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
960   { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
961 #else
962   { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
963 #endif
964 
965 #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
966 
967   { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
968 
969 #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
970         LPCSTR,LPBOOL))aSyscall[60].pCurrent)
971 
972   { "WriteFile",               (SYSCALL)WriteFile,               0 },
973 
974 #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
975         LPOVERLAPPED))aSyscall[61].pCurrent)
976 
977 #if SQLITE_OS_WINRT
978   { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
979 #else
980   { "CreateEventExW",          (SYSCALL)0,                       0 },
981 #endif
982 
983 #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
984         DWORD,DWORD))aSyscall[62].pCurrent)
985 
986 #if !SQLITE_OS_WINRT
987   { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
988 #else
989   { "WaitForSingleObject",     (SYSCALL)0,                       0 },
990 #endif
991 
992 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
993         DWORD))aSyscall[63].pCurrent)
994 
995 #if !SQLITE_OS_WINCE
996   { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
997 #else
998   { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
999 #endif
1000 
1001 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
1002         BOOL))aSyscall[64].pCurrent)
1003 
1004 #if SQLITE_OS_WINRT
1005   { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
1006 #else
1007   { "SetFilePointerEx",        (SYSCALL)0,                       0 },
1008 #endif
1009 
1010 #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
1011         PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
1012 
1013 #if SQLITE_OS_WINRT
1014   { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
1015 #else
1016   { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
1017 #endif
1018 
1019 #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
1020         FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
1021 
1022 #if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
1023   { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
1024 #else
1025   { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
1026 #endif
1027 
1028 #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
1029         SIZE_T))aSyscall[67].pCurrent)
1030 
1031 #if SQLITE_OS_WINRT
1032   { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
1033 #else
1034   { "CreateFile2",             (SYSCALL)0,                       0 },
1035 #endif
1036 
1037 #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
1038         LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
1039 
1040 #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
1041   { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
1042 #else
1043   { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
1044 #endif
1045 
1046 #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
1047         DWORD))aSyscall[69].pCurrent)
1048 
1049 #if SQLITE_OS_WINRT
1050   { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
1051 #else
1052   { "GetTickCount64",          (SYSCALL)0,                       0 },
1053 #endif
1054 
1055 #define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
1056 
1057 #if SQLITE_OS_WINRT
1058   { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
1059 #else
1060   { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
1061 #endif
1062 
1063 #define osGetNativeSystemInfo ((VOID(WINAPI*)( \
1064         LPSYSTEM_INFO))aSyscall[71].pCurrent)
1065 
1066 #if defined(SQLITE_WIN32_HAS_ANSI)
1067   { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
1068 #else
1069   { "OutputDebugStringA",      (SYSCALL)0,                       0 },
1070 #endif
1071 
1072 #define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
1073 
1074 #if defined(SQLITE_WIN32_HAS_WIDE)
1075   { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
1076 #else
1077   { "OutputDebugStringW",      (SYSCALL)0,                       0 },
1078 #endif
1079 
1080 #define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
1081 
1082   { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
1083 
1084 #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
1085 
1086 #if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
1087   { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
1088 #else
1089   { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
1090 #endif
1091 
1092 #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
1093         LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
1094 
1095 /*
1096 ** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
1097 **       is really just a macro that uses a compiler intrinsic (e.g. x64).
1098 **       So do not try to make this is into a redefinable interface.
1099 */
1100 #if defined(InterlockedCompareExchange)
1101   { "InterlockedCompareExchange", (SYSCALL)0,                    0 },
1102 
1103 #define osInterlockedCompareExchange InterlockedCompareExchange
1104 #else
1105   { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
1106 
1107 #define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
1108         SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
1109 #endif /* defined(InterlockedCompareExchange) */
1110 
1111 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
1112   { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
1113 #else
1114   { "UuidCreate",               (SYSCALL)0,                      0 },
1115 #endif
1116 
1117 #define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
1118 
1119 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
1120   { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
1121 #else
1122   { "UuidCreateSequential",     (SYSCALL)0,                      0 },
1123 #endif
1124 
1125 #define osUuidCreateSequential \
1126         ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
1127 
1128 #if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
1129   { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
1130 #else
1131   { "FlushViewOfFile",          (SYSCALL)0,                      0 },
1132 #endif
1133 
1134 #define osFlushViewOfFile \
1135         ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
1136 
1137 }; /* End of the overrideable system calls */
1138 
1139 /*
1140 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
1141 ** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
1142 ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
1143 ** system call named zName.
1144 */
1145 static int winSetSystemCall(
1146   sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
1147   const char *zName,            /* Name of system call to override */
1148   sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
1149 ){
1150   unsigned int i;
1151   int rc = SQLITE_NOTFOUND;
1152 
1153   UNUSED_PARAMETER(pNotUsed);
1154   if( zName==0 ){
1155     /* If no zName is given, restore all system calls to their default
1156     ** settings and return NULL
1157     */
1158     rc = SQLITE_OK;
1159     for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
1160       if( aSyscall[i].pDefault ){
1161         aSyscall[i].pCurrent = aSyscall[i].pDefault;
1162       }
1163     }
1164   }else{
1165     /* If zName is specified, operate on only the one system call
1166     ** specified.
1167     */
1168     for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
1169       if( strcmp(zName, aSyscall[i].zName)==0 ){
1170         if( aSyscall[i].pDefault==0 ){
1171           aSyscall[i].pDefault = aSyscall[i].pCurrent;
1172         }
1173         rc = SQLITE_OK;
1174         if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
1175         aSyscall[i].pCurrent = pNewFunc;
1176         break;
1177       }
1178     }
1179   }
1180   return rc;
1181 }
1182 
1183 /*
1184 ** Return the value of a system call.  Return NULL if zName is not a
1185 ** recognized system call name.  NULL is also returned if the system call
1186 ** is currently undefined.
1187 */
1188 static sqlite3_syscall_ptr winGetSystemCall(
1189   sqlite3_vfs *pNotUsed,
1190   const char *zName
1191 ){
1192   unsigned int i;
1193 
1194   UNUSED_PARAMETER(pNotUsed);
1195   for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
1196     if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
1197   }
1198   return 0;
1199 }
1200 
1201 /*
1202 ** Return the name of the first system call after zName.  If zName==NULL
1203 ** then return the name of the first system call.  Return NULL if zName
1204 ** is the last system call or if zName is not the name of a valid
1205 ** system call.
1206 */
1207 static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
1208   int i = -1;
1209 
1210   UNUSED_PARAMETER(p);
1211   if( zName ){
1212     for(i=0; i<ArraySize(aSyscall)-1; i++){
1213       if( strcmp(zName, aSyscall[i].zName)==0 ) break;
1214     }
1215   }
1216   for(i++; i<ArraySize(aSyscall); i++){
1217     if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
1218   }
1219   return 0;
1220 }
1221 
1222 #ifdef SQLITE_WIN32_MALLOC
1223 /*
1224 ** If a Win32 native heap has been configured, this function will attempt to
1225 ** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
1226 ** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
1227 ** "pnLargest" argument, if non-zero, will be used to return the size of the
1228 ** largest committed free block in the heap, in bytes.
1229 */
1230 int sqlite3_win32_compact_heap(LPUINT pnLargest){
1231   int rc = SQLITE_OK;
1232   UINT nLargest = 0;
1233   HANDLE hHeap;
1234 
1235   winMemAssertMagic();
1236   hHeap = winMemGetHeap();
1237   assert( hHeap!=0 );
1238   assert( hHeap!=INVALID_HANDLE_VALUE );
1239 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1240   assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
1241 #endif
1242 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
1243   if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
1244     DWORD lastErrno = osGetLastError();
1245     if( lastErrno==NO_ERROR ){
1246       sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
1247                   (void*)hHeap);
1248       rc = SQLITE_NOMEM_BKPT;
1249     }else{
1250       sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
1251                   osGetLastError(), (void*)hHeap);
1252       rc = SQLITE_ERROR;
1253     }
1254   }
1255 #else
1256   sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
1257               (void*)hHeap);
1258   rc = SQLITE_NOTFOUND;
1259 #endif
1260   if( pnLargest ) *pnLargest = nLargest;
1261   return rc;
1262 }
1263 
1264 /*
1265 ** If a Win32 native heap has been configured, this function will attempt to
1266 ** destroy and recreate it.  If the Win32 native heap is not isolated and/or
1267 ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
1268 ** be returned and no changes will be made to the Win32 native heap.
1269 */
1270 int sqlite3_win32_reset_heap(){
1271   int rc;
1272   MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
1273   MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
1274   MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
1275   MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
1276   sqlite3_mutex_enter(pMaster);
1277   sqlite3_mutex_enter(pMem);
1278   winMemAssertMagic();
1279   if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
1280     /*
1281     ** At this point, there should be no outstanding memory allocations on
1282     ** the heap.  Also, since both the master and memsys locks are currently
1283     ** being held by us, no other function (i.e. from another thread) should
1284     ** be able to even access the heap.  Attempt to destroy and recreate our
1285     ** isolated Win32 native heap now.
1286     */
1287     assert( winMemGetHeap()!=NULL );
1288     assert( winMemGetOwned() );
1289     assert( sqlite3_memory_used()==0 );
1290     winMemShutdown(winMemGetDataPtr());
1291     assert( winMemGetHeap()==NULL );
1292     assert( !winMemGetOwned() );
1293     assert( sqlite3_memory_used()==0 );
1294     rc = winMemInit(winMemGetDataPtr());
1295     assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
1296     assert( rc!=SQLITE_OK || winMemGetOwned() );
1297     assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
1298   }else{
1299     /*
1300     ** The Win32 native heap cannot be modified because it may be in use.
1301     */
1302     rc = SQLITE_BUSY;
1303   }
1304   sqlite3_mutex_leave(pMem);
1305   sqlite3_mutex_leave(pMaster);
1306   return rc;
1307 }
1308 #endif /* SQLITE_WIN32_MALLOC */
1309 
1310 /*
1311 ** This function outputs the specified (ANSI) string to the Win32 debugger
1312 ** (if available).
1313 */
1314 
1315 void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
1316   char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
1317   int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
1318   if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
1319   assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
1320 #ifdef SQLITE_ENABLE_API_ARMOR
1321   if( !zBuf ){
1322     (void)SQLITE_MISUSE_BKPT;
1323     return;
1324   }
1325 #endif
1326 #if defined(SQLITE_WIN32_HAS_ANSI)
1327   if( nMin>0 ){
1328     memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
1329     memcpy(zDbgBuf, zBuf, nMin);
1330     osOutputDebugStringA(zDbgBuf);
1331   }else{
1332     osOutputDebugStringA(zBuf);
1333   }
1334 #elif defined(SQLITE_WIN32_HAS_WIDE)
1335   memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
1336   if ( osMultiByteToWideChar(
1337           osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
1338           nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
1339     return;
1340   }
1341   osOutputDebugStringW((LPCWSTR)zDbgBuf);
1342 #else
1343   if( nMin>0 ){
1344     memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
1345     memcpy(zDbgBuf, zBuf, nMin);
1346     fprintf(stderr, "%s", zDbgBuf);
1347   }else{
1348     fprintf(stderr, "%s", zBuf);
1349   }
1350 #endif
1351 }
1352 
1353 /*
1354 ** The following routine suspends the current thread for at least ms
1355 ** milliseconds.  This is equivalent to the Win32 Sleep() interface.
1356 */
1357 #if SQLITE_OS_WINRT
1358 static HANDLE sleepObj = NULL;
1359 #endif
1360 
1361 void sqlite3_win32_sleep(DWORD milliseconds){
1362 #if SQLITE_OS_WINRT
1363   if ( sleepObj==NULL ){
1364     sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
1365                                 SYNCHRONIZE);
1366   }
1367   assert( sleepObj!=NULL );
1368   osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
1369 #else
1370   osSleep(milliseconds);
1371 #endif
1372 }
1373 
1374 #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
1375         SQLITE_THREADSAFE>0
1376 DWORD sqlite3Win32Wait(HANDLE hObject){
1377   DWORD rc;
1378   while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
1379                                        TRUE))==WAIT_IO_COMPLETION ){}
1380   return rc;
1381 }
1382 #endif
1383 
1384 /*
1385 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
1386 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
1387 **
1388 ** Here is an interesting observation:  Win95, Win98, and WinME lack
1389 ** the LockFileEx() API.  But we can still statically link against that
1390 ** API as long as we don't call it when running Win95/98/ME.  A call to
1391 ** this routine is used to determine if the host is Win95/98/ME or
1392 ** WinNT/2K/XP so that we will know whether or not we can safely call
1393 ** the LockFileEx() API.
1394 */
1395 
1396 #if !SQLITE_WIN32_GETVERSIONEX
1397 # define osIsNT()  (1)
1398 #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
1399 # define osIsNT()  (1)
1400 #elif !defined(SQLITE_WIN32_HAS_WIDE)
1401 # define osIsNT()  (0)
1402 #else
1403 # define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
1404 #endif
1405 
1406 /*
1407 ** This function determines if the machine is running a version of Windows
1408 ** based on the NT kernel.
1409 */
1410 int sqlite3_win32_is_nt(void){
1411 #if SQLITE_OS_WINRT
1412   /*
1413   ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
1414   **       kernel.
1415   */
1416   return 1;
1417 #elif SQLITE_WIN32_GETVERSIONEX
1418   if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
1419 #if defined(SQLITE_WIN32_HAS_ANSI)
1420     OSVERSIONINFOA sInfo;
1421     sInfo.dwOSVersionInfoSize = sizeof(sInfo);
1422     osGetVersionExA(&sInfo);
1423     osInterlockedCompareExchange(&sqlite3_os_type,
1424         (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
1425 #elif defined(SQLITE_WIN32_HAS_WIDE)
1426     OSVERSIONINFOW sInfo;
1427     sInfo.dwOSVersionInfoSize = sizeof(sInfo);
1428     osGetVersionExW(&sInfo);
1429     osInterlockedCompareExchange(&sqlite3_os_type,
1430         (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
1431 #endif
1432   }
1433   return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
1434 #elif SQLITE_TEST
1435   return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
1436 #else
1437   /*
1438   ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
1439   **       deprecated are always assumed to be based on the NT kernel.
1440   */
1441   return 1;
1442 #endif
1443 }
1444 
1445 #ifdef SQLITE_WIN32_MALLOC
1446 /*
1447 ** Allocate nBytes of memory.
1448 */
1449 static void *winMemMalloc(int nBytes){
1450   HANDLE hHeap;
1451   void *p;
1452 
1453   winMemAssertMagic();
1454   hHeap = winMemGetHeap();
1455   assert( hHeap!=0 );
1456   assert( hHeap!=INVALID_HANDLE_VALUE );
1457 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1458   assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
1459 #endif
1460   assert( nBytes>=0 );
1461   p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
1462   if( !p ){
1463     sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
1464                 nBytes, osGetLastError(), (void*)hHeap);
1465   }
1466   return p;
1467 }
1468 
1469 /*
1470 ** Free memory.
1471 */
1472 static void winMemFree(void *pPrior){
1473   HANDLE hHeap;
1474 
1475   winMemAssertMagic();
1476   hHeap = winMemGetHeap();
1477   assert( hHeap!=0 );
1478   assert( hHeap!=INVALID_HANDLE_VALUE );
1479 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1480   assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
1481 #endif
1482   if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
1483   if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
1484     sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
1485                 pPrior, osGetLastError(), (void*)hHeap);
1486   }
1487 }
1488 
1489 /*
1490 ** Change the size of an existing memory allocation
1491 */
1492 static void *winMemRealloc(void *pPrior, int nBytes){
1493   HANDLE hHeap;
1494   void *p;
1495 
1496   winMemAssertMagic();
1497   hHeap = winMemGetHeap();
1498   assert( hHeap!=0 );
1499   assert( hHeap!=INVALID_HANDLE_VALUE );
1500 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1501   assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
1502 #endif
1503   assert( nBytes>=0 );
1504   if( !pPrior ){
1505     p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
1506   }else{
1507     p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
1508   }
1509   if( !p ){
1510     sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
1511                 pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
1512                 (void*)hHeap);
1513   }
1514   return p;
1515 }
1516 
1517 /*
1518 ** Return the size of an outstanding allocation, in bytes.
1519 */
1520 static int winMemSize(void *p){
1521   HANDLE hHeap;
1522   SIZE_T n;
1523 
1524   winMemAssertMagic();
1525   hHeap = winMemGetHeap();
1526   assert( hHeap!=0 );
1527   assert( hHeap!=INVALID_HANDLE_VALUE );
1528 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1529   assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
1530 #endif
1531   if( !p ) return 0;
1532   n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
1533   if( n==(SIZE_T)-1 ){
1534     sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
1535                 p, osGetLastError(), (void*)hHeap);
1536     return 0;
1537   }
1538   return (int)n;
1539 }
1540 
1541 /*
1542 ** Round up a request size to the next valid allocation size.
1543 */
1544 static int winMemRoundup(int n){
1545   return n;
1546 }
1547 
1548 /*
1549 ** Initialize this module.
1550 */
1551 static int winMemInit(void *pAppData){
1552   winMemData *pWinMemData = (winMemData *)pAppData;
1553 
1554   if( !pWinMemData ) return SQLITE_ERROR;
1555   assert( pWinMemData->magic1==WINMEM_MAGIC1 );
1556   assert( pWinMemData->magic2==WINMEM_MAGIC2 );
1557 
1558 #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
1559   if( !pWinMemData->hHeap ){
1560     DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
1561     DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
1562     if( dwMaximumSize==0 ){
1563       dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
1564     }else if( dwInitialSize>dwMaximumSize ){
1565       dwInitialSize = dwMaximumSize;
1566     }
1567     pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
1568                                       dwInitialSize, dwMaximumSize);
1569     if( !pWinMemData->hHeap ){
1570       sqlite3_log(SQLITE_NOMEM,
1571           "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
1572           osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
1573           dwMaximumSize);
1574       return SQLITE_NOMEM_BKPT;
1575     }
1576     pWinMemData->bOwned = TRUE;
1577     assert( pWinMemData->bOwned );
1578   }
1579 #else
1580   pWinMemData->hHeap = osGetProcessHeap();
1581   if( !pWinMemData->hHeap ){
1582     sqlite3_log(SQLITE_NOMEM,
1583         "failed to GetProcessHeap (%lu)", osGetLastError());
1584     return SQLITE_NOMEM_BKPT;
1585   }
1586   pWinMemData->bOwned = FALSE;
1587   assert( !pWinMemData->bOwned );
1588 #endif
1589   assert( pWinMemData->hHeap!=0 );
1590   assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
1591 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1592   assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
1593 #endif
1594   return SQLITE_OK;
1595 }
1596 
1597 /*
1598 ** Deinitialize this module.
1599 */
1600 static void winMemShutdown(void *pAppData){
1601   winMemData *pWinMemData = (winMemData *)pAppData;
1602 
1603   if( !pWinMemData ) return;
1604   assert( pWinMemData->magic1==WINMEM_MAGIC1 );
1605   assert( pWinMemData->magic2==WINMEM_MAGIC2 );
1606 
1607   if( pWinMemData->hHeap ){
1608     assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
1609 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
1610     assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
1611 #endif
1612     if( pWinMemData->bOwned ){
1613       if( !osHeapDestroy(pWinMemData->hHeap) ){
1614         sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
1615                     osGetLastError(), (void*)pWinMemData->hHeap);
1616       }
1617       pWinMemData->bOwned = FALSE;
1618     }
1619     pWinMemData->hHeap = NULL;
1620   }
1621 }
1622 
1623 /*
1624 ** Populate the low-level memory allocation function pointers in
1625 ** sqlite3GlobalConfig.m with pointers to the routines in this file. The
1626 ** arguments specify the block of memory to manage.
1627 **
1628 ** This routine is only called by sqlite3_config(), and therefore
1629 ** is not required to be threadsafe (it is not).
1630 */
1631 const sqlite3_mem_methods *sqlite3MemGetWin32(void){
1632   static const sqlite3_mem_methods winMemMethods = {
1633     winMemMalloc,
1634     winMemFree,
1635     winMemRealloc,
1636     winMemSize,
1637     winMemRoundup,
1638     winMemInit,
1639     winMemShutdown,
1640     &win_mem_data
1641   };
1642   return &winMemMethods;
1643 }
1644 
1645 void sqlite3MemSetDefault(void){
1646   sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
1647 }
1648 #endif /* SQLITE_WIN32_MALLOC */
1649 
1650 /*
1651 ** Convert a UTF-8 string to Microsoft Unicode.
1652 **
1653 ** Space to hold the returned string is obtained from sqlite3_malloc().
1654 */
1655 static LPWSTR winUtf8ToUnicode(const char *zText){
1656   int nChar;
1657   LPWSTR zWideText;
1658 
1659   nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
1660   if( nChar==0 ){
1661     return 0;
1662   }
1663   zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
1664   if( zWideText==0 ){
1665     return 0;
1666   }
1667   nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
1668                                 nChar);
1669   if( nChar==0 ){
1670     sqlite3_free(zWideText);
1671     zWideText = 0;
1672   }
1673   return zWideText;
1674 }
1675 
1676 /*
1677 ** Convert a Microsoft Unicode string to UTF-8.
1678 **
1679 ** Space to hold the returned string is obtained from sqlite3_malloc().
1680 */
1681 static char *winUnicodeToUtf8(LPCWSTR zWideText){
1682   int nByte;
1683   char *zText;
1684 
1685   nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
1686   if( nByte == 0 ){
1687     return 0;
1688   }
1689   zText = sqlite3MallocZero( nByte );
1690   if( zText==0 ){
1691     return 0;
1692   }
1693   nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
1694                                 0, 0);
1695   if( nByte == 0 ){
1696     sqlite3_free(zText);
1697     zText = 0;
1698   }
1699   return zText;
1700 }
1701 
1702 /*
1703 ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
1704 ** code page.
1705 **
1706 ** Space to hold the returned string is obtained from sqlite3_malloc().
1707 */
1708 static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
1709   int nByte;
1710   LPWSTR zMbcsText;
1711   int codepage = useAnsi ? CP_ACP : CP_OEMCP;
1712 
1713   nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
1714                                 0)*sizeof(WCHAR);
1715   if( nByte==0 ){
1716     return 0;
1717   }
1718   zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
1719   if( zMbcsText==0 ){
1720     return 0;
1721   }
1722   nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
1723                                 nByte);
1724   if( nByte==0 ){
1725     sqlite3_free(zMbcsText);
1726     zMbcsText = 0;
1727   }
1728   return zMbcsText;
1729 }
1730 
1731 /*
1732 ** Convert a Microsoft Unicode string to a multi-byte character string,
1733 ** using the ANSI or OEM code page.
1734 **
1735 ** Space to hold the returned string is obtained from sqlite3_malloc().
1736 */
1737 static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
1738   int nByte;
1739   char *zText;
1740   int codepage = useAnsi ? CP_ACP : CP_OEMCP;
1741 
1742   nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
1743   if( nByte == 0 ){
1744     return 0;
1745   }
1746   zText = sqlite3MallocZero( nByte );
1747   if( zText==0 ){
1748     return 0;
1749   }
1750   nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
1751                                 nByte, 0, 0);
1752   if( nByte == 0 ){
1753     sqlite3_free(zText);
1754     zText = 0;
1755   }
1756   return zText;
1757 }
1758 
1759 /*
1760 ** Convert a multi-byte character string to UTF-8.
1761 **
1762 ** Space to hold the returned string is obtained from sqlite3_malloc().
1763 */
1764 static char *winMbcsToUtf8(const char *zText, int useAnsi){
1765   char *zTextUtf8;
1766   LPWSTR zTmpWide;
1767 
1768   zTmpWide = winMbcsToUnicode(zText, useAnsi);
1769   if( zTmpWide==0 ){
1770     return 0;
1771   }
1772   zTextUtf8 = winUnicodeToUtf8(zTmpWide);
1773   sqlite3_free(zTmpWide);
1774   return zTextUtf8;
1775 }
1776 
1777 /*
1778 ** Convert a UTF-8 string to a multi-byte character string.
1779 **
1780 ** Space to hold the returned string is obtained from sqlite3_malloc().
1781 */
1782 static char *winUtf8ToMbcs(const char *zText, int useAnsi){
1783   char *zTextMbcs;
1784   LPWSTR zTmpWide;
1785 
1786   zTmpWide = winUtf8ToUnicode(zText);
1787   if( zTmpWide==0 ){
1788     return 0;
1789   }
1790   zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
1791   sqlite3_free(zTmpWide);
1792   return zTextMbcs;
1793 }
1794 
1795 /*
1796 ** This is a public wrapper for the winUtf8ToUnicode() function.
1797 */
1798 LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
1799 #ifdef SQLITE_ENABLE_API_ARMOR
1800   if( !zText ){
1801     (void)SQLITE_MISUSE_BKPT;
1802     return 0;
1803   }
1804 #endif
1805 #ifndef SQLITE_OMIT_AUTOINIT
1806   if( sqlite3_initialize() ) return 0;
1807 #endif
1808   return winUtf8ToUnicode(zText);
1809 }
1810 
1811 /*
1812 ** This is a public wrapper for the winUnicodeToUtf8() function.
1813 */
1814 char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
1815 #ifdef SQLITE_ENABLE_API_ARMOR
1816   if( !zWideText ){
1817     (void)SQLITE_MISUSE_BKPT;
1818     return 0;
1819   }
1820 #endif
1821 #ifndef SQLITE_OMIT_AUTOINIT
1822   if( sqlite3_initialize() ) return 0;
1823 #endif
1824   return winUnicodeToUtf8(zWideText);
1825 }
1826 
1827 /*
1828 ** This is a public wrapper for the winMbcsToUtf8() function.
1829 */
1830 char *sqlite3_win32_mbcs_to_utf8(const char *zText){
1831 #ifdef SQLITE_ENABLE_API_ARMOR
1832   if( !zText ){
1833     (void)SQLITE_MISUSE_BKPT;
1834     return 0;
1835   }
1836 #endif
1837 #ifndef SQLITE_OMIT_AUTOINIT
1838   if( sqlite3_initialize() ) return 0;
1839 #endif
1840   return winMbcsToUtf8(zText, osAreFileApisANSI());
1841 }
1842 
1843 /*
1844 ** This is a public wrapper for the winMbcsToUtf8() function.
1845 */
1846 char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
1847 #ifdef SQLITE_ENABLE_API_ARMOR
1848   if( !zText ){
1849     (void)SQLITE_MISUSE_BKPT;
1850     return 0;
1851   }
1852 #endif
1853 #ifndef SQLITE_OMIT_AUTOINIT
1854   if( sqlite3_initialize() ) return 0;
1855 #endif
1856   return winMbcsToUtf8(zText, useAnsi);
1857 }
1858 
1859 /*
1860 ** This is a public wrapper for the winUtf8ToMbcs() function.
1861 */
1862 char *sqlite3_win32_utf8_to_mbcs(const char *zText){
1863 #ifdef SQLITE_ENABLE_API_ARMOR
1864   if( !zText ){
1865     (void)SQLITE_MISUSE_BKPT;
1866     return 0;
1867   }
1868 #endif
1869 #ifndef SQLITE_OMIT_AUTOINIT
1870   if( sqlite3_initialize() ) return 0;
1871 #endif
1872   return winUtf8ToMbcs(zText, osAreFileApisANSI());
1873 }
1874 
1875 /*
1876 ** This is a public wrapper for the winUtf8ToMbcs() function.
1877 */
1878 char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
1879 #ifdef SQLITE_ENABLE_API_ARMOR
1880   if( !zText ){
1881     (void)SQLITE_MISUSE_BKPT;
1882     return 0;
1883   }
1884 #endif
1885 #ifndef SQLITE_OMIT_AUTOINIT
1886   if( sqlite3_initialize() ) return 0;
1887 #endif
1888   return winUtf8ToMbcs(zText, useAnsi);
1889 }
1890 
1891 /*
1892 ** This function sets the data directory or the temporary directory based on
1893 ** the provided arguments.  The type argument must be 1 in order to set the
1894 ** data directory or 2 in order to set the temporary directory.  The zValue
1895 ** argument is the name of the directory to use.  The return value will be
1896 ** SQLITE_OK if successful.
1897 */
1898 int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
1899   char **ppDirectory = 0;
1900 #ifndef SQLITE_OMIT_AUTOINIT
1901   int rc = sqlite3_initialize();
1902   if( rc ) return rc;
1903 #endif
1904   if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
1905     ppDirectory = &sqlite3_data_directory;
1906   }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
1907     ppDirectory = &sqlite3_temp_directory;
1908   }
1909   assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
1910           || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
1911   );
1912   assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
1913   if( ppDirectory ){
1914     char *zValueUtf8 = 0;
1915     if( zValue && zValue[0] ){
1916       zValueUtf8 = winUnicodeToUtf8(zValue);
1917       if ( zValueUtf8==0 ){
1918         return SQLITE_NOMEM_BKPT;
1919       }
1920     }
1921     sqlite3_free(*ppDirectory);
1922     *ppDirectory = zValueUtf8;
1923     return SQLITE_OK;
1924   }
1925   return SQLITE_ERROR;
1926 }
1927 
1928 /*
1929 ** The return value of winGetLastErrorMsg
1930 ** is zero if the error message fits in the buffer, or non-zero
1931 ** otherwise (if the message was truncated).
1932 */
1933 static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
1934   /* FormatMessage returns 0 on failure.  Otherwise it
1935   ** returns the number of TCHARs written to the output
1936   ** buffer, excluding the terminating null char.
1937   */
1938   DWORD dwLen = 0;
1939   char *zOut = 0;
1940 
1941   if( osIsNT() ){
1942 #if SQLITE_OS_WINRT
1943     WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
1944     dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
1945                              FORMAT_MESSAGE_IGNORE_INSERTS,
1946                              NULL,
1947                              lastErrno,
1948                              0,
1949                              zTempWide,
1950                              SQLITE_WIN32_MAX_ERRMSG_CHARS,
1951                              0);
1952 #else
1953     LPWSTR zTempWide = NULL;
1954     dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1955                              FORMAT_MESSAGE_FROM_SYSTEM |
1956                              FORMAT_MESSAGE_IGNORE_INSERTS,
1957                              NULL,
1958                              lastErrno,
1959                              0,
1960                              (LPWSTR) &zTempWide,
1961                              0,
1962                              0);
1963 #endif
1964     if( dwLen > 0 ){
1965       /* allocate a buffer and convert to UTF8 */
1966       sqlite3BeginBenignMalloc();
1967       zOut = winUnicodeToUtf8(zTempWide);
1968       sqlite3EndBenignMalloc();
1969 #if !SQLITE_OS_WINRT
1970       /* free the system buffer allocated by FormatMessage */
1971       osLocalFree(zTempWide);
1972 #endif
1973     }
1974   }
1975 #ifdef SQLITE_WIN32_HAS_ANSI
1976   else{
1977     char *zTemp = NULL;
1978     dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1979                              FORMAT_MESSAGE_FROM_SYSTEM |
1980                              FORMAT_MESSAGE_IGNORE_INSERTS,
1981                              NULL,
1982                              lastErrno,
1983                              0,
1984                              (LPSTR) &zTemp,
1985                              0,
1986                              0);
1987     if( dwLen > 0 ){
1988       /* allocate a buffer and convert to UTF8 */
1989       sqlite3BeginBenignMalloc();
1990       zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
1991       sqlite3EndBenignMalloc();
1992       /* free the system buffer allocated by FormatMessage */
1993       osLocalFree(zTemp);
1994     }
1995   }
1996 #endif
1997   if( 0 == dwLen ){
1998     sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
1999   }else{
2000     /* copy a maximum of nBuf chars to output buffer */
2001     sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
2002     /* free the UTF8 buffer */
2003     sqlite3_free(zOut);
2004   }
2005   return 0;
2006 }
2007 
2008 /*
2009 **
2010 ** This function - winLogErrorAtLine() - is only ever called via the macro
2011 ** winLogError().
2012 **
2013 ** This routine is invoked after an error occurs in an OS function.
2014 ** It logs a message using sqlite3_log() containing the current value of
2015 ** error code and, if possible, the human-readable equivalent from
2016 ** FormatMessage.
2017 **
2018 ** The first argument passed to the macro should be the error code that
2019 ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
2020 ** The two subsequent arguments should be the name of the OS function that
2021 ** failed and the associated file-system path, if any.
2022 */
2023 #define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
2024 static int winLogErrorAtLine(
2025   int errcode,                    /* SQLite error code */
2026   DWORD lastErrno,                /* Win32 last error */
2027   const char *zFunc,              /* Name of OS function that failed */
2028   const char *zPath,              /* File path associated with error */
2029   int iLine                       /* Source line number where error occurred */
2030 ){
2031   char zMsg[500];                 /* Human readable error text */
2032   int i;                          /* Loop counter */
2033 
2034   zMsg[0] = 0;
2035   winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
2036   assert( errcode!=SQLITE_OK );
2037   if( zPath==0 ) zPath = "";
2038   for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
2039   zMsg[i] = 0;
2040   sqlite3_log(errcode,
2041       "os_win.c:%d: (%lu) %s(%s) - %s",
2042       iLine, lastErrno, zFunc, zPath, zMsg
2043   );
2044 
2045   return errcode;
2046 }
2047 
2048 /*
2049 ** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
2050 ** will be retried following a locking error - probably caused by
2051 ** antivirus software.  Also the initial delay before the first retry.
2052 ** The delay increases linearly with each retry.
2053 */
2054 #ifndef SQLITE_WIN32_IOERR_RETRY
2055 # define SQLITE_WIN32_IOERR_RETRY 10
2056 #endif
2057 #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
2058 # define SQLITE_WIN32_IOERR_RETRY_DELAY 25
2059 #endif
2060 static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
2061 static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
2062 
2063 /*
2064 ** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
2065 ** error code obtained via GetLastError() is eligible to be retried.  It
2066 ** must accept the error code DWORD as its only argument and should return
2067 ** non-zero if the error code is transient in nature and the operation
2068 ** responsible for generating the original error might succeed upon being
2069 ** retried.  The argument to this macro should be a variable.
2070 **
2071 ** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
2072 ** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
2073 ** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
2074 ** may be used to include additional error codes in the set that should
2075 ** result in the failing I/O operation being retried by the caller.  If
2076 ** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
2077 ** identical to those of the "winIoerrCanRetry1" macro.
2078 */
2079 #if !defined(winIoerrCanRetry1)
2080 #define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
2081                               ((a)==ERROR_SHARING_VIOLATION)    || \
2082                               ((a)==ERROR_LOCK_VIOLATION)       || \
2083                               ((a)==ERROR_DEV_NOT_EXIST)        || \
2084                               ((a)==ERROR_NETNAME_DELETED)      || \
2085                               ((a)==ERROR_SEM_TIMEOUT)          || \
2086                               ((a)==ERROR_NETWORK_UNREACHABLE))
2087 #endif
2088 
2089 /*
2090 ** If a ReadFile() or WriteFile() error occurs, invoke this routine
2091 ** to see if it should be retried.  Return TRUE to retry.  Return FALSE
2092 ** to give up with an error.
2093 */
2094 static int winRetryIoerr(int *pnRetry, DWORD *pError){
2095   DWORD e = osGetLastError();
2096   if( *pnRetry>=winIoerrRetry ){
2097     if( pError ){
2098       *pError = e;
2099     }
2100     return 0;
2101   }
2102   if( winIoerrCanRetry1(e) ){
2103     sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
2104     ++*pnRetry;
2105     return 1;
2106   }
2107 #if defined(winIoerrCanRetry2)
2108   else if( winIoerrCanRetry2(e) ){
2109     sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
2110     ++*pnRetry;
2111     return 1;
2112   }
2113 #endif
2114   if( pError ){
2115     *pError = e;
2116   }
2117   return 0;
2118 }
2119 
2120 /*
2121 ** Log a I/O error retry episode.
2122 */
2123 static void winLogIoerr(int nRetry, int lineno){
2124   if( nRetry ){
2125     sqlite3_log(SQLITE_NOTICE,
2126       "delayed %dms for lock/sharing conflict at line %d",
2127       winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
2128     );
2129   }
2130 }
2131 
2132 /*
2133 ** This #if does not rely on the SQLITE_OS_WINCE define because the
2134 ** corresponding section in "date.c" cannot use it.
2135 */
2136 #if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
2137     (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
2138 /*
2139 ** The MSVC CRT on Windows CE may not have a localtime() function.
2140 ** So define a substitute.
2141 */
2142 #  include <time.h>
2143 struct tm *__cdecl localtime(const time_t *t)
2144 {
2145   static struct tm y;
2146   FILETIME uTm, lTm;
2147   SYSTEMTIME pTm;
2148   sqlite3_int64 t64;
2149   t64 = *t;
2150   t64 = (t64 + 11644473600)*10000000;
2151   uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
2152   uTm.dwHighDateTime= (DWORD)(t64 >> 32);
2153   osFileTimeToLocalFileTime(&uTm,&lTm);
2154   osFileTimeToSystemTime(&lTm,&pTm);
2155   y.tm_year = pTm.wYear - 1900;
2156   y.tm_mon = pTm.wMonth - 1;
2157   y.tm_wday = pTm.wDayOfWeek;
2158   y.tm_mday = pTm.wDay;
2159   y.tm_hour = pTm.wHour;
2160   y.tm_min = pTm.wMinute;
2161   y.tm_sec = pTm.wSecond;
2162   return &y;
2163 }
2164 #endif
2165 
2166 #if SQLITE_OS_WINCE
2167 /*************************************************************************
2168 ** This section contains code for WinCE only.
2169 */
2170 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
2171 
2172 /*
2173 ** Acquire a lock on the handle h
2174 */
2175 static void winceMutexAcquire(HANDLE h){
2176    DWORD dwErr;
2177    do {
2178      dwErr = osWaitForSingleObject(h, INFINITE);
2179    } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
2180 }
2181 /*
2182 ** Release a lock acquired by winceMutexAcquire()
2183 */
2184 #define winceMutexRelease(h) ReleaseMutex(h)
2185 
2186 /*
2187 ** Create the mutex and shared memory used for locking in the file
2188 ** descriptor pFile
2189 */
2190 static int winceCreateLock(const char *zFilename, winFile *pFile){
2191   LPWSTR zTok;
2192   LPWSTR zName;
2193   DWORD lastErrno;
2194   BOOL bLogged = FALSE;
2195   BOOL bInit = TRUE;
2196 
2197   zName = winUtf8ToUnicode(zFilename);
2198   if( zName==0 ){
2199     /* out of memory */
2200     return SQLITE_IOERR_NOMEM_BKPT;
2201   }
2202 
2203   /* Initialize the local lockdata */
2204   memset(&pFile->local, 0, sizeof(pFile->local));
2205 
2206   /* Replace the backslashes from the filename and lowercase it
2207   ** to derive a mutex name. */
2208   zTok = osCharLowerW(zName);
2209   for (;*zTok;zTok++){
2210     if (*zTok == '\\') *zTok = '_';
2211   }
2212 
2213   /* Create/open the named mutex */
2214   pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
2215   if (!pFile->hMutex){
2216     pFile->lastErrno = osGetLastError();
2217     sqlite3_free(zName);
2218     return winLogError(SQLITE_IOERR, pFile->lastErrno,
2219                        "winceCreateLock1", zFilename);
2220   }
2221 
2222   /* Acquire the mutex before continuing */
2223   winceMutexAcquire(pFile->hMutex);
2224 
2225   /* Since the names of named mutexes, semaphores, file mappings etc are
2226   ** case-sensitive, take advantage of that by uppercasing the mutex name
2227   ** and using that as the shared filemapping name.
2228   */
2229   osCharUpperW(zName);
2230   pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
2231                                         PAGE_READWRITE, 0, sizeof(winceLock),
2232                                         zName);
2233 
2234   /* Set a flag that indicates we're the first to create the memory so it
2235   ** must be zero-initialized */
2236   lastErrno = osGetLastError();
2237   if (lastErrno == ERROR_ALREADY_EXISTS){
2238     bInit = FALSE;
2239   }
2240 
2241   sqlite3_free(zName);
2242 
2243   /* If we succeeded in making the shared memory handle, map it. */
2244   if( pFile->hShared ){
2245     pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
2246              FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
2247     /* If mapping failed, close the shared memory handle and erase it */
2248     if( !pFile->shared ){
2249       pFile->lastErrno = osGetLastError();
2250       winLogError(SQLITE_IOERR, pFile->lastErrno,
2251                   "winceCreateLock2", zFilename);
2252       bLogged = TRUE;
2253       osCloseHandle(pFile->hShared);
2254       pFile->hShared = NULL;
2255     }
2256   }
2257 
2258   /* If shared memory could not be created, then close the mutex and fail */
2259   if( pFile->hShared==NULL ){
2260     if( !bLogged ){
2261       pFile->lastErrno = lastErrno;
2262       winLogError(SQLITE_IOERR, pFile->lastErrno,
2263                   "winceCreateLock3", zFilename);
2264       bLogged = TRUE;
2265     }
2266     winceMutexRelease(pFile->hMutex);
2267     osCloseHandle(pFile->hMutex);
2268     pFile->hMutex = NULL;
2269     return SQLITE_IOERR;
2270   }
2271 
2272   /* Initialize the shared memory if we're supposed to */
2273   if( bInit ){
2274     memset(pFile->shared, 0, sizeof(winceLock));
2275   }
2276 
2277   winceMutexRelease(pFile->hMutex);
2278   return SQLITE_OK;
2279 }
2280 
2281 /*
2282 ** Destroy the part of winFile that deals with wince locks
2283 */
2284 static void winceDestroyLock(winFile *pFile){
2285   if (pFile->hMutex){
2286     /* Acquire the mutex */
2287     winceMutexAcquire(pFile->hMutex);
2288 
2289     /* The following blocks should probably assert in debug mode, but they
2290        are to cleanup in case any locks remained open */
2291     if (pFile->local.nReaders){
2292       pFile->shared->nReaders --;
2293     }
2294     if (pFile->local.bReserved){
2295       pFile->shared->bReserved = FALSE;
2296     }
2297     if (pFile->local.bPending){
2298       pFile->shared->bPending = FALSE;
2299     }
2300     if (pFile->local.bExclusive){
2301       pFile->shared->bExclusive = FALSE;
2302     }
2303 
2304     /* De-reference and close our copy of the shared memory handle */
2305     osUnmapViewOfFile(pFile->shared);
2306     osCloseHandle(pFile->hShared);
2307 
2308     /* Done with the mutex */
2309     winceMutexRelease(pFile->hMutex);
2310     osCloseHandle(pFile->hMutex);
2311     pFile->hMutex = NULL;
2312   }
2313 }
2314 
2315 /*
2316 ** An implementation of the LockFile() API of Windows for CE
2317 */
2318 static BOOL winceLockFile(
2319   LPHANDLE phFile,
2320   DWORD dwFileOffsetLow,
2321   DWORD dwFileOffsetHigh,
2322   DWORD nNumberOfBytesToLockLow,
2323   DWORD nNumberOfBytesToLockHigh
2324 ){
2325   winFile *pFile = HANDLE_TO_WINFILE(phFile);
2326   BOOL bReturn = FALSE;
2327 
2328   UNUSED_PARAMETER(dwFileOffsetHigh);
2329   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
2330 
2331   if (!pFile->hMutex) return TRUE;
2332   winceMutexAcquire(pFile->hMutex);
2333 
2334   /* Wanting an exclusive lock? */
2335   if (dwFileOffsetLow == (DWORD)SHARED_FIRST
2336        && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
2337     if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
2338        pFile->shared->bExclusive = TRUE;
2339        pFile->local.bExclusive = TRUE;
2340        bReturn = TRUE;
2341     }
2342   }
2343 
2344   /* Want a read-only lock? */
2345   else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
2346            nNumberOfBytesToLockLow == 1){
2347     if (pFile->shared->bExclusive == 0){
2348       pFile->local.nReaders ++;
2349       if (pFile->local.nReaders == 1){
2350         pFile->shared->nReaders ++;
2351       }
2352       bReturn = TRUE;
2353     }
2354   }
2355 
2356   /* Want a pending lock? */
2357   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
2358            && nNumberOfBytesToLockLow == 1){
2359     /* If no pending lock has been acquired, then acquire it */
2360     if (pFile->shared->bPending == 0) {
2361       pFile->shared->bPending = TRUE;
2362       pFile->local.bPending = TRUE;
2363       bReturn = TRUE;
2364     }
2365   }
2366 
2367   /* Want a reserved lock? */
2368   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
2369            && nNumberOfBytesToLockLow == 1){
2370     if (pFile->shared->bReserved == 0) {
2371       pFile->shared->bReserved = TRUE;
2372       pFile->local.bReserved = TRUE;
2373       bReturn = TRUE;
2374     }
2375   }
2376 
2377   winceMutexRelease(pFile->hMutex);
2378   return bReturn;
2379 }
2380 
2381 /*
2382 ** An implementation of the UnlockFile API of Windows for CE
2383 */
2384 static BOOL winceUnlockFile(
2385   LPHANDLE phFile,
2386   DWORD dwFileOffsetLow,
2387   DWORD dwFileOffsetHigh,
2388   DWORD nNumberOfBytesToUnlockLow,
2389   DWORD nNumberOfBytesToUnlockHigh
2390 ){
2391   winFile *pFile = HANDLE_TO_WINFILE(phFile);
2392   BOOL bReturn = FALSE;
2393 
2394   UNUSED_PARAMETER(dwFileOffsetHigh);
2395   UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
2396 
2397   if (!pFile->hMutex) return TRUE;
2398   winceMutexAcquire(pFile->hMutex);
2399 
2400   /* Releasing a reader lock or an exclusive lock */
2401   if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
2402     /* Did we have an exclusive lock? */
2403     if (pFile->local.bExclusive){
2404       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
2405       pFile->local.bExclusive = FALSE;
2406       pFile->shared->bExclusive = FALSE;
2407       bReturn = TRUE;
2408     }
2409 
2410     /* Did we just have a reader lock? */
2411     else if (pFile->local.nReaders){
2412       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
2413              || nNumberOfBytesToUnlockLow == 1);
2414       pFile->local.nReaders --;
2415       if (pFile->local.nReaders == 0)
2416       {
2417         pFile->shared->nReaders --;
2418       }
2419       bReturn = TRUE;
2420     }
2421   }
2422 
2423   /* Releasing a pending lock */
2424   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
2425            && nNumberOfBytesToUnlockLow == 1){
2426     if (pFile->local.bPending){
2427       pFile->local.bPending = FALSE;
2428       pFile->shared->bPending = FALSE;
2429       bReturn = TRUE;
2430     }
2431   }
2432   /* Releasing a reserved lock */
2433   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
2434            && nNumberOfBytesToUnlockLow == 1){
2435     if (pFile->local.bReserved) {
2436       pFile->local.bReserved = FALSE;
2437       pFile->shared->bReserved = FALSE;
2438       bReturn = TRUE;
2439     }
2440   }
2441 
2442   winceMutexRelease(pFile->hMutex);
2443   return bReturn;
2444 }
2445 /*
2446 ** End of the special code for wince
2447 *****************************************************************************/
2448 #endif /* SQLITE_OS_WINCE */
2449 
2450 /*
2451 ** Lock a file region.
2452 */
2453 static BOOL winLockFile(
2454   LPHANDLE phFile,
2455   DWORD flags,
2456   DWORD offsetLow,
2457   DWORD offsetHigh,
2458   DWORD numBytesLow,
2459   DWORD numBytesHigh
2460 ){
2461 #if SQLITE_OS_WINCE
2462   /*
2463   ** NOTE: Windows CE is handled differently here due its lack of the Win32
2464   **       API LockFile.
2465   */
2466   return winceLockFile(phFile, offsetLow, offsetHigh,
2467                        numBytesLow, numBytesHigh);
2468 #else
2469   if( osIsNT() ){
2470     OVERLAPPED ovlp;
2471     memset(&ovlp, 0, sizeof(OVERLAPPED));
2472     ovlp.Offset = offsetLow;
2473     ovlp.OffsetHigh = offsetHigh;
2474     return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
2475   }else{
2476     return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
2477                       numBytesHigh);
2478   }
2479 #endif
2480 }
2481 
2482 /*
2483 ** Unlock a file region.
2484  */
2485 static BOOL winUnlockFile(
2486   LPHANDLE phFile,
2487   DWORD offsetLow,
2488   DWORD offsetHigh,
2489   DWORD numBytesLow,
2490   DWORD numBytesHigh
2491 ){
2492 #if SQLITE_OS_WINCE
2493   /*
2494   ** NOTE: Windows CE is handled differently here due its lack of the Win32
2495   **       API UnlockFile.
2496   */
2497   return winceUnlockFile(phFile, offsetLow, offsetHigh,
2498                          numBytesLow, numBytesHigh);
2499 #else
2500   if( osIsNT() ){
2501     OVERLAPPED ovlp;
2502     memset(&ovlp, 0, sizeof(OVERLAPPED));
2503     ovlp.Offset = offsetLow;
2504     ovlp.OffsetHigh = offsetHigh;
2505     return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
2506   }else{
2507     return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
2508                         numBytesHigh);
2509   }
2510 #endif
2511 }
2512 
2513 /*****************************************************************************
2514 ** The next group of routines implement the I/O methods specified
2515 ** by the sqlite3_io_methods object.
2516 ******************************************************************************/
2517 
2518 /*
2519 ** Some Microsoft compilers lack this definition.
2520 */
2521 #ifndef INVALID_SET_FILE_POINTER
2522 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
2523 #endif
2524 
2525 /*
2526 ** Move the current position of the file handle passed as the first
2527 ** argument to offset iOffset within the file. If successful, return 0.
2528 ** Otherwise, set pFile->lastErrno and return non-zero.
2529 */
2530 static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
2531 #if !SQLITE_OS_WINRT
2532   LONG upperBits;                 /* Most sig. 32 bits of new offset */
2533   LONG lowerBits;                 /* Least sig. 32 bits of new offset */
2534   DWORD dwRet;                    /* Value returned by SetFilePointer() */
2535   DWORD lastErrno;                /* Value returned by GetLastError() */
2536 
2537   OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
2538 
2539   upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
2540   lowerBits = (LONG)(iOffset & 0xffffffff);
2541 
2542   /* API oddity: If successful, SetFilePointer() returns a dword
2543   ** containing the lower 32-bits of the new file-offset. Or, if it fails,
2544   ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
2545   ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
2546   ** whether an error has actually occurred, it is also necessary to call
2547   ** GetLastError().
2548   */
2549   dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
2550 
2551   if( (dwRet==INVALID_SET_FILE_POINTER
2552       && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
2553     pFile->lastErrno = lastErrno;
2554     winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
2555                 "winSeekFile", pFile->zPath);
2556     OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
2557     return 1;
2558   }
2559 
2560   OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
2561   return 0;
2562 #else
2563   /*
2564   ** Same as above, except that this implementation works for WinRT.
2565   */
2566 
2567   LARGE_INTEGER x;                /* The new offset */
2568   BOOL bRet;                      /* Value returned by SetFilePointerEx() */
2569 
2570   x.QuadPart = iOffset;
2571   bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
2572 
2573   if(!bRet){
2574     pFile->lastErrno = osGetLastError();
2575     winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
2576                 "winSeekFile", pFile->zPath);
2577     OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
2578     return 1;
2579   }
2580 
2581   OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
2582   return 0;
2583 #endif
2584 }
2585 
2586 #if SQLITE_MAX_MMAP_SIZE>0
2587 /* Forward references to VFS helper methods used for memory mapped files */
2588 static int winMapfile(winFile*, sqlite3_int64);
2589 static int winUnmapfile(winFile*);
2590 #endif
2591 
2592 /*
2593 ** Close a file.
2594 **
2595 ** It is reported that an attempt to close a handle might sometimes
2596 ** fail.  This is a very unreasonable result, but Windows is notorious
2597 ** for being unreasonable so I do not doubt that it might happen.  If
2598 ** the close fails, we pause for 100 milliseconds and try again.  As
2599 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
2600 ** giving up and returning an error.
2601 */
2602 #define MX_CLOSE_ATTEMPT 3
2603 static int winClose(sqlite3_file *id){
2604   int rc, cnt = 0;
2605   winFile *pFile = (winFile*)id;
2606 
2607   assert( id!=0 );
2608 #ifndef SQLITE_OMIT_WAL
2609   assert( pFile->pShm==0 );
2610 #endif
2611   assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
2612   OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
2613            osGetCurrentProcessId(), pFile, pFile->h));
2614 
2615 #if SQLITE_MAX_MMAP_SIZE>0
2616   winUnmapfile(pFile);
2617 #endif
2618 
2619   do{
2620     rc = osCloseHandle(pFile->h);
2621     /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
2622   }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
2623 #if SQLITE_OS_WINCE
2624 #define WINCE_DELETION_ATTEMPTS 3
2625   {
2626     winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData;
2627     if( pAppData==NULL || !pAppData->bNoLock ){
2628       winceDestroyLock(pFile);
2629     }
2630   }
2631   if( pFile->zDeleteOnClose ){
2632     int cnt = 0;
2633     while(
2634            osDeleteFileW(pFile->zDeleteOnClose)==0
2635         && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
2636         && cnt++ < WINCE_DELETION_ATTEMPTS
2637     ){
2638        sqlite3_win32_sleep(100);  /* Wait a little before trying again */
2639     }
2640     sqlite3_free(pFile->zDeleteOnClose);
2641   }
2642 #endif
2643   if( rc ){
2644     pFile->h = NULL;
2645   }
2646   OpenCounter(-1);
2647   OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
2648            osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
2649   return rc ? SQLITE_OK
2650             : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
2651                           "winClose", pFile->zPath);
2652 }
2653 
2654 /*
2655 ** Read data from a file into a buffer.  Return SQLITE_OK if all
2656 ** bytes were read successfully and SQLITE_IOERR if anything goes
2657 ** wrong.
2658 */
2659 static int winRead(
2660   sqlite3_file *id,          /* File to read from */
2661   void *pBuf,                /* Write content into this buffer */
2662   int amt,                   /* Number of bytes to read */
2663   sqlite3_int64 offset       /* Begin reading at this offset */
2664 ){
2665 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
2666   OVERLAPPED overlapped;          /* The offset for ReadFile. */
2667 #endif
2668   winFile *pFile = (winFile*)id;  /* file handle */
2669   DWORD nRead;                    /* Number of bytes actually read from file */
2670   int nRetry = 0;                 /* Number of retrys */
2671 
2672   assert( id!=0 );
2673   assert( amt>0 );
2674   assert( offset>=0 );
2675   SimulateIOError(return SQLITE_IOERR_READ);
2676   OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
2677            "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
2678            pFile->h, pBuf, amt, offset, pFile->locktype));
2679 
2680 #if SQLITE_MAX_MMAP_SIZE>0
2681   /* Deal with as much of this read request as possible by transfering
2682   ** data from the memory mapping using memcpy().  */
2683   if( offset<pFile->mmapSize ){
2684     if( offset+amt <= pFile->mmapSize ){
2685       memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
2686       OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2687                osGetCurrentProcessId(), pFile, pFile->h));
2688       return SQLITE_OK;
2689     }else{
2690       int nCopy = (int)(pFile->mmapSize - offset);
2691       memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
2692       pBuf = &((u8 *)pBuf)[nCopy];
2693       amt -= nCopy;
2694       offset += nCopy;
2695     }
2696   }
2697 #endif
2698 
2699 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
2700   if( winSeekFile(pFile, offset) ){
2701     OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
2702              osGetCurrentProcessId(), pFile, pFile->h));
2703     return SQLITE_FULL;
2704   }
2705   while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
2706 #else
2707   memset(&overlapped, 0, sizeof(OVERLAPPED));
2708   overlapped.Offset = (LONG)(offset & 0xffffffff);
2709   overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
2710   while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
2711          osGetLastError()!=ERROR_HANDLE_EOF ){
2712 #endif
2713     DWORD lastErrno;
2714     if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
2715     pFile->lastErrno = lastErrno;
2716     OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
2717              osGetCurrentProcessId(), pFile, pFile->h));
2718     return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
2719                        "winRead", pFile->zPath);
2720   }
2721   winLogIoerr(nRetry, __LINE__);
2722   if( nRead<(DWORD)amt ){
2723     /* Unread parts of the buffer must be zero-filled */
2724     memset(&((char*)pBuf)[nRead], 0, amt-nRead);
2725     OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
2726              osGetCurrentProcessId(), pFile, pFile->h));
2727     return SQLITE_IOERR_SHORT_READ;
2728   }
2729 
2730   OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2731            osGetCurrentProcessId(), pFile, pFile->h));
2732   return SQLITE_OK;
2733 }
2734 
2735 /*
2736 ** Write data from a buffer into a file.  Return SQLITE_OK on success
2737 ** or some other error code on failure.
2738 */
2739 static int winWrite(
2740   sqlite3_file *id,               /* File to write into */
2741   const void *pBuf,               /* The bytes to be written */
2742   int amt,                        /* Number of bytes to write */
2743   sqlite3_int64 offset            /* Offset into the file to begin writing at */
2744 ){
2745   int rc = 0;                     /* True if error has occurred, else false */
2746   winFile *pFile = (winFile*)id;  /* File handle */
2747   int nRetry = 0;                 /* Number of retries */
2748 
2749   assert( amt>0 );
2750   assert( pFile );
2751   SimulateIOError(return SQLITE_IOERR_WRITE);
2752   SimulateDiskfullError(return SQLITE_FULL);
2753 
2754   OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
2755            "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
2756            pFile->h, pBuf, amt, offset, pFile->locktype));
2757 
2758 #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
2759   /* Deal with as much of this write request as possible by transfering
2760   ** data from the memory mapping using memcpy().  */
2761   if( offset<pFile->mmapSize ){
2762     if( offset+amt <= pFile->mmapSize ){
2763       memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
2764       OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2765                osGetCurrentProcessId(), pFile, pFile->h));
2766       return SQLITE_OK;
2767     }else{
2768       int nCopy = (int)(pFile->mmapSize - offset);
2769       memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
2770       pBuf = &((u8 *)pBuf)[nCopy];
2771       amt -= nCopy;
2772       offset += nCopy;
2773     }
2774   }
2775 #endif
2776 
2777 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
2778   rc = winSeekFile(pFile, offset);
2779   if( rc==0 ){
2780 #else
2781   {
2782 #endif
2783 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
2784     OVERLAPPED overlapped;        /* The offset for WriteFile. */
2785 #endif
2786     u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
2787     int nRem = amt;               /* Number of bytes yet to be written */
2788     DWORD nWrite;                 /* Bytes written by each WriteFile() call */
2789     DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
2790 
2791 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
2792     memset(&overlapped, 0, sizeof(OVERLAPPED));
2793     overlapped.Offset = (LONG)(offset & 0xffffffff);
2794     overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
2795 #endif
2796 
2797     while( nRem>0 ){
2798 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
2799       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
2800 #else
2801       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
2802 #endif
2803         if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
2804         break;
2805       }
2806       assert( nWrite==0 || nWrite<=(DWORD)nRem );
2807       if( nWrite==0 || nWrite>(DWORD)nRem ){
2808         lastErrno = osGetLastError();
2809         break;
2810       }
2811 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
2812       offset += nWrite;
2813       overlapped.Offset = (LONG)(offset & 0xffffffff);
2814       overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
2815 #endif
2816       aRem += nWrite;
2817       nRem -= nWrite;
2818     }
2819     if( nRem>0 ){
2820       pFile->lastErrno = lastErrno;
2821       rc = 1;
2822     }
2823   }
2824 
2825   if( rc ){
2826     if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
2827        || ( pFile->lastErrno==ERROR_DISK_FULL )){
2828       OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
2829                osGetCurrentProcessId(), pFile, pFile->h));
2830       return winLogError(SQLITE_FULL, pFile->lastErrno,
2831                          "winWrite1", pFile->zPath);
2832     }
2833     OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
2834              osGetCurrentProcessId(), pFile, pFile->h));
2835     return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
2836                        "winWrite2", pFile->zPath);
2837   }else{
2838     winLogIoerr(nRetry, __LINE__);
2839   }
2840   OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2841            osGetCurrentProcessId(), pFile, pFile->h));
2842   return SQLITE_OK;
2843 }
2844 
2845 /*
2846 ** Truncate an open file to a specified size
2847 */
2848 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
2849   winFile *pFile = (winFile*)id;  /* File handle object */
2850   int rc = SQLITE_OK;             /* Return code for this function */
2851   DWORD lastErrno;
2852 
2853   assert( pFile );
2854   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
2855   OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
2856            osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
2857 
2858   /* If the user has configured a chunk-size for this file, truncate the
2859   ** file so that it consists of an integer number of chunks (i.e. the
2860   ** actual file size after the operation may be larger than the requested
2861   ** size).
2862   */
2863   if( pFile->szChunk>0 ){
2864     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
2865   }
2866 
2867   /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
2868   if( winSeekFile(pFile, nByte) ){
2869     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
2870                      "winTruncate1", pFile->zPath);
2871   }else if( 0==osSetEndOfFile(pFile->h) &&
2872             ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
2873     pFile->lastErrno = lastErrno;
2874     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
2875                      "winTruncate2", pFile->zPath);
2876   }
2877 
2878 #if SQLITE_MAX_MMAP_SIZE>0
2879   /* If the file was truncated to a size smaller than the currently
2880   ** mapped region, reduce the effective mapping size as well. SQLite will
2881   ** use read() and write() to access data beyond this point from now on.
2882   */
2883   if( pFile->pMapRegion && nByte<pFile->mmapSize ){
2884     pFile->mmapSize = nByte;
2885   }
2886 #endif
2887 
2888   OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
2889            osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
2890   return rc;
2891 }
2892 
2893 #ifdef SQLITE_TEST
2894 /*
2895 ** Count the number of fullsyncs and normal syncs.  This is used to test
2896 ** that syncs and fullsyncs are occuring at the right times.
2897 */
2898 int sqlite3_sync_count = 0;
2899 int sqlite3_fullsync_count = 0;
2900 #endif
2901 
2902 /*
2903 ** Make sure all writes to a particular file are committed to disk.
2904 */
2905 static int winSync(sqlite3_file *id, int flags){
2906 #ifndef SQLITE_NO_SYNC
2907   /*
2908   ** Used only when SQLITE_NO_SYNC is not defined.
2909    */
2910   BOOL rc;
2911 #endif
2912 #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
2913     defined(SQLITE_HAVE_OS_TRACE)
2914   /*
2915   ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
2916   ** OSTRACE() macros.
2917    */
2918   winFile *pFile = (winFile*)id;
2919 #else
2920   UNUSED_PARAMETER(id);
2921 #endif
2922 
2923   assert( pFile );
2924   /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
2925   assert((flags&0x0F)==SQLITE_SYNC_NORMAL
2926       || (flags&0x0F)==SQLITE_SYNC_FULL
2927   );
2928 
2929   /* Unix cannot, but some systems may return SQLITE_FULL from here. This
2930   ** line is to test that doing so does not cause any problems.
2931   */
2932   SimulateDiskfullError( return SQLITE_FULL );
2933 
2934   OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
2935            osGetCurrentProcessId(), pFile, pFile->h, flags,
2936            pFile->locktype));
2937 
2938 #ifndef SQLITE_TEST
2939   UNUSED_PARAMETER(flags);
2940 #else
2941   if( (flags&0x0F)==SQLITE_SYNC_FULL ){
2942     sqlite3_fullsync_count++;
2943   }
2944   sqlite3_sync_count++;
2945 #endif
2946 
2947   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
2948   ** no-op
2949   */
2950 #ifdef SQLITE_NO_SYNC
2951   OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2952            osGetCurrentProcessId(), pFile, pFile->h));
2953   return SQLITE_OK;
2954 #else
2955 #if SQLITE_MAX_MMAP_SIZE>0
2956   if( pFile->pMapRegion ){
2957     if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
2958       OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
2959                "rc=SQLITE_OK\n", osGetCurrentProcessId(),
2960                pFile, pFile->pMapRegion));
2961     }else{
2962       pFile->lastErrno = osGetLastError();
2963       OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
2964                "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
2965                pFile, pFile->pMapRegion));
2966       return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
2967                          "winSync1", pFile->zPath);
2968     }
2969   }
2970 #endif
2971   rc = osFlushFileBuffers(pFile->h);
2972   SimulateIOError( rc=FALSE );
2973   if( rc ){
2974     OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
2975              osGetCurrentProcessId(), pFile, pFile->h));
2976     return SQLITE_OK;
2977   }else{
2978     pFile->lastErrno = osGetLastError();
2979     OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
2980              osGetCurrentProcessId(), pFile, pFile->h));
2981     return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
2982                        "winSync2", pFile->zPath);
2983   }
2984 #endif
2985 }
2986 
2987 /*
2988 ** Determine the current size of a file in bytes
2989 */
2990 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
2991   winFile *pFile = (winFile*)id;
2992   int rc = SQLITE_OK;
2993 
2994   assert( id!=0 );
2995   assert( pSize!=0 );
2996   SimulateIOError(return SQLITE_IOERR_FSTAT);
2997   OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
2998 
2999 #if SQLITE_OS_WINRT
3000   {
3001     FILE_STANDARD_INFO info;
3002     if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
3003                                      &info, sizeof(info)) ){
3004       *pSize = info.EndOfFile.QuadPart;
3005     }else{
3006       pFile->lastErrno = osGetLastError();
3007       rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
3008                        "winFileSize", pFile->zPath);
3009     }
3010   }
3011 #else
3012   {
3013     DWORD upperBits;
3014     DWORD lowerBits;
3015     DWORD lastErrno;
3016 
3017     lowerBits = osGetFileSize(pFile->h, &upperBits);
3018     *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
3019     if(   (lowerBits == INVALID_FILE_SIZE)
3020        && ((lastErrno = osGetLastError())!=NO_ERROR) ){
3021       pFile->lastErrno = lastErrno;
3022       rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
3023                        "winFileSize", pFile->zPath);
3024     }
3025   }
3026 #endif
3027   OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
3028            pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
3029   return rc;
3030 }
3031 
3032 /*
3033 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
3034 */
3035 #ifndef LOCKFILE_FAIL_IMMEDIATELY
3036 # define LOCKFILE_FAIL_IMMEDIATELY 1
3037 #endif
3038 
3039 #ifndef LOCKFILE_EXCLUSIVE_LOCK
3040 # define LOCKFILE_EXCLUSIVE_LOCK 2
3041 #endif
3042 
3043 /*
3044 ** Historically, SQLite has used both the LockFile and LockFileEx functions.
3045 ** When the LockFile function was used, it was always expected to fail
3046 ** immediately if the lock could not be obtained.  Also, it always expected to
3047 ** obtain an exclusive lock.  These flags are used with the LockFileEx function
3048 ** and reflect those expectations; therefore, they should not be changed.
3049 */
3050 #ifndef SQLITE_LOCKFILE_FLAGS
3051 # define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
3052                                   LOCKFILE_EXCLUSIVE_LOCK)
3053 #endif
3054 
3055 /*
3056 ** Currently, SQLite never calls the LockFileEx function without wanting the
3057 ** call to fail immediately if the lock cannot be obtained.
3058 */
3059 #ifndef SQLITE_LOCKFILEEX_FLAGS
3060 # define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
3061 #endif
3062 
3063 /*
3064 ** Acquire a reader lock.
3065 ** Different API routines are called depending on whether or not this
3066 ** is Win9x or WinNT.
3067 */
3068 static int winGetReadLock(winFile *pFile){
3069   int res;
3070   OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
3071   if( osIsNT() ){
3072 #if SQLITE_OS_WINCE
3073     /*
3074     ** NOTE: Windows CE is handled differently here due its lack of the Win32
3075     **       API LockFileEx.
3076     */
3077     res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
3078 #else
3079     res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
3080                       SHARED_SIZE, 0);
3081 #endif
3082   }
3083 #ifdef SQLITE_WIN32_HAS_ANSI
3084   else{
3085     int lk;
3086     sqlite3_randomness(sizeof(lk), &lk);
3087     pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
3088     res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
3089                       SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
3090   }
3091 #endif
3092   if( res == 0 ){
3093     pFile->lastErrno = osGetLastError();
3094     /* No need to log a failure to lock */
3095   }
3096   OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
3097   return res;
3098 }
3099 
3100 /*
3101 ** Undo a readlock
3102 */
3103 static int winUnlockReadLock(winFile *pFile){
3104   int res;
3105   DWORD lastErrno;
3106   OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
3107   if( osIsNT() ){
3108     res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
3109   }
3110 #ifdef SQLITE_WIN32_HAS_ANSI
3111   else{
3112     res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
3113   }
3114 #endif
3115   if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
3116     pFile->lastErrno = lastErrno;
3117     winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
3118                 "winUnlockReadLock", pFile->zPath);
3119   }
3120   OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
3121   return res;
3122 }
3123 
3124 /*
3125 ** Lock the file with the lock specified by parameter locktype - one
3126 ** of the following:
3127 **
3128 **     (1) SHARED_LOCK
3129 **     (2) RESERVED_LOCK
3130 **     (3) PENDING_LOCK
3131 **     (4) EXCLUSIVE_LOCK
3132 **
3133 ** Sometimes when requesting one lock state, additional lock states
3134 ** are inserted in between.  The locking might fail on one of the later
3135 ** transitions leaving the lock state different from what it started but
3136 ** still short of its goal.  The following chart shows the allowed
3137 ** transitions and the inserted intermediate states:
3138 **
3139 **    UNLOCKED -> SHARED
3140 **    SHARED -> RESERVED
3141 **    SHARED -> (PENDING) -> EXCLUSIVE
3142 **    RESERVED -> (PENDING) -> EXCLUSIVE
3143 **    PENDING -> EXCLUSIVE
3144 **
3145 ** This routine will only increase a lock.  The winUnlock() routine
3146 ** erases all locks at once and returns us immediately to locking level 0.
3147 ** It is not possible to lower the locking level one step at a time.  You
3148 ** must go straight to locking level 0.
3149 */
3150 static int winLock(sqlite3_file *id, int locktype){
3151   int rc = SQLITE_OK;    /* Return code from subroutines */
3152   int res = 1;           /* Result of a Windows lock call */
3153   int newLocktype;       /* Set pFile->locktype to this value before exiting */
3154   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
3155   winFile *pFile = (winFile*)id;
3156   DWORD lastErrno = NO_ERROR;
3157 
3158   assert( id!=0 );
3159   OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
3160            pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
3161 
3162   /* If there is already a lock of this type or more restrictive on the
3163   ** OsFile, do nothing. Don't use the end_lock: exit path, as
3164   ** sqlite3OsEnterMutex() hasn't been called yet.
3165   */
3166   if( pFile->locktype>=locktype ){
3167     OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
3168     return SQLITE_OK;
3169   }
3170 
3171   /* Do not allow any kind of write-lock on a read-only database
3172   */
3173   if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
3174     return SQLITE_IOERR_LOCK;
3175   }
3176 
3177   /* Make sure the locking sequence is correct
3178   */
3179   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
3180   assert( locktype!=PENDING_LOCK );
3181   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
3182 
3183   /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
3184   ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
3185   ** the PENDING_LOCK byte is temporary.
3186   */
3187   newLocktype = pFile->locktype;
3188   if( pFile->locktype==NO_LOCK
3189    || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
3190   ){
3191     int cnt = 3;
3192     while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
3193                                          PENDING_BYTE, 0, 1, 0))==0 ){
3194       /* Try 3 times to get the pending lock.  This is needed to work
3195       ** around problems caused by indexing and/or anti-virus software on
3196       ** Windows systems.
3197       ** If you are using this code as a model for alternative VFSes, do not
3198       ** copy this retry logic.  It is a hack intended for Windows only.
3199       */
3200       lastErrno = osGetLastError();
3201       OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
3202                pFile->h, cnt, res));
3203       if( lastErrno==ERROR_INVALID_HANDLE ){
3204         pFile->lastErrno = lastErrno;
3205         rc = SQLITE_IOERR_LOCK;
3206         OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
3207                  pFile->h, cnt, sqlite3ErrName(rc)));
3208         return rc;
3209       }
3210       if( cnt ) sqlite3_win32_sleep(1);
3211     }
3212     gotPendingLock = res;
3213     if( !res ){
3214       lastErrno = osGetLastError();
3215     }
3216   }
3217 
3218   /* Acquire a shared lock
3219   */
3220   if( locktype==SHARED_LOCK && res ){
3221     assert( pFile->locktype==NO_LOCK );
3222     res = winGetReadLock(pFile);
3223     if( res ){
3224       newLocktype = SHARED_LOCK;
3225     }else{
3226       lastErrno = osGetLastError();
3227     }
3228   }
3229 
3230   /* Acquire a RESERVED lock
3231   */
3232   if( locktype==RESERVED_LOCK && res ){
3233     assert( pFile->locktype==SHARED_LOCK );
3234     res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
3235     if( res ){
3236       newLocktype = RESERVED_LOCK;
3237     }else{
3238       lastErrno = osGetLastError();
3239     }
3240   }
3241 
3242   /* Acquire a PENDING lock
3243   */
3244   if( locktype==EXCLUSIVE_LOCK && res ){
3245     newLocktype = PENDING_LOCK;
3246     gotPendingLock = 0;
3247   }
3248 
3249   /* Acquire an EXCLUSIVE lock
3250   */
3251   if( locktype==EXCLUSIVE_LOCK && res ){
3252     assert( pFile->locktype>=SHARED_LOCK );
3253     res = winUnlockReadLock(pFile);
3254     res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
3255                       SHARED_SIZE, 0);
3256     if( res ){
3257       newLocktype = EXCLUSIVE_LOCK;
3258     }else{
3259       lastErrno = osGetLastError();
3260       winGetReadLock(pFile);
3261     }
3262   }
3263 
3264   /* If we are holding a PENDING lock that ought to be released, then
3265   ** release it now.
3266   */
3267   if( gotPendingLock && locktype==SHARED_LOCK ){
3268     winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
3269   }
3270 
3271   /* Update the state of the lock has held in the file descriptor then
3272   ** return the appropriate result code.
3273   */
3274   if( res ){
3275     rc = SQLITE_OK;
3276   }else{
3277     pFile->lastErrno = lastErrno;
3278     rc = SQLITE_BUSY;
3279     OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
3280              pFile->h, locktype, newLocktype));
3281   }
3282   pFile->locktype = (u8)newLocktype;
3283   OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
3284            pFile->h, pFile->locktype, sqlite3ErrName(rc)));
3285   return rc;
3286 }
3287 
3288 /*
3289 ** This routine checks if there is a RESERVED lock held on the specified
3290 ** file by this or any other process. If such a lock is held, return
3291 ** non-zero, otherwise zero.
3292 */
3293 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
3294   int res;
3295   winFile *pFile = (winFile*)id;
3296 
3297   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
3298   OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
3299 
3300   assert( id!=0 );
3301   if( pFile->locktype>=RESERVED_LOCK ){
3302     res = 1;
3303     OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
3304   }else{
3305     res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0);
3306     if( res ){
3307       winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
3308     }
3309     res = !res;
3310     OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
3311   }
3312   *pResOut = res;
3313   OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
3314            pFile->h, pResOut, *pResOut));
3315   return SQLITE_OK;
3316 }
3317 
3318 /*
3319 ** Lower the locking level on file descriptor id to locktype.  locktype
3320 ** must be either NO_LOCK or SHARED_LOCK.
3321 **
3322 ** If the locking level of the file descriptor is already at or below
3323 ** the requested locking level, this routine is a no-op.
3324 **
3325 ** It is not possible for this routine to fail if the second argument
3326 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
3327 ** might return SQLITE_IOERR;
3328 */
3329 static int winUnlock(sqlite3_file *id, int locktype){
3330   int type;
3331   winFile *pFile = (winFile*)id;
3332   int rc = SQLITE_OK;
3333   assert( pFile!=0 );
3334   assert( locktype<=SHARED_LOCK );
3335   OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
3336            pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
3337   type = pFile->locktype;
3338   if( type>=EXCLUSIVE_LOCK ){
3339     winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
3340     if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
3341       /* This should never happen.  We should always be able to
3342       ** reacquire the read lock */
3343       rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
3344                        "winUnlock", pFile->zPath);
3345     }
3346   }
3347   if( type>=RESERVED_LOCK ){
3348     winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
3349   }
3350   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
3351     winUnlockReadLock(pFile);
3352   }
3353   if( type>=PENDING_LOCK ){
3354     winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
3355   }
3356   pFile->locktype = (u8)locktype;
3357   OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
3358            pFile->h, pFile->locktype, sqlite3ErrName(rc)));
3359   return rc;
3360 }
3361 
3362 /******************************************************************************
3363 ****************************** No-op Locking **********************************
3364 **
3365 ** Of the various locking implementations available, this is by far the
3366 ** simplest:  locking is ignored.  No attempt is made to lock the database
3367 ** file for reading or writing.
3368 **
3369 ** This locking mode is appropriate for use on read-only databases
3370 ** (ex: databases that are burned into CD-ROM, for example.)  It can
3371 ** also be used if the application employs some external mechanism to
3372 ** prevent simultaneous access of the same database by two or more
3373 ** database connections.  But there is a serious risk of database
3374 ** corruption if this locking mode is used in situations where multiple
3375 ** database connections are accessing the same database file at the same
3376 ** time and one or more of those connections are writing.
3377 */
3378 
3379 static int winNolockLock(sqlite3_file *id, int locktype){
3380   UNUSED_PARAMETER(id);
3381   UNUSED_PARAMETER(locktype);
3382   return SQLITE_OK;
3383 }
3384 
3385 static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){
3386   UNUSED_PARAMETER(id);
3387   UNUSED_PARAMETER(pResOut);
3388   return SQLITE_OK;
3389 }
3390 
3391 static int winNolockUnlock(sqlite3_file *id, int locktype){
3392   UNUSED_PARAMETER(id);
3393   UNUSED_PARAMETER(locktype);
3394   return SQLITE_OK;
3395 }
3396 
3397 /******************* End of the no-op lock implementation *********************
3398 ******************************************************************************/
3399 
3400 /*
3401 ** If *pArg is initially negative then this is a query.  Set *pArg to
3402 ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
3403 **
3404 ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
3405 */
3406 static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
3407   if( *pArg<0 ){
3408     *pArg = (pFile->ctrlFlags & mask)!=0;
3409   }else if( (*pArg)==0 ){
3410     pFile->ctrlFlags &= ~mask;
3411   }else{
3412     pFile->ctrlFlags |= mask;
3413   }
3414 }
3415 
3416 /* Forward references to VFS helper methods used for temporary files */
3417 static int winGetTempname(sqlite3_vfs *, char **);
3418 static int winIsDir(const void *);
3419 static BOOL winIsDriveLetterAndColon(const char *);
3420 
3421 /*
3422 ** Control and query of the open file handle.
3423 */
3424 static int winFileControl(sqlite3_file *id, int op, void *pArg){
3425   winFile *pFile = (winFile*)id;
3426   OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
3427   switch( op ){
3428     case SQLITE_FCNTL_LOCKSTATE: {
3429       *(int*)pArg = pFile->locktype;
3430       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3431       return SQLITE_OK;
3432     }
3433     case SQLITE_FCNTL_LAST_ERRNO: {
3434       *(int*)pArg = (int)pFile->lastErrno;
3435       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3436       return SQLITE_OK;
3437     }
3438     case SQLITE_FCNTL_CHUNK_SIZE: {
3439       pFile->szChunk = *(int *)pArg;
3440       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3441       return SQLITE_OK;
3442     }
3443     case SQLITE_FCNTL_SIZE_HINT: {
3444       if( pFile->szChunk>0 ){
3445         sqlite3_int64 oldSz;
3446         int rc = winFileSize(id, &oldSz);
3447         if( rc==SQLITE_OK ){
3448           sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
3449           if( newSz>oldSz ){
3450             SimulateIOErrorBenign(1);
3451             rc = winTruncate(id, newSz);
3452             SimulateIOErrorBenign(0);
3453           }
3454         }
3455         OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
3456         return rc;
3457       }
3458       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3459       return SQLITE_OK;
3460     }
3461     case SQLITE_FCNTL_PERSIST_WAL: {
3462       winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
3463       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3464       return SQLITE_OK;
3465     }
3466     case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
3467       winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
3468       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3469       return SQLITE_OK;
3470     }
3471     case SQLITE_FCNTL_VFSNAME: {
3472       *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
3473       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3474       return SQLITE_OK;
3475     }
3476     case SQLITE_FCNTL_WIN32_AV_RETRY: {
3477       int *a = (int*)pArg;
3478       if( a[0]>0 ){
3479         winIoerrRetry = a[0];
3480       }else{
3481         a[0] = winIoerrRetry;
3482       }
3483       if( a[1]>0 ){
3484         winIoerrRetryDelay = a[1];
3485       }else{
3486         a[1] = winIoerrRetryDelay;
3487       }
3488       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
3489       return SQLITE_OK;
3490     }
3491 #ifdef SQLITE_TEST
3492     case SQLITE_FCNTL_WIN32_SET_HANDLE: {
3493       LPHANDLE phFile = (LPHANDLE)pArg;
3494       HANDLE hOldFile = pFile->h;
3495       pFile->h = *phFile;
3496       *phFile = hOldFile;
3497       OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
3498                hOldFile, pFile->h));
3499       return SQLITE_OK;
3500     }
3501 #endif
3502     case SQLITE_FCNTL_TEMPFILENAME: {
3503       char *zTFile = 0;
3504       int rc = winGetTempname(pFile->pVfs, &zTFile);
3505       if( rc==SQLITE_OK ){
3506         *(char**)pArg = zTFile;
3507       }
3508       OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
3509       return rc;
3510     }
3511 #if SQLITE_MAX_MMAP_SIZE>0
3512     case SQLITE_FCNTL_MMAP_SIZE: {
3513       i64 newLimit = *(i64*)pArg;
3514       int rc = SQLITE_OK;
3515       if( newLimit>sqlite3GlobalConfig.mxMmap ){
3516         newLimit = sqlite3GlobalConfig.mxMmap;
3517       }
3518       *(i64*)pArg = pFile->mmapSizeMax;
3519       if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
3520         pFile->mmapSizeMax = newLimit;
3521         if( pFile->mmapSize>0 ){
3522           winUnmapfile(pFile);
3523           rc = winMapfile(pFile, -1);
3524         }
3525       }
3526       OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
3527       return rc;
3528     }
3529 #endif
3530   }
3531   OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
3532   return SQLITE_NOTFOUND;
3533 }
3534 
3535 /*
3536 ** Return the sector size in bytes of the underlying block device for
3537 ** the specified file. This is almost always 512 bytes, but may be
3538 ** larger for some devices.
3539 **
3540 ** SQLite code assumes this function cannot fail. It also assumes that
3541 ** if two files are created in the same file-system directory (i.e.
3542 ** a database and its journal file) that the sector size will be the
3543 ** same for both.
3544 */
3545 static int winSectorSize(sqlite3_file *id){
3546   (void)id;
3547   return SQLITE_DEFAULT_SECTOR_SIZE;
3548 }
3549 
3550 /*
3551 ** Return a vector of device characteristics.
3552 */
3553 static int winDeviceCharacteristics(sqlite3_file *id){
3554   winFile *p = (winFile*)id;
3555   return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
3556          ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
3557 }
3558 
3559 /*
3560 ** Windows will only let you create file view mappings
3561 ** on allocation size granularity boundaries.
3562 ** During sqlite3_os_init() we do a GetSystemInfo()
3563 ** to get the granularity size.
3564 */
3565 static SYSTEM_INFO winSysInfo;
3566 
3567 #ifndef SQLITE_OMIT_WAL
3568 
3569 /*
3570 ** Helper functions to obtain and relinquish the global mutex. The
3571 ** global mutex is used to protect the winLockInfo objects used by
3572 ** this file, all of which may be shared by multiple threads.
3573 **
3574 ** Function winShmMutexHeld() is used to assert() that the global mutex
3575 ** is held when required. This function is only used as part of assert()
3576 ** statements. e.g.
3577 **
3578 **   winShmEnterMutex()
3579 **     assert( winShmMutexHeld() );
3580 **   winShmLeaveMutex()
3581 */
3582 static void winShmEnterMutex(void){
3583   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
3584 }
3585 static void winShmLeaveMutex(void){
3586   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
3587 }
3588 #ifndef NDEBUG
3589 static int winShmMutexHeld(void) {
3590   return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
3591 }
3592 #endif
3593 
3594 /*
3595 ** Object used to represent a single file opened and mmapped to provide
3596 ** shared memory.  When multiple threads all reference the same
3597 ** log-summary, each thread has its own winFile object, but they all
3598 ** point to a single instance of this object.  In other words, each
3599 ** log-summary is opened only once per process.
3600 **
3601 ** winShmMutexHeld() must be true when creating or destroying
3602 ** this object or while reading or writing the following fields:
3603 **
3604 **      nRef
3605 **      pNext
3606 **
3607 ** The following fields are read-only after the object is created:
3608 **
3609 **      fid
3610 **      zFilename
3611 **
3612 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
3613 ** winShmMutexHeld() is true when reading or writing any other field
3614 ** in this structure.
3615 **
3616 */
3617 struct winShmNode {
3618   sqlite3_mutex *mutex;      /* Mutex to access this object */
3619   char *zFilename;           /* Name of the file */
3620   winFile hFile;             /* File handle from winOpen */
3621 
3622   int szRegion;              /* Size of shared-memory regions */
3623   int nRegion;               /* Size of array apRegion */
3624   struct ShmRegion {
3625     HANDLE hMap;             /* File handle from CreateFileMapping */
3626     void *pMap;
3627   } *aRegion;
3628   DWORD lastErrno;           /* The Windows errno from the last I/O error */
3629 
3630   int nRef;                  /* Number of winShm objects pointing to this */
3631   winShm *pFirst;            /* All winShm objects pointing to this */
3632   winShmNode *pNext;         /* Next in list of all winShmNode objects */
3633 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
3634   u8 nextShmId;              /* Next available winShm.id value */
3635 #endif
3636 };
3637 
3638 /*
3639 ** A global array of all winShmNode objects.
3640 **
3641 ** The winShmMutexHeld() must be true while reading or writing this list.
3642 */
3643 static winShmNode *winShmNodeList = 0;
3644 
3645 /*
3646 ** Structure used internally by this VFS to record the state of an
3647 ** open shared memory connection.
3648 **
3649 ** The following fields are initialized when this object is created and
3650 ** are read-only thereafter:
3651 **
3652 **    winShm.pShmNode
3653 **    winShm.id
3654 **
3655 ** All other fields are read/write.  The winShm.pShmNode->mutex must be held
3656 ** while accessing any read/write fields.
3657 */
3658 struct winShm {
3659   winShmNode *pShmNode;      /* The underlying winShmNode object */
3660   winShm *pNext;             /* Next winShm with the same winShmNode */
3661   u8 hasMutex;               /* True if holding the winShmNode mutex */
3662   u16 sharedMask;            /* Mask of shared locks held */
3663   u16 exclMask;              /* Mask of exclusive locks held */
3664 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
3665   u8 id;                     /* Id of this connection with its winShmNode */
3666 #endif
3667 };
3668 
3669 /*
3670 ** Constants used for locking
3671 */
3672 #define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
3673 #define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
3674 
3675 /*
3676 ** Apply advisory locks for all n bytes beginning at ofst.
3677 */
3678 #define WINSHM_UNLCK  1
3679 #define WINSHM_RDLCK  2
3680 #define WINSHM_WRLCK  3
3681 static int winShmSystemLock(
3682   winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
3683   int lockType,         /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
3684   int ofst,             /* Offset to first byte to be locked/unlocked */
3685   int nByte             /* Number of bytes to lock or unlock */
3686 ){
3687   int rc = 0;           /* Result code form Lock/UnlockFileEx() */
3688 
3689   /* Access to the winShmNode object is serialized by the caller */
3690   assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
3691 
3692   OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
3693            pFile->hFile.h, lockType, ofst, nByte));
3694 
3695   /* Release/Acquire the system-level lock */
3696   if( lockType==WINSHM_UNLCK ){
3697     rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
3698   }else{
3699     /* Initialize the locking parameters */
3700     DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
3701     if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
3702     rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
3703   }
3704 
3705   if( rc!= 0 ){
3706     rc = SQLITE_OK;
3707   }else{
3708     pFile->lastErrno =  osGetLastError();
3709     rc = SQLITE_BUSY;
3710   }
3711 
3712   OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
3713            pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" :
3714            "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
3715 
3716   return rc;
3717 }
3718 
3719 /* Forward references to VFS methods */
3720 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
3721 static int winDelete(sqlite3_vfs *,const char*,int);
3722 
3723 /*
3724 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
3725 **
3726 ** This is not a VFS shared-memory method; it is a utility function called
3727 ** by VFS shared-memory methods.
3728 */
3729 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
3730   winShmNode **pp;
3731   winShmNode *p;
3732   assert( winShmMutexHeld() );
3733   OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
3734            osGetCurrentProcessId(), deleteFlag));
3735   pp = &winShmNodeList;
3736   while( (p = *pp)!=0 ){
3737     if( p->nRef==0 ){
3738       int i;
3739       if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
3740       for(i=0; i<p->nRegion; i++){
3741         BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
3742         OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
3743                  osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
3744         UNUSED_VARIABLE_VALUE(bRc);
3745         bRc = osCloseHandle(p->aRegion[i].hMap);
3746         OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
3747                  osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
3748         UNUSED_VARIABLE_VALUE(bRc);
3749       }
3750       if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
3751         SimulateIOErrorBenign(1);
3752         winClose((sqlite3_file *)&p->hFile);
3753         SimulateIOErrorBenign(0);
3754       }
3755       if( deleteFlag ){
3756         SimulateIOErrorBenign(1);
3757         sqlite3BeginBenignMalloc();
3758         winDelete(pVfs, p->zFilename, 0);
3759         sqlite3EndBenignMalloc();
3760         SimulateIOErrorBenign(0);
3761       }
3762       *pp = p->pNext;
3763       sqlite3_free(p->aRegion);
3764       sqlite3_free(p);
3765     }else{
3766       pp = &p->pNext;
3767     }
3768   }
3769 }
3770 
3771 /*
3772 ** Open the shared-memory area associated with database file pDbFd.
3773 **
3774 ** When opening a new shared-memory file, if no other instances of that
3775 ** file are currently open, in this process or in other processes, then
3776 ** the file must be truncated to zero length or have its header cleared.
3777 */
3778 static int winOpenSharedMemory(winFile *pDbFd){
3779   struct winShm *p;                  /* The connection to be opened */
3780   struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
3781   int rc;                            /* Result code */
3782   struct winShmNode *pNew;           /* Newly allocated winShmNode */
3783   int nName;                         /* Size of zName in bytes */
3784 
3785   assert( pDbFd->pShm==0 );    /* Not previously opened */
3786 
3787   /* Allocate space for the new sqlite3_shm object.  Also speculatively
3788   ** allocate space for a new winShmNode and filename.
3789   */
3790   p = sqlite3MallocZero( sizeof(*p) );
3791   if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
3792   nName = sqlite3Strlen30(pDbFd->zPath);
3793   pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
3794   if( pNew==0 ){
3795     sqlite3_free(p);
3796     return SQLITE_IOERR_NOMEM_BKPT;
3797   }
3798   pNew->zFilename = (char*)&pNew[1];
3799   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
3800   sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
3801 
3802   /* Look to see if there is an existing winShmNode that can be used.
3803   ** If no matching winShmNode currently exists, create a new one.
3804   */
3805   winShmEnterMutex();
3806   for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
3807     /* TBD need to come up with better match here.  Perhaps
3808     ** use FILE_ID_BOTH_DIR_INFO Structure.
3809     */
3810     if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
3811   }
3812   if( pShmNode ){
3813     sqlite3_free(pNew);
3814   }else{
3815     pShmNode = pNew;
3816     pNew = 0;
3817     ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
3818     pShmNode->pNext = winShmNodeList;
3819     winShmNodeList = pShmNode;
3820 
3821     if( sqlite3GlobalConfig.bCoreMutex ){
3822       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
3823       if( pShmNode->mutex==0 ){
3824         rc = SQLITE_IOERR_NOMEM_BKPT;
3825         goto shm_open_err;
3826       }
3827     }
3828 
3829     rc = winOpen(pDbFd->pVfs,
3830                  pShmNode->zFilename,             /* Name of the file (UTF-8) */
3831                  (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
3832                  SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
3833                  0);
3834     if( SQLITE_OK!=rc ){
3835       goto shm_open_err;
3836     }
3837 
3838     /* Check to see if another process is holding the dead-man switch.
3839     ** If not, truncate the file to zero length.
3840     */
3841     if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
3842       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
3843       if( rc!=SQLITE_OK ){
3844         rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
3845                          "winOpenShm", pDbFd->zPath);
3846       }
3847     }
3848     if( rc==SQLITE_OK ){
3849       winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
3850       rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
3851     }
3852     if( rc ) goto shm_open_err;
3853   }
3854 
3855   /* Make the new connection a child of the winShmNode */
3856   p->pShmNode = pShmNode;
3857 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
3858   p->id = pShmNode->nextShmId++;
3859 #endif
3860   pShmNode->nRef++;
3861   pDbFd->pShm = p;
3862   winShmLeaveMutex();
3863 
3864   /* The reference count on pShmNode has already been incremented under
3865   ** the cover of the winShmEnterMutex() mutex and the pointer from the
3866   ** new (struct winShm) object to the pShmNode has been set. All that is
3867   ** left to do is to link the new object into the linked list starting
3868   ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
3869   ** mutex.
3870   */
3871   sqlite3_mutex_enter(pShmNode->mutex);
3872   p->pNext = pShmNode->pFirst;
3873   pShmNode->pFirst = p;
3874   sqlite3_mutex_leave(pShmNode->mutex);
3875   return SQLITE_OK;
3876 
3877   /* Jump here on any error */
3878 shm_open_err:
3879   winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
3880   winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
3881   sqlite3_free(p);
3882   sqlite3_free(pNew);
3883   winShmLeaveMutex();
3884   return rc;
3885 }
3886 
3887 /*
3888 ** Close a connection to shared-memory.  Delete the underlying
3889 ** storage if deleteFlag is true.
3890 */
3891 static int winShmUnmap(
3892   sqlite3_file *fd,          /* Database holding shared memory */
3893   int deleteFlag             /* Delete after closing if true */
3894 ){
3895   winFile *pDbFd;       /* Database holding shared-memory */
3896   winShm *p;            /* The connection to be closed */
3897   winShmNode *pShmNode; /* The underlying shared-memory file */
3898   winShm **pp;          /* For looping over sibling connections */
3899 
3900   pDbFd = (winFile*)fd;
3901   p = pDbFd->pShm;
3902   if( p==0 ) return SQLITE_OK;
3903   pShmNode = p->pShmNode;
3904 
3905   /* Remove connection p from the set of connections associated
3906   ** with pShmNode */
3907   sqlite3_mutex_enter(pShmNode->mutex);
3908   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
3909   *pp = p->pNext;
3910 
3911   /* Free the connection p */
3912   sqlite3_free(p);
3913   pDbFd->pShm = 0;
3914   sqlite3_mutex_leave(pShmNode->mutex);
3915 
3916   /* If pShmNode->nRef has reached 0, then close the underlying
3917   ** shared-memory file, too */
3918   winShmEnterMutex();
3919   assert( pShmNode->nRef>0 );
3920   pShmNode->nRef--;
3921   if( pShmNode->nRef==0 ){
3922     winShmPurge(pDbFd->pVfs, deleteFlag);
3923   }
3924   winShmLeaveMutex();
3925 
3926   return SQLITE_OK;
3927 }
3928 
3929 /*
3930 ** Change the lock state for a shared-memory segment.
3931 */
3932 static int winShmLock(
3933   sqlite3_file *fd,          /* Database file holding the shared memory */
3934   int ofst,                  /* First lock to acquire or release */
3935   int n,                     /* Number of locks to acquire or release */
3936   int flags                  /* What to do with the lock */
3937 ){
3938   winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
3939   winShm *p = pDbFd->pShm;              /* The shared memory being locked */
3940   winShm *pX;                           /* For looping over all siblings */
3941   winShmNode *pShmNode = p->pShmNode;
3942   int rc = SQLITE_OK;                   /* Result code */
3943   u16 mask;                             /* Mask of locks to take or release */
3944 
3945   assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
3946   assert( n>=1 );
3947   assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
3948        || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
3949        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
3950        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
3951   assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
3952 
3953   mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
3954   assert( n>1 || mask==(1<<ofst) );
3955   sqlite3_mutex_enter(pShmNode->mutex);
3956   if( flags & SQLITE_SHM_UNLOCK ){
3957     u16 allMask = 0; /* Mask of locks held by siblings */
3958 
3959     /* See if any siblings hold this same lock */
3960     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
3961       if( pX==p ) continue;
3962       assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
3963       allMask |= pX->sharedMask;
3964     }
3965 
3966     /* Unlock the system-level locks */
3967     if( (mask & allMask)==0 ){
3968       rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n);
3969     }else{
3970       rc = SQLITE_OK;
3971     }
3972 
3973     /* Undo the local locks */
3974     if( rc==SQLITE_OK ){
3975       p->exclMask &= ~mask;
3976       p->sharedMask &= ~mask;
3977     }
3978   }else if( flags & SQLITE_SHM_SHARED ){
3979     u16 allShared = 0;  /* Union of locks held by connections other than "p" */
3980 
3981     /* Find out which shared locks are already held by sibling connections.
3982     ** If any sibling already holds an exclusive lock, go ahead and return
3983     ** SQLITE_BUSY.
3984     */
3985     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
3986       if( (pX->exclMask & mask)!=0 ){
3987         rc = SQLITE_BUSY;
3988         break;
3989       }
3990       allShared |= pX->sharedMask;
3991     }
3992 
3993     /* Get shared locks at the system level, if necessary */
3994     if( rc==SQLITE_OK ){
3995       if( (allShared & mask)==0 ){
3996         rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n);
3997       }else{
3998         rc = SQLITE_OK;
3999       }
4000     }
4001 
4002     /* Get the local shared locks */
4003     if( rc==SQLITE_OK ){
4004       p->sharedMask |= mask;
4005     }
4006   }else{
4007     /* Make sure no sibling connections hold locks that will block this
4008     ** lock.  If any do, return SQLITE_BUSY right away.
4009     */
4010     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
4011       if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
4012         rc = SQLITE_BUSY;
4013         break;
4014       }
4015     }
4016 
4017     /* Get the exclusive locks at the system level.  Then if successful
4018     ** also mark the local connection as being locked.
4019     */
4020     if( rc==SQLITE_OK ){
4021       rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n);
4022       if( rc==SQLITE_OK ){
4023         assert( (p->sharedMask & mask)==0 );
4024         p->exclMask |= mask;
4025       }
4026     }
4027   }
4028   sqlite3_mutex_leave(pShmNode->mutex);
4029   OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
4030            osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
4031            sqlite3ErrName(rc)));
4032   return rc;
4033 }
4034 
4035 /*
4036 ** Implement a memory barrier or memory fence on shared memory.
4037 **
4038 ** All loads and stores begun before the barrier must complete before
4039 ** any load or store begun after the barrier.
4040 */
4041 static void winShmBarrier(
4042   sqlite3_file *fd          /* Database holding the shared memory */
4043 ){
4044   UNUSED_PARAMETER(fd);
4045   sqlite3MemoryBarrier();   /* compiler-defined memory barrier */
4046   winShmEnterMutex();       /* Also mutex, for redundancy */
4047   winShmLeaveMutex();
4048 }
4049 
4050 /*
4051 ** This function is called to obtain a pointer to region iRegion of the
4052 ** shared-memory associated with the database file fd. Shared-memory regions
4053 ** are numbered starting from zero. Each shared-memory region is szRegion
4054 ** bytes in size.
4055 **
4056 ** If an error occurs, an error code is returned and *pp is set to NULL.
4057 **
4058 ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
4059 ** region has not been allocated (by any client, including one running in a
4060 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If
4061 ** isWrite is non-zero and the requested shared-memory region has not yet
4062 ** been allocated, it is allocated by this function.
4063 **
4064 ** If the shared-memory region has already been allocated or is allocated by
4065 ** this call as described above, then it is mapped into this processes
4066 ** address space (if it is not already), *pp is set to point to the mapped
4067 ** memory and SQLITE_OK returned.
4068 */
4069 static int winShmMap(
4070   sqlite3_file *fd,               /* Handle open on database file */
4071   int iRegion,                    /* Region to retrieve */
4072   int szRegion,                   /* Size of regions */
4073   int isWrite,                    /* True to extend file if necessary */
4074   void volatile **pp              /* OUT: Mapped memory */
4075 ){
4076   winFile *pDbFd = (winFile*)fd;
4077   winShm *pShm = pDbFd->pShm;
4078   winShmNode *pShmNode;
4079   int rc = SQLITE_OK;
4080 
4081   if( !pShm ){
4082     rc = winOpenSharedMemory(pDbFd);
4083     if( rc!=SQLITE_OK ) return rc;
4084     pShm = pDbFd->pShm;
4085   }
4086   pShmNode = pShm->pShmNode;
4087 
4088   sqlite3_mutex_enter(pShmNode->mutex);
4089   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
4090 
4091   if( pShmNode->nRegion<=iRegion ){
4092     struct ShmRegion *apNew;           /* New aRegion[] array */
4093     int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
4094     sqlite3_int64 sz;                  /* Current size of wal-index file */
4095 
4096     pShmNode->szRegion = szRegion;
4097 
4098     /* The requested region is not mapped into this processes address space.
4099     ** Check to see if it has been allocated (i.e. if the wal-index file is
4100     ** large enough to contain the requested region).
4101     */
4102     rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
4103     if( rc!=SQLITE_OK ){
4104       rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
4105                        "winShmMap1", pDbFd->zPath);
4106       goto shmpage_out;
4107     }
4108 
4109     if( sz<nByte ){
4110       /* The requested memory region does not exist. If isWrite is set to
4111       ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
4112       **
4113       ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
4114       ** the requested memory region.
4115       */
4116       if( !isWrite ) goto shmpage_out;
4117       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
4118       if( rc!=SQLITE_OK ){
4119         rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
4120                          "winShmMap2", pDbFd->zPath);
4121         goto shmpage_out;
4122       }
4123     }
4124 
4125     /* Map the requested memory region into this processes address space. */
4126     apNew = (struct ShmRegion *)sqlite3_realloc64(
4127         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
4128     );
4129     if( !apNew ){
4130       rc = SQLITE_IOERR_NOMEM_BKPT;
4131       goto shmpage_out;
4132     }
4133     pShmNode->aRegion = apNew;
4134 
4135     while( pShmNode->nRegion<=iRegion ){
4136       HANDLE hMap = NULL;         /* file-mapping handle */
4137       void *pMap = 0;             /* Mapped memory region */
4138 
4139 #if SQLITE_OS_WINRT
4140       hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
4141           NULL, PAGE_READWRITE, nByte, NULL
4142       );
4143 #elif defined(SQLITE_WIN32_HAS_WIDE)
4144       hMap = osCreateFileMappingW(pShmNode->hFile.h,
4145           NULL, PAGE_READWRITE, 0, nByte, NULL
4146       );
4147 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
4148       hMap = osCreateFileMappingA(pShmNode->hFile.h,
4149           NULL, PAGE_READWRITE, 0, nByte, NULL
4150       );
4151 #endif
4152       OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
4153                osGetCurrentProcessId(), pShmNode->nRegion, nByte,
4154                hMap ? "ok" : "failed"));
4155       if( hMap ){
4156         int iOffset = pShmNode->nRegion*szRegion;
4157         int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
4158 #if SQLITE_OS_WINRT
4159         pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
4160             iOffset - iOffsetShift, szRegion + iOffsetShift
4161         );
4162 #else
4163         pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
4164             0, iOffset - iOffsetShift, szRegion + iOffsetShift
4165         );
4166 #endif
4167         OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
4168                  osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
4169                  szRegion, pMap ? "ok" : "failed"));
4170       }
4171       if( !pMap ){
4172         pShmNode->lastErrno = osGetLastError();
4173         rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
4174                          "winShmMap3", pDbFd->zPath);
4175         if( hMap ) osCloseHandle(hMap);
4176         goto shmpage_out;
4177       }
4178 
4179       pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
4180       pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
4181       pShmNode->nRegion++;
4182     }
4183   }
4184 
4185 shmpage_out:
4186   if( pShmNode->nRegion>iRegion ){
4187     int iOffset = iRegion*szRegion;
4188     int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
4189     char *p = (char *)pShmNode->aRegion[iRegion].pMap;
4190     *pp = (void *)&p[iOffsetShift];
4191   }else{
4192     *pp = 0;
4193   }
4194   sqlite3_mutex_leave(pShmNode->mutex);
4195   return rc;
4196 }
4197 
4198 #else
4199 # define winShmMap     0
4200 # define winShmLock    0
4201 # define winShmBarrier 0
4202 # define winShmUnmap   0
4203 #endif /* #ifndef SQLITE_OMIT_WAL */
4204 
4205 /*
4206 ** Cleans up the mapped region of the specified file, if any.
4207 */
4208 #if SQLITE_MAX_MMAP_SIZE>0
4209 static int winUnmapfile(winFile *pFile){
4210   assert( pFile!=0 );
4211   OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
4212            "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
4213            osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
4214            pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
4215   if( pFile->pMapRegion ){
4216     if( !osUnmapViewOfFile(pFile->pMapRegion) ){
4217       pFile->lastErrno = osGetLastError();
4218       OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
4219                "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
4220                pFile->pMapRegion));
4221       return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
4222                          "winUnmapfile1", pFile->zPath);
4223     }
4224     pFile->pMapRegion = 0;
4225     pFile->mmapSize = 0;
4226     pFile->mmapSizeActual = 0;
4227   }
4228   if( pFile->hMap!=NULL ){
4229     if( !osCloseHandle(pFile->hMap) ){
4230       pFile->lastErrno = osGetLastError();
4231       OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
4232                osGetCurrentProcessId(), pFile, pFile->hMap));
4233       return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
4234                          "winUnmapfile2", pFile->zPath);
4235     }
4236     pFile->hMap = NULL;
4237   }
4238   OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
4239            osGetCurrentProcessId(), pFile));
4240   return SQLITE_OK;
4241 }
4242 
4243 /*
4244 ** Memory map or remap the file opened by file-descriptor pFd (if the file
4245 ** is already mapped, the existing mapping is replaced by the new). Or, if
4246 ** there already exists a mapping for this file, and there are still
4247 ** outstanding xFetch() references to it, this function is a no-op.
4248 **
4249 ** If parameter nByte is non-negative, then it is the requested size of
4250 ** the mapping to create. Otherwise, if nByte is less than zero, then the
4251 ** requested size is the size of the file on disk. The actual size of the
4252 ** created mapping is either the requested size or the value configured
4253 ** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
4254 **
4255 ** SQLITE_OK is returned if no error occurs (even if the mapping is not
4256 ** recreated as a result of outstanding references) or an SQLite error
4257 ** code otherwise.
4258 */
4259 static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
4260   sqlite3_int64 nMap = nByte;
4261   int rc;
4262 
4263   assert( nMap>=0 || pFd->nFetchOut==0 );
4264   OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
4265            osGetCurrentProcessId(), pFd, nByte));
4266 
4267   if( pFd->nFetchOut>0 ) return SQLITE_OK;
4268 
4269   if( nMap<0 ){
4270     rc = winFileSize((sqlite3_file*)pFd, &nMap);
4271     if( rc ){
4272       OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
4273                osGetCurrentProcessId(), pFd));
4274       return SQLITE_IOERR_FSTAT;
4275     }
4276   }
4277   if( nMap>pFd->mmapSizeMax ){
4278     nMap = pFd->mmapSizeMax;
4279   }
4280   nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
4281 
4282   if( nMap==0 && pFd->mmapSize>0 ){
4283     winUnmapfile(pFd);
4284   }
4285   if( nMap!=pFd->mmapSize ){
4286     void *pNew = 0;
4287     DWORD protect = PAGE_READONLY;
4288     DWORD flags = FILE_MAP_READ;
4289 
4290     winUnmapfile(pFd);
4291 #ifdef SQLITE_MMAP_READWRITE
4292     if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
4293       protect = PAGE_READWRITE;
4294       flags |= FILE_MAP_WRITE;
4295     }
4296 #endif
4297 #if SQLITE_OS_WINRT
4298     pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
4299 #elif defined(SQLITE_WIN32_HAS_WIDE)
4300     pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
4301                                 (DWORD)((nMap>>32) & 0xffffffff),
4302                                 (DWORD)(nMap & 0xffffffff), NULL);
4303 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
4304     pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
4305                                 (DWORD)((nMap>>32) & 0xffffffff),
4306                                 (DWORD)(nMap & 0xffffffff), NULL);
4307 #endif
4308     if( pFd->hMap==NULL ){
4309       pFd->lastErrno = osGetLastError();
4310       rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
4311                        "winMapfile1", pFd->zPath);
4312       /* Log the error, but continue normal operation using xRead/xWrite */
4313       OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
4314                osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
4315       return SQLITE_OK;
4316     }
4317     assert( (nMap % winSysInfo.dwPageSize)==0 );
4318     assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
4319 #if SQLITE_OS_WINRT
4320     pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
4321 #else
4322     pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
4323 #endif
4324     if( pNew==NULL ){
4325       osCloseHandle(pFd->hMap);
4326       pFd->hMap = NULL;
4327       pFd->lastErrno = osGetLastError();
4328       rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
4329                        "winMapfile2", pFd->zPath);
4330       /* Log the error, but continue normal operation using xRead/xWrite */
4331       OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
4332                osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
4333       return SQLITE_OK;
4334     }
4335     pFd->pMapRegion = pNew;
4336     pFd->mmapSize = nMap;
4337     pFd->mmapSizeActual = nMap;
4338   }
4339 
4340   OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
4341            osGetCurrentProcessId(), pFd));
4342   return SQLITE_OK;
4343 }
4344 #endif /* SQLITE_MAX_MMAP_SIZE>0 */
4345 
4346 /*
4347 ** If possible, return a pointer to a mapping of file fd starting at offset
4348 ** iOff. The mapping must be valid for at least nAmt bytes.
4349 **
4350 ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
4351 ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
4352 ** Finally, if an error does occur, return an SQLite error code. The final
4353 ** value of *pp is undefined in this case.
4354 **
4355 ** If this function does return a pointer, the caller must eventually
4356 ** release the reference by calling winUnfetch().
4357 */
4358 static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
4359 #if SQLITE_MAX_MMAP_SIZE>0
4360   winFile *pFd = (winFile*)fd;   /* The underlying database file */
4361 #endif
4362   *pp = 0;
4363 
4364   OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
4365            osGetCurrentProcessId(), fd, iOff, nAmt, pp));
4366 
4367 #if SQLITE_MAX_MMAP_SIZE>0
4368   if( pFd->mmapSizeMax>0 ){
4369     if( pFd->pMapRegion==0 ){
4370       int rc = winMapfile(pFd, -1);
4371       if( rc!=SQLITE_OK ){
4372         OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
4373                  osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
4374         return rc;
4375       }
4376     }
4377     if( pFd->mmapSize >= iOff+nAmt ){
4378       *pp = &((u8 *)pFd->pMapRegion)[iOff];
4379       pFd->nFetchOut++;
4380     }
4381   }
4382 #endif
4383 
4384   OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
4385            osGetCurrentProcessId(), fd, pp, *pp));
4386   return SQLITE_OK;
4387 }
4388 
4389 /*
4390 ** If the third argument is non-NULL, then this function releases a
4391 ** reference obtained by an earlier call to winFetch(). The second
4392 ** argument passed to this function must be the same as the corresponding
4393 ** argument that was passed to the winFetch() invocation.
4394 **
4395 ** Or, if the third argument is NULL, then this function is being called
4396 ** to inform the VFS layer that, according to POSIX, any existing mapping
4397 ** may now be invalid and should be unmapped.
4398 */
4399 static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
4400 #if SQLITE_MAX_MMAP_SIZE>0
4401   winFile *pFd = (winFile*)fd;   /* The underlying database file */
4402 
4403   /* If p==0 (unmap the entire file) then there must be no outstanding
4404   ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
4405   ** then there must be at least one outstanding.  */
4406   assert( (p==0)==(pFd->nFetchOut==0) );
4407 
4408   /* If p!=0, it must match the iOff value. */
4409   assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
4410 
4411   OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
4412            osGetCurrentProcessId(), pFd, iOff, p));
4413 
4414   if( p ){
4415     pFd->nFetchOut--;
4416   }else{
4417     /* FIXME:  If Windows truly always prevents truncating or deleting a
4418     ** file while a mapping is held, then the following winUnmapfile() call
4419     ** is unnecessary can be omitted - potentially improving
4420     ** performance.  */
4421     winUnmapfile(pFd);
4422   }
4423 
4424   assert( pFd->nFetchOut>=0 );
4425 #endif
4426 
4427   OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
4428            osGetCurrentProcessId(), fd));
4429   return SQLITE_OK;
4430 }
4431 
4432 /*
4433 ** Here ends the implementation of all sqlite3_file methods.
4434 **
4435 ********************** End sqlite3_file Methods *******************************
4436 ******************************************************************************/
4437 
4438 /*
4439 ** This vector defines all the methods that can operate on an
4440 ** sqlite3_file for win32.
4441 */
4442 static const sqlite3_io_methods winIoMethod = {
4443   3,                              /* iVersion */
4444   winClose,                       /* xClose */
4445   winRead,                        /* xRead */
4446   winWrite,                       /* xWrite */
4447   winTruncate,                    /* xTruncate */
4448   winSync,                        /* xSync */
4449   winFileSize,                    /* xFileSize */
4450   winLock,                        /* xLock */
4451   winUnlock,                      /* xUnlock */
4452   winCheckReservedLock,           /* xCheckReservedLock */
4453   winFileControl,                 /* xFileControl */
4454   winSectorSize,                  /* xSectorSize */
4455   winDeviceCharacteristics,       /* xDeviceCharacteristics */
4456   winShmMap,                      /* xShmMap */
4457   winShmLock,                     /* xShmLock */
4458   winShmBarrier,                  /* xShmBarrier */
4459   winShmUnmap,                    /* xShmUnmap */
4460   winFetch,                       /* xFetch */
4461   winUnfetch                      /* xUnfetch */
4462 };
4463 
4464 /*
4465 ** This vector defines all the methods that can operate on an
4466 ** sqlite3_file for win32 without performing any locking.
4467 */
4468 static const sqlite3_io_methods winIoNolockMethod = {
4469   3,                              /* iVersion */
4470   winClose,                       /* xClose */
4471   winRead,                        /* xRead */
4472   winWrite,                       /* xWrite */
4473   winTruncate,                    /* xTruncate */
4474   winSync,                        /* xSync */
4475   winFileSize,                    /* xFileSize */
4476   winNolockLock,                  /* xLock */
4477   winNolockUnlock,                /* xUnlock */
4478   winNolockCheckReservedLock,     /* xCheckReservedLock */
4479   winFileControl,                 /* xFileControl */
4480   winSectorSize,                  /* xSectorSize */
4481   winDeviceCharacteristics,       /* xDeviceCharacteristics */
4482   winShmMap,                      /* xShmMap */
4483   winShmLock,                     /* xShmLock */
4484   winShmBarrier,                  /* xShmBarrier */
4485   winShmUnmap,                    /* xShmUnmap */
4486   winFetch,                       /* xFetch */
4487   winUnfetch                      /* xUnfetch */
4488 };
4489 
4490 static winVfsAppData winAppData = {
4491   &winIoMethod,       /* pMethod */
4492   0,                  /* pAppData */
4493   0                   /* bNoLock */
4494 };
4495 
4496 static winVfsAppData winNolockAppData = {
4497   &winIoNolockMethod, /* pMethod */
4498   0,                  /* pAppData */
4499   1                   /* bNoLock */
4500 };
4501 
4502 /****************************************************************************
4503 **************************** sqlite3_vfs methods ****************************
4504 **
4505 ** This division contains the implementation of methods on the
4506 ** sqlite3_vfs object.
4507 */
4508 
4509 #if defined(__CYGWIN__)
4510 /*
4511 ** Convert a filename from whatever the underlying operating system
4512 ** supports for filenames into UTF-8.  Space to hold the result is
4513 ** obtained from malloc and must be freed by the calling function.
4514 */
4515 static char *winConvertToUtf8Filename(const void *zFilename){
4516   char *zConverted = 0;
4517   if( osIsNT() ){
4518     zConverted = winUnicodeToUtf8(zFilename);
4519   }
4520 #ifdef SQLITE_WIN32_HAS_ANSI
4521   else{
4522     zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
4523   }
4524 #endif
4525   /* caller will handle out of memory */
4526   return zConverted;
4527 }
4528 #endif
4529 
4530 /*
4531 ** Convert a UTF-8 filename into whatever form the underlying
4532 ** operating system wants filenames in.  Space to hold the result
4533 ** is obtained from malloc and must be freed by the calling
4534 ** function.
4535 */
4536 static void *winConvertFromUtf8Filename(const char *zFilename){
4537   void *zConverted = 0;
4538   if( osIsNT() ){
4539     zConverted = winUtf8ToUnicode(zFilename);
4540   }
4541 #ifdef SQLITE_WIN32_HAS_ANSI
4542   else{
4543     zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
4544   }
4545 #endif
4546   /* caller will handle out of memory */
4547   return zConverted;
4548 }
4549 
4550 /*
4551 ** This function returns non-zero if the specified UTF-8 string buffer
4552 ** ends with a directory separator character or one was successfully
4553 ** added to it.
4554 */
4555 static int winMakeEndInDirSep(int nBuf, char *zBuf){
4556   if( zBuf ){
4557     int nLen = sqlite3Strlen30(zBuf);
4558     if( nLen>0 ){
4559       if( winIsDirSep(zBuf[nLen-1]) ){
4560         return 1;
4561       }else if( nLen+1<nBuf ){
4562         zBuf[nLen] = winGetDirSep();
4563         zBuf[nLen+1] = '\0';
4564         return 1;
4565       }
4566     }
4567   }
4568   return 0;
4569 }
4570 
4571 /*
4572 ** Create a temporary file name and store the resulting pointer into pzBuf.
4573 ** The pointer returned in pzBuf must be freed via sqlite3_free().
4574 */
4575 static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
4576   static char zChars[] =
4577     "abcdefghijklmnopqrstuvwxyz"
4578     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
4579     "0123456789";
4580   size_t i, j;
4581   int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
4582   int nMax, nBuf, nDir, nLen;
4583   char *zBuf;
4584 
4585   /* It's odd to simulate an io-error here, but really this is just
4586   ** using the io-error infrastructure to test that SQLite handles this
4587   ** function failing.
4588   */
4589   SimulateIOError( return SQLITE_IOERR );
4590 
4591   /* Allocate a temporary buffer to store the fully qualified file
4592   ** name for the temporary file.  If this fails, we cannot continue.
4593   */
4594   nMax = pVfs->mxPathname; nBuf = nMax + 2;
4595   zBuf = sqlite3MallocZero( nBuf );
4596   if( !zBuf ){
4597     OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4598     return SQLITE_IOERR_NOMEM_BKPT;
4599   }
4600 
4601   /* Figure out the effective temporary directory.  First, check if one
4602   ** has been explicitly set by the application; otherwise, use the one
4603   ** configured by the operating system.
4604   */
4605   nDir = nMax - (nPre + 15);
4606   assert( nDir>0 );
4607   if( sqlite3_temp_directory ){
4608     int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
4609     if( nDirLen>0 ){
4610       if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
4611         nDirLen++;
4612       }
4613       if( nDirLen>nDir ){
4614         sqlite3_free(zBuf);
4615         OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
4616         return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
4617       }
4618       sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
4619     }
4620   }
4621 #if defined(__CYGWIN__)
4622   else{
4623     static const char *azDirs[] = {
4624        0, /* getenv("SQLITE_TMPDIR") */
4625        0, /* getenv("TMPDIR") */
4626        0, /* getenv("TMP") */
4627        0, /* getenv("TEMP") */
4628        0, /* getenv("USERPROFILE") */
4629        "/var/tmp",
4630        "/usr/tmp",
4631        "/tmp",
4632        ".",
4633        0        /* List terminator */
4634     };
4635     unsigned int i;
4636     const char *zDir = 0;
4637 
4638     if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
4639     if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
4640     if( !azDirs[2] ) azDirs[2] = getenv("TMP");
4641     if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
4642     if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
4643     for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
4644       void *zConverted;
4645       if( zDir==0 ) continue;
4646       /* If the path starts with a drive letter followed by the colon
4647       ** character, assume it is already a native Win32 path; otherwise,
4648       ** it must be converted to a native Win32 path via the Cygwin API
4649       ** prior to using it.
4650       */
4651       if( winIsDriveLetterAndColon(zDir) ){
4652         zConverted = winConvertFromUtf8Filename(zDir);
4653         if( !zConverted ){
4654           sqlite3_free(zBuf);
4655           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4656           return SQLITE_IOERR_NOMEM_BKPT;
4657         }
4658         if( winIsDir(zConverted) ){
4659           sqlite3_snprintf(nMax, zBuf, "%s", zDir);
4660           sqlite3_free(zConverted);
4661           break;
4662         }
4663         sqlite3_free(zConverted);
4664       }else{
4665         zConverted = sqlite3MallocZero( nMax+1 );
4666         if( !zConverted ){
4667           sqlite3_free(zBuf);
4668           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4669           return SQLITE_IOERR_NOMEM_BKPT;
4670         }
4671         if( cygwin_conv_path(
4672                 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
4673                 zConverted, nMax+1)<0 ){
4674           sqlite3_free(zConverted);
4675           sqlite3_free(zBuf);
4676           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
4677           return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
4678                              "winGetTempname2", zDir);
4679         }
4680         if( winIsDir(zConverted) ){
4681           /* At this point, we know the candidate directory exists and should
4682           ** be used.  However, we may need to convert the string containing
4683           ** its name into UTF-8 (i.e. if it is UTF-16 right now).
4684           */
4685           char *zUtf8 = winConvertToUtf8Filename(zConverted);
4686           if( !zUtf8 ){
4687             sqlite3_free(zConverted);
4688             sqlite3_free(zBuf);
4689             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4690             return SQLITE_IOERR_NOMEM_BKPT;
4691           }
4692           sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
4693           sqlite3_free(zUtf8);
4694           sqlite3_free(zConverted);
4695           break;
4696         }
4697         sqlite3_free(zConverted);
4698       }
4699     }
4700   }
4701 #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
4702   else if( osIsNT() ){
4703     char *zMulti;
4704     LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
4705     if( !zWidePath ){
4706       sqlite3_free(zBuf);
4707       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4708       return SQLITE_IOERR_NOMEM_BKPT;
4709     }
4710     if( osGetTempPathW(nMax, zWidePath)==0 ){
4711       sqlite3_free(zWidePath);
4712       sqlite3_free(zBuf);
4713       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
4714       return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
4715                          "winGetTempname2", 0);
4716     }
4717     zMulti = winUnicodeToUtf8(zWidePath);
4718     if( zMulti ){
4719       sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
4720       sqlite3_free(zMulti);
4721       sqlite3_free(zWidePath);
4722     }else{
4723       sqlite3_free(zWidePath);
4724       sqlite3_free(zBuf);
4725       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4726       return SQLITE_IOERR_NOMEM_BKPT;
4727     }
4728   }
4729 #ifdef SQLITE_WIN32_HAS_ANSI
4730   else{
4731     char *zUtf8;
4732     char *zMbcsPath = sqlite3MallocZero( nMax );
4733     if( !zMbcsPath ){
4734       sqlite3_free(zBuf);
4735       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4736       return SQLITE_IOERR_NOMEM_BKPT;
4737     }
4738     if( osGetTempPathA(nMax, zMbcsPath)==0 ){
4739       sqlite3_free(zBuf);
4740       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
4741       return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
4742                          "winGetTempname3", 0);
4743     }
4744     zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
4745     if( zUtf8 ){
4746       sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
4747       sqlite3_free(zUtf8);
4748     }else{
4749       sqlite3_free(zBuf);
4750       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
4751       return SQLITE_IOERR_NOMEM_BKPT;
4752     }
4753   }
4754 #endif /* SQLITE_WIN32_HAS_ANSI */
4755 #endif /* !SQLITE_OS_WINRT */
4756 
4757   /*
4758   ** Check to make sure the temporary directory ends with an appropriate
4759   ** separator.  If it does not and there is not enough space left to add
4760   ** one, fail.
4761   */
4762   if( !winMakeEndInDirSep(nDir+1, zBuf) ){
4763     sqlite3_free(zBuf);
4764     OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
4765     return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
4766   }
4767 
4768   /*
4769   ** Check that the output buffer is large enough for the temporary file
4770   ** name in the following format:
4771   **
4772   **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
4773   **
4774   ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
4775   ** account for the space used by the 15 character random suffix and the
4776   ** two trailing NUL characters.  The final directory separator character
4777   ** has already added if it was not already present.
4778   */
4779   nLen = sqlite3Strlen30(zBuf);
4780   if( (nLen + nPre + 17) > nBuf ){
4781     sqlite3_free(zBuf);
4782     OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
4783     return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
4784   }
4785 
4786   sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
4787 
4788   j = sqlite3Strlen30(zBuf);
4789   sqlite3_randomness(15, &zBuf[j]);
4790   for(i=0; i<15; i++, j++){
4791     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
4792   }
4793   zBuf[j] = 0;
4794   zBuf[j+1] = 0;
4795   *pzBuf = zBuf;
4796 
4797   OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
4798   return SQLITE_OK;
4799 }
4800 
4801 /*
4802 ** Return TRUE if the named file is really a directory.  Return false if
4803 ** it is something other than a directory, or if there is any kind of memory
4804 ** allocation failure.
4805 */
4806 static int winIsDir(const void *zConverted){
4807   DWORD attr;
4808   int rc = 0;
4809   DWORD lastErrno;
4810 
4811   if( osIsNT() ){
4812     int cnt = 0;
4813     WIN32_FILE_ATTRIBUTE_DATA sAttrData;
4814     memset(&sAttrData, 0, sizeof(sAttrData));
4815     while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
4816                              GetFileExInfoStandard,
4817                              &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
4818     if( !rc ){
4819       return 0; /* Invalid name? */
4820     }
4821     attr = sAttrData.dwFileAttributes;
4822 #if SQLITE_OS_WINCE==0
4823   }else{
4824     attr = osGetFileAttributesA((char*)zConverted);
4825 #endif
4826   }
4827   return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
4828 }
4829 
4830 /*
4831 ** Open a file.
4832 */
4833 static int winOpen(
4834   sqlite3_vfs *pVfs,        /* Used to get maximum path length and AppData */
4835   const char *zName,        /* Name of the file (UTF-8) */
4836   sqlite3_file *id,         /* Write the SQLite file handle here */
4837   int flags,                /* Open mode flags */
4838   int *pOutFlags            /* Status return flags */
4839 ){
4840   HANDLE h;
4841   DWORD lastErrno = 0;
4842   DWORD dwDesiredAccess;
4843   DWORD dwShareMode;
4844   DWORD dwCreationDisposition;
4845   DWORD dwFlagsAndAttributes = 0;
4846 #if SQLITE_OS_WINCE
4847   int isTemp = 0;
4848 #endif
4849   winVfsAppData *pAppData;
4850   winFile *pFile = (winFile*)id;
4851   void *zConverted;              /* Filename in OS encoding */
4852   const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
4853   int cnt = 0;
4854 
4855   /* If argument zPath is a NULL pointer, this function is required to open
4856   ** a temporary file. Use this buffer to store the file name in.
4857   */
4858   char *zTmpname = 0; /* For temporary filename, if necessary. */
4859 
4860   int rc = SQLITE_OK;            /* Function Return Code */
4861 #if !defined(NDEBUG) || SQLITE_OS_WINCE
4862   int eType = flags&0xFFFFFF00;  /* Type of file to open */
4863 #endif
4864 
4865   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
4866   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
4867   int isCreate     = (flags & SQLITE_OPEN_CREATE);
4868   int isReadonly   = (flags & SQLITE_OPEN_READONLY);
4869   int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
4870 
4871 #ifndef NDEBUG
4872   int isOpenJournal = (isCreate && (
4873         eType==SQLITE_OPEN_MASTER_JOURNAL
4874      || eType==SQLITE_OPEN_MAIN_JOURNAL
4875      || eType==SQLITE_OPEN_WAL
4876   ));
4877 #endif
4878 
4879   OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
4880            zUtf8Name, id, flags, pOutFlags));
4881 
4882   /* Check the following statements are true:
4883   **
4884   **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
4885   **   (b) if CREATE is set, then READWRITE must also be set, and
4886   **   (c) if EXCLUSIVE is set, then CREATE must also be set.
4887   **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
4888   */
4889   assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
4890   assert(isCreate==0 || isReadWrite);
4891   assert(isExclusive==0 || isCreate);
4892   assert(isDelete==0 || isCreate);
4893 
4894   /* The main DB, main journal, WAL file and master journal are never
4895   ** automatically deleted. Nor are they ever temporary files.  */
4896   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
4897   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
4898   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
4899   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
4900 
4901   /* Assert that the upper layer has set one of the "file-type" flags. */
4902   assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
4903        || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
4904        || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
4905        || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
4906   );
4907 
4908   assert( pFile!=0 );
4909   memset(pFile, 0, sizeof(winFile));
4910   pFile->h = INVALID_HANDLE_VALUE;
4911 
4912 #if SQLITE_OS_WINRT
4913   if( !zUtf8Name && !sqlite3_temp_directory ){
4914     sqlite3_log(SQLITE_ERROR,
4915         "sqlite3_temp_directory variable should be set for WinRT");
4916   }
4917 #endif
4918 
4919   /* If the second argument to this function is NULL, generate a
4920   ** temporary file name to use
4921   */
4922   if( !zUtf8Name ){
4923     assert( isDelete && !isOpenJournal );
4924     rc = winGetTempname(pVfs, &zTmpname);
4925     if( rc!=SQLITE_OK ){
4926       OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
4927       return rc;
4928     }
4929     zUtf8Name = zTmpname;
4930   }
4931 
4932   /* Database filenames are double-zero terminated if they are not
4933   ** URIs with parameters.  Hence, they can always be passed into
4934   ** sqlite3_uri_parameter().
4935   */
4936   assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
4937        zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
4938 
4939   /* Convert the filename to the system encoding. */
4940   zConverted = winConvertFromUtf8Filename(zUtf8Name);
4941   if( zConverted==0 ){
4942     sqlite3_free(zTmpname);
4943     OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
4944     return SQLITE_IOERR_NOMEM_BKPT;
4945   }
4946 
4947   if( winIsDir(zConverted) ){
4948     sqlite3_free(zConverted);
4949     sqlite3_free(zTmpname);
4950     OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
4951     return SQLITE_CANTOPEN_ISDIR;
4952   }
4953 
4954   if( isReadWrite ){
4955     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
4956   }else{
4957     dwDesiredAccess = GENERIC_READ;
4958   }
4959 
4960   /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
4961   ** created. SQLite doesn't use it to indicate "exclusive access"
4962   ** as it is usually understood.
4963   */
4964   if( isExclusive ){
4965     /* Creates a new file, only if it does not already exist. */
4966     /* If the file exists, it fails. */
4967     dwCreationDisposition = CREATE_NEW;
4968   }else if( isCreate ){
4969     /* Open existing file, or create if it doesn't exist */
4970     dwCreationDisposition = OPEN_ALWAYS;
4971   }else{
4972     /* Opens a file, only if it exists. */
4973     dwCreationDisposition = OPEN_EXISTING;
4974   }
4975 
4976   dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
4977 
4978   if( isDelete ){
4979 #if SQLITE_OS_WINCE
4980     dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
4981     isTemp = 1;
4982 #else
4983     dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
4984                                | FILE_ATTRIBUTE_HIDDEN
4985                                | FILE_FLAG_DELETE_ON_CLOSE;
4986 #endif
4987   }else{
4988     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
4989   }
4990   /* Reports from the internet are that performance is always
4991   ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
4992 #if SQLITE_OS_WINCE
4993   dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
4994 #endif
4995 
4996   if( osIsNT() ){
4997 #if SQLITE_OS_WINRT
4998     CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
4999     extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
5000     extendedParameters.dwFileAttributes =
5001             dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
5002     extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
5003     extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
5004     extendedParameters.lpSecurityAttributes = NULL;
5005     extendedParameters.hTemplateFile = NULL;
5006     while( (h = osCreateFile2((LPCWSTR)zConverted,
5007                               dwDesiredAccess,
5008                               dwShareMode,
5009                               dwCreationDisposition,
5010                               &extendedParameters))==INVALID_HANDLE_VALUE &&
5011                               winRetryIoerr(&cnt, &lastErrno) ){
5012                /* Noop */
5013     }
5014 #else
5015     while( (h = osCreateFileW((LPCWSTR)zConverted,
5016                               dwDesiredAccess,
5017                               dwShareMode, NULL,
5018                               dwCreationDisposition,
5019                               dwFlagsAndAttributes,
5020                               NULL))==INVALID_HANDLE_VALUE &&
5021                               winRetryIoerr(&cnt, &lastErrno) ){
5022                /* Noop */
5023     }
5024 #endif
5025   }
5026 #ifdef SQLITE_WIN32_HAS_ANSI
5027   else{
5028     while( (h = osCreateFileA((LPCSTR)zConverted,
5029                               dwDesiredAccess,
5030                               dwShareMode, NULL,
5031                               dwCreationDisposition,
5032                               dwFlagsAndAttributes,
5033                               NULL))==INVALID_HANDLE_VALUE &&
5034                               winRetryIoerr(&cnt, &lastErrno) ){
5035                /* Noop */
5036     }
5037   }
5038 #endif
5039   winLogIoerr(cnt, __LINE__);
5040 
5041   OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
5042            dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
5043 
5044   if( h==INVALID_HANDLE_VALUE ){
5045     pFile->lastErrno = lastErrno;
5046     winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
5047     sqlite3_free(zConverted);
5048     sqlite3_free(zTmpname);
5049     if( isReadWrite && !isExclusive ){
5050       return winOpen(pVfs, zName, id,
5051          ((flags|SQLITE_OPEN_READONLY) &
5052                      ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
5053          pOutFlags);
5054     }else{
5055       return SQLITE_CANTOPEN_BKPT;
5056     }
5057   }
5058 
5059   if( pOutFlags ){
5060     if( isReadWrite ){
5061       *pOutFlags = SQLITE_OPEN_READWRITE;
5062     }else{
5063       *pOutFlags = SQLITE_OPEN_READONLY;
5064     }
5065   }
5066 
5067   OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
5068            "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
5069            *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
5070 
5071   pAppData = (winVfsAppData*)pVfs->pAppData;
5072 
5073 #if SQLITE_OS_WINCE
5074   {
5075     if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
5076          && ((pAppData==NULL) || !pAppData->bNoLock)
5077          && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
5078     ){
5079       osCloseHandle(h);
5080       sqlite3_free(zConverted);
5081       sqlite3_free(zTmpname);
5082       OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
5083       return rc;
5084     }
5085   }
5086   if( isTemp ){
5087     pFile->zDeleteOnClose = zConverted;
5088   }else
5089 #endif
5090   {
5091     sqlite3_free(zConverted);
5092   }
5093 
5094   sqlite3_free(zTmpname);
5095   pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod;
5096   pFile->pVfs = pVfs;
5097   pFile->h = h;
5098   if( isReadonly ){
5099     pFile->ctrlFlags |= WINFILE_RDONLY;
5100   }
5101   if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
5102     pFile->ctrlFlags |= WINFILE_PSOW;
5103   }
5104   pFile->lastErrno = NO_ERROR;
5105   pFile->zPath = zName;
5106 #if SQLITE_MAX_MMAP_SIZE>0
5107   pFile->hMap = NULL;
5108   pFile->pMapRegion = 0;
5109   pFile->mmapSize = 0;
5110   pFile->mmapSizeActual = 0;
5111   pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
5112 #endif
5113 
5114   OpenCounter(+1);
5115   return rc;
5116 }
5117 
5118 /*
5119 ** Delete the named file.
5120 **
5121 ** Note that Windows does not allow a file to be deleted if some other
5122 ** process has it open.  Sometimes a virus scanner or indexing program
5123 ** will open a journal file shortly after it is created in order to do
5124 ** whatever it does.  While this other process is holding the
5125 ** file open, we will be unable to delete it.  To work around this
5126 ** problem, we delay 100 milliseconds and try to delete again.  Up
5127 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
5128 ** up and returning an error.
5129 */
5130 static int winDelete(
5131   sqlite3_vfs *pVfs,          /* Not used on win32 */
5132   const char *zFilename,      /* Name of file to delete */
5133   int syncDir                 /* Not used on win32 */
5134 ){
5135   int cnt = 0;
5136   int rc;
5137   DWORD attr;
5138   DWORD lastErrno = 0;
5139   void *zConverted;
5140   UNUSED_PARAMETER(pVfs);
5141   UNUSED_PARAMETER(syncDir);
5142 
5143   SimulateIOError(return SQLITE_IOERR_DELETE);
5144   OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
5145 
5146   zConverted = winConvertFromUtf8Filename(zFilename);
5147   if( zConverted==0 ){
5148     OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
5149     return SQLITE_IOERR_NOMEM_BKPT;
5150   }
5151   if( osIsNT() ){
5152     do {
5153 #if SQLITE_OS_WINRT
5154       WIN32_FILE_ATTRIBUTE_DATA sAttrData;
5155       memset(&sAttrData, 0, sizeof(sAttrData));
5156       if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
5157                                   &sAttrData) ){
5158         attr = sAttrData.dwFileAttributes;
5159       }else{
5160         lastErrno = osGetLastError();
5161         if( lastErrno==ERROR_FILE_NOT_FOUND
5162          || lastErrno==ERROR_PATH_NOT_FOUND ){
5163           rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
5164         }else{
5165           rc = SQLITE_ERROR;
5166         }
5167         break;
5168       }
5169 #else
5170       attr = osGetFileAttributesW(zConverted);
5171 #endif
5172       if ( attr==INVALID_FILE_ATTRIBUTES ){
5173         lastErrno = osGetLastError();
5174         if( lastErrno==ERROR_FILE_NOT_FOUND
5175          || lastErrno==ERROR_PATH_NOT_FOUND ){
5176           rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
5177         }else{
5178           rc = SQLITE_ERROR;
5179         }
5180         break;
5181       }
5182       if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
5183         rc = SQLITE_ERROR; /* Files only. */
5184         break;
5185       }
5186       if ( osDeleteFileW(zConverted) ){
5187         rc = SQLITE_OK; /* Deleted OK. */
5188         break;
5189       }
5190       if ( !winRetryIoerr(&cnt, &lastErrno) ){
5191         rc = SQLITE_ERROR; /* No more retries. */
5192         break;
5193       }
5194     } while(1);
5195   }
5196 #ifdef SQLITE_WIN32_HAS_ANSI
5197   else{
5198     do {
5199       attr = osGetFileAttributesA(zConverted);
5200       if ( attr==INVALID_FILE_ATTRIBUTES ){
5201         lastErrno = osGetLastError();
5202         if( lastErrno==ERROR_FILE_NOT_FOUND
5203          || lastErrno==ERROR_PATH_NOT_FOUND ){
5204           rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
5205         }else{
5206           rc = SQLITE_ERROR;
5207         }
5208         break;
5209       }
5210       if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
5211         rc = SQLITE_ERROR; /* Files only. */
5212         break;
5213       }
5214       if ( osDeleteFileA(zConverted) ){
5215         rc = SQLITE_OK; /* Deleted OK. */
5216         break;
5217       }
5218       if ( !winRetryIoerr(&cnt, &lastErrno) ){
5219         rc = SQLITE_ERROR; /* No more retries. */
5220         break;
5221       }
5222     } while(1);
5223   }
5224 #endif
5225   if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
5226     rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
5227   }else{
5228     winLogIoerr(cnt, __LINE__);
5229   }
5230   sqlite3_free(zConverted);
5231   OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
5232   return rc;
5233 }
5234 
5235 /*
5236 ** Check the existence and status of a file.
5237 */
5238 static int winAccess(
5239   sqlite3_vfs *pVfs,         /* Not used on win32 */
5240   const char *zFilename,     /* Name of file to check */
5241   int flags,                 /* Type of test to make on this file */
5242   int *pResOut               /* OUT: Result */
5243 ){
5244   DWORD attr;
5245   int rc = 0;
5246   DWORD lastErrno = 0;
5247   void *zConverted;
5248   UNUSED_PARAMETER(pVfs);
5249 
5250   SimulateIOError( return SQLITE_IOERR_ACCESS; );
5251   OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
5252            zFilename, flags, pResOut));
5253 
5254   zConverted = winConvertFromUtf8Filename(zFilename);
5255   if( zConverted==0 ){
5256     OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
5257     return SQLITE_IOERR_NOMEM_BKPT;
5258   }
5259   if( osIsNT() ){
5260     int cnt = 0;
5261     WIN32_FILE_ATTRIBUTE_DATA sAttrData;
5262     memset(&sAttrData, 0, sizeof(sAttrData));
5263     while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
5264                              GetFileExInfoStandard,
5265                              &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
5266     if( rc ){
5267       /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
5268       ** as if it does not exist.
5269       */
5270       if(    flags==SQLITE_ACCESS_EXISTS
5271           && sAttrData.nFileSizeHigh==0
5272           && sAttrData.nFileSizeLow==0 ){
5273         attr = INVALID_FILE_ATTRIBUTES;
5274       }else{
5275         attr = sAttrData.dwFileAttributes;
5276       }
5277     }else{
5278       winLogIoerr(cnt, __LINE__);
5279       if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
5280         sqlite3_free(zConverted);
5281         return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
5282                            zFilename);
5283       }else{
5284         attr = INVALID_FILE_ATTRIBUTES;
5285       }
5286     }
5287   }
5288 #ifdef SQLITE_WIN32_HAS_ANSI
5289   else{
5290     attr = osGetFileAttributesA((char*)zConverted);
5291   }
5292 #endif
5293   sqlite3_free(zConverted);
5294   switch( flags ){
5295     case SQLITE_ACCESS_READ:
5296     case SQLITE_ACCESS_EXISTS:
5297       rc = attr!=INVALID_FILE_ATTRIBUTES;
5298       break;
5299     case SQLITE_ACCESS_READWRITE:
5300       rc = attr!=INVALID_FILE_ATTRIBUTES &&
5301              (attr & FILE_ATTRIBUTE_READONLY)==0;
5302       break;
5303     default:
5304       assert(!"Invalid flags argument");
5305   }
5306   *pResOut = rc;
5307   OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
5308            zFilename, pResOut, *pResOut));
5309   return SQLITE_OK;
5310 }
5311 
5312 /*
5313 ** Returns non-zero if the specified path name starts with a drive letter
5314 ** followed by a colon character.
5315 */
5316 static BOOL winIsDriveLetterAndColon(
5317   const char *zPathname
5318 ){
5319   return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
5320 }
5321 
5322 /*
5323 ** Returns non-zero if the specified path name should be used verbatim.  If
5324 ** non-zero is returned from this function, the calling function must simply
5325 ** use the provided path name verbatim -OR- resolve it into a full path name
5326 ** using the GetFullPathName Win32 API function (if available).
5327 */
5328 static BOOL winIsVerbatimPathname(
5329   const char *zPathname
5330 ){
5331   /*
5332   ** If the path name starts with a forward slash or a backslash, it is either
5333   ** a legal UNC name, a volume relative path, or an absolute path name in the
5334   ** "Unix" format on Windows.  There is no easy way to differentiate between
5335   ** the final two cases; therefore, we return the safer return value of TRUE
5336   ** so that callers of this function will simply use it verbatim.
5337   */
5338   if ( winIsDirSep(zPathname[0]) ){
5339     return TRUE;
5340   }
5341 
5342   /*
5343   ** If the path name starts with a letter and a colon it is either a volume
5344   ** relative path or an absolute path.  Callers of this function must not
5345   ** attempt to treat it as a relative path name (i.e. they should simply use
5346   ** it verbatim).
5347   */
5348   if ( winIsDriveLetterAndColon(zPathname) ){
5349     return TRUE;
5350   }
5351 
5352   /*
5353   ** If we get to this point, the path name should almost certainly be a purely
5354   ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
5355   */
5356   return FALSE;
5357 }
5358 
5359 /*
5360 ** Turn a relative pathname into a full pathname.  Write the full
5361 ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
5362 ** bytes in size.
5363 */
5364 static int winFullPathname(
5365   sqlite3_vfs *pVfs,            /* Pointer to vfs object */
5366   const char *zRelative,        /* Possibly relative input path */
5367   int nFull,                    /* Size of output buffer in bytes */
5368   char *zFull                   /* Output buffer */
5369 ){
5370 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
5371   DWORD nByte;
5372   void *zConverted;
5373   char *zOut;
5374 #endif
5375 
5376   /* If this path name begins with "/X:", where "X" is any alphabetic
5377   ** character, discard the initial "/" from the pathname.
5378   */
5379   if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
5380     zRelative++;
5381   }
5382 
5383 #if defined(__CYGWIN__)
5384   SimulateIOError( return SQLITE_ERROR );
5385   UNUSED_PARAMETER(nFull);
5386   assert( nFull>=pVfs->mxPathname );
5387   if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
5388     /*
5389     ** NOTE: We are dealing with a relative path name and the data
5390     **       directory has been set.  Therefore, use it as the basis
5391     **       for converting the relative path name to an absolute
5392     **       one by prepending the data directory and a slash.
5393     */
5394     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
5395     if( !zOut ){
5396       return SQLITE_IOERR_NOMEM_BKPT;
5397     }
5398     if( cygwin_conv_path(
5399             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
5400             CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
5401       sqlite3_free(zOut);
5402       return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
5403                          "winFullPathname1", zRelative);
5404     }else{
5405       char *zUtf8 = winConvertToUtf8Filename(zOut);
5406       if( !zUtf8 ){
5407         sqlite3_free(zOut);
5408         return SQLITE_IOERR_NOMEM_BKPT;
5409       }
5410       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
5411                        sqlite3_data_directory, winGetDirSep(), zUtf8);
5412       sqlite3_free(zUtf8);
5413       sqlite3_free(zOut);
5414     }
5415   }else{
5416     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
5417     if( !zOut ){
5418       return SQLITE_IOERR_NOMEM_BKPT;
5419     }
5420     if( cygwin_conv_path(
5421             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
5422             zRelative, zOut, pVfs->mxPathname+1)<0 ){
5423       sqlite3_free(zOut);
5424       return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
5425                          "winFullPathname2", zRelative);
5426     }else{
5427       char *zUtf8 = winConvertToUtf8Filename(zOut);
5428       if( !zUtf8 ){
5429         sqlite3_free(zOut);
5430         return SQLITE_IOERR_NOMEM_BKPT;
5431       }
5432       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
5433       sqlite3_free(zUtf8);
5434       sqlite3_free(zOut);
5435     }
5436   }
5437   return SQLITE_OK;
5438 #endif
5439 
5440 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
5441   SimulateIOError( return SQLITE_ERROR );
5442   /* WinCE has no concept of a relative pathname, or so I am told. */
5443   /* WinRT has no way to convert a relative path to an absolute one. */
5444   if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
5445     /*
5446     ** NOTE: We are dealing with a relative path name and the data
5447     **       directory has been set.  Therefore, use it as the basis
5448     **       for converting the relative path name to an absolute
5449     **       one by prepending the data directory and a backslash.
5450     */
5451     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
5452                      sqlite3_data_directory, winGetDirSep(), zRelative);
5453   }else{
5454     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
5455   }
5456   return SQLITE_OK;
5457 #endif
5458 
5459 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
5460   /* It's odd to simulate an io-error here, but really this is just
5461   ** using the io-error infrastructure to test that SQLite handles this
5462   ** function failing. This function could fail if, for example, the
5463   ** current working directory has been unlinked.
5464   */
5465   SimulateIOError( return SQLITE_ERROR );
5466   if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
5467     /*
5468     ** NOTE: We are dealing with a relative path name and the data
5469     **       directory has been set.  Therefore, use it as the basis
5470     **       for converting the relative path name to an absolute
5471     **       one by prepending the data directory and a backslash.
5472     */
5473     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
5474                      sqlite3_data_directory, winGetDirSep(), zRelative);
5475     return SQLITE_OK;
5476   }
5477   zConverted = winConvertFromUtf8Filename(zRelative);
5478   if( zConverted==0 ){
5479     return SQLITE_IOERR_NOMEM_BKPT;
5480   }
5481   if( osIsNT() ){
5482     LPWSTR zTemp;
5483     nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
5484     if( nByte==0 ){
5485       sqlite3_free(zConverted);
5486       return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
5487                          "winFullPathname1", zRelative);
5488     }
5489     nByte += 3;
5490     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
5491     if( zTemp==0 ){
5492       sqlite3_free(zConverted);
5493       return SQLITE_IOERR_NOMEM_BKPT;
5494     }
5495     nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
5496     if( nByte==0 ){
5497       sqlite3_free(zConverted);
5498       sqlite3_free(zTemp);
5499       return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
5500                          "winFullPathname2", zRelative);
5501     }
5502     sqlite3_free(zConverted);
5503     zOut = winUnicodeToUtf8(zTemp);
5504     sqlite3_free(zTemp);
5505   }
5506 #ifdef SQLITE_WIN32_HAS_ANSI
5507   else{
5508     char *zTemp;
5509     nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
5510     if( nByte==0 ){
5511       sqlite3_free(zConverted);
5512       return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
5513                          "winFullPathname3", zRelative);
5514     }
5515     nByte += 3;
5516     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
5517     if( zTemp==0 ){
5518       sqlite3_free(zConverted);
5519       return SQLITE_IOERR_NOMEM_BKPT;
5520     }
5521     nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
5522     if( nByte==0 ){
5523       sqlite3_free(zConverted);
5524       sqlite3_free(zTemp);
5525       return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
5526                          "winFullPathname4", zRelative);
5527     }
5528     sqlite3_free(zConverted);
5529     zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
5530     sqlite3_free(zTemp);
5531   }
5532 #endif
5533   if( zOut ){
5534     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
5535     sqlite3_free(zOut);
5536     return SQLITE_OK;
5537   }else{
5538     return SQLITE_IOERR_NOMEM_BKPT;
5539   }
5540 #endif
5541 }
5542 
5543 #ifndef SQLITE_OMIT_LOAD_EXTENSION
5544 /*
5545 ** Interfaces for opening a shared library, finding entry points
5546 ** within the shared library, and closing the shared library.
5547 */
5548 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
5549   HANDLE h;
5550 #if defined(__CYGWIN__)
5551   int nFull = pVfs->mxPathname+1;
5552   char *zFull = sqlite3MallocZero( nFull );
5553   void *zConverted = 0;
5554   if( zFull==0 ){
5555     OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
5556     return 0;
5557   }
5558   if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
5559     sqlite3_free(zFull);
5560     OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
5561     return 0;
5562   }
5563   zConverted = winConvertFromUtf8Filename(zFull);
5564   sqlite3_free(zFull);
5565 #else
5566   void *zConverted = winConvertFromUtf8Filename(zFilename);
5567   UNUSED_PARAMETER(pVfs);
5568 #endif
5569   if( zConverted==0 ){
5570     OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
5571     return 0;
5572   }
5573   if( osIsNT() ){
5574 #if SQLITE_OS_WINRT
5575     h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
5576 #else
5577     h = osLoadLibraryW((LPCWSTR)zConverted);
5578 #endif
5579   }
5580 #ifdef SQLITE_WIN32_HAS_ANSI
5581   else{
5582     h = osLoadLibraryA((char*)zConverted);
5583   }
5584 #endif
5585   OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
5586   sqlite3_free(zConverted);
5587   return (void*)h;
5588 }
5589 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
5590   UNUSED_PARAMETER(pVfs);
5591   winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
5592 }
5593 static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
5594   FARPROC proc;
5595   UNUSED_PARAMETER(pVfs);
5596   proc = osGetProcAddressA((HANDLE)pH, zSym);
5597   OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
5598            (void*)pH, zSym, (void*)proc));
5599   return (void(*)(void))proc;
5600 }
5601 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
5602   UNUSED_PARAMETER(pVfs);
5603   osFreeLibrary((HANDLE)pHandle);
5604   OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
5605 }
5606 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
5607   #define winDlOpen  0
5608   #define winDlError 0
5609   #define winDlSym   0
5610   #define winDlClose 0
5611 #endif
5612 
5613 /* State information for the randomness gatherer. */
5614 typedef struct EntropyGatherer EntropyGatherer;
5615 struct EntropyGatherer {
5616   unsigned char *a;   /* Gather entropy into this buffer */
5617   int na;             /* Size of a[] in bytes */
5618   int i;              /* XOR next input into a[i] */
5619   int nXor;           /* Number of XOR operations done */
5620 };
5621 
5622 #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
5623 /* Mix sz bytes of entropy into p. */
5624 static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
5625   int j, k;
5626   for(j=0, k=p->i; j<sz; j++){
5627     p->a[k++] ^= x[j];
5628     if( k>=p->na ) k = 0;
5629   }
5630   p->i = k;
5631   p->nXor += sz;
5632 }
5633 #endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
5634 
5635 /*
5636 ** Write up to nBuf bytes of randomness into zBuf.
5637 */
5638 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
5639 #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
5640   UNUSED_PARAMETER(pVfs);
5641   memset(zBuf, 0, nBuf);
5642   return nBuf;
5643 #else
5644   EntropyGatherer e;
5645   UNUSED_PARAMETER(pVfs);
5646   memset(zBuf, 0, nBuf);
5647 #if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE
5648   rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
5649 #endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
5650   e.a = (unsigned char*)zBuf;
5651   e.na = nBuf;
5652   e.nXor = 0;
5653   e.i = 0;
5654   {
5655     SYSTEMTIME x;
5656     osGetSystemTime(&x);
5657     xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
5658   }
5659   {
5660     DWORD pid = osGetCurrentProcessId();
5661     xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
5662   }
5663 #if SQLITE_OS_WINRT
5664   {
5665     ULONGLONG cnt = osGetTickCount64();
5666     xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
5667   }
5668 #else
5669   {
5670     DWORD cnt = osGetTickCount();
5671     xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
5672   }
5673 #endif /* SQLITE_OS_WINRT */
5674   {
5675     LARGE_INTEGER i;
5676     osQueryPerformanceCounter(&i);
5677     xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
5678   }
5679 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
5680   {
5681     UUID id;
5682     memset(&id, 0, sizeof(UUID));
5683     osUuidCreate(&id);
5684     xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
5685     memset(&id, 0, sizeof(UUID));
5686     osUuidCreateSequential(&id);
5687     xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
5688   }
5689 #endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
5690   return e.nXor>nBuf ? nBuf : e.nXor;
5691 #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
5692 }
5693 
5694 
5695 /*
5696 ** Sleep for a little while.  Return the amount of time slept.
5697 */
5698 static int winSleep(sqlite3_vfs *pVfs, int microsec){
5699   sqlite3_win32_sleep((microsec+999)/1000);
5700   UNUSED_PARAMETER(pVfs);
5701   return ((microsec+999)/1000)*1000;
5702 }
5703 
5704 /*
5705 ** The following variable, if set to a non-zero value, is interpreted as
5706 ** the number of seconds since 1970 and is used to set the result of
5707 ** sqlite3OsCurrentTime() during testing.
5708 */
5709 #ifdef SQLITE_TEST
5710 int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
5711 #endif
5712 
5713 /*
5714 ** Find the current time (in Universal Coordinated Time).  Write into *piNow
5715 ** the current time and date as a Julian Day number times 86_400_000.  In
5716 ** other words, write into *piNow the number of milliseconds since the Julian
5717 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
5718 ** proleptic Gregorian calendar.
5719 **
5720 ** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date
5721 ** cannot be found.
5722 */
5723 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
5724   /* FILETIME structure is a 64-bit value representing the number of
5725      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
5726   */
5727   FILETIME ft;
5728   static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
5729 #ifdef SQLITE_TEST
5730   static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
5731 #endif
5732   /* 2^32 - to avoid use of LL and warnings in gcc */
5733   static const sqlite3_int64 max32BitValue =
5734       (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
5735       (sqlite3_int64)294967296;
5736 
5737 #if SQLITE_OS_WINCE
5738   SYSTEMTIME time;
5739   osGetSystemTime(&time);
5740   /* if SystemTimeToFileTime() fails, it returns zero. */
5741   if (!osSystemTimeToFileTime(&time,&ft)){
5742     return SQLITE_ERROR;
5743   }
5744 #else
5745   osGetSystemTimeAsFileTime( &ft );
5746 #endif
5747 
5748   *piNow = winFiletimeEpoch +
5749             ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
5750                (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
5751 
5752 #ifdef SQLITE_TEST
5753   if( sqlite3_current_time ){
5754     *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
5755   }
5756 #endif
5757   UNUSED_PARAMETER(pVfs);
5758   return SQLITE_OK;
5759 }
5760 
5761 /*
5762 ** Find the current time (in Universal Coordinated Time).  Write the
5763 ** current time and date as a Julian Day number into *prNow and
5764 ** return 0.  Return 1 if the time and date cannot be found.
5765 */
5766 static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
5767   int rc;
5768   sqlite3_int64 i;
5769   rc = winCurrentTimeInt64(pVfs, &i);
5770   if( !rc ){
5771     *prNow = i/86400000.0;
5772   }
5773   return rc;
5774 }
5775 
5776 /*
5777 ** The idea is that this function works like a combination of
5778 ** GetLastError() and FormatMessage() on Windows (or errno and
5779 ** strerror_r() on Unix). After an error is returned by an OS
5780 ** function, SQLite calls this function with zBuf pointing to
5781 ** a buffer of nBuf bytes. The OS layer should populate the
5782 ** buffer with a nul-terminated UTF-8 encoded error message
5783 ** describing the last IO error to have occurred within the calling
5784 ** thread.
5785 **
5786 ** If the error message is too large for the supplied buffer,
5787 ** it should be truncated. The return value of xGetLastError
5788 ** is zero if the error message fits in the buffer, or non-zero
5789 ** otherwise (if the message was truncated). If non-zero is returned,
5790 ** then it is not necessary to include the nul-terminator character
5791 ** in the output buffer.
5792 **
5793 ** Not supplying an error message will have no adverse effect
5794 ** on SQLite. It is fine to have an implementation that never
5795 ** returns an error message:
5796 **
5797 **   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
5798 **     assert(zBuf[0]=='\0');
5799 **     return 0;
5800 **   }
5801 **
5802 ** However if an error message is supplied, it will be incorporated
5803 ** by sqlite into the error message available to the user using
5804 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
5805 */
5806 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
5807   DWORD e = osGetLastError();
5808   UNUSED_PARAMETER(pVfs);
5809   if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
5810   return e;
5811 }
5812 
5813 /*
5814 ** Initialize and deinitialize the operating system interface.
5815 */
5816 int sqlite3_os_init(void){
5817   static sqlite3_vfs winVfs = {
5818     3,                     /* iVersion */
5819     sizeof(winFile),       /* szOsFile */
5820     SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
5821     0,                     /* pNext */
5822     "win32",               /* zName */
5823     &winAppData,           /* pAppData */
5824     winOpen,               /* xOpen */
5825     winDelete,             /* xDelete */
5826     winAccess,             /* xAccess */
5827     winFullPathname,       /* xFullPathname */
5828     winDlOpen,             /* xDlOpen */
5829     winDlError,            /* xDlError */
5830     winDlSym,              /* xDlSym */
5831     winDlClose,            /* xDlClose */
5832     winRandomness,         /* xRandomness */
5833     winSleep,              /* xSleep */
5834     winCurrentTime,        /* xCurrentTime */
5835     winGetLastError,       /* xGetLastError */
5836     winCurrentTimeInt64,   /* xCurrentTimeInt64 */
5837     winSetSystemCall,      /* xSetSystemCall */
5838     winGetSystemCall,      /* xGetSystemCall */
5839     winNextSystemCall,     /* xNextSystemCall */
5840   };
5841 #if defined(SQLITE_WIN32_HAS_WIDE)
5842   static sqlite3_vfs winLongPathVfs = {
5843     3,                     /* iVersion */
5844     sizeof(winFile),       /* szOsFile */
5845     SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
5846     0,                     /* pNext */
5847     "win32-longpath",      /* zName */
5848     &winAppData,           /* pAppData */
5849     winOpen,               /* xOpen */
5850     winDelete,             /* xDelete */
5851     winAccess,             /* xAccess */
5852     winFullPathname,       /* xFullPathname */
5853     winDlOpen,             /* xDlOpen */
5854     winDlError,            /* xDlError */
5855     winDlSym,              /* xDlSym */
5856     winDlClose,            /* xDlClose */
5857     winRandomness,         /* xRandomness */
5858     winSleep,              /* xSleep */
5859     winCurrentTime,        /* xCurrentTime */
5860     winGetLastError,       /* xGetLastError */
5861     winCurrentTimeInt64,   /* xCurrentTimeInt64 */
5862     winSetSystemCall,      /* xSetSystemCall */
5863     winGetSystemCall,      /* xGetSystemCall */
5864     winNextSystemCall,     /* xNextSystemCall */
5865   };
5866 #endif
5867   static sqlite3_vfs winNolockVfs = {
5868     3,                     /* iVersion */
5869     sizeof(winFile),       /* szOsFile */
5870     SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
5871     0,                     /* pNext */
5872     "win32-none",          /* zName */
5873     &winNolockAppData,     /* pAppData */
5874     winOpen,               /* xOpen */
5875     winDelete,             /* xDelete */
5876     winAccess,             /* xAccess */
5877     winFullPathname,       /* xFullPathname */
5878     winDlOpen,             /* xDlOpen */
5879     winDlError,            /* xDlError */
5880     winDlSym,              /* xDlSym */
5881     winDlClose,            /* xDlClose */
5882     winRandomness,         /* xRandomness */
5883     winSleep,              /* xSleep */
5884     winCurrentTime,        /* xCurrentTime */
5885     winGetLastError,       /* xGetLastError */
5886     winCurrentTimeInt64,   /* xCurrentTimeInt64 */
5887     winSetSystemCall,      /* xSetSystemCall */
5888     winGetSystemCall,      /* xGetSystemCall */
5889     winNextSystemCall,     /* xNextSystemCall */
5890   };
5891 #if defined(SQLITE_WIN32_HAS_WIDE)
5892   static sqlite3_vfs winLongPathNolockVfs = {
5893     3,                     /* iVersion */
5894     sizeof(winFile),       /* szOsFile */
5895     SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
5896     0,                     /* pNext */
5897     "win32-longpath-none", /* zName */
5898     &winNolockAppData,     /* pAppData */
5899     winOpen,               /* xOpen */
5900     winDelete,             /* xDelete */
5901     winAccess,             /* xAccess */
5902     winFullPathname,       /* xFullPathname */
5903     winDlOpen,             /* xDlOpen */
5904     winDlError,            /* xDlError */
5905     winDlSym,              /* xDlSym */
5906     winDlClose,            /* xDlClose */
5907     winRandomness,         /* xRandomness */
5908     winSleep,              /* xSleep */
5909     winCurrentTime,        /* xCurrentTime */
5910     winGetLastError,       /* xGetLastError */
5911     winCurrentTimeInt64,   /* xCurrentTimeInt64 */
5912     winSetSystemCall,      /* xSetSystemCall */
5913     winGetSystemCall,      /* xGetSystemCall */
5914     winNextSystemCall,     /* xNextSystemCall */
5915   };
5916 #endif
5917 
5918   /* Double-check that the aSyscall[] array has been constructed
5919   ** correctly.  See ticket [bb3a86e890c8e96ab] */
5920   assert( ArraySize(aSyscall)==80 );
5921 
5922   /* get memory map allocation granularity */
5923   memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
5924 #if SQLITE_OS_WINRT
5925   osGetNativeSystemInfo(&winSysInfo);
5926 #else
5927   osGetSystemInfo(&winSysInfo);
5928 #endif
5929   assert( winSysInfo.dwAllocationGranularity>0 );
5930   assert( winSysInfo.dwPageSize>0 );
5931 
5932   sqlite3_vfs_register(&winVfs, 1);
5933 
5934 #if defined(SQLITE_WIN32_HAS_WIDE)
5935   sqlite3_vfs_register(&winLongPathVfs, 0);
5936 #endif
5937 
5938   sqlite3_vfs_register(&winNolockVfs, 0);
5939 
5940 #if defined(SQLITE_WIN32_HAS_WIDE)
5941   sqlite3_vfs_register(&winLongPathNolockVfs, 0);
5942 #endif
5943 
5944   return SQLITE_OK;
5945 }
5946 
5947 int sqlite3_os_end(void){
5948 #if SQLITE_OS_WINRT
5949   if( sleepObj!=NULL ){
5950     osCloseHandle(sleepObj);
5951     sleepObj = NULL;
5952   }
5953 #endif
5954   return SQLITE_OK;
5955 }
5956 
5957 #endif /* SQLITE_OS_WIN */
5958