File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / src / os_win.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:17 2012 UTC (12 years, 8 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    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>