Annotation of embedaddon/sqlite3/src/os_win.c, revision 1.1

1.1     ! misho       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: #ifdef __CYGWIN__
        !            19: # include <sys/cygwin.h>
        !            20: #endif
        !            21: 
        !            22: /*
        !            23: ** Include code that is common to all os_*.c files
        !            24: */
        !            25: #include "os_common.h"
        !            26: 
        !            27: /*
        !            28: ** Some Microsoft compilers lack this definition.
        !            29: */
        !            30: #ifndef INVALID_FILE_ATTRIBUTES
        !            31: # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 
        !            32: #endif
        !            33: 
        !            34: /* Forward references */
        !            35: typedef struct winShm winShm;           /* A connection to shared-memory */
        !            36: typedef struct winShmNode winShmNode;   /* A region of shared-memory */
        !            37: 
        !            38: /*
        !            39: ** WinCE lacks native support for file locking so we have to fake it
        !            40: ** with some code of our own.
        !            41: */
        !            42: #if SQLITE_OS_WINCE
        !            43: typedef struct winceLock {
        !            44:   int nReaders;       /* Number of reader locks obtained */
        !            45:   BOOL bPending;      /* Indicates a pending lock has been obtained */
        !            46:   BOOL bReserved;     /* Indicates a reserved lock has been obtained */
        !            47:   BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
        !            48: } winceLock;
        !            49: #endif
        !            50: 
        !            51: /*
        !            52: ** The winFile structure is a subclass of sqlite3_file* specific to the win32
        !            53: ** portability layer.
        !            54: */
        !            55: typedef struct winFile winFile;
        !            56: struct winFile {
        !            57:   const sqlite3_io_methods *pMethod; /*** Must be first ***/
        !            58:   sqlite3_vfs *pVfs;      /* The VFS used to open this file */
        !            59:   HANDLE h;               /* Handle for accessing the file */
        !            60:   u8 locktype;            /* Type of lock currently held on this file */
        !            61:   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
        !            62:   u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
        !            63:   DWORD lastErrno;        /* The Windows errno from the last I/O error */
        !            64:   winShm *pShm;           /* Instance of shared memory on this file */
        !            65:   const char *zPath;      /* Full pathname of this file */
        !            66:   int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
        !            67: #if SQLITE_OS_WINCE
        !            68:   LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
        !            69:   HANDLE hMutex;          /* Mutex used to control access to shared lock */  
        !            70:   HANDLE hShared;         /* Shared memory segment used for locking */
        !            71:   winceLock local;        /* Locks obtained by this instance of winFile */
        !            72:   winceLock *shared;      /* Global shared lock memory for the file  */
        !            73: #endif
        !            74: };
        !            75: 
        !            76: /*
        !            77: ** Allowed values for winFile.ctrlFlags
        !            78: */
        !            79: #define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
        !            80: #define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
        !            81: 
        !            82: /*
        !            83:  * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
        !            84:  * various Win32 API heap functions instead of our own.
        !            85:  */
        !            86: #ifdef SQLITE_WIN32_MALLOC
        !            87: /*
        !            88:  * The initial size of the Win32-specific heap.  This value may be zero.
        !            89:  */
        !            90: #ifndef SQLITE_WIN32_HEAP_INIT_SIZE
        !            91: #  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
        !            92:                                        (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
        !            93: #endif
        !            94: 
        !            95: /*
        !            96:  * The maximum size of the Win32-specific heap.  This value may be zero.
        !            97:  */
        !            98: #ifndef SQLITE_WIN32_HEAP_MAX_SIZE
        !            99: #  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
        !           100: #endif
        !           101: 
        !           102: /*
        !           103:  * The extra flags to use in calls to the Win32 heap APIs.  This value may be
        !           104:  * zero for the default behavior.
        !           105:  */
        !           106: #ifndef SQLITE_WIN32_HEAP_FLAGS
        !           107: #  define SQLITE_WIN32_HEAP_FLAGS     (0)
        !           108: #endif
        !           109: 
        !           110: /*
        !           111: ** The winMemData structure stores information required by the Win32-specific
        !           112: ** sqlite3_mem_methods implementation.
        !           113: */
        !           114: typedef struct winMemData winMemData;
        !           115: struct winMemData {
        !           116: #ifndef NDEBUG
        !           117:   u32 magic;    /* Magic number to detect structure corruption. */
        !           118: #endif
        !           119:   HANDLE hHeap; /* The handle to our heap. */
        !           120:   BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
        !           121: };
        !           122: 
        !           123: #ifndef NDEBUG
        !           124: #define WINMEM_MAGIC     0x42b2830b
        !           125: #endif
        !           126: 
        !           127: static struct winMemData win_mem_data = {
        !           128: #ifndef NDEBUG
        !           129:   WINMEM_MAGIC,
        !           130: #endif
        !           131:   NULL, FALSE
        !           132: };
        !           133: 
        !           134: #ifndef NDEBUG
        !           135: #define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
        !           136: #else
        !           137: #define winMemAssertMagic()
        !           138: #endif
        !           139: 
        !           140: #define winMemGetHeap() win_mem_data.hHeap
        !           141: 
        !           142: static void *winMemMalloc(int nBytes);
        !           143: static void winMemFree(void *pPrior);
        !           144: static void *winMemRealloc(void *pPrior, int nBytes);
        !           145: static int winMemSize(void *p);
        !           146: static int winMemRoundup(int n);
        !           147: static int winMemInit(void *pAppData);
        !           148: static void winMemShutdown(void *pAppData);
        !           149: 
        !           150: const sqlite3_mem_methods *sqlite3MemGetWin32(void);
        !           151: #endif /* SQLITE_WIN32_MALLOC */
        !           152: 
        !           153: /*
        !           154: ** The following variable is (normally) set once and never changes
        !           155: ** thereafter.  It records whether the operating system is Win9x
        !           156: ** or WinNT.
        !           157: **
        !           158: ** 0:   Operating system unknown.
        !           159: ** 1:   Operating system is Win9x.
        !           160: ** 2:   Operating system is WinNT.
        !           161: **
        !           162: ** In order to facilitate testing on a WinNT system, the test fixture
        !           163: ** can manually set this value to 1 to emulate Win98 behavior.
        !           164: */
        !           165: #ifdef SQLITE_TEST
        !           166: int sqlite3_os_type = 0;
        !           167: #else
        !           168: static int sqlite3_os_type = 0;
        !           169: #endif
        !           170: 
        !           171: /*
        !           172: ** Many system calls are accessed through pointer-to-functions so that
        !           173: ** they may be overridden at runtime to facilitate fault injection during
        !           174: ** testing and sandboxing.  The following array holds the names and pointers
        !           175: ** to all overrideable system calls.
        !           176: */
        !           177: #if !SQLITE_OS_WINCE
        !           178: #  define SQLITE_WIN32_HAS_ANSI
        !           179: #endif
        !           180: 
        !           181: #if SQLITE_OS_WINCE || SQLITE_OS_WINNT
        !           182: #  define SQLITE_WIN32_HAS_WIDE
        !           183: #endif
        !           184: 
        !           185: #ifndef SYSCALL
        !           186: #  define SYSCALL sqlite3_syscall_ptr
        !           187: #endif
        !           188: 
        !           189: #if SQLITE_OS_WINCE
        !           190: /*
        !           191: ** These macros are necessary because Windows CE does not natively support the
        !           192: ** Win32 APIs LockFile, UnlockFile, and LockFileEx.
        !           193:  */
        !           194: 
        !           195: #  define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
        !           196: #  define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
        !           197: #  define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
        !           198: 
        !           199: /*
        !           200: ** These are the special syscall hacks for Windows CE.  The locking related
        !           201: ** defines here refer to the macros defined just above.
        !           202:  */
        !           203: 
        !           204: #  define osAreFileApisANSI()       1
        !           205: #  define osLockFile                LockFile
        !           206: #  define osUnlockFile              UnlockFile
        !           207: #  define osLockFileEx              LockFileEx
        !           208: #endif
        !           209: 
        !           210: static struct win_syscall {
        !           211:   const char *zName;            /* Name of the sytem call */
        !           212:   sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
        !           213:   sqlite3_syscall_ptr pDefault; /* Default value */
        !           214: } aSyscall[] = {
        !           215: #if !SQLITE_OS_WINCE
        !           216:   { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
        !           217: 
        !           218: #define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
        !           219: #else
        !           220:   { "AreFileApisANSI",         (SYSCALL)0,                       0 },
        !           221: #endif
        !           222: 
        !           223: #if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
        !           224:   { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
        !           225: #else
        !           226:   { "CharLowerW",              (SYSCALL)0,                       0 },
        !           227: #endif
        !           228: 
        !           229: #define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
        !           230: 
        !           231: #if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
        !           232:   { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
        !           233: #else
        !           234:   { "CharUpperW",              (SYSCALL)0,                       0 },
        !           235: #endif
        !           236: 
        !           237: #define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
        !           238: 
        !           239:   { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
        !           240: 
        !           241: #define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
        !           242: 
        !           243: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           244:   { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
        !           245: #else
        !           246:   { "CreateFileA",             (SYSCALL)0,                       0 },
        !           247: #endif
        !           248: 
        !           249: #define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
        !           250:         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
        !           251: 
        !           252: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           253:   { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
        !           254: #else
        !           255:   { "CreateFileW",             (SYSCALL)0,                       0 },
        !           256: #endif
        !           257: 
        !           258: #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
        !           259:         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
        !           260: 
        !           261:   { "CreateFileMapping",       (SYSCALL)CreateFileMapping,       0 },
        !           262: 
        !           263: #define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        !           264:         DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent)
        !           265: 
        !           266: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           267:   { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
        !           268: #else
        !           269:   { "CreateFileMappingW",      (SYSCALL)0,                       0 },
        !           270: #endif
        !           271: 
        !           272: #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
        !           273:         DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
        !           274: 
        !           275: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           276:   { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
        !           277: #else
        !           278:   { "CreateMutexW",            (SYSCALL)0,                       0 },
        !           279: #endif
        !           280: 
        !           281: #define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
        !           282:         LPCWSTR))aSyscall[8].pCurrent)
        !           283: 
        !           284: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           285:   { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
        !           286: #else
        !           287:   { "DeleteFileA",             (SYSCALL)0,                       0 },
        !           288: #endif
        !           289: 
        !           290: #define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
        !           291: 
        !           292: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           293:   { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
        !           294: #else
        !           295:   { "DeleteFileW",             (SYSCALL)0,                       0 },
        !           296: #endif
        !           297: 
        !           298: #define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
        !           299: 
        !           300: #if SQLITE_OS_WINCE
        !           301:   { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
        !           302: #else
        !           303:   { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
        !           304: #endif
        !           305: 
        !           306: #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
        !           307:         LPFILETIME))aSyscall[11].pCurrent)
        !           308: 
        !           309: #if SQLITE_OS_WINCE
        !           310:   { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
        !           311: #else
        !           312:   { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
        !           313: #endif
        !           314: 
        !           315: #define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
        !           316:         LPSYSTEMTIME))aSyscall[12].pCurrent)
        !           317: 
        !           318:   { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
        !           319: 
        !           320: #define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
        !           321: 
        !           322: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           323:   { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
        !           324: #else
        !           325:   { "FormatMessageA",          (SYSCALL)0,                       0 },
        !           326: #endif
        !           327: 
        !           328: #define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
        !           329:         DWORD,va_list*))aSyscall[14].pCurrent)
        !           330: 
        !           331: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           332:   { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
        !           333: #else
        !           334:   { "FormatMessageW",          (SYSCALL)0,                       0 },
        !           335: #endif
        !           336: 
        !           337: #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
        !           338:         DWORD,va_list*))aSyscall[15].pCurrent)
        !           339: 
        !           340:   { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
        !           341: 
        !           342: #define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
        !           343: 
        !           344:   { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
        !           345: 
        !           346: #define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
        !           347: 
        !           348: #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
        !           349:   { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
        !           350: #else
        !           351:   { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
        !           352: #endif
        !           353: 
        !           354: #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
        !           355:         LPDWORD))aSyscall[18].pCurrent)
        !           356: 
        !           357: #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
        !           358:   { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
        !           359: #else
        !           360:   { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
        !           361: #endif
        !           362: 
        !           363: #define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
        !           364:         LPDWORD))aSyscall[19].pCurrent)
        !           365: 
        !           366: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           367:   { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
        !           368: #else
        !           369:   { "GetFileAttributesA",      (SYSCALL)0,                       0 },
        !           370: #endif
        !           371: 
        !           372: #define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
        !           373: 
        !           374: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           375:   { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
        !           376: #else
        !           377:   { "GetFileAttributesW",      (SYSCALL)0,                       0 },
        !           378: #endif
        !           379: 
        !           380: #define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
        !           381: 
        !           382: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           383:   { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
        !           384: #else
        !           385:   { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
        !           386: #endif
        !           387: 
        !           388: #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
        !           389:         LPVOID))aSyscall[22].pCurrent)
        !           390: 
        !           391:   { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
        !           392: 
        !           393: #define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
        !           394: 
        !           395: #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
        !           396:   { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
        !           397: #else
        !           398:   { "GetFullPathNameA",        (SYSCALL)0,                       0 },
        !           399: #endif
        !           400: 
        !           401: #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
        !           402:         LPSTR*))aSyscall[24].pCurrent)
        !           403: 
        !           404: #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
        !           405:   { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
        !           406: #else
        !           407:   { "GetFullPathNameW",        (SYSCALL)0,                       0 },
        !           408: #endif
        !           409: 
        !           410: #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
        !           411:         LPWSTR*))aSyscall[25].pCurrent)
        !           412: 
        !           413:   { "GetLastError",            (SYSCALL)GetLastError,            0 },
        !           414: 
        !           415: #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
        !           416: 
        !           417: #if SQLITE_OS_WINCE
        !           418:   /* The GetProcAddressA() routine is only available on Windows CE. */
        !           419:   { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
        !           420: #else
        !           421:   /* All other Windows platforms expect GetProcAddress() to take
        !           422:   ** an ANSI string regardless of the _UNICODE setting */
        !           423:   { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
        !           424: #endif
        !           425: 
        !           426: #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
        !           427:         LPCSTR))aSyscall[27].pCurrent)
        !           428: 
        !           429:   { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
        !           430: 
        !           431: #define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
        !           432: 
        !           433:   { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
        !           434: 
        !           435: #define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
        !           436: 
        !           437: #if !SQLITE_OS_WINCE
        !           438:   { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
        !           439: #else
        !           440:   { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
        !           441: #endif
        !           442: 
        !           443: #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
        !           444:         LPFILETIME))aSyscall[30].pCurrent)
        !           445: 
        !           446: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           447:   { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
        !           448: #else
        !           449:   { "GetTempPathA",            (SYSCALL)0,                       0 },
        !           450: #endif
        !           451: 
        !           452: #define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
        !           453: 
        !           454: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           455:   { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
        !           456: #else
        !           457:   { "GetTempPathW",            (SYSCALL)0,                       0 },
        !           458: #endif
        !           459: 
        !           460: #define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
        !           461: 
        !           462:   { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
        !           463: 
        !           464: #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
        !           465: 
        !           466: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           467:   { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
        !           468: #else
        !           469:   { "GetVersionExA",           (SYSCALL)0,                       0 },
        !           470: #endif
        !           471: 
        !           472: #define osGetVersionExA ((BOOL(WINAPI*)( \
        !           473:         LPOSVERSIONINFOA))aSyscall[34].pCurrent)
        !           474: 
        !           475:   { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
        !           476: 
        !           477: #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
        !           478:         SIZE_T))aSyscall[35].pCurrent)
        !           479: 
        !           480:   { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
        !           481: 
        !           482: #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
        !           483:         SIZE_T))aSyscall[36].pCurrent)
        !           484: 
        !           485:   { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
        !           486: 
        !           487: #define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
        !           488: 
        !           489:   { "HeapFree",                (SYSCALL)HeapFree,                0 },
        !           490: 
        !           491: #define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
        !           492: 
        !           493:   { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
        !           494: 
        !           495: #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
        !           496:         SIZE_T))aSyscall[39].pCurrent)
        !           497: 
        !           498:   { "HeapSize",                (SYSCALL)HeapSize,                0 },
        !           499: 
        !           500: #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
        !           501:         LPCVOID))aSyscall[40].pCurrent)
        !           502: 
        !           503:   { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
        !           504: 
        !           505: #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
        !           506:         LPCVOID))aSyscall[41].pCurrent)
        !           507: 
        !           508: #if defined(SQLITE_WIN32_HAS_ANSI)
        !           509:   { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
        !           510: #else
        !           511:   { "LoadLibraryA",            (SYSCALL)0,                       0 },
        !           512: #endif
        !           513: 
        !           514: #define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
        !           515: 
        !           516: #if defined(SQLITE_WIN32_HAS_WIDE)
        !           517:   { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
        !           518: #else
        !           519:   { "LoadLibraryW",            (SYSCALL)0,                       0 },
        !           520: #endif
        !           521: 
        !           522: #define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
        !           523: 
        !           524:   { "LocalFree",               (SYSCALL)LocalFree,               0 },
        !           525: 
        !           526: #define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
        !           527: 
        !           528: #if !SQLITE_OS_WINCE
        !           529:   { "LockFile",                (SYSCALL)LockFile,                0 },
        !           530: 
        !           531: #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        !           532:         DWORD))aSyscall[45].pCurrent)
        !           533: #else
        !           534:   { "LockFile",                (SYSCALL)0,                       0 },
        !           535: #endif
        !           536: 
        !           537: #if !SQLITE_OS_WINCE
        !           538:   { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
        !           539: 
        !           540: #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
        !           541:         LPOVERLAPPED))aSyscall[46].pCurrent)
        !           542: #else
        !           543:   { "LockFileEx",              (SYSCALL)0,                       0 },
        !           544: #endif
        !           545: 
        !           546:   { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
        !           547: 
        !           548: #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        !           549:         SIZE_T))aSyscall[47].pCurrent)
        !           550: 
        !           551:   { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
        !           552: 
        !           553: #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
        !           554:         int))aSyscall[48].pCurrent)
        !           555: 
        !           556:   { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
        !           557: 
        !           558: #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
        !           559:         LARGE_INTEGER*))aSyscall[49].pCurrent)
        !           560: 
        !           561:   { "ReadFile",                (SYSCALL)ReadFile,                0 },
        !           562: 
        !           563: #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
        !           564:         LPOVERLAPPED))aSyscall[50].pCurrent)
        !           565: 
        !           566:   { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
        !           567: 
        !           568: #define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
        !           569: 
        !           570:   { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
        !           571: 
        !           572: #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
        !           573:         DWORD))aSyscall[52].pCurrent)
        !           574: 
        !           575:   { "Sleep",                   (SYSCALL)Sleep,                   0 },
        !           576: 
        !           577: #define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
        !           578: 
        !           579:   { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
        !           580: 
        !           581: #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
        !           582:         LPFILETIME))aSyscall[54].pCurrent)
        !           583: 
        !           584: #if !SQLITE_OS_WINCE
        !           585:   { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
        !           586: 
        !           587: #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        !           588:         DWORD))aSyscall[55].pCurrent)
        !           589: #else
        !           590:   { "UnlockFile",              (SYSCALL)0,                       0 },
        !           591: #endif
        !           592: 
        !           593: #if !SQLITE_OS_WINCE
        !           594:   { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
        !           595: 
        !           596: #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
        !           597:         LPOVERLAPPED))aSyscall[56].pCurrent)
        !           598: #else
        !           599:   { "UnlockFileEx",            (SYSCALL)0,                       0 },
        !           600: #endif
        !           601: 
        !           602:   { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
        !           603: 
        !           604: #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
        !           605: 
        !           606:   { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
        !           607: 
        !           608: #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
        !           609:         LPCSTR,LPBOOL))aSyscall[58].pCurrent)
        !           610: 
        !           611:   { "WriteFile",               (SYSCALL)WriteFile,               0 },
        !           612: 
        !           613: #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
        !           614:         LPOVERLAPPED))aSyscall[59].pCurrent)
        !           615: 
        !           616: }; /* End of the overrideable system calls */
        !           617: 
        !           618: /*
        !           619: ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
        !           620: ** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
        !           621: ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
        !           622: ** system call named zName.
        !           623: */
        !           624: static int winSetSystemCall(
        !           625:   sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
        !           626:   const char *zName,            /* Name of system call to override */
        !           627:   sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
        !           628: ){
        !           629:   unsigned int i;
        !           630:   int rc = SQLITE_NOTFOUND;
        !           631: 
        !           632:   UNUSED_PARAMETER(pNotUsed);
        !           633:   if( zName==0 ){
        !           634:     /* If no zName is given, restore all system calls to their default
        !           635:     ** settings and return NULL
        !           636:     */
        !           637:     rc = SQLITE_OK;
        !           638:     for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
        !           639:       if( aSyscall[i].pDefault ){
        !           640:         aSyscall[i].pCurrent = aSyscall[i].pDefault;
        !           641:       }
        !           642:     }
        !           643:   }else{
        !           644:     /* If zName is specified, operate on only the one system call
        !           645:     ** specified.
        !           646:     */
        !           647:     for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
        !           648:       if( strcmp(zName, aSyscall[i].zName)==0 ){
        !           649:         if( aSyscall[i].pDefault==0 ){
        !           650:           aSyscall[i].pDefault = aSyscall[i].pCurrent;
        !           651:         }
        !           652:         rc = SQLITE_OK;
        !           653:         if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
        !           654:         aSyscall[i].pCurrent = pNewFunc;
        !           655:         break;
        !           656:       }
        !           657:     }
        !           658:   }
        !           659:   return rc;
        !           660: }
        !           661: 
        !           662: /*
        !           663: ** Return the value of a system call.  Return NULL if zName is not a
        !           664: ** recognized system call name.  NULL is also returned if the system call
        !           665: ** is currently undefined.
        !           666: */
        !           667: static sqlite3_syscall_ptr winGetSystemCall(
        !           668:   sqlite3_vfs *pNotUsed,
        !           669:   const char *zName
        !           670: ){
        !           671:   unsigned int i;
        !           672: 
        !           673:   UNUSED_PARAMETER(pNotUsed);
        !           674:   for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
        !           675:     if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
        !           676:   }
        !           677:   return 0;
        !           678: }
        !           679: 
        !           680: /*
        !           681: ** Return the name of the first system call after zName.  If zName==NULL
        !           682: ** then return the name of the first system call.  Return NULL if zName
        !           683: ** is the last system call or if zName is not the name of a valid
        !           684: ** system call.
        !           685: */
        !           686: static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
        !           687:   int i = -1;
        !           688: 
        !           689:   UNUSED_PARAMETER(p);
        !           690:   if( zName ){
        !           691:     for(i=0; i<ArraySize(aSyscall)-1; i++){
        !           692:       if( strcmp(zName, aSyscall[i].zName)==0 ) break;
        !           693:     }
        !           694:   }
        !           695:   for(i++; i<ArraySize(aSyscall); i++){
        !           696:     if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
        !           697:   }
        !           698:   return 0;
        !           699: }
        !           700: 
        !           701: /*
        !           702: ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
        !           703: ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
        !           704: **
        !           705: ** Here is an interesting observation:  Win95, Win98, and WinME lack
        !           706: ** the LockFileEx() API.  But we can still statically link against that
        !           707: ** API as long as we don't call it when running Win95/98/ME.  A call to
        !           708: ** this routine is used to determine if the host is Win95/98/ME or
        !           709: ** WinNT/2K/XP so that we will know whether or not we can safely call
        !           710: ** the LockFileEx() API.
        !           711: */
        !           712: #if SQLITE_OS_WINCE
        !           713: # define isNT()  (1)
        !           714: #else
        !           715:   static int isNT(void){
        !           716:     if( sqlite3_os_type==0 ){
        !           717:       OSVERSIONINFOA sInfo;
        !           718:       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
        !           719:       osGetVersionExA(&sInfo);
        !           720:       sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
        !           721:     }
        !           722:     return sqlite3_os_type==2;
        !           723:   }
        !           724: #endif /* SQLITE_OS_WINCE */
        !           725: 
        !           726: #ifdef SQLITE_WIN32_MALLOC
        !           727: /*
        !           728: ** Allocate nBytes of memory.
        !           729: */
        !           730: static void *winMemMalloc(int nBytes){
        !           731:   HANDLE hHeap;
        !           732:   void *p;
        !           733: 
        !           734:   winMemAssertMagic();
        !           735:   hHeap = winMemGetHeap();
        !           736:   assert( hHeap!=0 );
        !           737:   assert( hHeap!=INVALID_HANDLE_VALUE );
        !           738: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           739:   assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
        !           740: #endif
        !           741:   assert( nBytes>=0 );
        !           742:   p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
        !           743:   if( !p ){
        !           744:     sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
        !           745:                 nBytes, osGetLastError(), (void*)hHeap);
        !           746:   }
        !           747:   return p;
        !           748: }
        !           749: 
        !           750: /*
        !           751: ** Free memory.
        !           752: */
        !           753: static void winMemFree(void *pPrior){
        !           754:   HANDLE hHeap;
        !           755: 
        !           756:   winMemAssertMagic();
        !           757:   hHeap = winMemGetHeap();
        !           758:   assert( hHeap!=0 );
        !           759:   assert( hHeap!=INVALID_HANDLE_VALUE );
        !           760: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           761:   assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
        !           762: #endif
        !           763:   if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
        !           764:   if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
        !           765:     sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
        !           766:                 pPrior, osGetLastError(), (void*)hHeap);
        !           767:   }
        !           768: }
        !           769: 
        !           770: /*
        !           771: ** Change the size of an existing memory allocation
        !           772: */
        !           773: static void *winMemRealloc(void *pPrior, int nBytes){
        !           774:   HANDLE hHeap;
        !           775:   void *p;
        !           776: 
        !           777:   winMemAssertMagic();
        !           778:   hHeap = winMemGetHeap();
        !           779:   assert( hHeap!=0 );
        !           780:   assert( hHeap!=INVALID_HANDLE_VALUE );
        !           781: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           782:   assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
        !           783: #endif
        !           784:   assert( nBytes>=0 );
        !           785:   if( !pPrior ){
        !           786:     p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
        !           787:   }else{
        !           788:     p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
        !           789:   }
        !           790:   if( !p ){
        !           791:     sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
        !           792:                 pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
        !           793:                 (void*)hHeap);
        !           794:   }
        !           795:   return p;
        !           796: }
        !           797: 
        !           798: /*
        !           799: ** Return the size of an outstanding allocation, in bytes.
        !           800: */
        !           801: static int winMemSize(void *p){
        !           802:   HANDLE hHeap;
        !           803:   SIZE_T n;
        !           804: 
        !           805:   winMemAssertMagic();
        !           806:   hHeap = winMemGetHeap();
        !           807:   assert( hHeap!=0 );
        !           808:   assert( hHeap!=INVALID_HANDLE_VALUE );
        !           809: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           810:   assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
        !           811: #endif
        !           812:   if( !p ) return 0;
        !           813:   n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
        !           814:   if( n==(SIZE_T)-1 ){
        !           815:     sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
        !           816:                 p, osGetLastError(), (void*)hHeap);
        !           817:     return 0;
        !           818:   }
        !           819:   return (int)n;
        !           820: }
        !           821: 
        !           822: /*
        !           823: ** Round up a request size to the next valid allocation size.
        !           824: */
        !           825: static int winMemRoundup(int n){
        !           826:   return n;
        !           827: }
        !           828: 
        !           829: /*
        !           830: ** Initialize this module.
        !           831: */
        !           832: static int winMemInit(void *pAppData){
        !           833:   winMemData *pWinMemData = (winMemData *)pAppData;
        !           834: 
        !           835:   if( !pWinMemData ) return SQLITE_ERROR;
        !           836:   assert( pWinMemData->magic==WINMEM_MAGIC );
        !           837:   if( !pWinMemData->hHeap ){
        !           838:     pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
        !           839:                                       SQLITE_WIN32_HEAP_INIT_SIZE,
        !           840:                                       SQLITE_WIN32_HEAP_MAX_SIZE);
        !           841:     if( !pWinMemData->hHeap ){
        !           842:       sqlite3_log(SQLITE_NOMEM,
        !           843:           "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
        !           844:           osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
        !           845:           SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
        !           846:       return SQLITE_NOMEM;
        !           847:     }
        !           848:     pWinMemData->bOwned = TRUE;
        !           849:   }
        !           850:   assert( pWinMemData->hHeap!=0 );
        !           851:   assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
        !           852: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           853:   assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
        !           854: #endif
        !           855:   return SQLITE_OK;
        !           856: }
        !           857: 
        !           858: /*
        !           859: ** Deinitialize this module.
        !           860: */
        !           861: static void winMemShutdown(void *pAppData){
        !           862:   winMemData *pWinMemData = (winMemData *)pAppData;
        !           863: 
        !           864:   if( !pWinMemData ) return;
        !           865:   if( pWinMemData->hHeap ){
        !           866:     assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
        !           867: #ifdef SQLITE_WIN32_MALLOC_VALIDATE
        !           868:     assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
        !           869: #endif
        !           870:     if( pWinMemData->bOwned ){
        !           871:       if( !osHeapDestroy(pWinMemData->hHeap) ){
        !           872:         sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
        !           873:                     osGetLastError(), (void*)pWinMemData->hHeap);
        !           874:       }
        !           875:       pWinMemData->bOwned = FALSE;
        !           876:     }
        !           877:     pWinMemData->hHeap = NULL;
        !           878:   }
        !           879: }
        !           880: 
        !           881: /*
        !           882: ** Populate the low-level memory allocation function pointers in
        !           883: ** sqlite3GlobalConfig.m with pointers to the routines in this file. The
        !           884: ** arguments specify the block of memory to manage.
        !           885: **
        !           886: ** This routine is only called by sqlite3_config(), and therefore
        !           887: ** is not required to be threadsafe (it is not).
        !           888: */
        !           889: const sqlite3_mem_methods *sqlite3MemGetWin32(void){
        !           890:   static const sqlite3_mem_methods winMemMethods = {
        !           891:     winMemMalloc,
        !           892:     winMemFree,
        !           893:     winMemRealloc,
        !           894:     winMemSize,
        !           895:     winMemRoundup,
        !           896:     winMemInit,
        !           897:     winMemShutdown,
        !           898:     &win_mem_data
        !           899:   };
        !           900:   return &winMemMethods;
        !           901: }
        !           902: 
        !           903: void sqlite3MemSetDefault(void){
        !           904:   sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
        !           905: }
        !           906: #endif /* SQLITE_WIN32_MALLOC */
        !           907: 
        !           908: /*
        !           909: ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
        !           910: **
        !           911: ** Space to hold the returned string is obtained from malloc.
        !           912: */
        !           913: static LPWSTR utf8ToUnicode(const char *zFilename){
        !           914:   int nChar;
        !           915:   LPWSTR zWideFilename;
        !           916: 
        !           917:   nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
        !           918:   if( nChar==0 ){
        !           919:     return 0;
        !           920:   }
        !           921:   zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
        !           922:   if( zWideFilename==0 ){
        !           923:     return 0;
        !           924:   }
        !           925:   nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
        !           926:                                 nChar);
        !           927:   if( nChar==0 ){
        !           928:     sqlite3_free(zWideFilename);
        !           929:     zWideFilename = 0;
        !           930:   }
        !           931:   return zWideFilename;
        !           932: }
        !           933: 
        !           934: /*
        !           935: ** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
        !           936: ** obtained from sqlite3_malloc().
        !           937: */
        !           938: static char *unicodeToUtf8(LPCWSTR zWideFilename){
        !           939:   int nByte;
        !           940:   char *zFilename;
        !           941: 
        !           942:   nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
        !           943:   if( nByte == 0 ){
        !           944:     return 0;
        !           945:   }
        !           946:   zFilename = sqlite3_malloc( nByte );
        !           947:   if( zFilename==0 ){
        !           948:     return 0;
        !           949:   }
        !           950:   nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
        !           951:                                 0, 0);
        !           952:   if( nByte == 0 ){
        !           953:     sqlite3_free(zFilename);
        !           954:     zFilename = 0;
        !           955:   }
        !           956:   return zFilename;
        !           957: }
        !           958: 
        !           959: /*
        !           960: ** Convert an ANSI string to Microsoft Unicode, based on the
        !           961: ** current codepage settings for file apis.
        !           962: ** 
        !           963: ** Space to hold the returned string is obtained
        !           964: ** from sqlite3_malloc.
        !           965: */
        !           966: static LPWSTR mbcsToUnicode(const char *zFilename){
        !           967:   int nByte;
        !           968:   LPWSTR zMbcsFilename;
        !           969:   int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
        !           970: 
        !           971:   nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
        !           972:                                 0)*sizeof(WCHAR);
        !           973:   if( nByte==0 ){
        !           974:     return 0;
        !           975:   }
        !           976:   zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
        !           977:   if( zMbcsFilename==0 ){
        !           978:     return 0;
        !           979:   }
        !           980:   nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
        !           981:                                 nByte);
        !           982:   if( nByte==0 ){
        !           983:     sqlite3_free(zMbcsFilename);
        !           984:     zMbcsFilename = 0;
        !           985:   }
        !           986:   return zMbcsFilename;
        !           987: }
        !           988: 
        !           989: /*
        !           990: ** Convert Microsoft Unicode to multi-byte character string, based on the
        !           991: ** user's ANSI codepage.
        !           992: **
        !           993: ** Space to hold the returned string is obtained from
        !           994: ** sqlite3_malloc().
        !           995: */
        !           996: static char *unicodeToMbcs(LPCWSTR zWideFilename){
        !           997:   int nByte;
        !           998:   char *zFilename;
        !           999:   int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
        !          1000: 
        !          1001:   nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
        !          1002:   if( nByte == 0 ){
        !          1003:     return 0;
        !          1004:   }
        !          1005:   zFilename = sqlite3_malloc( nByte );
        !          1006:   if( zFilename==0 ){
        !          1007:     return 0;
        !          1008:   }
        !          1009:   nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
        !          1010:                                 nByte, 0, 0);
        !          1011:   if( nByte == 0 ){
        !          1012:     sqlite3_free(zFilename);
        !          1013:     zFilename = 0;
        !          1014:   }
        !          1015:   return zFilename;
        !          1016: }
        !          1017: 
        !          1018: /*
        !          1019: ** Convert multibyte character string to UTF-8.  Space to hold the
        !          1020: ** returned string is obtained from sqlite3_malloc().
        !          1021: */
        !          1022: char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
        !          1023:   char *zFilenameUtf8;
        !          1024:   LPWSTR zTmpWide;
        !          1025: 
        !          1026:   zTmpWide = mbcsToUnicode(zFilename);
        !          1027:   if( zTmpWide==0 ){
        !          1028:     return 0;
        !          1029:   }
        !          1030:   zFilenameUtf8 = unicodeToUtf8(zTmpWide);
        !          1031:   sqlite3_free(zTmpWide);
        !          1032:   return zFilenameUtf8;
        !          1033: }
        !          1034: 
        !          1035: /*
        !          1036: ** Convert UTF-8 to multibyte character string.  Space to hold the 
        !          1037: ** returned string is obtained from sqlite3_malloc().
        !          1038: */
        !          1039: char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
        !          1040:   char *zFilenameMbcs;
        !          1041:   LPWSTR zTmpWide;
        !          1042: 
        !          1043:   zTmpWide = utf8ToUnicode(zFilename);
        !          1044:   if( zTmpWide==0 ){
        !          1045:     return 0;
        !          1046:   }
        !          1047:   zFilenameMbcs = unicodeToMbcs(zTmpWide);
        !          1048:   sqlite3_free(zTmpWide);
        !          1049:   return zFilenameMbcs;
        !          1050: }
        !          1051: 
        !          1052: 
        !          1053: /*
        !          1054: ** The return value of getLastErrorMsg
        !          1055: ** is zero if the error message fits in the buffer, or non-zero
        !          1056: ** otherwise (if the message was truncated).
        !          1057: */
        !          1058: static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
        !          1059:   /* FormatMessage returns 0 on failure.  Otherwise it
        !          1060:   ** returns the number of TCHARs written to the output
        !          1061:   ** buffer, excluding the terminating null char.
        !          1062:   */
        !          1063:   DWORD dwLen = 0;
        !          1064:   char *zOut = 0;
        !          1065: 
        !          1066:   if( isNT() ){
        !          1067:     LPWSTR zTempWide = NULL;
        !          1068:     dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        !          1069:                              FORMAT_MESSAGE_FROM_SYSTEM |
        !          1070:                              FORMAT_MESSAGE_IGNORE_INSERTS,
        !          1071:                              NULL,
        !          1072:                              lastErrno,
        !          1073:                              0,
        !          1074:                              (LPWSTR) &zTempWide,
        !          1075:                              0,
        !          1076:                              0);
        !          1077:     if( dwLen > 0 ){
        !          1078:       /* allocate a buffer and convert to UTF8 */
        !          1079:       sqlite3BeginBenignMalloc();
        !          1080:       zOut = unicodeToUtf8(zTempWide);
        !          1081:       sqlite3EndBenignMalloc();
        !          1082:       /* free the system buffer allocated by FormatMessage */
        !          1083:       osLocalFree(zTempWide);
        !          1084:     }
        !          1085: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          1086: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          1087: ** it's important to not reference them for WINCE builds.
        !          1088: */
        !          1089: #if SQLITE_OS_WINCE==0
        !          1090:   }else{
        !          1091:     char *zTemp = NULL;
        !          1092:     dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        !          1093:                              FORMAT_MESSAGE_FROM_SYSTEM |
        !          1094:                              FORMAT_MESSAGE_IGNORE_INSERTS,
        !          1095:                              NULL,
        !          1096:                              lastErrno,
        !          1097:                              0,
        !          1098:                              (LPSTR) &zTemp,
        !          1099:                              0,
        !          1100:                              0);
        !          1101:     if( dwLen > 0 ){
        !          1102:       /* allocate a buffer and convert to UTF8 */
        !          1103:       sqlite3BeginBenignMalloc();
        !          1104:       zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
        !          1105:       sqlite3EndBenignMalloc();
        !          1106:       /* free the system buffer allocated by FormatMessage */
        !          1107:       osLocalFree(zTemp);
        !          1108:     }
        !          1109: #endif
        !          1110:   }
        !          1111:   if( 0 == dwLen ){
        !          1112:     sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
        !          1113:   }else{
        !          1114:     /* copy a maximum of nBuf chars to output buffer */
        !          1115:     sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
        !          1116:     /* free the UTF8 buffer */
        !          1117:     sqlite3_free(zOut);
        !          1118:   }
        !          1119:   return 0;
        !          1120: }
        !          1121: 
        !          1122: /*
        !          1123: **
        !          1124: ** This function - winLogErrorAtLine() - is only ever called via the macro
        !          1125: ** winLogError().
        !          1126: **
        !          1127: ** This routine is invoked after an error occurs in an OS function.
        !          1128: ** It logs a message using sqlite3_log() containing the current value of
        !          1129: ** error code and, if possible, the human-readable equivalent from 
        !          1130: ** FormatMessage.
        !          1131: **
        !          1132: ** The first argument passed to the macro should be the error code that
        !          1133: ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
        !          1134: ** The two subsequent arguments should be the name of the OS function that
        !          1135: ** failed and the the associated file-system path, if any.
        !          1136: */
        !          1137: #define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
        !          1138: static int winLogErrorAtLine(
        !          1139:   int errcode,                    /* SQLite error code */
        !          1140:   DWORD lastErrno,                /* Win32 last error */
        !          1141:   const char *zFunc,              /* Name of OS function that failed */
        !          1142:   const char *zPath,              /* File path associated with error */
        !          1143:   int iLine                       /* Source line number where error occurred */
        !          1144: ){
        !          1145:   char zMsg[500];                 /* Human readable error text */
        !          1146:   int i;                          /* Loop counter */
        !          1147: 
        !          1148:   zMsg[0] = 0;
        !          1149:   getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
        !          1150:   assert( errcode!=SQLITE_OK );
        !          1151:   if( zPath==0 ) zPath = "";
        !          1152:   for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
        !          1153:   zMsg[i] = 0;
        !          1154:   sqlite3_log(errcode,
        !          1155:       "os_win.c:%d: (%d) %s(%s) - %s",
        !          1156:       iLine, lastErrno, zFunc, zPath, zMsg
        !          1157:   );
        !          1158: 
        !          1159:   return errcode;
        !          1160: }
        !          1161: 
        !          1162: /*
        !          1163: ** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
        !          1164: ** will be retried following a locking error - probably caused by 
        !          1165: ** antivirus software.  Also the initial delay before the first retry.
        !          1166: ** The delay increases linearly with each retry.
        !          1167: */
        !          1168: #ifndef SQLITE_WIN32_IOERR_RETRY
        !          1169: # define SQLITE_WIN32_IOERR_RETRY 10
        !          1170: #endif
        !          1171: #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
        !          1172: # define SQLITE_WIN32_IOERR_RETRY_DELAY 25
        !          1173: #endif
        !          1174: static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
        !          1175: static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
        !          1176: 
        !          1177: /*
        !          1178: ** If a ReadFile() or WriteFile() error occurs, invoke this routine
        !          1179: ** to see if it should be retried.  Return TRUE to retry.  Return FALSE
        !          1180: ** to give up with an error.
        !          1181: */
        !          1182: static int retryIoerr(int *pnRetry, DWORD *pError){
        !          1183:   DWORD e = osGetLastError();
        !          1184:   if( *pnRetry>=win32IoerrRetry ){
        !          1185:     if( pError ){
        !          1186:       *pError = e;
        !          1187:     }
        !          1188:     return 0;
        !          1189:   }
        !          1190:   if( e==ERROR_ACCESS_DENIED ||
        !          1191:       e==ERROR_LOCK_VIOLATION ||
        !          1192:       e==ERROR_SHARING_VIOLATION ){
        !          1193:     osSleep(win32IoerrRetryDelay*(1+*pnRetry));
        !          1194:     ++*pnRetry;
        !          1195:     return 1;
        !          1196:   }
        !          1197:   if( pError ){
        !          1198:     *pError = e;
        !          1199:   }
        !          1200:   return 0;
        !          1201: }
        !          1202: 
        !          1203: /*
        !          1204: ** Log a I/O error retry episode.
        !          1205: */
        !          1206: static void logIoerr(int nRetry){
        !          1207:   if( nRetry ){
        !          1208:     sqlite3_log(SQLITE_IOERR, 
        !          1209:       "delayed %dms for lock/sharing conflict",
        !          1210:       win32IoerrRetryDelay*nRetry*(nRetry+1)/2
        !          1211:     );
        !          1212:   }
        !          1213: }
        !          1214: 
        !          1215: #if SQLITE_OS_WINCE
        !          1216: /*************************************************************************
        !          1217: ** This section contains code for WinCE only.
        !          1218: */
        !          1219: /*
        !          1220: ** Windows CE does not have a localtime() function.  So create a
        !          1221: ** substitute.
        !          1222: */
        !          1223: #include <time.h>
        !          1224: struct tm *__cdecl localtime(const time_t *t)
        !          1225: {
        !          1226:   static struct tm y;
        !          1227:   FILETIME uTm, lTm;
        !          1228:   SYSTEMTIME pTm;
        !          1229:   sqlite3_int64 t64;
        !          1230:   t64 = *t;
        !          1231:   t64 = (t64 + 11644473600)*10000000;
        !          1232:   uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
        !          1233:   uTm.dwHighDateTime= (DWORD)(t64 >> 32);
        !          1234:   osFileTimeToLocalFileTime(&uTm,&lTm);
        !          1235:   osFileTimeToSystemTime(&lTm,&pTm);
        !          1236:   y.tm_year = pTm.wYear - 1900;
        !          1237:   y.tm_mon = pTm.wMonth - 1;
        !          1238:   y.tm_wday = pTm.wDayOfWeek;
        !          1239:   y.tm_mday = pTm.wDay;
        !          1240:   y.tm_hour = pTm.wHour;
        !          1241:   y.tm_min = pTm.wMinute;
        !          1242:   y.tm_sec = pTm.wSecond;
        !          1243:   return &y;
        !          1244: }
        !          1245: 
        !          1246: #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
        !          1247: 
        !          1248: /*
        !          1249: ** Acquire a lock on the handle h
        !          1250: */
        !          1251: static void winceMutexAcquire(HANDLE h){
        !          1252:    DWORD dwErr;
        !          1253:    do {
        !          1254:      dwErr = WaitForSingleObject(h, INFINITE);
        !          1255:    } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
        !          1256: }
        !          1257: /*
        !          1258: ** Release a lock acquired by winceMutexAcquire()
        !          1259: */
        !          1260: #define winceMutexRelease(h) ReleaseMutex(h)
        !          1261: 
        !          1262: /*
        !          1263: ** Create the mutex and shared memory used for locking in the file
        !          1264: ** descriptor pFile
        !          1265: */
        !          1266: static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
        !          1267:   LPWSTR zTok;
        !          1268:   LPWSTR zName;
        !          1269:   BOOL bInit = TRUE;
        !          1270: 
        !          1271:   zName = utf8ToUnicode(zFilename);
        !          1272:   if( zName==0 ){
        !          1273:     /* out of memory */
        !          1274:     return FALSE;
        !          1275:   }
        !          1276: 
        !          1277:   /* Initialize the local lockdata */
        !          1278:   memset(&pFile->local, 0, sizeof(pFile->local));
        !          1279: 
        !          1280:   /* Replace the backslashes from the filename and lowercase it
        !          1281:   ** to derive a mutex name. */
        !          1282:   zTok = osCharLowerW(zName);
        !          1283:   for (;*zTok;zTok++){
        !          1284:     if (*zTok == '\\') *zTok = '_';
        !          1285:   }
        !          1286: 
        !          1287:   /* Create/open the named mutex */
        !          1288:   pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
        !          1289:   if (!pFile->hMutex){
        !          1290:     pFile->lastErrno = osGetLastError();
        !          1291:     winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
        !          1292:     sqlite3_free(zName);
        !          1293:     return FALSE;
        !          1294:   }
        !          1295: 
        !          1296:   /* Acquire the mutex before continuing */
        !          1297:   winceMutexAcquire(pFile->hMutex);
        !          1298:   
        !          1299:   /* Since the names of named mutexes, semaphores, file mappings etc are 
        !          1300:   ** case-sensitive, take advantage of that by uppercasing the mutex name
        !          1301:   ** and using that as the shared filemapping name.
        !          1302:   */
        !          1303:   osCharUpperW(zName);
        !          1304:   pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
        !          1305:                                         PAGE_READWRITE, 0, sizeof(winceLock),
        !          1306:                                         zName);  
        !          1307: 
        !          1308:   /* Set a flag that indicates we're the first to create the memory so it 
        !          1309:   ** must be zero-initialized */
        !          1310:   if (osGetLastError() == ERROR_ALREADY_EXISTS){
        !          1311:     bInit = FALSE;
        !          1312:   }
        !          1313: 
        !          1314:   sqlite3_free(zName);
        !          1315: 
        !          1316:   /* If we succeeded in making the shared memory handle, map it. */
        !          1317:   if (pFile->hShared){
        !          1318:     pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, 
        !          1319:              FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
        !          1320:     /* If mapping failed, close the shared memory handle and erase it */
        !          1321:     if (!pFile->shared){
        !          1322:       pFile->lastErrno = osGetLastError();
        !          1323:       winLogError(SQLITE_ERROR, pFile->lastErrno,
        !          1324:                "winceCreateLock2", zFilename);
        !          1325:       osCloseHandle(pFile->hShared);
        !          1326:       pFile->hShared = NULL;
        !          1327:     }
        !          1328:   }
        !          1329: 
        !          1330:   /* If shared memory could not be created, then close the mutex and fail */
        !          1331:   if (pFile->hShared == NULL){
        !          1332:     winceMutexRelease(pFile->hMutex);
        !          1333:     osCloseHandle(pFile->hMutex);
        !          1334:     pFile->hMutex = NULL;
        !          1335:     return FALSE;
        !          1336:   }
        !          1337:   
        !          1338:   /* Initialize the shared memory if we're supposed to */
        !          1339:   if (bInit) {
        !          1340:     memset(pFile->shared, 0, sizeof(winceLock));
        !          1341:   }
        !          1342: 
        !          1343:   winceMutexRelease(pFile->hMutex);
        !          1344:   return TRUE;
        !          1345: }
        !          1346: 
        !          1347: /*
        !          1348: ** Destroy the part of winFile that deals with wince locks
        !          1349: */
        !          1350: static void winceDestroyLock(winFile *pFile){
        !          1351:   if (pFile->hMutex){
        !          1352:     /* Acquire the mutex */
        !          1353:     winceMutexAcquire(pFile->hMutex);
        !          1354: 
        !          1355:     /* The following blocks should probably assert in debug mode, but they
        !          1356:        are to cleanup in case any locks remained open */
        !          1357:     if (pFile->local.nReaders){
        !          1358:       pFile->shared->nReaders --;
        !          1359:     }
        !          1360:     if (pFile->local.bReserved){
        !          1361:       pFile->shared->bReserved = FALSE;
        !          1362:     }
        !          1363:     if (pFile->local.bPending){
        !          1364:       pFile->shared->bPending = FALSE;
        !          1365:     }
        !          1366:     if (pFile->local.bExclusive){
        !          1367:       pFile->shared->bExclusive = FALSE;
        !          1368:     }
        !          1369: 
        !          1370:     /* De-reference and close our copy of the shared memory handle */
        !          1371:     osUnmapViewOfFile(pFile->shared);
        !          1372:     osCloseHandle(pFile->hShared);
        !          1373: 
        !          1374:     /* Done with the mutex */
        !          1375:     winceMutexRelease(pFile->hMutex);    
        !          1376:     osCloseHandle(pFile->hMutex);
        !          1377:     pFile->hMutex = NULL;
        !          1378:   }
        !          1379: }
        !          1380: 
        !          1381: /* 
        !          1382: ** An implementation of the LockFile() API of Windows for CE
        !          1383: */
        !          1384: static BOOL winceLockFile(
        !          1385:   HANDLE *phFile,
        !          1386:   DWORD dwFileOffsetLow,
        !          1387:   DWORD dwFileOffsetHigh,
        !          1388:   DWORD nNumberOfBytesToLockLow,
        !          1389:   DWORD nNumberOfBytesToLockHigh
        !          1390: ){
        !          1391:   winFile *pFile = HANDLE_TO_WINFILE(phFile);
        !          1392:   BOOL bReturn = FALSE;
        !          1393: 
        !          1394:   UNUSED_PARAMETER(dwFileOffsetHigh);
        !          1395:   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
        !          1396: 
        !          1397:   if (!pFile->hMutex) return TRUE;
        !          1398:   winceMutexAcquire(pFile->hMutex);
        !          1399: 
        !          1400:   /* Wanting an exclusive lock? */
        !          1401:   if (dwFileOffsetLow == (DWORD)SHARED_FIRST
        !          1402:        && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
        !          1403:     if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
        !          1404:        pFile->shared->bExclusive = TRUE;
        !          1405:        pFile->local.bExclusive = TRUE;
        !          1406:        bReturn = TRUE;
        !          1407:     }
        !          1408:   }
        !          1409: 
        !          1410:   /* Want a read-only lock? */
        !          1411:   else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
        !          1412:            nNumberOfBytesToLockLow == 1){
        !          1413:     if (pFile->shared->bExclusive == 0){
        !          1414:       pFile->local.nReaders ++;
        !          1415:       if (pFile->local.nReaders == 1){
        !          1416:         pFile->shared->nReaders ++;
        !          1417:       }
        !          1418:       bReturn = TRUE;
        !          1419:     }
        !          1420:   }
        !          1421: 
        !          1422:   /* Want a pending lock? */
        !          1423:   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
        !          1424:     /* If no pending lock has been acquired, then acquire it */
        !          1425:     if (pFile->shared->bPending == 0) {
        !          1426:       pFile->shared->bPending = TRUE;
        !          1427:       pFile->local.bPending = TRUE;
        !          1428:       bReturn = TRUE;
        !          1429:     }
        !          1430:   }
        !          1431: 
        !          1432:   /* Want a reserved lock? */
        !          1433:   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
        !          1434:     if (pFile->shared->bReserved == 0) {
        !          1435:       pFile->shared->bReserved = TRUE;
        !          1436:       pFile->local.bReserved = TRUE;
        !          1437:       bReturn = TRUE;
        !          1438:     }
        !          1439:   }
        !          1440: 
        !          1441:   winceMutexRelease(pFile->hMutex);
        !          1442:   return bReturn;
        !          1443: }
        !          1444: 
        !          1445: /*
        !          1446: ** An implementation of the UnlockFile API of Windows for CE
        !          1447: */
        !          1448: static BOOL winceUnlockFile(
        !          1449:   HANDLE *phFile,
        !          1450:   DWORD dwFileOffsetLow,
        !          1451:   DWORD dwFileOffsetHigh,
        !          1452:   DWORD nNumberOfBytesToUnlockLow,
        !          1453:   DWORD nNumberOfBytesToUnlockHigh
        !          1454: ){
        !          1455:   winFile *pFile = HANDLE_TO_WINFILE(phFile);
        !          1456:   BOOL bReturn = FALSE;
        !          1457: 
        !          1458:   UNUSED_PARAMETER(dwFileOffsetHigh);
        !          1459:   UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
        !          1460: 
        !          1461:   if (!pFile->hMutex) return TRUE;
        !          1462:   winceMutexAcquire(pFile->hMutex);
        !          1463: 
        !          1464:   /* Releasing a reader lock or an exclusive lock */
        !          1465:   if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
        !          1466:     /* Did we have an exclusive lock? */
        !          1467:     if (pFile->local.bExclusive){
        !          1468:       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
        !          1469:       pFile->local.bExclusive = FALSE;
        !          1470:       pFile->shared->bExclusive = FALSE;
        !          1471:       bReturn = TRUE;
        !          1472:     }
        !          1473: 
        !          1474:     /* Did we just have a reader lock? */
        !          1475:     else if (pFile->local.nReaders){
        !          1476:       assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
        !          1477:       pFile->local.nReaders --;
        !          1478:       if (pFile->local.nReaders == 0)
        !          1479:       {
        !          1480:         pFile->shared->nReaders --;
        !          1481:       }
        !          1482:       bReturn = TRUE;
        !          1483:     }
        !          1484:   }
        !          1485: 
        !          1486:   /* Releasing a pending lock */
        !          1487:   else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
        !          1488:     if (pFile->local.bPending){
        !          1489:       pFile->local.bPending = FALSE;
        !          1490:       pFile->shared->bPending = FALSE;
        !          1491:       bReturn = TRUE;
        !          1492:     }
        !          1493:   }
        !          1494:   /* Releasing a reserved lock */
        !          1495:   else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
        !          1496:     if (pFile->local.bReserved) {
        !          1497:       pFile->local.bReserved = FALSE;
        !          1498:       pFile->shared->bReserved = FALSE;
        !          1499:       bReturn = TRUE;
        !          1500:     }
        !          1501:   }
        !          1502: 
        !          1503:   winceMutexRelease(pFile->hMutex);
        !          1504:   return bReturn;
        !          1505: }
        !          1506: 
        !          1507: /*
        !          1508: ** An implementation of the LockFileEx() API of Windows for CE
        !          1509: */
        !          1510: static BOOL winceLockFileEx(
        !          1511:   HANDLE *phFile,
        !          1512:   DWORD dwFlags,
        !          1513:   DWORD dwReserved,
        !          1514:   DWORD nNumberOfBytesToLockLow,
        !          1515:   DWORD nNumberOfBytesToLockHigh,
        !          1516:   LPOVERLAPPED lpOverlapped
        !          1517: ){
        !          1518:   UNUSED_PARAMETER(dwReserved);
        !          1519:   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
        !          1520: 
        !          1521:   /* If the caller wants a shared read lock, forward this call
        !          1522:   ** to winceLockFile */
        !          1523:   if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
        !          1524:       dwFlags == 1 &&
        !          1525:       nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
        !          1526:     return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
        !          1527:   }
        !          1528:   return FALSE;
        !          1529: }
        !          1530: /*
        !          1531: ** End of the special code for wince
        !          1532: *****************************************************************************/
        !          1533: #endif /* SQLITE_OS_WINCE */
        !          1534: 
        !          1535: /*****************************************************************************
        !          1536: ** The next group of routines implement the I/O methods specified
        !          1537: ** by the sqlite3_io_methods object.
        !          1538: ******************************************************************************/
        !          1539: 
        !          1540: /*
        !          1541: ** Some Microsoft compilers lack this definition.
        !          1542: */
        !          1543: #ifndef INVALID_SET_FILE_POINTER
        !          1544: # define INVALID_SET_FILE_POINTER ((DWORD)-1)
        !          1545: #endif
        !          1546: 
        !          1547: /*
        !          1548: ** Move the current position of the file handle passed as the first 
        !          1549: ** argument to offset iOffset within the file. If successful, return 0. 
        !          1550: ** Otherwise, set pFile->lastErrno and return non-zero.
        !          1551: */
        !          1552: static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
        !          1553:   LONG upperBits;                 /* Most sig. 32 bits of new offset */
        !          1554:   LONG lowerBits;                 /* Least sig. 32 bits of new offset */
        !          1555:   DWORD dwRet;                    /* Value returned by SetFilePointer() */
        !          1556:   DWORD lastErrno;                /* Value returned by GetLastError() */
        !          1557: 
        !          1558:   upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
        !          1559:   lowerBits = (LONG)(iOffset & 0xffffffff);
        !          1560: 
        !          1561:   /* API oddity: If successful, SetFilePointer() returns a dword 
        !          1562:   ** containing the lower 32-bits of the new file-offset. Or, if it fails,
        !          1563:   ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, 
        !          1564:   ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
        !          1565:   ** whether an error has actually occured, it is also necessary to call 
        !          1566:   ** GetLastError().
        !          1567:   */
        !          1568:   dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
        !          1569: 
        !          1570:   if( (dwRet==INVALID_SET_FILE_POINTER
        !          1571:       && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
        !          1572:     pFile->lastErrno = lastErrno;
        !          1573:     winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
        !          1574:              "seekWinFile", pFile->zPath);
        !          1575:     return 1;
        !          1576:   }
        !          1577: 
        !          1578:   return 0;
        !          1579: }
        !          1580: 
        !          1581: /*
        !          1582: ** Close a file.
        !          1583: **
        !          1584: ** It is reported that an attempt to close a handle might sometimes
        !          1585: ** fail.  This is a very unreasonable result, but Windows is notorious
        !          1586: ** for being unreasonable so I do not doubt that it might happen.  If
        !          1587: ** the close fails, we pause for 100 milliseconds and try again.  As
        !          1588: ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
        !          1589: ** giving up and returning an error.
        !          1590: */
        !          1591: #define MX_CLOSE_ATTEMPT 3
        !          1592: static int winClose(sqlite3_file *id){
        !          1593:   int rc, cnt = 0;
        !          1594:   winFile *pFile = (winFile*)id;
        !          1595: 
        !          1596:   assert( id!=0 );
        !          1597:   assert( pFile->pShm==0 );
        !          1598:   OSTRACE(("CLOSE %d\n", pFile->h));
        !          1599:   do{
        !          1600:     rc = osCloseHandle(pFile->h);
        !          1601:     /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
        !          1602:   }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) );
        !          1603: #if SQLITE_OS_WINCE
        !          1604: #define WINCE_DELETION_ATTEMPTS 3
        !          1605:   winceDestroyLock(pFile);
        !          1606:   if( pFile->zDeleteOnClose ){
        !          1607:     int cnt = 0;
        !          1608:     while(
        !          1609:            osDeleteFileW(pFile->zDeleteOnClose)==0
        !          1610:         && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 
        !          1611:         && cnt++ < WINCE_DELETION_ATTEMPTS
        !          1612:     ){
        !          1613:        osSleep(100);  /* Wait a little before trying again */
        !          1614:     }
        !          1615:     sqlite3_free(pFile->zDeleteOnClose);
        !          1616:   }
        !          1617: #endif
        !          1618:   OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
        !          1619:   OpenCounter(-1);
        !          1620:   return rc ? SQLITE_OK
        !          1621:             : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
        !          1622:                           "winClose", pFile->zPath);
        !          1623: }
        !          1624: 
        !          1625: /*
        !          1626: ** Read data from a file into a buffer.  Return SQLITE_OK if all
        !          1627: ** bytes were read successfully and SQLITE_IOERR if anything goes
        !          1628: ** wrong.
        !          1629: */
        !          1630: static int winRead(
        !          1631:   sqlite3_file *id,          /* File to read from */
        !          1632:   void *pBuf,                /* Write content into this buffer */
        !          1633:   int amt,                   /* Number of bytes to read */
        !          1634:   sqlite3_int64 offset       /* Begin reading at this offset */
        !          1635: ){
        !          1636:   winFile *pFile = (winFile*)id;  /* file handle */
        !          1637:   DWORD nRead;                    /* Number of bytes actually read from file */
        !          1638:   int nRetry = 0;                 /* Number of retrys */
        !          1639: 
        !          1640:   assert( id!=0 );
        !          1641:   SimulateIOError(return SQLITE_IOERR_READ);
        !          1642:   OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
        !          1643: 
        !          1644:   if( seekWinFile(pFile, offset) ){
        !          1645:     return SQLITE_FULL;
        !          1646:   }
        !          1647:   while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
        !          1648:     DWORD lastErrno;
        !          1649:     if( retryIoerr(&nRetry, &lastErrno) ) continue;
        !          1650:     pFile->lastErrno = lastErrno;
        !          1651:     return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
        !          1652:              "winRead", pFile->zPath);
        !          1653:   }
        !          1654:   logIoerr(nRetry);
        !          1655:   if( nRead<(DWORD)amt ){
        !          1656:     /* Unread parts of the buffer must be zero-filled */
        !          1657:     memset(&((char*)pBuf)[nRead], 0, amt-nRead);
        !          1658:     return SQLITE_IOERR_SHORT_READ;
        !          1659:   }
        !          1660: 
        !          1661:   return SQLITE_OK;
        !          1662: }
        !          1663: 
        !          1664: /*
        !          1665: ** Write data from a buffer into a file.  Return SQLITE_OK on success
        !          1666: ** or some other error code on failure.
        !          1667: */
        !          1668: static int winWrite(
        !          1669:   sqlite3_file *id,               /* File to write into */
        !          1670:   const void *pBuf,               /* The bytes to be written */
        !          1671:   int amt,                        /* Number of bytes to write */
        !          1672:   sqlite3_int64 offset            /* Offset into the file to begin writing at */
        !          1673: ){
        !          1674:   int rc;                         /* True if error has occured, else false */
        !          1675:   winFile *pFile = (winFile*)id;  /* File handle */
        !          1676:   int nRetry = 0;                 /* Number of retries */
        !          1677: 
        !          1678:   assert( amt>0 );
        !          1679:   assert( pFile );
        !          1680:   SimulateIOError(return SQLITE_IOERR_WRITE);
        !          1681:   SimulateDiskfullError(return SQLITE_FULL);
        !          1682: 
        !          1683:   OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
        !          1684: 
        !          1685:   rc = seekWinFile(pFile, offset);
        !          1686:   if( rc==0 ){
        !          1687:     u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
        !          1688:     int nRem = amt;               /* Number of bytes yet to be written */
        !          1689:     DWORD nWrite;                 /* Bytes written by each WriteFile() call */
        !          1690:     DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
        !          1691: 
        !          1692:     while( nRem>0 ){
        !          1693:       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
        !          1694:         if( retryIoerr(&nRetry, &lastErrno) ) continue;
        !          1695:         break;
        !          1696:       }
        !          1697:       if( nWrite<=0 ) break;
        !          1698:       aRem += nWrite;
        !          1699:       nRem -= nWrite;
        !          1700:     }
        !          1701:     if( nRem>0 ){
        !          1702:       pFile->lastErrno = lastErrno;
        !          1703:       rc = 1;
        !          1704:     }
        !          1705:   }
        !          1706: 
        !          1707:   if( rc ){
        !          1708:     if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
        !          1709:        || ( pFile->lastErrno==ERROR_DISK_FULL )){
        !          1710:       return SQLITE_FULL;
        !          1711:     }
        !          1712:     return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
        !          1713:              "winWrite", pFile->zPath);
        !          1714:   }else{
        !          1715:     logIoerr(nRetry);
        !          1716:   }
        !          1717:   return SQLITE_OK;
        !          1718: }
        !          1719: 
        !          1720: /*
        !          1721: ** Truncate an open file to a specified size
        !          1722: */
        !          1723: static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
        !          1724:   winFile *pFile = (winFile*)id;  /* File handle object */
        !          1725:   int rc = SQLITE_OK;             /* Return code for this function */
        !          1726: 
        !          1727:   assert( pFile );
        !          1728: 
        !          1729:   OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
        !          1730:   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
        !          1731: 
        !          1732:   /* If the user has configured a chunk-size for this file, truncate the
        !          1733:   ** file so that it consists of an integer number of chunks (i.e. the
        !          1734:   ** actual file size after the operation may be larger than the requested
        !          1735:   ** size).
        !          1736:   */
        !          1737:   if( pFile->szChunk>0 ){
        !          1738:     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
        !          1739:   }
        !          1740: 
        !          1741:   /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
        !          1742:   if( seekWinFile(pFile, nByte) ){
        !          1743:     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
        !          1744:              "winTruncate1", pFile->zPath);
        !          1745:   }else if( 0==osSetEndOfFile(pFile->h) ){
        !          1746:     pFile->lastErrno = osGetLastError();
        !          1747:     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
        !          1748:              "winTruncate2", pFile->zPath);
        !          1749:   }
        !          1750: 
        !          1751:   OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
        !          1752:   return rc;
        !          1753: }
        !          1754: 
        !          1755: #ifdef SQLITE_TEST
        !          1756: /*
        !          1757: ** Count the number of fullsyncs and normal syncs.  This is used to test
        !          1758: ** that syncs and fullsyncs are occuring at the right times.
        !          1759: */
        !          1760: int sqlite3_sync_count = 0;
        !          1761: int sqlite3_fullsync_count = 0;
        !          1762: #endif
        !          1763: 
        !          1764: /*
        !          1765: ** Make sure all writes to a particular file are committed to disk.
        !          1766: */
        !          1767: static int winSync(sqlite3_file *id, int flags){
        !          1768: #ifndef SQLITE_NO_SYNC
        !          1769:   /*
        !          1770:   ** Used only when SQLITE_NO_SYNC is not defined.
        !          1771:    */
        !          1772:   BOOL rc;
        !          1773: #endif
        !          1774: #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
        !          1775:     (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
        !          1776:   /*
        !          1777:   ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
        !          1778:   ** OSTRACE() macros.
        !          1779:    */
        !          1780:   winFile *pFile = (winFile*)id;
        !          1781: #else
        !          1782:   UNUSED_PARAMETER(id);
        !          1783: #endif
        !          1784: 
        !          1785:   assert( pFile );
        !          1786:   /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
        !          1787:   assert((flags&0x0F)==SQLITE_SYNC_NORMAL
        !          1788:       || (flags&0x0F)==SQLITE_SYNC_FULL
        !          1789:   );
        !          1790: 
        !          1791:   OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
        !          1792: 
        !          1793:   /* Unix cannot, but some systems may return SQLITE_FULL from here. This
        !          1794:   ** line is to test that doing so does not cause any problems.
        !          1795:   */
        !          1796:   SimulateDiskfullError( return SQLITE_FULL );
        !          1797: 
        !          1798: #ifndef SQLITE_TEST
        !          1799:   UNUSED_PARAMETER(flags);
        !          1800: #else
        !          1801:   if( (flags&0x0F)==SQLITE_SYNC_FULL ){
        !          1802:     sqlite3_fullsync_count++;
        !          1803:   }
        !          1804:   sqlite3_sync_count++;
        !          1805: #endif
        !          1806: 
        !          1807:   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
        !          1808:   ** no-op
        !          1809:   */
        !          1810: #ifdef SQLITE_NO_SYNC
        !          1811:   return SQLITE_OK;
        !          1812: #else
        !          1813:   rc = osFlushFileBuffers(pFile->h);
        !          1814:   SimulateIOError( rc=FALSE );
        !          1815:   if( rc ){
        !          1816:     return SQLITE_OK;
        !          1817:   }else{
        !          1818:     pFile->lastErrno = osGetLastError();
        !          1819:     return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
        !          1820:              "winSync", pFile->zPath);
        !          1821:   }
        !          1822: #endif
        !          1823: }
        !          1824: 
        !          1825: /*
        !          1826: ** Determine the current size of a file in bytes
        !          1827: */
        !          1828: static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
        !          1829:   DWORD upperBits;
        !          1830:   DWORD lowerBits;
        !          1831:   winFile *pFile = (winFile*)id;
        !          1832:   DWORD lastErrno;
        !          1833: 
        !          1834:   assert( id!=0 );
        !          1835:   SimulateIOError(return SQLITE_IOERR_FSTAT);
        !          1836:   lowerBits = osGetFileSize(pFile->h, &upperBits);
        !          1837:   if(   (lowerBits == INVALID_FILE_SIZE)
        !          1838:      && ((lastErrno = osGetLastError())!=NO_ERROR) )
        !          1839:   {
        !          1840:     pFile->lastErrno = lastErrno;
        !          1841:     return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
        !          1842:              "winFileSize", pFile->zPath);
        !          1843:   }
        !          1844:   *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
        !          1845:   return SQLITE_OK;
        !          1846: }
        !          1847: 
        !          1848: /*
        !          1849: ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
        !          1850: */
        !          1851: #ifndef LOCKFILE_FAIL_IMMEDIATELY
        !          1852: # define LOCKFILE_FAIL_IMMEDIATELY 1
        !          1853: #endif
        !          1854: 
        !          1855: /*
        !          1856: ** Acquire a reader lock.
        !          1857: ** Different API routines are called depending on whether or not this
        !          1858: ** is Win9x or WinNT.
        !          1859: */
        !          1860: static int getReadLock(winFile *pFile){
        !          1861:   int res;
        !          1862:   if( isNT() ){
        !          1863:     OVERLAPPED ovlp;
        !          1864:     ovlp.Offset = SHARED_FIRST;
        !          1865:     ovlp.OffsetHigh = 0;
        !          1866:     ovlp.hEvent = 0;
        !          1867:     res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
        !          1868:                        0, SHARED_SIZE, 0, &ovlp);
        !          1869: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          1870: */
        !          1871: #if SQLITE_OS_WINCE==0
        !          1872:   }else{
        !          1873:     int lk;
        !          1874:     sqlite3_randomness(sizeof(lk), &lk);
        !          1875:     pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
        !          1876:     res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
        !          1877: #endif
        !          1878:   }
        !          1879:   if( res == 0 ){
        !          1880:     pFile->lastErrno = osGetLastError();
        !          1881:     /* No need to log a failure to lock */
        !          1882:   }
        !          1883:   return res;
        !          1884: }
        !          1885: 
        !          1886: /*
        !          1887: ** Undo a readlock
        !          1888: */
        !          1889: static int unlockReadLock(winFile *pFile){
        !          1890:   int res;
        !          1891:   DWORD lastErrno;
        !          1892:   if( isNT() ){
        !          1893:     res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
        !          1894: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          1895: */
        !          1896: #if SQLITE_OS_WINCE==0
        !          1897:   }else{
        !          1898:     res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
        !          1899: #endif
        !          1900:   }
        !          1901:   if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
        !          1902:     pFile->lastErrno = lastErrno;
        !          1903:     winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
        !          1904:              "unlockReadLock", pFile->zPath);
        !          1905:   }
        !          1906:   return res;
        !          1907: }
        !          1908: 
        !          1909: /*
        !          1910: ** Lock the file with the lock specified by parameter locktype - one
        !          1911: ** of the following:
        !          1912: **
        !          1913: **     (1) SHARED_LOCK
        !          1914: **     (2) RESERVED_LOCK
        !          1915: **     (3) PENDING_LOCK
        !          1916: **     (4) EXCLUSIVE_LOCK
        !          1917: **
        !          1918: ** Sometimes when requesting one lock state, additional lock states
        !          1919: ** are inserted in between.  The locking might fail on one of the later
        !          1920: ** transitions leaving the lock state different from what it started but
        !          1921: ** still short of its goal.  The following chart shows the allowed
        !          1922: ** transitions and the inserted intermediate states:
        !          1923: **
        !          1924: **    UNLOCKED -> SHARED
        !          1925: **    SHARED -> RESERVED
        !          1926: **    SHARED -> (PENDING) -> EXCLUSIVE
        !          1927: **    RESERVED -> (PENDING) -> EXCLUSIVE
        !          1928: **    PENDING -> EXCLUSIVE
        !          1929: **
        !          1930: ** This routine will only increase a lock.  The winUnlock() routine
        !          1931: ** erases all locks at once and returns us immediately to locking level 0.
        !          1932: ** It is not possible to lower the locking level one step at a time.  You
        !          1933: ** must go straight to locking level 0.
        !          1934: */
        !          1935: static int winLock(sqlite3_file *id, int locktype){
        !          1936:   int rc = SQLITE_OK;    /* Return code from subroutines */
        !          1937:   int res = 1;           /* Result of a Windows lock call */
        !          1938:   int newLocktype;       /* Set pFile->locktype to this value before exiting */
        !          1939:   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
        !          1940:   winFile *pFile = (winFile*)id;
        !          1941:   DWORD lastErrno = NO_ERROR;
        !          1942: 
        !          1943:   assert( id!=0 );
        !          1944:   OSTRACE(("LOCK %d %d was %d(%d)\n",
        !          1945:            pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
        !          1946: 
        !          1947:   /* If there is already a lock of this type or more restrictive on the
        !          1948:   ** OsFile, do nothing. Don't use the end_lock: exit path, as
        !          1949:   ** sqlite3OsEnterMutex() hasn't been called yet.
        !          1950:   */
        !          1951:   if( pFile->locktype>=locktype ){
        !          1952:     return SQLITE_OK;
        !          1953:   }
        !          1954: 
        !          1955:   /* Make sure the locking sequence is correct
        !          1956:   */
        !          1957:   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
        !          1958:   assert( locktype!=PENDING_LOCK );
        !          1959:   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
        !          1960: 
        !          1961:   /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
        !          1962:   ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
        !          1963:   ** the PENDING_LOCK byte is temporary.
        !          1964:   */
        !          1965:   newLocktype = pFile->locktype;
        !          1966:   if(   (pFile->locktype==NO_LOCK)
        !          1967:      || (   (locktype==EXCLUSIVE_LOCK)
        !          1968:          && (pFile->locktype==RESERVED_LOCK))
        !          1969:   ){
        !          1970:     int cnt = 3;
        !          1971:     while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
        !          1972:       /* Try 3 times to get the pending lock.  This is needed to work
        !          1973:       ** around problems caused by indexing and/or anti-virus software on
        !          1974:       ** Windows systems.
        !          1975:       ** If you are using this code as a model for alternative VFSes, do not
        !          1976:       ** copy this retry logic.  It is a hack intended for Windows only.
        !          1977:       */
        !          1978:       OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
        !          1979:       if( cnt ) osSleep(1);
        !          1980:     }
        !          1981:     gotPendingLock = res;
        !          1982:     if( !res ){
        !          1983:       lastErrno = osGetLastError();
        !          1984:     }
        !          1985:   }
        !          1986: 
        !          1987:   /* Acquire a shared lock
        !          1988:   */
        !          1989:   if( locktype==SHARED_LOCK && res ){
        !          1990:     assert( pFile->locktype==NO_LOCK );
        !          1991:     res = getReadLock(pFile);
        !          1992:     if( res ){
        !          1993:       newLocktype = SHARED_LOCK;
        !          1994:     }else{
        !          1995:       lastErrno = osGetLastError();
        !          1996:     }
        !          1997:   }
        !          1998: 
        !          1999:   /* Acquire a RESERVED lock
        !          2000:   */
        !          2001:   if( locktype==RESERVED_LOCK && res ){
        !          2002:     assert( pFile->locktype==SHARED_LOCK );
        !          2003:     res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
        !          2004:     if( res ){
        !          2005:       newLocktype = RESERVED_LOCK;
        !          2006:     }else{
        !          2007:       lastErrno = osGetLastError();
        !          2008:     }
        !          2009:   }
        !          2010: 
        !          2011:   /* Acquire a PENDING lock
        !          2012:   */
        !          2013:   if( locktype==EXCLUSIVE_LOCK && res ){
        !          2014:     newLocktype = PENDING_LOCK;
        !          2015:     gotPendingLock = 0;
        !          2016:   }
        !          2017: 
        !          2018:   /* Acquire an EXCLUSIVE lock
        !          2019:   */
        !          2020:   if( locktype==EXCLUSIVE_LOCK && res ){
        !          2021:     assert( pFile->locktype>=SHARED_LOCK );
        !          2022:     res = unlockReadLock(pFile);
        !          2023:     OSTRACE(("unreadlock = %d\n", res));
        !          2024:     res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
        !          2025:     if( res ){
        !          2026:       newLocktype = EXCLUSIVE_LOCK;
        !          2027:     }else{
        !          2028:       lastErrno = osGetLastError();
        !          2029:       OSTRACE(("error-code = %d\n", lastErrno));
        !          2030:       getReadLock(pFile);
        !          2031:     }
        !          2032:   }
        !          2033: 
        !          2034:   /* If we are holding a PENDING lock that ought to be released, then
        !          2035:   ** release it now.
        !          2036:   */
        !          2037:   if( gotPendingLock && locktype==SHARED_LOCK ){
        !          2038:     osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
        !          2039:   }
        !          2040: 
        !          2041:   /* Update the state of the lock has held in the file descriptor then
        !          2042:   ** return the appropriate result code.
        !          2043:   */
        !          2044:   if( res ){
        !          2045:     rc = SQLITE_OK;
        !          2046:   }else{
        !          2047:     OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
        !          2048:            locktype, newLocktype));
        !          2049:     pFile->lastErrno = lastErrno;
        !          2050:     rc = SQLITE_BUSY;
        !          2051:   }
        !          2052:   pFile->locktype = (u8)newLocktype;
        !          2053:   return rc;
        !          2054: }
        !          2055: 
        !          2056: /*
        !          2057: ** This routine checks if there is a RESERVED lock held on the specified
        !          2058: ** file by this or any other process. If such a lock is held, return
        !          2059: ** non-zero, otherwise zero.
        !          2060: */
        !          2061: static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
        !          2062:   int rc;
        !          2063:   winFile *pFile = (winFile*)id;
        !          2064: 
        !          2065:   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
        !          2066: 
        !          2067:   assert( id!=0 );
        !          2068:   if( pFile->locktype>=RESERVED_LOCK ){
        !          2069:     rc = 1;
        !          2070:     OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
        !          2071:   }else{
        !          2072:     rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
        !          2073:     if( rc ){
        !          2074:       osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
        !          2075:     }
        !          2076:     rc = !rc;
        !          2077:     OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
        !          2078:   }
        !          2079:   *pResOut = rc;
        !          2080:   return SQLITE_OK;
        !          2081: }
        !          2082: 
        !          2083: /*
        !          2084: ** Lower the locking level on file descriptor id to locktype.  locktype
        !          2085: ** must be either NO_LOCK or SHARED_LOCK.
        !          2086: **
        !          2087: ** If the locking level of the file descriptor is already at or below
        !          2088: ** the requested locking level, this routine is a no-op.
        !          2089: **
        !          2090: ** It is not possible for this routine to fail if the second argument
        !          2091: ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
        !          2092: ** might return SQLITE_IOERR;
        !          2093: */
        !          2094: static int winUnlock(sqlite3_file *id, int locktype){
        !          2095:   int type;
        !          2096:   winFile *pFile = (winFile*)id;
        !          2097:   int rc = SQLITE_OK;
        !          2098:   assert( pFile!=0 );
        !          2099:   assert( locktype<=SHARED_LOCK );
        !          2100:   OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
        !          2101:           pFile->locktype, pFile->sharedLockByte));
        !          2102:   type = pFile->locktype;
        !          2103:   if( type>=EXCLUSIVE_LOCK ){
        !          2104:     osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
        !          2105:     if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
        !          2106:       /* This should never happen.  We should always be able to
        !          2107:       ** reacquire the read lock */
        !          2108:       rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
        !          2109:                "winUnlock", pFile->zPath);
        !          2110:     }
        !          2111:   }
        !          2112:   if( type>=RESERVED_LOCK ){
        !          2113:     osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
        !          2114:   }
        !          2115:   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
        !          2116:     unlockReadLock(pFile);
        !          2117:   }
        !          2118:   if( type>=PENDING_LOCK ){
        !          2119:     osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
        !          2120:   }
        !          2121:   pFile->locktype = (u8)locktype;
        !          2122:   return rc;
        !          2123: }
        !          2124: 
        !          2125: /*
        !          2126: ** If *pArg is inititially negative then this is a query.  Set *pArg to
        !          2127: ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
        !          2128: **
        !          2129: ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
        !          2130: */
        !          2131: static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
        !          2132:   if( *pArg<0 ){
        !          2133:     *pArg = (pFile->ctrlFlags & mask)!=0;
        !          2134:   }else if( (*pArg)==0 ){
        !          2135:     pFile->ctrlFlags &= ~mask;
        !          2136:   }else{
        !          2137:     pFile->ctrlFlags |= mask;
        !          2138:   }
        !          2139: }
        !          2140: 
        !          2141: /*
        !          2142: ** Control and query of the open file handle.
        !          2143: */
        !          2144: static int winFileControl(sqlite3_file *id, int op, void *pArg){
        !          2145:   winFile *pFile = (winFile*)id;
        !          2146:   switch( op ){
        !          2147:     case SQLITE_FCNTL_LOCKSTATE: {
        !          2148:       *(int*)pArg = pFile->locktype;
        !          2149:       return SQLITE_OK;
        !          2150:     }
        !          2151:     case SQLITE_LAST_ERRNO: {
        !          2152:       *(int*)pArg = (int)pFile->lastErrno;
        !          2153:       return SQLITE_OK;
        !          2154:     }
        !          2155:     case SQLITE_FCNTL_CHUNK_SIZE: {
        !          2156:       pFile->szChunk = *(int *)pArg;
        !          2157:       return SQLITE_OK;
        !          2158:     }
        !          2159:     case SQLITE_FCNTL_SIZE_HINT: {
        !          2160:       if( pFile->szChunk>0 ){
        !          2161:         sqlite3_int64 oldSz;
        !          2162:         int rc = winFileSize(id, &oldSz);
        !          2163:         if( rc==SQLITE_OK ){
        !          2164:           sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
        !          2165:           if( newSz>oldSz ){
        !          2166:             SimulateIOErrorBenign(1);
        !          2167:             rc = winTruncate(id, newSz);
        !          2168:             SimulateIOErrorBenign(0);
        !          2169:           }
        !          2170:         }
        !          2171:         return rc;
        !          2172:       }
        !          2173:       return SQLITE_OK;
        !          2174:     }
        !          2175:     case SQLITE_FCNTL_PERSIST_WAL: {
        !          2176:       winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
        !          2177:       return SQLITE_OK;
        !          2178:     }
        !          2179:     case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
        !          2180:       winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
        !          2181:       return SQLITE_OK;
        !          2182:     }
        !          2183:     case SQLITE_FCNTL_VFSNAME: {
        !          2184:       *(char**)pArg = sqlite3_mprintf("win32");
        !          2185:       return SQLITE_OK;
        !          2186:     }
        !          2187:     case SQLITE_FCNTL_WIN32_AV_RETRY: {
        !          2188:       int *a = (int*)pArg;
        !          2189:       if( a[0]>0 ){
        !          2190:         win32IoerrRetry = a[0];
        !          2191:       }else{
        !          2192:         a[0] = win32IoerrRetry;
        !          2193:       }
        !          2194:       if( a[1]>0 ){
        !          2195:         win32IoerrRetryDelay = a[1];
        !          2196:       }else{
        !          2197:         a[1] = win32IoerrRetryDelay;
        !          2198:       }
        !          2199:       return SQLITE_OK;
        !          2200:     }
        !          2201:   }
        !          2202:   return SQLITE_NOTFOUND;
        !          2203: }
        !          2204: 
        !          2205: /*
        !          2206: ** Return the sector size in bytes of the underlying block device for
        !          2207: ** the specified file. This is almost always 512 bytes, but may be
        !          2208: ** larger for some devices.
        !          2209: **
        !          2210: ** SQLite code assumes this function cannot fail. It also assumes that
        !          2211: ** if two files are created in the same file-system directory (i.e.
        !          2212: ** a database and its journal file) that the sector size will be the
        !          2213: ** same for both.
        !          2214: */
        !          2215: static int winSectorSize(sqlite3_file *id){
        !          2216:   (void)id;
        !          2217:   return SQLITE_DEFAULT_SECTOR_SIZE;
        !          2218: }
        !          2219: 
        !          2220: /*
        !          2221: ** Return a vector of device characteristics.
        !          2222: */
        !          2223: static int winDeviceCharacteristics(sqlite3_file *id){
        !          2224:   winFile *p = (winFile*)id;
        !          2225:   return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
        !          2226:          ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
        !          2227: }
        !          2228: 
        !          2229: #ifndef SQLITE_OMIT_WAL
        !          2230: 
        !          2231: /* 
        !          2232: ** Windows will only let you create file view mappings
        !          2233: ** on allocation size granularity boundaries.
        !          2234: ** During sqlite3_os_init() we do a GetSystemInfo()
        !          2235: ** to get the granularity size.
        !          2236: */
        !          2237: SYSTEM_INFO winSysInfo;
        !          2238: 
        !          2239: /*
        !          2240: ** Helper functions to obtain and relinquish the global mutex. The
        !          2241: ** global mutex is used to protect the winLockInfo objects used by 
        !          2242: ** this file, all of which may be shared by multiple threads.
        !          2243: **
        !          2244: ** Function winShmMutexHeld() is used to assert() that the global mutex 
        !          2245: ** is held when required. This function is only used as part of assert() 
        !          2246: ** statements. e.g.
        !          2247: **
        !          2248: **   winShmEnterMutex()
        !          2249: **     assert( winShmMutexHeld() );
        !          2250: **   winShmLeaveMutex()
        !          2251: */
        !          2252: static void winShmEnterMutex(void){
        !          2253:   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
        !          2254: }
        !          2255: static void winShmLeaveMutex(void){
        !          2256:   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
        !          2257: }
        !          2258: #ifdef SQLITE_DEBUG
        !          2259: static int winShmMutexHeld(void) {
        !          2260:   return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
        !          2261: }
        !          2262: #endif
        !          2263: 
        !          2264: /*
        !          2265: ** Object used to represent a single file opened and mmapped to provide
        !          2266: ** shared memory.  When multiple threads all reference the same
        !          2267: ** log-summary, each thread has its own winFile object, but they all
        !          2268: ** point to a single instance of this object.  In other words, each
        !          2269: ** log-summary is opened only once per process.
        !          2270: **
        !          2271: ** winShmMutexHeld() must be true when creating or destroying
        !          2272: ** this object or while reading or writing the following fields:
        !          2273: **
        !          2274: **      nRef
        !          2275: **      pNext 
        !          2276: **
        !          2277: ** The following fields are read-only after the object is created:
        !          2278: ** 
        !          2279: **      fid
        !          2280: **      zFilename
        !          2281: **
        !          2282: ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
        !          2283: ** winShmMutexHeld() is true when reading or writing any other field
        !          2284: ** in this structure.
        !          2285: **
        !          2286: */
        !          2287: struct winShmNode {
        !          2288:   sqlite3_mutex *mutex;      /* Mutex to access this object */
        !          2289:   char *zFilename;           /* Name of the file */
        !          2290:   winFile hFile;             /* File handle from winOpen */
        !          2291: 
        !          2292:   int szRegion;              /* Size of shared-memory regions */
        !          2293:   int nRegion;               /* Size of array apRegion */
        !          2294:   struct ShmRegion {
        !          2295:     HANDLE hMap;             /* File handle from CreateFileMapping */
        !          2296:     void *pMap;
        !          2297:   } *aRegion;
        !          2298:   DWORD lastErrno;           /* The Windows errno from the last I/O error */
        !          2299: 
        !          2300:   int nRef;                  /* Number of winShm objects pointing to this */
        !          2301:   winShm *pFirst;            /* All winShm objects pointing to this */
        !          2302:   winShmNode *pNext;         /* Next in list of all winShmNode objects */
        !          2303: #ifdef SQLITE_DEBUG
        !          2304:   u8 nextShmId;              /* Next available winShm.id value */
        !          2305: #endif
        !          2306: };
        !          2307: 
        !          2308: /*
        !          2309: ** A global array of all winShmNode objects.
        !          2310: **
        !          2311: ** The winShmMutexHeld() must be true while reading or writing this list.
        !          2312: */
        !          2313: static winShmNode *winShmNodeList = 0;
        !          2314: 
        !          2315: /*
        !          2316: ** Structure used internally by this VFS to record the state of an
        !          2317: ** open shared memory connection.
        !          2318: **
        !          2319: ** The following fields are initialized when this object is created and
        !          2320: ** are read-only thereafter:
        !          2321: **
        !          2322: **    winShm.pShmNode
        !          2323: **    winShm.id
        !          2324: **
        !          2325: ** All other fields are read/write.  The winShm.pShmNode->mutex must be held
        !          2326: ** while accessing any read/write fields.
        !          2327: */
        !          2328: struct winShm {
        !          2329:   winShmNode *pShmNode;      /* The underlying winShmNode object */
        !          2330:   winShm *pNext;             /* Next winShm with the same winShmNode */
        !          2331:   u8 hasMutex;               /* True if holding the winShmNode mutex */
        !          2332:   u16 sharedMask;            /* Mask of shared locks held */
        !          2333:   u16 exclMask;              /* Mask of exclusive locks held */
        !          2334: #ifdef SQLITE_DEBUG
        !          2335:   u8 id;                     /* Id of this connection with its winShmNode */
        !          2336: #endif
        !          2337: };
        !          2338: 
        !          2339: /*
        !          2340: ** Constants used for locking
        !          2341: */
        !          2342: #define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
        !          2343: #define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
        !          2344: 
        !          2345: /*
        !          2346: ** Apply advisory locks for all n bytes beginning at ofst.
        !          2347: */
        !          2348: #define _SHM_UNLCK  1
        !          2349: #define _SHM_RDLCK  2
        !          2350: #define _SHM_WRLCK  3
        !          2351: static int winShmSystemLock(
        !          2352:   winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
        !          2353:   int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
        !          2354:   int ofst,             /* Offset to first byte to be locked/unlocked */
        !          2355:   int nByte             /* Number of bytes to lock or unlock */
        !          2356: ){
        !          2357:   OVERLAPPED ovlp;
        !          2358:   DWORD dwFlags;
        !          2359:   int rc = 0;           /* Result code form Lock/UnlockFileEx() */
        !          2360: 
        !          2361:   /* Access to the winShmNode object is serialized by the caller */
        !          2362:   assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
        !          2363: 
        !          2364:   /* Initialize the locking parameters */
        !          2365:   dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
        !          2366:   if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
        !          2367: 
        !          2368:   memset(&ovlp, 0, sizeof(OVERLAPPED));
        !          2369:   ovlp.Offset = ofst;
        !          2370: 
        !          2371:   /* Release/Acquire the system-level lock */
        !          2372:   if( lockType==_SHM_UNLCK ){
        !          2373:     rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
        !          2374:   }else{
        !          2375:     rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
        !          2376:   }
        !          2377:   
        !          2378:   if( rc!= 0 ){
        !          2379:     rc = SQLITE_OK;
        !          2380:   }else{
        !          2381:     pFile->lastErrno =  osGetLastError();
        !          2382:     rc = SQLITE_BUSY;
        !          2383:   }
        !          2384: 
        !          2385:   OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
        !          2386:            pFile->hFile.h,
        !          2387:            rc==SQLITE_OK ? "ok" : "failed",
        !          2388:            lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
        !          2389:            pFile->lastErrno));
        !          2390: 
        !          2391:   return rc;
        !          2392: }
        !          2393: 
        !          2394: /* Forward references to VFS methods */
        !          2395: static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
        !          2396: static int winDelete(sqlite3_vfs *,const char*,int);
        !          2397: 
        !          2398: /*
        !          2399: ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
        !          2400: **
        !          2401: ** This is not a VFS shared-memory method; it is a utility function called
        !          2402: ** by VFS shared-memory methods.
        !          2403: */
        !          2404: static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
        !          2405:   winShmNode **pp;
        !          2406:   winShmNode *p;
        !          2407:   BOOL bRc;
        !          2408:   assert( winShmMutexHeld() );
        !          2409:   pp = &winShmNodeList;
        !          2410:   while( (p = *pp)!=0 ){
        !          2411:     if( p->nRef==0 ){
        !          2412:       int i;
        !          2413:       if( p->mutex ) sqlite3_mutex_free(p->mutex);
        !          2414:       for(i=0; i<p->nRegion; i++){
        !          2415:         bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
        !          2416:         OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
        !          2417:                  (int)osGetCurrentProcessId(), i,
        !          2418:                  bRc ? "ok" : "failed"));
        !          2419:         bRc = osCloseHandle(p->aRegion[i].hMap);
        !          2420:         OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
        !          2421:                  (int)osGetCurrentProcessId(), i,
        !          2422:                  bRc ? "ok" : "failed"));
        !          2423:       }
        !          2424:       if( p->hFile.h != INVALID_HANDLE_VALUE ){
        !          2425:         SimulateIOErrorBenign(1);
        !          2426:         winClose((sqlite3_file *)&p->hFile);
        !          2427:         SimulateIOErrorBenign(0);
        !          2428:       }
        !          2429:       if( deleteFlag ){
        !          2430:         SimulateIOErrorBenign(1);
        !          2431:         sqlite3BeginBenignMalloc();
        !          2432:         winDelete(pVfs, p->zFilename, 0);
        !          2433:         sqlite3EndBenignMalloc();
        !          2434:         SimulateIOErrorBenign(0);
        !          2435:       }
        !          2436:       *pp = p->pNext;
        !          2437:       sqlite3_free(p->aRegion);
        !          2438:       sqlite3_free(p);
        !          2439:     }else{
        !          2440:       pp = &p->pNext;
        !          2441:     }
        !          2442:   }
        !          2443: }
        !          2444: 
        !          2445: /*
        !          2446: ** Open the shared-memory area associated with database file pDbFd.
        !          2447: **
        !          2448: ** When opening a new shared-memory file, if no other instances of that
        !          2449: ** file are currently open, in this process or in other processes, then
        !          2450: ** the file must be truncated to zero length or have its header cleared.
        !          2451: */
        !          2452: static int winOpenSharedMemory(winFile *pDbFd){
        !          2453:   struct winShm *p;                  /* The connection to be opened */
        !          2454:   struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
        !          2455:   int rc;                            /* Result code */
        !          2456:   struct winShmNode *pNew;           /* Newly allocated winShmNode */
        !          2457:   int nName;                         /* Size of zName in bytes */
        !          2458: 
        !          2459:   assert( pDbFd->pShm==0 );    /* Not previously opened */
        !          2460: 
        !          2461:   /* Allocate space for the new sqlite3_shm object.  Also speculatively
        !          2462:   ** allocate space for a new winShmNode and filename.
        !          2463:   */
        !          2464:   p = sqlite3_malloc( sizeof(*p) );
        !          2465:   if( p==0 ) return SQLITE_IOERR_NOMEM;
        !          2466:   memset(p, 0, sizeof(*p));
        !          2467:   nName = sqlite3Strlen30(pDbFd->zPath);
        !          2468:   pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 );
        !          2469:   if( pNew==0 ){
        !          2470:     sqlite3_free(p);
        !          2471:     return SQLITE_IOERR_NOMEM;
        !          2472:   }
        !          2473:   memset(pNew, 0, sizeof(*pNew) + nName + 17);
        !          2474:   pNew->zFilename = (char*)&pNew[1];
        !          2475:   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
        !          2476:   sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 
        !          2477: 
        !          2478:   /* Look to see if there is an existing winShmNode that can be used.
        !          2479:   ** If no matching winShmNode currently exists, create a new one.
        !          2480:   */
        !          2481:   winShmEnterMutex();
        !          2482:   for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
        !          2483:     /* TBD need to come up with better match here.  Perhaps
        !          2484:     ** use FILE_ID_BOTH_DIR_INFO Structure.
        !          2485:     */
        !          2486:     if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
        !          2487:   }
        !          2488:   if( pShmNode ){
        !          2489:     sqlite3_free(pNew);
        !          2490:   }else{
        !          2491:     pShmNode = pNew;
        !          2492:     pNew = 0;
        !          2493:     ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
        !          2494:     pShmNode->pNext = winShmNodeList;
        !          2495:     winShmNodeList = pShmNode;
        !          2496: 
        !          2497:     pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
        !          2498:     if( pShmNode->mutex==0 ){
        !          2499:       rc = SQLITE_IOERR_NOMEM;
        !          2500:       goto shm_open_err;
        !          2501:     }
        !          2502: 
        !          2503:     rc = winOpen(pDbFd->pVfs,
        !          2504:                  pShmNode->zFilename,             /* Name of the file (UTF-8) */
        !          2505:                  (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
        !          2506:                  SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
        !          2507:                  0);
        !          2508:     if( SQLITE_OK!=rc ){
        !          2509:       goto shm_open_err;
        !          2510:     }
        !          2511: 
        !          2512:     /* Check to see if another process is holding the dead-man switch.
        !          2513:     ** If not, truncate the file to zero length. 
        !          2514:     */
        !          2515:     if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
        !          2516:       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
        !          2517:       if( rc!=SQLITE_OK ){
        !          2518:         rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
        !          2519:                  "winOpenShm", pDbFd->zPath);
        !          2520:       }
        !          2521:     }
        !          2522:     if( rc==SQLITE_OK ){
        !          2523:       winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
        !          2524:       rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
        !          2525:     }
        !          2526:     if( rc ) goto shm_open_err;
        !          2527:   }
        !          2528: 
        !          2529:   /* Make the new connection a child of the winShmNode */
        !          2530:   p->pShmNode = pShmNode;
        !          2531: #ifdef SQLITE_DEBUG
        !          2532:   p->id = pShmNode->nextShmId++;
        !          2533: #endif
        !          2534:   pShmNode->nRef++;
        !          2535:   pDbFd->pShm = p;
        !          2536:   winShmLeaveMutex();
        !          2537: 
        !          2538:   /* The reference count on pShmNode has already been incremented under
        !          2539:   ** the cover of the winShmEnterMutex() mutex and the pointer from the
        !          2540:   ** new (struct winShm) object to the pShmNode has been set. All that is
        !          2541:   ** left to do is to link the new object into the linked list starting
        !          2542:   ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
        !          2543:   ** mutex.
        !          2544:   */
        !          2545:   sqlite3_mutex_enter(pShmNode->mutex);
        !          2546:   p->pNext = pShmNode->pFirst;
        !          2547:   pShmNode->pFirst = p;
        !          2548:   sqlite3_mutex_leave(pShmNode->mutex);
        !          2549:   return SQLITE_OK;
        !          2550: 
        !          2551:   /* Jump here on any error */
        !          2552: shm_open_err:
        !          2553:   winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
        !          2554:   winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
        !          2555:   sqlite3_free(p);
        !          2556:   sqlite3_free(pNew);
        !          2557:   winShmLeaveMutex();
        !          2558:   return rc;
        !          2559: }
        !          2560: 
        !          2561: /*
        !          2562: ** Close a connection to shared-memory.  Delete the underlying 
        !          2563: ** storage if deleteFlag is true.
        !          2564: */
        !          2565: static int winShmUnmap(
        !          2566:   sqlite3_file *fd,          /* Database holding shared memory */
        !          2567:   int deleteFlag             /* Delete after closing if true */
        !          2568: ){
        !          2569:   winFile *pDbFd;       /* Database holding shared-memory */
        !          2570:   winShm *p;            /* The connection to be closed */
        !          2571:   winShmNode *pShmNode; /* The underlying shared-memory file */
        !          2572:   winShm **pp;          /* For looping over sibling connections */
        !          2573: 
        !          2574:   pDbFd = (winFile*)fd;
        !          2575:   p = pDbFd->pShm;
        !          2576:   if( p==0 ) return SQLITE_OK;
        !          2577:   pShmNode = p->pShmNode;
        !          2578: 
        !          2579:   /* Remove connection p from the set of connections associated
        !          2580:   ** with pShmNode */
        !          2581:   sqlite3_mutex_enter(pShmNode->mutex);
        !          2582:   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
        !          2583:   *pp = p->pNext;
        !          2584: 
        !          2585:   /* Free the connection p */
        !          2586:   sqlite3_free(p);
        !          2587:   pDbFd->pShm = 0;
        !          2588:   sqlite3_mutex_leave(pShmNode->mutex);
        !          2589: 
        !          2590:   /* If pShmNode->nRef has reached 0, then close the underlying
        !          2591:   ** shared-memory file, too */
        !          2592:   winShmEnterMutex();
        !          2593:   assert( pShmNode->nRef>0 );
        !          2594:   pShmNode->nRef--;
        !          2595:   if( pShmNode->nRef==0 ){
        !          2596:     winShmPurge(pDbFd->pVfs, deleteFlag);
        !          2597:   }
        !          2598:   winShmLeaveMutex();
        !          2599: 
        !          2600:   return SQLITE_OK;
        !          2601: }
        !          2602: 
        !          2603: /*
        !          2604: ** Change the lock state for a shared-memory segment.
        !          2605: */
        !          2606: static int winShmLock(
        !          2607:   sqlite3_file *fd,          /* Database file holding the shared memory */
        !          2608:   int ofst,                  /* First lock to acquire or release */
        !          2609:   int n,                     /* Number of locks to acquire or release */
        !          2610:   int flags                  /* What to do with the lock */
        !          2611: ){
        !          2612:   winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
        !          2613:   winShm *p = pDbFd->pShm;              /* The shared memory being locked */
        !          2614:   winShm *pX;                           /* For looping over all siblings */
        !          2615:   winShmNode *pShmNode = p->pShmNode;
        !          2616:   int rc = SQLITE_OK;                   /* Result code */
        !          2617:   u16 mask;                             /* Mask of locks to take or release */
        !          2618: 
        !          2619:   assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
        !          2620:   assert( n>=1 );
        !          2621:   assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
        !          2622:        || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
        !          2623:        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
        !          2624:        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
        !          2625:   assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
        !          2626: 
        !          2627:   mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
        !          2628:   assert( n>1 || mask==(1<<ofst) );
        !          2629:   sqlite3_mutex_enter(pShmNode->mutex);
        !          2630:   if( flags & SQLITE_SHM_UNLOCK ){
        !          2631:     u16 allMask = 0; /* Mask of locks held by siblings */
        !          2632: 
        !          2633:     /* See if any siblings hold this same lock */
        !          2634:     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
        !          2635:       if( pX==p ) continue;
        !          2636:       assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
        !          2637:       allMask |= pX->sharedMask;
        !          2638:     }
        !          2639: 
        !          2640:     /* Unlock the system-level locks */
        !          2641:     if( (mask & allMask)==0 ){
        !          2642:       rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
        !          2643:     }else{
        !          2644:       rc = SQLITE_OK;
        !          2645:     }
        !          2646: 
        !          2647:     /* Undo the local locks */
        !          2648:     if( rc==SQLITE_OK ){
        !          2649:       p->exclMask &= ~mask;
        !          2650:       p->sharedMask &= ~mask;
        !          2651:     } 
        !          2652:   }else if( flags & SQLITE_SHM_SHARED ){
        !          2653:     u16 allShared = 0;  /* Union of locks held by connections other than "p" */
        !          2654: 
        !          2655:     /* Find out which shared locks are already held by sibling connections.
        !          2656:     ** If any sibling already holds an exclusive lock, go ahead and return
        !          2657:     ** SQLITE_BUSY.
        !          2658:     */
        !          2659:     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
        !          2660:       if( (pX->exclMask & mask)!=0 ){
        !          2661:         rc = SQLITE_BUSY;
        !          2662:         break;
        !          2663:       }
        !          2664:       allShared |= pX->sharedMask;
        !          2665:     }
        !          2666: 
        !          2667:     /* Get shared locks at the system level, if necessary */
        !          2668:     if( rc==SQLITE_OK ){
        !          2669:       if( (allShared & mask)==0 ){
        !          2670:         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
        !          2671:       }else{
        !          2672:         rc = SQLITE_OK;
        !          2673:       }
        !          2674:     }
        !          2675: 
        !          2676:     /* Get the local shared locks */
        !          2677:     if( rc==SQLITE_OK ){
        !          2678:       p->sharedMask |= mask;
        !          2679:     }
        !          2680:   }else{
        !          2681:     /* Make sure no sibling connections hold locks that will block this
        !          2682:     ** lock.  If any do, return SQLITE_BUSY right away.
        !          2683:     */
        !          2684:     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
        !          2685:       if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
        !          2686:         rc = SQLITE_BUSY;
        !          2687:         break;
        !          2688:       }
        !          2689:     }
        !          2690:   
        !          2691:     /* Get the exclusive locks at the system level.  Then if successful
        !          2692:     ** also mark the local connection as being locked.
        !          2693:     */
        !          2694:     if( rc==SQLITE_OK ){
        !          2695:       rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
        !          2696:       if( rc==SQLITE_OK ){
        !          2697:         assert( (p->sharedMask & mask)==0 );
        !          2698:         p->exclMask |= mask;
        !          2699:       }
        !          2700:     }
        !          2701:   }
        !          2702:   sqlite3_mutex_leave(pShmNode->mutex);
        !          2703:   OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
        !          2704:            p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask,
        !          2705:            rc ? "failed" : "ok"));
        !          2706:   return rc;
        !          2707: }
        !          2708: 
        !          2709: /*
        !          2710: ** Implement a memory barrier or memory fence on shared memory.  
        !          2711: **
        !          2712: ** All loads and stores begun before the barrier must complete before
        !          2713: ** any load or store begun after the barrier.
        !          2714: */
        !          2715: static void winShmBarrier(
        !          2716:   sqlite3_file *fd          /* Database holding the shared memory */
        !          2717: ){
        !          2718:   UNUSED_PARAMETER(fd);
        !          2719:   /* MemoryBarrier(); // does not work -- do not know why not */
        !          2720:   winShmEnterMutex();
        !          2721:   winShmLeaveMutex();
        !          2722: }
        !          2723: 
        !          2724: /*
        !          2725: ** This function is called to obtain a pointer to region iRegion of the 
        !          2726: ** shared-memory associated with the database file fd. Shared-memory regions 
        !          2727: ** are numbered starting from zero. Each shared-memory region is szRegion 
        !          2728: ** bytes in size.
        !          2729: **
        !          2730: ** If an error occurs, an error code is returned and *pp is set to NULL.
        !          2731: **
        !          2732: ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
        !          2733: ** region has not been allocated (by any client, including one running in a
        !          2734: ** separate process), then *pp is set to NULL and SQLITE_OK returned. If 
        !          2735: ** isWrite is non-zero and the requested shared-memory region has not yet 
        !          2736: ** been allocated, it is allocated by this function.
        !          2737: **
        !          2738: ** If the shared-memory region has already been allocated or is allocated by
        !          2739: ** this call as described above, then it is mapped into this processes 
        !          2740: ** address space (if it is not already), *pp is set to point to the mapped 
        !          2741: ** memory and SQLITE_OK returned.
        !          2742: */
        !          2743: static int winShmMap(
        !          2744:   sqlite3_file *fd,               /* Handle open on database file */
        !          2745:   int iRegion,                    /* Region to retrieve */
        !          2746:   int szRegion,                   /* Size of regions */
        !          2747:   int isWrite,                    /* True to extend file if necessary */
        !          2748:   void volatile **pp              /* OUT: Mapped memory */
        !          2749: ){
        !          2750:   winFile *pDbFd = (winFile*)fd;
        !          2751:   winShm *p = pDbFd->pShm;
        !          2752:   winShmNode *pShmNode;
        !          2753:   int rc = SQLITE_OK;
        !          2754: 
        !          2755:   if( !p ){
        !          2756:     rc = winOpenSharedMemory(pDbFd);
        !          2757:     if( rc!=SQLITE_OK ) return rc;
        !          2758:     p = pDbFd->pShm;
        !          2759:   }
        !          2760:   pShmNode = p->pShmNode;
        !          2761: 
        !          2762:   sqlite3_mutex_enter(pShmNode->mutex);
        !          2763:   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
        !          2764: 
        !          2765:   if( pShmNode->nRegion<=iRegion ){
        !          2766:     struct ShmRegion *apNew;           /* New aRegion[] array */
        !          2767:     int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
        !          2768:     sqlite3_int64 sz;                  /* Current size of wal-index file */
        !          2769: 
        !          2770:     pShmNode->szRegion = szRegion;
        !          2771: 
        !          2772:     /* The requested region is not mapped into this processes address space.
        !          2773:     ** Check to see if it has been allocated (i.e. if the wal-index file is
        !          2774:     ** large enough to contain the requested region).
        !          2775:     */
        !          2776:     rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
        !          2777:     if( rc!=SQLITE_OK ){
        !          2778:       rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
        !          2779:                "winShmMap1", pDbFd->zPath);
        !          2780:       goto shmpage_out;
        !          2781:     }
        !          2782: 
        !          2783:     if( sz<nByte ){
        !          2784:       /* The requested memory region does not exist. If isWrite is set to
        !          2785:       ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
        !          2786:       **
        !          2787:       ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
        !          2788:       ** the requested memory region.
        !          2789:       */
        !          2790:       if( !isWrite ) goto shmpage_out;
        !          2791:       rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
        !          2792:       if( rc!=SQLITE_OK ){
        !          2793:         rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
        !          2794:                  "winShmMap2", pDbFd->zPath);
        !          2795:         goto shmpage_out;
        !          2796:       }
        !          2797:     }
        !          2798: 
        !          2799:     /* Map the requested memory region into this processes address space. */
        !          2800:     apNew = (struct ShmRegion *)sqlite3_realloc(
        !          2801:         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
        !          2802:     );
        !          2803:     if( !apNew ){
        !          2804:       rc = SQLITE_IOERR_NOMEM;
        !          2805:       goto shmpage_out;
        !          2806:     }
        !          2807:     pShmNode->aRegion = apNew;
        !          2808: 
        !          2809:     while( pShmNode->nRegion<=iRegion ){
        !          2810:       HANDLE hMap;                /* file-mapping handle */
        !          2811:       void *pMap = 0;             /* Mapped memory region */
        !          2812:      
        !          2813:       hMap = osCreateFileMapping(pShmNode->hFile.h, 
        !          2814:           NULL, PAGE_READWRITE, 0, nByte, NULL
        !          2815:       );
        !          2816:       OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
        !          2817:                (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
        !          2818:                hMap ? "ok" : "failed"));
        !          2819:       if( hMap ){
        !          2820:         int iOffset = pShmNode->nRegion*szRegion;
        !          2821:         int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
        !          2822:         pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
        !          2823:             0, iOffset - iOffsetShift, szRegion + iOffsetShift
        !          2824:         );
        !          2825:         OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
        !          2826:                  (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
        !          2827:                  szRegion, pMap ? "ok" : "failed"));
        !          2828:       }
        !          2829:       if( !pMap ){
        !          2830:         pShmNode->lastErrno = osGetLastError();
        !          2831:         rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
        !          2832:                  "winShmMap3", pDbFd->zPath);
        !          2833:         if( hMap ) osCloseHandle(hMap);
        !          2834:         goto shmpage_out;
        !          2835:       }
        !          2836: 
        !          2837:       pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
        !          2838:       pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
        !          2839:       pShmNode->nRegion++;
        !          2840:     }
        !          2841:   }
        !          2842: 
        !          2843: shmpage_out:
        !          2844:   if( pShmNode->nRegion>iRegion ){
        !          2845:     int iOffset = iRegion*szRegion;
        !          2846:     int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
        !          2847:     char *p = (char *)pShmNode->aRegion[iRegion].pMap;
        !          2848:     *pp = (void *)&p[iOffsetShift];
        !          2849:   }else{
        !          2850:     *pp = 0;
        !          2851:   }
        !          2852:   sqlite3_mutex_leave(pShmNode->mutex);
        !          2853:   return rc;
        !          2854: }
        !          2855: 
        !          2856: #else
        !          2857: # define winShmMap     0
        !          2858: # define winShmLock    0
        !          2859: # define winShmBarrier 0
        !          2860: # define winShmUnmap   0
        !          2861: #endif /* #ifndef SQLITE_OMIT_WAL */
        !          2862: 
        !          2863: /*
        !          2864: ** Here ends the implementation of all sqlite3_file methods.
        !          2865: **
        !          2866: ********************** End sqlite3_file Methods *******************************
        !          2867: ******************************************************************************/
        !          2868: 
        !          2869: /*
        !          2870: ** This vector defines all the methods that can operate on an
        !          2871: ** sqlite3_file for win32.
        !          2872: */
        !          2873: static const sqlite3_io_methods winIoMethod = {
        !          2874:   2,                              /* iVersion */
        !          2875:   winClose,                       /* xClose */
        !          2876:   winRead,                        /* xRead */
        !          2877:   winWrite,                       /* xWrite */
        !          2878:   winTruncate,                    /* xTruncate */
        !          2879:   winSync,                        /* xSync */
        !          2880:   winFileSize,                    /* xFileSize */
        !          2881:   winLock,                        /* xLock */
        !          2882:   winUnlock,                      /* xUnlock */
        !          2883:   winCheckReservedLock,           /* xCheckReservedLock */
        !          2884:   winFileControl,                 /* xFileControl */
        !          2885:   winSectorSize,                  /* xSectorSize */
        !          2886:   winDeviceCharacteristics,       /* xDeviceCharacteristics */
        !          2887:   winShmMap,                      /* xShmMap */
        !          2888:   winShmLock,                     /* xShmLock */
        !          2889:   winShmBarrier,                  /* xShmBarrier */
        !          2890:   winShmUnmap                     /* xShmUnmap */
        !          2891: };
        !          2892: 
        !          2893: /****************************************************************************
        !          2894: **************************** sqlite3_vfs methods ****************************
        !          2895: **
        !          2896: ** This division contains the implementation of methods on the
        !          2897: ** sqlite3_vfs object.
        !          2898: */
        !          2899: 
        !          2900: /*
        !          2901: ** Convert a UTF-8 filename into whatever form the underlying
        !          2902: ** operating system wants filenames in.  Space to hold the result
        !          2903: ** is obtained from malloc and must be freed by the calling
        !          2904: ** function.
        !          2905: */
        !          2906: static void *convertUtf8Filename(const char *zFilename){
        !          2907:   void *zConverted = 0;
        !          2908:   if( isNT() ){
        !          2909:     zConverted = utf8ToUnicode(zFilename);
        !          2910: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          2911: */
        !          2912: #if SQLITE_OS_WINCE==0
        !          2913:   }else{
        !          2914:     zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
        !          2915: #endif
        !          2916:   }
        !          2917:   /* caller will handle out of memory */
        !          2918:   return zConverted;
        !          2919: }
        !          2920: 
        !          2921: /*
        !          2922: ** Create a temporary file name in zBuf.  zBuf must be big enough to
        !          2923: ** hold at pVfs->mxPathname characters.
        !          2924: */
        !          2925: static int getTempname(int nBuf, char *zBuf){
        !          2926:   static char zChars[] =
        !          2927:     "abcdefghijklmnopqrstuvwxyz"
        !          2928:     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        !          2929:     "0123456789";
        !          2930:   size_t i, j;
        !          2931:   char zTempPath[MAX_PATH+2];
        !          2932: 
        !          2933:   /* It's odd to simulate an io-error here, but really this is just
        !          2934:   ** using the io-error infrastructure to test that SQLite handles this
        !          2935:   ** function failing. 
        !          2936:   */
        !          2937:   SimulateIOError( return SQLITE_IOERR );
        !          2938: 
        !          2939:   if( sqlite3_temp_directory ){
        !          2940:     sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
        !          2941:   }else if( isNT() ){
        !          2942:     char *zMulti;
        !          2943:     WCHAR zWidePath[MAX_PATH];
        !          2944:     osGetTempPathW(MAX_PATH-30, zWidePath);
        !          2945:     zMulti = unicodeToUtf8(zWidePath);
        !          2946:     if( zMulti ){
        !          2947:       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
        !          2948:       sqlite3_free(zMulti);
        !          2949:     }else{
        !          2950:       return SQLITE_IOERR_NOMEM;
        !          2951:     }
        !          2952: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          2953: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          2954: ** it's important to not reference them for WINCE builds.
        !          2955: */
        !          2956: #if SQLITE_OS_WINCE==0
        !          2957:   }else{
        !          2958:     char *zUtf8;
        !          2959:     char zMbcsPath[MAX_PATH];
        !          2960:     osGetTempPathA(MAX_PATH-30, zMbcsPath);
        !          2961:     zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
        !          2962:     if( zUtf8 ){
        !          2963:       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
        !          2964:       sqlite3_free(zUtf8);
        !          2965:     }else{
        !          2966:       return SQLITE_IOERR_NOMEM;
        !          2967:     }
        !          2968: #endif
        !          2969:   }
        !          2970: 
        !          2971:   /* Check that the output buffer is large enough for the temporary file 
        !          2972:   ** name. If it is not, return SQLITE_ERROR.
        !          2973:   */
        !          2974:   if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
        !          2975:     return SQLITE_ERROR;
        !          2976:   }
        !          2977: 
        !          2978:   for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
        !          2979:   zTempPath[i] = 0;
        !          2980: 
        !          2981:   sqlite3_snprintf(nBuf-18, zBuf,
        !          2982:                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
        !          2983:   j = sqlite3Strlen30(zBuf);
        !          2984:   sqlite3_randomness(15, &zBuf[j]);
        !          2985:   for(i=0; i<15; i++, j++){
        !          2986:     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
        !          2987:   }
        !          2988:   zBuf[j] = 0;
        !          2989:   zBuf[j+1] = 0;
        !          2990: 
        !          2991:   OSTRACE(("TEMP FILENAME: %s\n", zBuf));
        !          2992:   return SQLITE_OK; 
        !          2993: }
        !          2994: 
        !          2995: /*
        !          2996: ** Open a file.
        !          2997: */
        !          2998: static int winOpen(
        !          2999:   sqlite3_vfs *pVfs,        /* Not used */
        !          3000:   const char *zName,        /* Name of the file (UTF-8) */
        !          3001:   sqlite3_file *id,         /* Write the SQLite file handle here */
        !          3002:   int flags,                /* Open mode flags */
        !          3003:   int *pOutFlags            /* Status return flags */
        !          3004: ){
        !          3005:   HANDLE h;
        !          3006:   DWORD lastErrno;
        !          3007:   DWORD dwDesiredAccess;
        !          3008:   DWORD dwShareMode;
        !          3009:   DWORD dwCreationDisposition;
        !          3010:   DWORD dwFlagsAndAttributes = 0;
        !          3011: #if SQLITE_OS_WINCE
        !          3012:   int isTemp = 0;
        !          3013: #endif
        !          3014:   winFile *pFile = (winFile*)id;
        !          3015:   void *zConverted;              /* Filename in OS encoding */
        !          3016:   const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
        !          3017:   int cnt = 0;
        !          3018: 
        !          3019:   /* If argument zPath is a NULL pointer, this function is required to open
        !          3020:   ** a temporary file. Use this buffer to store the file name in.
        !          3021:   */
        !          3022:   char zTmpname[MAX_PATH+2];     /* Buffer used to create temp filename */
        !          3023: 
        !          3024:   int rc = SQLITE_OK;            /* Function Return Code */
        !          3025: #if !defined(NDEBUG) || SQLITE_OS_WINCE
        !          3026:   int eType = flags&0xFFFFFF00;  /* Type of file to open */
        !          3027: #endif
        !          3028: 
        !          3029:   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
        !          3030:   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
        !          3031:   int isCreate     = (flags & SQLITE_OPEN_CREATE);
        !          3032: #ifndef NDEBUG
        !          3033:   int isReadonly   = (flags & SQLITE_OPEN_READONLY);
        !          3034: #endif
        !          3035:   int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
        !          3036: 
        !          3037: #ifndef NDEBUG
        !          3038:   int isOpenJournal = (isCreate && (
        !          3039:         eType==SQLITE_OPEN_MASTER_JOURNAL 
        !          3040:      || eType==SQLITE_OPEN_MAIN_JOURNAL 
        !          3041:      || eType==SQLITE_OPEN_WAL
        !          3042:   ));
        !          3043: #endif
        !          3044: 
        !          3045:   /* Check the following statements are true: 
        !          3046:   **
        !          3047:   **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
        !          3048:   **   (b) if CREATE is set, then READWRITE must also be set, and
        !          3049:   **   (c) if EXCLUSIVE is set, then CREATE must also be set.
        !          3050:   **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
        !          3051:   */
        !          3052:   assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
        !          3053:   assert(isCreate==0 || isReadWrite);
        !          3054:   assert(isExclusive==0 || isCreate);
        !          3055:   assert(isDelete==0 || isCreate);
        !          3056: 
        !          3057:   /* The main DB, main journal, WAL file and master journal are never 
        !          3058:   ** automatically deleted. Nor are they ever temporary files.  */
        !          3059:   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
        !          3060:   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
        !          3061:   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
        !          3062:   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
        !          3063: 
        !          3064:   /* Assert that the upper layer has set one of the "file-type" flags. */
        !          3065:   assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
        !          3066:        || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
        !          3067:        || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
        !          3068:        || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
        !          3069:   );
        !          3070: 
        !          3071:   assert( id!=0 );
        !          3072:   UNUSED_PARAMETER(pVfs);
        !          3073: 
        !          3074:   pFile->h = INVALID_HANDLE_VALUE;
        !          3075: 
        !          3076:   /* If the second argument to this function is NULL, generate a 
        !          3077:   ** temporary file name to use 
        !          3078:   */
        !          3079:   if( !zUtf8Name ){
        !          3080:     assert(isDelete && !isOpenJournal);
        !          3081:     rc = getTempname(MAX_PATH+2, zTmpname);
        !          3082:     if( rc!=SQLITE_OK ){
        !          3083:       return rc;
        !          3084:     }
        !          3085:     zUtf8Name = zTmpname;
        !          3086:   }
        !          3087: 
        !          3088:   /* Database filenames are double-zero terminated if they are not
        !          3089:   ** URIs with parameters.  Hence, they can always be passed into
        !          3090:   ** sqlite3_uri_parameter().
        !          3091:   */
        !          3092:   assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
        !          3093:         zUtf8Name[strlen(zUtf8Name)+1]==0 );
        !          3094: 
        !          3095:   /* Convert the filename to the system encoding. */
        !          3096:   zConverted = convertUtf8Filename(zUtf8Name);
        !          3097:   if( zConverted==0 ){
        !          3098:     return SQLITE_IOERR_NOMEM;
        !          3099:   }
        !          3100: 
        !          3101:   if( isReadWrite ){
        !          3102:     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
        !          3103:   }else{
        !          3104:     dwDesiredAccess = GENERIC_READ;
        !          3105:   }
        !          3106: 
        !          3107:   /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 
        !          3108:   ** created. SQLite doesn't use it to indicate "exclusive access" 
        !          3109:   ** as it is usually understood.
        !          3110:   */
        !          3111:   if( isExclusive ){
        !          3112:     /* Creates a new file, only if it does not already exist. */
        !          3113:     /* If the file exists, it fails. */
        !          3114:     dwCreationDisposition = CREATE_NEW;
        !          3115:   }else if( isCreate ){
        !          3116:     /* Open existing file, or create if it doesn't exist */
        !          3117:     dwCreationDisposition = OPEN_ALWAYS;
        !          3118:   }else{
        !          3119:     /* Opens a file, only if it exists. */
        !          3120:     dwCreationDisposition = OPEN_EXISTING;
        !          3121:   }
        !          3122: 
        !          3123:   dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
        !          3124: 
        !          3125:   if( isDelete ){
        !          3126: #if SQLITE_OS_WINCE
        !          3127:     dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
        !          3128:     isTemp = 1;
        !          3129: #else
        !          3130:     dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
        !          3131:                                | FILE_ATTRIBUTE_HIDDEN
        !          3132:                                | FILE_FLAG_DELETE_ON_CLOSE;
        !          3133: #endif
        !          3134:   }else{
        !          3135:     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
        !          3136:   }
        !          3137:   /* Reports from the internet are that performance is always
        !          3138:   ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
        !          3139: #if SQLITE_OS_WINCE
        !          3140:   dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
        !          3141: #endif
        !          3142: 
        !          3143:   if( isNT() ){
        !          3144:     while( (h = osCreateFileW((LPCWSTR)zConverted,
        !          3145:                               dwDesiredAccess,
        !          3146:                               dwShareMode, NULL,
        !          3147:                               dwCreationDisposition,
        !          3148:                               dwFlagsAndAttributes,
        !          3149:                               NULL))==INVALID_HANDLE_VALUE &&
        !          3150:                               retryIoerr(&cnt, &lastErrno) ){}
        !          3151: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          3152: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          3153: ** it's important to not reference them for WINCE builds.
        !          3154: */
        !          3155: #if SQLITE_OS_WINCE==0
        !          3156:   }else{
        !          3157:     while( (h = osCreateFileA((LPCSTR)zConverted,
        !          3158:                               dwDesiredAccess,
        !          3159:                               dwShareMode, NULL,
        !          3160:                               dwCreationDisposition,
        !          3161:                               dwFlagsAndAttributes,
        !          3162:                               NULL))==INVALID_HANDLE_VALUE &&
        !          3163:                               retryIoerr(&cnt, &lastErrno) ){}
        !          3164: #endif
        !          3165:   }
        !          3166: 
        !          3167:   logIoerr(cnt);
        !          3168: 
        !          3169:   OSTRACE(("OPEN %d %s 0x%lx %s\n", 
        !          3170:            h, zName, dwDesiredAccess, 
        !          3171:            h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
        !          3172: 
        !          3173:   if( h==INVALID_HANDLE_VALUE ){
        !          3174:     pFile->lastErrno = lastErrno;
        !          3175:     winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
        !          3176:     sqlite3_free(zConverted);
        !          3177:     if( isReadWrite && !isExclusive ){
        !          3178:       return winOpen(pVfs, zName, id, 
        !          3179:              ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
        !          3180:     }else{
        !          3181:       return SQLITE_CANTOPEN_BKPT;
        !          3182:     }
        !          3183:   }
        !          3184: 
        !          3185:   if( pOutFlags ){
        !          3186:     if( isReadWrite ){
        !          3187:       *pOutFlags = SQLITE_OPEN_READWRITE;
        !          3188:     }else{
        !          3189:       *pOutFlags = SQLITE_OPEN_READONLY;
        !          3190:     }
        !          3191:   }
        !          3192: 
        !          3193:   memset(pFile, 0, sizeof(*pFile));
        !          3194:   pFile->pMethod = &winIoMethod;
        !          3195:   pFile->h = h;
        !          3196:   pFile->lastErrno = NO_ERROR;
        !          3197:   pFile->pVfs = pVfs;
        !          3198:   pFile->pShm = 0;
        !          3199:   pFile->zPath = zName;
        !          3200:   if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
        !          3201:     pFile->ctrlFlags |= WINFILE_PSOW;
        !          3202:   }
        !          3203: 
        !          3204: #if SQLITE_OS_WINCE
        !          3205:   if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
        !          3206:        && !winceCreateLock(zName, pFile)
        !          3207:   ){
        !          3208:     osCloseHandle(h);
        !          3209:     sqlite3_free(zConverted);
        !          3210:     return SQLITE_CANTOPEN_BKPT;
        !          3211:   }
        !          3212:   if( isTemp ){
        !          3213:     pFile->zDeleteOnClose = zConverted;
        !          3214:   }else
        !          3215: #endif
        !          3216:   {
        !          3217:     sqlite3_free(zConverted);
        !          3218:   }
        !          3219: 
        !          3220:   OpenCounter(+1);
        !          3221:   return rc;
        !          3222: }
        !          3223: 
        !          3224: /*
        !          3225: ** Delete the named file.
        !          3226: **
        !          3227: ** Note that Windows does not allow a file to be deleted if some other
        !          3228: ** process has it open.  Sometimes a virus scanner or indexing program
        !          3229: ** will open a journal file shortly after it is created in order to do
        !          3230: ** whatever it does.  While this other process is holding the
        !          3231: ** file open, we will be unable to delete it.  To work around this
        !          3232: ** problem, we delay 100 milliseconds and try to delete again.  Up
        !          3233: ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
        !          3234: ** up and returning an error.
        !          3235: */
        !          3236: static int winDelete(
        !          3237:   sqlite3_vfs *pVfs,          /* Not used on win32 */
        !          3238:   const char *zFilename,      /* Name of file to delete */
        !          3239:   int syncDir                 /* Not used on win32 */
        !          3240: ){
        !          3241:   int cnt = 0;
        !          3242:   int rc;
        !          3243:   DWORD lastErrno;
        !          3244:   void *zConverted;
        !          3245:   UNUSED_PARAMETER(pVfs);
        !          3246:   UNUSED_PARAMETER(syncDir);
        !          3247: 
        !          3248:   SimulateIOError(return SQLITE_IOERR_DELETE);
        !          3249:   zConverted = convertUtf8Filename(zFilename);
        !          3250:   if( zConverted==0 ){
        !          3251:     return SQLITE_IOERR_NOMEM;
        !          3252:   }
        !          3253:   if( isNT() ){
        !          3254:     rc = 1;
        !          3255:     while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES &&
        !          3256:          (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){}
        !          3257:     rc = rc ? SQLITE_OK : SQLITE_ERROR;
        !          3258: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          3259: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          3260: ** it's important to not reference them for WINCE builds.
        !          3261: */
        !          3262: #if SQLITE_OS_WINCE==0
        !          3263:   }else{
        !          3264:     rc = 1;
        !          3265:     while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
        !          3266:          (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){}
        !          3267:     rc = rc ? SQLITE_OK : SQLITE_ERROR;
        !          3268: #endif
        !          3269:   }
        !          3270:   if( rc ){
        !          3271:     rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
        !          3272:              "winDelete", zFilename);
        !          3273:   }else{
        !          3274:     logIoerr(cnt);
        !          3275:   }
        !          3276:   sqlite3_free(zConverted);
        !          3277:   OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
        !          3278:   return rc;
        !          3279: }
        !          3280: 
        !          3281: /*
        !          3282: ** Check the existance and status of a file.
        !          3283: */
        !          3284: static int winAccess(
        !          3285:   sqlite3_vfs *pVfs,         /* Not used on win32 */
        !          3286:   const char *zFilename,     /* Name of file to check */
        !          3287:   int flags,                 /* Type of test to make on this file */
        !          3288:   int *pResOut               /* OUT: Result */
        !          3289: ){
        !          3290:   DWORD attr;
        !          3291:   int rc = 0;
        !          3292:   DWORD lastErrno;
        !          3293:   void *zConverted;
        !          3294:   UNUSED_PARAMETER(pVfs);
        !          3295: 
        !          3296:   SimulateIOError( return SQLITE_IOERR_ACCESS; );
        !          3297:   zConverted = convertUtf8Filename(zFilename);
        !          3298:   if( zConverted==0 ){
        !          3299:     return SQLITE_IOERR_NOMEM;
        !          3300:   }
        !          3301:   if( isNT() ){
        !          3302:     int cnt = 0;
        !          3303:     WIN32_FILE_ATTRIBUTE_DATA sAttrData;
        !          3304:     memset(&sAttrData, 0, sizeof(sAttrData));
        !          3305:     while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
        !          3306:                              GetFileExInfoStandard, 
        !          3307:                              &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
        !          3308:     if( rc ){
        !          3309:       /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
        !          3310:       ** as if it does not exist.
        !          3311:       */
        !          3312:       if(    flags==SQLITE_ACCESS_EXISTS
        !          3313:           && sAttrData.nFileSizeHigh==0 
        !          3314:           && sAttrData.nFileSizeLow==0 ){
        !          3315:         attr = INVALID_FILE_ATTRIBUTES;
        !          3316:       }else{
        !          3317:         attr = sAttrData.dwFileAttributes;
        !          3318:       }
        !          3319:     }else{
        !          3320:       logIoerr(cnt);
        !          3321:       if( lastErrno!=ERROR_FILE_NOT_FOUND ){
        !          3322:         winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
        !          3323:         sqlite3_free(zConverted);
        !          3324:         return SQLITE_IOERR_ACCESS;
        !          3325:       }else{
        !          3326:         attr = INVALID_FILE_ATTRIBUTES;
        !          3327:       }
        !          3328:     }
        !          3329: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          3330: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          3331: ** it's important to not reference them for WINCE builds.
        !          3332: */
        !          3333: #if SQLITE_OS_WINCE==0
        !          3334:   }else{
        !          3335:     attr = osGetFileAttributesA((char*)zConverted);
        !          3336: #endif
        !          3337:   }
        !          3338:   sqlite3_free(zConverted);
        !          3339:   switch( flags ){
        !          3340:     case SQLITE_ACCESS_READ:
        !          3341:     case SQLITE_ACCESS_EXISTS:
        !          3342:       rc = attr!=INVALID_FILE_ATTRIBUTES;
        !          3343:       break;
        !          3344:     case SQLITE_ACCESS_READWRITE:
        !          3345:       rc = attr!=INVALID_FILE_ATTRIBUTES &&
        !          3346:              (attr & FILE_ATTRIBUTE_READONLY)==0;
        !          3347:       break;
        !          3348:     default:
        !          3349:       assert(!"Invalid flags argument");
        !          3350:   }
        !          3351:   *pResOut = rc;
        !          3352:   return SQLITE_OK;
        !          3353: }
        !          3354: 
        !          3355: 
        !          3356: /*
        !          3357: ** Turn a relative pathname into a full pathname.  Write the full
        !          3358: ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
        !          3359: ** bytes in size.
        !          3360: */
        !          3361: static int winFullPathname(
        !          3362:   sqlite3_vfs *pVfs,            /* Pointer to vfs object */
        !          3363:   const char *zRelative,        /* Possibly relative input path */
        !          3364:   int nFull,                    /* Size of output buffer in bytes */
        !          3365:   char *zFull                   /* Output buffer */
        !          3366: ){
        !          3367:   
        !          3368: #if defined(__CYGWIN__)
        !          3369:   SimulateIOError( return SQLITE_ERROR );
        !          3370:   UNUSED_PARAMETER(nFull);
        !          3371:   cygwin_conv_to_full_win32_path(zRelative, zFull);
        !          3372:   return SQLITE_OK;
        !          3373: #endif
        !          3374: 
        !          3375: #if SQLITE_OS_WINCE
        !          3376:   SimulateIOError( return SQLITE_ERROR );
        !          3377:   UNUSED_PARAMETER(nFull);
        !          3378:   /* WinCE has no concept of a relative pathname, or so I am told. */
        !          3379:   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
        !          3380:   return SQLITE_OK;
        !          3381: #endif
        !          3382: 
        !          3383: #if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
        !          3384:   int nByte;
        !          3385:   void *zConverted;
        !          3386:   char *zOut;
        !          3387: 
        !          3388:   /* If this path name begins with "/X:", where "X" is any alphabetic
        !          3389:   ** character, discard the initial "/" from the pathname.
        !          3390:   */
        !          3391:   if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
        !          3392:     zRelative++;
        !          3393:   }
        !          3394: 
        !          3395:   /* It's odd to simulate an io-error here, but really this is just
        !          3396:   ** using the io-error infrastructure to test that SQLite handles this
        !          3397:   ** function failing. This function could fail if, for example, the
        !          3398:   ** current working directory has been unlinked.
        !          3399:   */
        !          3400:   SimulateIOError( return SQLITE_ERROR );
        !          3401:   UNUSED_PARAMETER(nFull);
        !          3402:   zConverted = convertUtf8Filename(zRelative);
        !          3403:   if( zConverted==0 ){
        !          3404:     return SQLITE_IOERR_NOMEM;
        !          3405:   }
        !          3406:   if( isNT() ){
        !          3407:     LPWSTR zTemp;
        !          3408:     nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
        !          3409:     zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
        !          3410:     if( zTemp==0 ){
        !          3411:       sqlite3_free(zConverted);
        !          3412:       return SQLITE_IOERR_NOMEM;
        !          3413:     }
        !          3414:     osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
        !          3415:     sqlite3_free(zConverted);
        !          3416:     zOut = unicodeToUtf8(zTemp);
        !          3417:     sqlite3_free(zTemp);
        !          3418: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          3419: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          3420: ** it's important to not reference them for WINCE builds.
        !          3421: */
        !          3422: #if SQLITE_OS_WINCE==0
        !          3423:   }else{
        !          3424:     char *zTemp;
        !          3425:     nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
        !          3426:     zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
        !          3427:     if( zTemp==0 ){
        !          3428:       sqlite3_free(zConverted);
        !          3429:       return SQLITE_IOERR_NOMEM;
        !          3430:     }
        !          3431:     osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
        !          3432:     sqlite3_free(zConverted);
        !          3433:     zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
        !          3434:     sqlite3_free(zTemp);
        !          3435: #endif
        !          3436:   }
        !          3437:   if( zOut ){
        !          3438:     sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
        !          3439:     sqlite3_free(zOut);
        !          3440:     return SQLITE_OK;
        !          3441:   }else{
        !          3442:     return SQLITE_IOERR_NOMEM;
        !          3443:   }
        !          3444: #endif
        !          3445: }
        !          3446: 
        !          3447: #ifndef SQLITE_OMIT_LOAD_EXTENSION
        !          3448: /*
        !          3449: ** Interfaces for opening a shared library, finding entry points
        !          3450: ** within the shared library, and closing the shared library.
        !          3451: */
        !          3452: /*
        !          3453: ** Interfaces for opening a shared library, finding entry points
        !          3454: ** within the shared library, and closing the shared library.
        !          3455: */
        !          3456: static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
        !          3457:   HANDLE h;
        !          3458:   void *zConverted = convertUtf8Filename(zFilename);
        !          3459:   UNUSED_PARAMETER(pVfs);
        !          3460:   if( zConverted==0 ){
        !          3461:     return 0;
        !          3462:   }
        !          3463:   if( isNT() ){
        !          3464:     h = osLoadLibraryW((LPCWSTR)zConverted);
        !          3465: /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
        !          3466: ** Since the ANSI version of these Windows API do not exist for WINCE,
        !          3467: ** it's important to not reference them for WINCE builds.
        !          3468: */
        !          3469: #if SQLITE_OS_WINCE==0
        !          3470:   }else{
        !          3471:     h = osLoadLibraryA((char*)zConverted);
        !          3472: #endif
        !          3473:   }
        !          3474:   sqlite3_free(zConverted);
        !          3475:   return (void*)h;
        !          3476: }
        !          3477: static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
        !          3478:   UNUSED_PARAMETER(pVfs);
        !          3479:   getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
        !          3480: }
        !          3481: static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
        !          3482:   UNUSED_PARAMETER(pVfs);
        !          3483:   return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
        !          3484: }
        !          3485: static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
        !          3486:   UNUSED_PARAMETER(pVfs);
        !          3487:   osFreeLibrary((HANDLE)pHandle);
        !          3488: }
        !          3489: #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
        !          3490:   #define winDlOpen  0
        !          3491:   #define winDlError 0
        !          3492:   #define winDlSym   0
        !          3493:   #define winDlClose 0
        !          3494: #endif
        !          3495: 
        !          3496: 
        !          3497: /*
        !          3498: ** Write up to nBuf bytes of randomness into zBuf.
        !          3499: */
        !          3500: static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
        !          3501:   int n = 0;
        !          3502:   UNUSED_PARAMETER(pVfs);
        !          3503: #if defined(SQLITE_TEST)
        !          3504:   n = nBuf;
        !          3505:   memset(zBuf, 0, nBuf);
        !          3506: #else
        !          3507:   if( sizeof(SYSTEMTIME)<=nBuf-n ){
        !          3508:     SYSTEMTIME x;
        !          3509:     osGetSystemTime(&x);
        !          3510:     memcpy(&zBuf[n], &x, sizeof(x));
        !          3511:     n += sizeof(x);
        !          3512:   }
        !          3513:   if( sizeof(DWORD)<=nBuf-n ){
        !          3514:     DWORD pid = osGetCurrentProcessId();
        !          3515:     memcpy(&zBuf[n], &pid, sizeof(pid));
        !          3516:     n += sizeof(pid);
        !          3517:   }
        !          3518:   if( sizeof(DWORD)<=nBuf-n ){
        !          3519:     DWORD cnt = osGetTickCount();
        !          3520:     memcpy(&zBuf[n], &cnt, sizeof(cnt));
        !          3521:     n += sizeof(cnt);
        !          3522:   }
        !          3523:   if( sizeof(LARGE_INTEGER)<=nBuf-n ){
        !          3524:     LARGE_INTEGER i;
        !          3525:     osQueryPerformanceCounter(&i);
        !          3526:     memcpy(&zBuf[n], &i, sizeof(i));
        !          3527:     n += sizeof(i);
        !          3528:   }
        !          3529: #endif
        !          3530:   return n;
        !          3531: }
        !          3532: 
        !          3533: 
        !          3534: /*
        !          3535: ** Sleep for a little while.  Return the amount of time slept.
        !          3536: */
        !          3537: static int winSleep(sqlite3_vfs *pVfs, int microsec){
        !          3538:   osSleep((microsec+999)/1000);
        !          3539:   UNUSED_PARAMETER(pVfs);
        !          3540:   return ((microsec+999)/1000)*1000;
        !          3541: }
        !          3542: 
        !          3543: /*
        !          3544: ** The following variable, if set to a non-zero value, is interpreted as
        !          3545: ** the number of seconds since 1970 and is used to set the result of
        !          3546: ** sqlite3OsCurrentTime() during testing.
        !          3547: */
        !          3548: #ifdef SQLITE_TEST
        !          3549: int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
        !          3550: #endif
        !          3551: 
        !          3552: /*
        !          3553: ** Find the current time (in Universal Coordinated Time).  Write into *piNow
        !          3554: ** the current time and date as a Julian Day number times 86_400_000.  In
        !          3555: ** other words, write into *piNow the number of milliseconds since the Julian
        !          3556: ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
        !          3557: ** proleptic Gregorian calendar.
        !          3558: **
        !          3559: ** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date 
        !          3560: ** cannot be found.
        !          3561: */
        !          3562: static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
        !          3563:   /* FILETIME structure is a 64-bit value representing the number of 
        !          3564:      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
        !          3565:   */
        !          3566:   FILETIME ft;
        !          3567:   static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
        !          3568: #ifdef SQLITE_TEST
        !          3569:   static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
        !          3570: #endif
        !          3571:   /* 2^32 - to avoid use of LL and warnings in gcc */
        !          3572:   static const sqlite3_int64 max32BitValue = 
        !          3573:       (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
        !          3574: 
        !          3575: #if SQLITE_OS_WINCE
        !          3576:   SYSTEMTIME time;
        !          3577:   osGetSystemTime(&time);
        !          3578:   /* if SystemTimeToFileTime() fails, it returns zero. */
        !          3579:   if (!osSystemTimeToFileTime(&time,&ft)){
        !          3580:     return SQLITE_ERROR;
        !          3581:   }
        !          3582: #else
        !          3583:   osGetSystemTimeAsFileTime( &ft );
        !          3584: #endif
        !          3585: 
        !          3586:   *piNow = winFiletimeEpoch +
        !          3587:             ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
        !          3588:                (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
        !          3589: 
        !          3590: #ifdef SQLITE_TEST
        !          3591:   if( sqlite3_current_time ){
        !          3592:     *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
        !          3593:   }
        !          3594: #endif
        !          3595:   UNUSED_PARAMETER(pVfs);
        !          3596:   return SQLITE_OK;
        !          3597: }
        !          3598: 
        !          3599: /*
        !          3600: ** Find the current time (in Universal Coordinated Time).  Write the
        !          3601: ** current time and date as a Julian Day number into *prNow and
        !          3602: ** return 0.  Return 1 if the time and date cannot be found.
        !          3603: */
        !          3604: static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
        !          3605:   int rc;
        !          3606:   sqlite3_int64 i;
        !          3607:   rc = winCurrentTimeInt64(pVfs, &i);
        !          3608:   if( !rc ){
        !          3609:     *prNow = i/86400000.0;
        !          3610:   }
        !          3611:   return rc;
        !          3612: }
        !          3613: 
        !          3614: /*
        !          3615: ** The idea is that this function works like a combination of
        !          3616: ** GetLastError() and FormatMessage() on Windows (or errno and
        !          3617: ** strerror_r() on Unix). After an error is returned by an OS
        !          3618: ** function, SQLite calls this function with zBuf pointing to
        !          3619: ** a buffer of nBuf bytes. The OS layer should populate the
        !          3620: ** buffer with a nul-terminated UTF-8 encoded error message
        !          3621: ** describing the last IO error to have occurred within the calling
        !          3622: ** thread.
        !          3623: **
        !          3624: ** If the error message is too large for the supplied buffer,
        !          3625: ** it should be truncated. The return value of xGetLastError
        !          3626: ** is zero if the error message fits in the buffer, or non-zero
        !          3627: ** otherwise (if the message was truncated). If non-zero is returned,
        !          3628: ** then it is not necessary to include the nul-terminator character
        !          3629: ** in the output buffer.
        !          3630: **
        !          3631: ** Not supplying an error message will have no adverse effect
        !          3632: ** on SQLite. It is fine to have an implementation that never
        !          3633: ** returns an error message:
        !          3634: **
        !          3635: **   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
        !          3636: **     assert(zBuf[0]=='\0');
        !          3637: **     return 0;
        !          3638: **   }
        !          3639: **
        !          3640: ** However if an error message is supplied, it will be incorporated
        !          3641: ** by sqlite into the error message available to the user using
        !          3642: ** sqlite3_errmsg(), possibly making IO errors easier to debug.
        !          3643: */
        !          3644: static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
        !          3645:   UNUSED_PARAMETER(pVfs);
        !          3646:   return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
        !          3647: }
        !          3648: 
        !          3649: /*
        !          3650: ** Initialize and deinitialize the operating system interface.
        !          3651: */
        !          3652: int sqlite3_os_init(void){
        !          3653:   static sqlite3_vfs winVfs = {
        !          3654:     3,                   /* iVersion */
        !          3655:     sizeof(winFile),     /* szOsFile */
        !          3656:     MAX_PATH,            /* mxPathname */
        !          3657:     0,                   /* pNext */
        !          3658:     "win32",             /* zName */
        !          3659:     0,                   /* pAppData */
        !          3660:     winOpen,             /* xOpen */
        !          3661:     winDelete,           /* xDelete */
        !          3662:     winAccess,           /* xAccess */
        !          3663:     winFullPathname,     /* xFullPathname */
        !          3664:     winDlOpen,           /* xDlOpen */
        !          3665:     winDlError,          /* xDlError */
        !          3666:     winDlSym,            /* xDlSym */
        !          3667:     winDlClose,          /* xDlClose */
        !          3668:     winRandomness,       /* xRandomness */
        !          3669:     winSleep,            /* xSleep */
        !          3670:     winCurrentTime,      /* xCurrentTime */
        !          3671:     winGetLastError,     /* xGetLastError */
        !          3672:     winCurrentTimeInt64, /* xCurrentTimeInt64 */
        !          3673:     winSetSystemCall,    /* xSetSystemCall */
        !          3674:     winGetSystemCall,    /* xGetSystemCall */
        !          3675:     winNextSystemCall,   /* xNextSystemCall */
        !          3676:   };
        !          3677: 
        !          3678:   /* Double-check that the aSyscall[] array has been constructed
        !          3679:   ** correctly.  See ticket [bb3a86e890c8e96ab] */
        !          3680:   assert( ArraySize(aSyscall)==60 );
        !          3681: 
        !          3682: #ifndef SQLITE_OMIT_WAL
        !          3683:   /* get memory map allocation granularity */
        !          3684:   memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
        !          3685:   osGetSystemInfo(&winSysInfo);
        !          3686:   assert(winSysInfo.dwAllocationGranularity > 0);
        !          3687: #endif
        !          3688: 
        !          3689:   sqlite3_vfs_register(&winVfs, 1);
        !          3690:   return SQLITE_OK; 
        !          3691: }
        !          3692: 
        !          3693: int sqlite3_os_end(void){ 
        !          3694:   return SQLITE_OK;
        !          3695: }
        !          3696: 
        !          3697: #endif /* SQLITE_OS_WIN */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>