/ Check-in [c1fab9ac]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge the windows xSyscall enhancements into trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c1fab9aca1fe1dda2b4c7e4fdc0a406998847bdb
User & Date: drh 2011-11-12 15:41:52
Context
2011-11-12
16:46
Remove a couple of incorrect assert statements so that the test suite will run with -DSQLITE_DEFAULT_CACHE_SIZE=0. check-in: 87614b62 user: drh tags: trunk
15:41
Merge the windows xSyscall enhancements into trunk. check-in: c1fab9ac user: drh tags: trunk
03:17
Make sure to flag benign malloc failures in the Windows VFS as such. Expand use of the DO_OS_MALLOC_TEST to cover the VFS functions that can now return an out of memory error. Support an experimental --match option to the test suite that will run only those tests matching the specified pattern. Closed-Leaf check-in: 76dec8aa user: mistachkin tags: winSyscall
2011-11-11
23:51
Catch and report errors from sqlite3OsFullPathname(). check-in: 77119785 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os.c.

    23     23   ** from within OsOpen()), but some third-party implementations may.
    24     24   ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
    25     25   ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
    26     26   **
    27     27   ** The following functions are instrumented for malloc() failure 
    28     28   ** testing:
    29     29   **
    30         -**     sqlite3OsOpen()
    31     30   **     sqlite3OsRead()
    32     31   **     sqlite3OsWrite()
    33     32   **     sqlite3OsSync()
           33  +**     sqlite3OsFileSize()
    34     34   **     sqlite3OsLock()
           35  +**     sqlite3OsCheckReservedLock()
           36  +**     sqlite3OsFileControl()
           37  +**     sqlite3OsShmMap()
           38  +**     sqlite3OsOpen()
           39  +**     sqlite3OsDelete()
           40  +**     sqlite3OsAccess()
           41  +**     sqlite3OsFullPathname()
    35     42   **
    36     43   */
    37     44   #if defined(SQLITE_TEST)
    38     45   int sqlite3_memdebug_vfs_oom_test = 1;
    39     46     #define DO_OS_MALLOC_TEST(x)                                       \
    40     47     if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
    41     48       void *pTstAlloc = sqlite3Malloc(10);                             \
................................................................................
    87     94     return id->pMethods->xUnlock(id, lockType);
    88     95   }
    89     96   int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
    90     97     DO_OS_MALLOC_TEST(id);
    91     98     return id->pMethods->xCheckReservedLock(id, pResOut);
    92     99   }
    93    100   int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
          101  +  DO_OS_MALLOC_TEST(id);
    94    102     return id->pMethods->xFileControl(id, op, pArg);
    95    103   }
    96    104   int sqlite3OsSectorSize(sqlite3_file *id){
    97    105     int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
    98    106     return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
    99    107   }
   100    108   int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
................................................................................
   112    120   int sqlite3OsShmMap(
   113    121     sqlite3_file *id,               /* Database file handle */
   114    122     int iPage,
   115    123     int pgsz,
   116    124     int bExtend,                    /* True to extend file if necessary */
   117    125     void volatile **pp              /* OUT: Pointer to mapping */
   118    126   ){
          127  +  DO_OS_MALLOC_TEST(id);
   119    128     return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
   120    129   }
   121    130   
   122    131   /*
   123    132   ** The next group of routines are convenience wrappers around the
   124    133   ** VFS methods.
   125    134   */
................................................................................
   137    146     ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
   138    147     ** reaching the VFS. */
   139    148     rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
   140    149     assert( rc==SQLITE_OK || pFile->pMethods==0 );
   141    150     return rc;
   142    151   }
   143    152   int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
          153  +  DO_OS_MALLOC_TEST(0);
   144    154     return pVfs->xDelete(pVfs, zPath, dirSync);
   145    155   }
   146    156   int sqlite3OsAccess(
   147    157     sqlite3_vfs *pVfs, 
   148    158     const char *zPath, 
   149    159     int flags, 
   150    160     int *pResOut
................................................................................
   154    164   }
   155    165   int sqlite3OsFullPathname(
   156    166     sqlite3_vfs *pVfs, 
   157    167     const char *zPath, 
   158    168     int nPathOut, 
   159    169     char *zPathOut
   160    170   ){
          171  +  DO_OS_MALLOC_TEST(0);
   161    172     zPathOut[0] = 0;
   162    173     return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
   163    174   }
   164    175   #ifndef SQLITE_OMIT_LOAD_EXTENSION
   165    176   void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   166    177     return pVfs->xDlOpen(pVfs, zPath);
   167    178   }

Changes to src/os_win.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   ******************************************************************************
    12     12   **
    13         -** This file contains code that is specific to windows.
           13  +** This file contains code that is specific to Windows.
    14     14   */
    15     15   #include "sqliteInt.h"
    16         -#if SQLITE_OS_WIN               /* This file is used for windows only */
    17         -
    18         -
    19         -/*
    20         -** A Note About Memory Allocation:
    21         -**
    22         -** This driver uses malloc()/free() directly rather than going through
    23         -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
    24         -** are designed for use on embedded systems where memory is scarce and
    25         -** malloc failures happen frequently.  Win32 does not typically run on
    26         -** embedded systems, and when it does the developers normally have bigger
    27         -** problems to worry about than running out of memory.  So there is not
    28         -** a compelling need to use the wrappers.
    29         -**
    30         -** But there is a good reason to not use the wrappers.  If we use the
    31         -** wrappers then we will get simulated malloc() failures within this
    32         -** driver.  And that causes all kinds of problems for our tests.  We
    33         -** could enhance SQLite to deal with simulated malloc failures within
    34         -** the OS driver, but the code to deal with those failure would not
    35         -** be exercised on Linux (which does not need to malloc() in the driver)
    36         -** and so we would have difficulty writing coverage tests for that
    37         -** code.  Better to leave the code out, we think.
    38         -**
    39         -** The point of this discussion is as follows:  When creating a new
    40         -** OS layer for an embedded system, if you use this file as an example,
    41         -** avoid the use of malloc()/free().  Those routines work ok on windows
    42         -** desktops but not so well in embedded systems.
    43         -*/
    44         -
    45         -#include <winbase.h>
           16  +#if SQLITE_OS_WIN               /* This file is used for Windows only */
    46     17   
    47     18   #ifdef __CYGWIN__
    48     19   # include <sys/cygwin.h>
    49     20   #endif
    50     21   
    51     22   /*
    52     23   ** Include code that is common to all os_*.c files
    53     24   */
    54     25   #include "os_common.h"
    55     26   
    56     27   /*
    57         -** Some microsoft compilers lack this definition.
           28  +** Some Microsoft compilers lack this definition.
    58     29   */
    59     30   #ifndef INVALID_FILE_ATTRIBUTES
    60     31   # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 
    61     32   #endif
    62     33   
    63         -/*
    64         -** Determine if we are dealing with WindowsCE - which has a much
    65         -** reduced API.
    66         -*/
    67         -#if SQLITE_OS_WINCE
    68         -# define AreFileApisANSI() 1
    69         -# define FormatMessageW(a,b,c,d,e,f,g) 0
    70         -#endif
    71         -
    72     34   /* Forward references */
    73     35   typedef struct winShm winShm;           /* A connection to shared-memory */
    74     36   typedef struct winShmNode winShmNode;   /* A region of shared-memory */
    75     37   
    76     38   /*
    77     39   ** WinCE lacks native support for file locking so we have to fake it
    78     40   ** with some code of our own.
................................................................................
   100     62     u8 bPersistWal;         /* True to persist WAL files */
   101     63     DWORD lastErrno;        /* The Windows errno from the last I/O error */
   102     64     DWORD sectorSize;       /* Sector size of the device file is on */
   103     65     winShm *pShm;           /* Instance of shared memory on this file */
   104     66     const char *zPath;      /* Full pathname of this file */
   105     67     int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
   106     68   #if SQLITE_OS_WINCE
   107         -  WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
           69  +  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
   108     70     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   109     71     HANDLE hShared;         /* Shared memory segment used for locking */
   110     72     winceLock local;        /* Locks obtained by this instance of winFile */
   111     73     winceLock *shared;      /* Global shared lock memory for the file  */
   112     74   #endif
   113     75   };
   114     76   
................................................................................
   189    151   static int getSectorSize(
   190    152       sqlite3_vfs *pVfs,
   191    153       const char *zRelative     /* UTF-8 file name */
   192    154   );
   193    155   
   194    156   /*
   195    157   ** The following variable is (normally) set once and never changes
   196         -** thereafter.  It records whether the operating system is Win95
          158  +** thereafter.  It records whether the operating system is Win9x
   197    159   ** or WinNT.
   198    160   **
   199    161   ** 0:   Operating system unknown.
   200         -** 1:   Operating system is Win95.
          162  +** 1:   Operating system is Win9x.
   201    163   ** 2:   Operating system is WinNT.
   202    164   **
   203    165   ** In order to facilitate testing on a WinNT system, the test fixture
   204    166   ** can manually set this value to 1 to emulate Win98 behavior.
   205    167   */
   206    168   #ifdef SQLITE_TEST
   207    169   int sqlite3_os_type = 0;
   208    170   #else
   209    171   static int sqlite3_os_type = 0;
   210    172   #endif
          173  +
          174  +/*
          175  +** Many system calls are accessed through pointer-to-functions so that
          176  +** they may be overridden at runtime to facilitate fault injection during
          177  +** testing and sandboxing.  The following array holds the names and pointers
          178  +** to all overrideable system calls.
          179  +*/
          180  +#if !SQLITE_OS_WINCE
          181  +#  define SQLITE_WIN32_HAS_ANSI
          182  +#endif
          183  +
          184  +#if SQLITE_OS_WINCE || defined(_WIN32_WINNT)
          185  +#  define SQLITE_WIN32_HAS_WIDE
          186  +#endif
          187  +
          188  +#ifndef SYSCALL
          189  +#  define SYSCALL sqlite3_syscall_ptr
          190  +#endif
          191  +
          192  +#if SQLITE_OS_WINCE
          193  +/*
          194  +** These macros are necessary because Windows CE does not natively support the
          195  +** Win32 APIs LockFile, UnlockFile, and LockFileEx.
          196  + */
          197  +
          198  +#  define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
          199  +#  define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
          200  +#  define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
          201  +
          202  +/*
          203  +** These are the special syscall hacks for Windows CE.  The locking related
          204  +** defines here refer to the macros defined just above.
          205  + */
          206  +
          207  +#  define osAreFileApisANSI()       1
          208  +#  define osLockFile                LockFile
          209  +#  define osUnlockFile              UnlockFile
          210  +#  define osLockFileEx              LockFileEx
          211  +#endif
          212  +
          213  +static struct win_syscall {
          214  +  const char *zName;            /* Name of the sytem call */
          215  +  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
          216  +  sqlite3_syscall_ptr pDefault; /* Default value */
          217  +} aSyscall[] = {
          218  +#if !SQLITE_OS_WINCE
          219  +  { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
          220  +
          221  +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
          222  +#else
          223  +  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
          224  +#endif
          225  +
          226  +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
          227  +  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
          228  +#else
          229  +  { "CharLowerW",              (SYSCALL)0,                       0 },
          230  +#endif
          231  +
          232  +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
          233  +
          234  +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
          235  +  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
          236  +#else
          237  +  { "CharUpperW",              (SYSCALL)0,                       0 },
          238  +#endif
          239  +
          240  +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
          241  +
          242  +  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
          243  +
          244  +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
          245  +
          246  +#if defined(SQLITE_WIN32_HAS_ANSI)
          247  +  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
          248  +#else
          249  +  { "CreateFileA",             (SYSCALL)0,                       0 },
          250  +#endif
          251  +
          252  +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
          253  +        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
          254  +
          255  +#if defined(SQLITE_WIN32_HAS_WIDE)
          256  +  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
          257  +#else
          258  +  { "CreateFileW",             (SYSCALL)0,                       0 },
          259  +#endif
          260  +
          261  +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
          262  +        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
          263  +
          264  +  { "CreateFileMapping",       (SYSCALL)CreateFileMapping,       0 },
          265  +
          266  +#define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
          267  +        DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent)
          268  +
          269  +#if defined(SQLITE_WIN32_HAS_WIDE)
          270  +  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
          271  +#else
          272  +  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
          273  +#endif
          274  +
          275  +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
          276  +        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
          277  +
          278  +#if defined(SQLITE_WIN32_HAS_WIDE)
          279  +  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
          280  +#else
          281  +  { "CreateMutexW",            (SYSCALL)0,                       0 },
          282  +#endif
          283  +
          284  +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
          285  +        LPCWSTR))aSyscall[8].pCurrent)
          286  +
          287  +#if defined(SQLITE_WIN32_HAS_ANSI)
          288  +  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
          289  +#else
          290  +  { "DeleteFileA",             (SYSCALL)0,                       0 },
          291  +#endif
          292  +
          293  +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
          294  +
          295  +#if defined(SQLITE_WIN32_HAS_WIDE)
          296  +  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
          297  +#else
          298  +  { "DeleteFileW",             (SYSCALL)0,                       0 },
          299  +#endif
          300  +
          301  +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
          302  +
          303  +#if SQLITE_OS_WINCE
          304  +  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
          305  +#else
          306  +  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
          307  +#endif
          308  +
          309  +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
          310  +        LPFILETIME))aSyscall[11].pCurrent)
          311  +
          312  +#if SQLITE_OS_WINCE
          313  +  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
          314  +#else
          315  +  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
          316  +#endif
          317  +
          318  +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
          319  +        LPSYSTEMTIME))aSyscall[12].pCurrent)
          320  +
          321  +  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
          322  +
          323  +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
          324  +
          325  +#if defined(SQLITE_WIN32_HAS_ANSI)
          326  +  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
          327  +#else
          328  +  { "FormatMessageA",          (SYSCALL)0,                       0 },
          329  +#endif
          330  +
          331  +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
          332  +        DWORD,va_list*))aSyscall[14].pCurrent)
          333  +
          334  +#if defined(SQLITE_WIN32_HAS_WIDE)
          335  +  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
          336  +#else
          337  +  { "FormatMessageW",          (SYSCALL)0,                       0 },
          338  +#endif
          339  +
          340  +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
          341  +        DWORD,va_list*))aSyscall[15].pCurrent)
          342  +
          343  +  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
          344  +
          345  +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
          346  +
          347  +  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
          348  +
          349  +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
          350  +
          351  +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
          352  +  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
          353  +#else
          354  +  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
          355  +#endif
          356  +
          357  +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
          358  +        LPDWORD))aSyscall[18].pCurrent)
          359  +
          360  +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
          361  +  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
          362  +#else
          363  +  { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
          364  +#endif
          365  +
          366  +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
          367  +        LPDWORD))aSyscall[19].pCurrent)
          368  +
          369  +#if defined(SQLITE_WIN32_HAS_ANSI)
          370  +  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
          371  +#else
          372  +  { "GetFileAttributesA",      (SYSCALL)0,                       0 },
          373  +#endif
          374  +
          375  +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
          376  +
          377  +#if defined(SQLITE_WIN32_HAS_WIDE)
          378  +  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
          379  +#else
          380  +  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
          381  +#endif
          382  +
          383  +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
          384  +
          385  +#if defined(SQLITE_WIN32_HAS_WIDE)
          386  +  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
          387  +#else
          388  +  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
          389  +#endif
          390  +
          391  +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
          392  +        LPVOID))aSyscall[22].pCurrent)
          393  +
          394  +  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
          395  +
          396  +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
          397  +
          398  +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
          399  +  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
          400  +#else
          401  +  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
          402  +#endif
          403  +
          404  +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
          405  +        LPSTR*))aSyscall[24].pCurrent)
          406  +
          407  +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
          408  +  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
          409  +#else
          410  +  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
          411  +#endif
          412  +
          413  +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
          414  +        LPWSTR*))aSyscall[25].pCurrent)
          415  +
          416  +  { "GetLastError",            (SYSCALL)GetLastError,            0 },
          417  +
          418  +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
          419  +
          420  +#if SQLITE_OS_WINCE
          421  +  /* The GetProcAddressA() routine is only available on Windows CE. */
          422  +  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
          423  +#else
          424  +  /* All other Windows platforms expect GetProcAddress() to take
          425  +  ** an ANSI string regardless of the _UNICODE setting */
          426  +  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
          427  +#endif
          428  +
          429  +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
          430  +        LPCSTR))aSyscall[27].pCurrent)
          431  +
          432  +  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
          433  +
          434  +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
          435  +
          436  +  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
          437  +
          438  +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
          439  +
          440  +#if !SQLITE_OS_WINCE
          441  +  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
          442  +#else
          443  +  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
          444  +#endif
          445  +
          446  +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
          447  +        LPFILETIME))aSyscall[30].pCurrent)
          448  +
          449  +#if defined(SQLITE_WIN32_HAS_ANSI)
          450  +  { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
          451  +#else
          452  +  { "GetTempPathA",            (SYSCALL)0,                       0 },
          453  +#endif
          454  +
          455  +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
          456  +
          457  +#if defined(SQLITE_WIN32_HAS_WIDE)
          458  +  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
          459  +#else
          460  +  { "GetTempPathW",            (SYSCALL)0,                       0 },
          461  +#endif
          462  +
          463  +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
          464  +
          465  +  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
          466  +
          467  +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
          468  +
          469  +#if defined(SQLITE_WIN32_HAS_ANSI)
          470  +  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
          471  +#else
          472  +  { "GetVersionExA",           (SYSCALL)0,                       0 },
          473  +#endif
          474  +
          475  +#define osGetVersionExA ((BOOL(WINAPI*)( \
          476  +        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
          477  +
          478  +  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
          479  +
          480  +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
          481  +        SIZE_T))aSyscall[35].pCurrent)
          482  +
          483  +  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
          484  +
          485  +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
          486  +        SIZE_T))aSyscall[36].pCurrent)
          487  +
          488  +  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
          489  +
          490  +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
          491  +
          492  +  { "HeapFree",                (SYSCALL)HeapFree,                0 },
          493  +
          494  +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
          495  +
          496  +  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
          497  +
          498  +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
          499  +        SIZE_T))aSyscall[39].pCurrent)
          500  +
          501  +  { "HeapSize",                (SYSCALL)HeapSize,                0 },
          502  +
          503  +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
          504  +        LPCVOID))aSyscall[40].pCurrent)
          505  +
          506  +  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
          507  +
          508  +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
          509  +        LPCVOID))aSyscall[41].pCurrent)
          510  +
          511  +#if defined(SQLITE_WIN32_HAS_ANSI)
          512  +  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
          513  +#else
          514  +  { "LoadLibraryA",            (SYSCALL)0,                       0 },
          515  +#endif
          516  +
          517  +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
          518  +
          519  +#if defined(SQLITE_WIN32_HAS_WIDE)
          520  +  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
          521  +#else
          522  +  { "LoadLibraryW",            (SYSCALL)0,                       0 },
          523  +#endif
          524  +
          525  +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
          526  +
          527  +  { "LocalFree",               (SYSCALL)LocalFree,               0 },
          528  +
          529  +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
          530  +
          531  +#if !SQLITE_OS_WINCE
          532  +  { "LockFile",                (SYSCALL)LockFile,                0 },
          533  +
          534  +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
          535  +        DWORD))aSyscall[45].pCurrent)
          536  +#else
          537  +  { "LockFile",                (SYSCALL)0,                       0 },
          538  +#endif
          539  +
          540  +#if !SQLITE_OS_WINCE
          541  +  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
          542  +
          543  +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
          544  +        LPOVERLAPPED))aSyscall[46].pCurrent)
          545  +#else
          546  +  { "LockFileEx",              (SYSCALL)0,                       0 },
          547  +#endif
          548  +
          549  +  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
          550  +
          551  +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
          552  +        SIZE_T))aSyscall[47].pCurrent)
          553  +
          554  +  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
          555  +
          556  +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
          557  +        int))aSyscall[48].pCurrent)
          558  +
          559  +  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
          560  +
          561  +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
          562  +        LARGE_INTEGER*))aSyscall[49].pCurrent)
          563  +
          564  +  { "ReadFile",                (SYSCALL)ReadFile,                0 },
          565  +
          566  +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
          567  +        LPOVERLAPPED))aSyscall[50].pCurrent)
          568  +
          569  +  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
          570  +
          571  +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
          572  +
          573  +  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
          574  +
          575  +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
          576  +        DWORD))aSyscall[52].pCurrent)
          577  +
          578  +  { "Sleep",                   (SYSCALL)Sleep,                   0 },
          579  +
          580  +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
          581  +
          582  +  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
          583  +
          584  +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
          585  +        LPFILETIME))aSyscall[54].pCurrent)
          586  +
          587  +#if !SQLITE_OS_WINCE
          588  +  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
          589  +
          590  +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
          591  +        DWORD))aSyscall[55].pCurrent)
          592  +#else
          593  +  { "UnlockFile",              (SYSCALL)0,                       0 },
          594  +#endif
          595  +
          596  +#if !SQLITE_OS_WINCE
          597  +  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
          598  +
          599  +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
          600  +        LPOVERLAPPED))aSyscall[56].pCurrent)
          601  +#else
          602  +  { "UnlockFileEx",            (SYSCALL)0,                       0 },
          603  +#endif
          604  +
          605  +  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
          606  +
          607  +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
          608  +
          609  +  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
          610  +
          611  +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
          612  +        LPCSTR,LPBOOL))aSyscall[58].pCurrent)
          613  +
          614  +  { "WriteFile",               (SYSCALL)WriteFile,               0 },
          615  +
          616  +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
          617  +        LPOVERLAPPED))aSyscall[59].pCurrent)
          618  +
          619  +}; /* End of the overrideable system calls */
          620  +
          621  +/*
          622  +** This is the xSetSystemCall() method of sqlite3_vfs for all of the
          623  +** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
          624  +** system call pointer, or SQLITE_NOTFOUND if there is no configurable
          625  +** system call named zName.
          626  +*/
          627  +static int winSetSystemCall(
          628  +  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
          629  +  const char *zName,            /* Name of system call to override */
          630  +  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
          631  +){
          632  +  unsigned int i;
          633  +  int rc = SQLITE_NOTFOUND;
          634  +
          635  +  UNUSED_PARAMETER(pNotUsed);
          636  +  if( zName==0 ){
          637  +    /* If no zName is given, restore all system calls to their default
          638  +    ** settings and return NULL
          639  +    */
          640  +    rc = SQLITE_OK;
          641  +    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          642  +      if( aSyscall[i].pDefault ){
          643  +        aSyscall[i].pCurrent = aSyscall[i].pDefault;
          644  +      }
          645  +    }
          646  +  }else{
          647  +    /* If zName is specified, operate on only the one system call
          648  +    ** specified.
          649  +    */
          650  +    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          651  +      if( strcmp(zName, aSyscall[i].zName)==0 ){
          652  +        if( aSyscall[i].pDefault==0 ){
          653  +          aSyscall[i].pDefault = aSyscall[i].pCurrent;
          654  +        }
          655  +        rc = SQLITE_OK;
          656  +        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
          657  +        aSyscall[i].pCurrent = pNewFunc;
          658  +        break;
          659  +      }
          660  +    }
          661  +  }
          662  +  return rc;
          663  +}
          664  +
          665  +/*
          666  +** Return the value of a system call.  Return NULL if zName is not a
          667  +** recognized system call name.  NULL is also returned if the system call
          668  +** is currently undefined.
          669  +*/
          670  +static sqlite3_syscall_ptr winGetSystemCall(
          671  +  sqlite3_vfs *pNotUsed,
          672  +  const char *zName
          673  +){
          674  +  unsigned int i;
          675  +
          676  +  UNUSED_PARAMETER(pNotUsed);
          677  +  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          678  +    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
          679  +  }
          680  +  return 0;
          681  +}
          682  +
          683  +/*
          684  +** Return the name of the first system call after zName.  If zName==NULL
          685  +** then return the name of the first system call.  Return NULL if zName
          686  +** is the last system call or if zName is not the name of a valid
          687  +** system call.
          688  +*/
          689  +static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
          690  +  int i = -1;
          691  +
          692  +  UNUSED_PARAMETER(p);
          693  +  if( zName ){
          694  +    for(i=0; i<ArraySize(aSyscall)-1; i++){
          695  +      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
          696  +    }
          697  +  }
          698  +  for(i++; i<ArraySize(aSyscall); i++){
          699  +    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
          700  +  }
          701  +  return 0;
          702  +}
   211    703   
   212    704   /*
   213    705   ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
   214    706   ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
   215    707   **
   216    708   ** Here is an interesting observation:  Win95, Win98, and WinME lack
   217    709   ** the LockFileEx() API.  But we can still statically link against that
................................................................................
   221    713   ** the LockFileEx() API.
   222    714   */
   223    715   #if SQLITE_OS_WINCE
   224    716   # define isNT()  (1)
   225    717   #else
   226    718     static int isNT(void){
   227    719       if( sqlite3_os_type==0 ){
   228         -      OSVERSIONINFO sInfo;
          720  +      OSVERSIONINFOA sInfo;
   229    721         sInfo.dwOSVersionInfoSize = sizeof(sInfo);
   230         -      GetVersionEx(&sInfo);
          722  +      osGetVersionExA(&sInfo);
   231    723         sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
   232    724       }
   233    725       return sqlite3_os_type==2;
   234    726     }
   235    727   #endif /* SQLITE_OS_WINCE */
   236    728   
   237    729   #ifdef SQLITE_WIN32_MALLOC
................................................................................
   243    735     void *p;
   244    736   
   245    737     winMemAssertMagic();
   246    738     hHeap = winMemGetHeap();
   247    739     assert( hHeap!=0 );
   248    740     assert( hHeap!=INVALID_HANDLE_VALUE );
   249    741   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   250         -  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          742  +  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
   251    743   #endif
   252    744     assert( nBytes>=0 );
   253         -  p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
          745  +  p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
   254    746     if( !p ){
   255    747       sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
   256         -        nBytes, GetLastError(), (void*)hHeap);
          748  +                nBytes, osGetLastError(), (void*)hHeap);
   257    749     }
   258    750     return p;
   259    751   }
   260    752   
   261    753   /*
   262    754   ** Free memory.
   263    755   */
................................................................................
   265    757     HANDLE hHeap;
   266    758   
   267    759     winMemAssertMagic();
   268    760     hHeap = winMemGetHeap();
   269    761     assert( hHeap!=0 );
   270    762     assert( hHeap!=INVALID_HANDLE_VALUE );
   271    763   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   272         -  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
          764  +  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
   273    765   #endif
   274    766     if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
   275         -  if( !HeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
          767  +  if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
   276    768       sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
   277         -        pPrior, GetLastError(), (void*)hHeap);
          769  +                pPrior, osGetLastError(), (void*)hHeap);
   278    770     }
   279    771   }
   280    772   
   281    773   /*
   282    774   ** Change the size of an existing memory allocation
   283    775   */
   284    776   static void *winMemRealloc(void *pPrior, int nBytes){
................................................................................
   286    778     void *p;
   287    779   
   288    780     winMemAssertMagic();
   289    781     hHeap = winMemGetHeap();
   290    782     assert( hHeap!=0 );
   291    783     assert( hHeap!=INVALID_HANDLE_VALUE );
   292    784   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   293         -  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
          785  +  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
   294    786   #endif
   295    787     assert( nBytes>=0 );
   296    788     if( !pPrior ){
   297         -    p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
          789  +    p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
   298    790     }else{
   299         -    p = HeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
          791  +    p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
   300    792     }
   301    793     if( !p ){
   302    794       sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
   303         -        pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(),
   304         -        (void*)hHeap);
          795  +                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
          796  +                (void*)hHeap);
   305    797     }
   306    798     return p;
   307    799   }
   308    800   
   309    801   /*
   310    802   ** Return the size of an outstanding allocation, in bytes.
   311    803   */
................................................................................
   314    806     SIZE_T n;
   315    807   
   316    808     winMemAssertMagic();
   317    809     hHeap = winMemGetHeap();
   318    810     assert( hHeap!=0 );
   319    811     assert( hHeap!=INVALID_HANDLE_VALUE );
   320    812   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   321         -  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          813  +  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
   322    814   #endif
   323    815     if( !p ) return 0;
   324         -  n = HeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
          816  +  n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
   325    817     if( n==(SIZE_T)-1 ){
   326    818       sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
   327         -        p, GetLastError(), (void*)hHeap);
          819  +                p, osGetLastError(), (void*)hHeap);
   328    820       return 0;
   329    821     }
   330    822     return (int)n;
   331    823   }
   332    824   
   333    825   /*
   334    826   ** Round up a request size to the next valid allocation size.
................................................................................
   342    834   */
   343    835   static int winMemInit(void *pAppData){
   344    836     winMemData *pWinMemData = (winMemData *)pAppData;
   345    837   
   346    838     if( !pWinMemData ) return SQLITE_ERROR;
   347    839     assert( pWinMemData->magic==WINMEM_MAGIC );
   348    840     if( !pWinMemData->hHeap ){
   349         -    pWinMemData->hHeap = HeapCreate(SQLITE_WIN32_HEAP_FLAGS,
   350         -                                    SQLITE_WIN32_HEAP_INIT_SIZE,
   351         -                                    SQLITE_WIN32_HEAP_MAX_SIZE);
          841  +    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
          842  +                                      SQLITE_WIN32_HEAP_INIT_SIZE,
          843  +                                      SQLITE_WIN32_HEAP_MAX_SIZE);
   352    844       if( !pWinMemData->hHeap ){
   353    845         sqlite3_log(SQLITE_NOMEM,
   354    846             "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
   355         -          GetLastError(), SQLITE_WIN32_HEAP_FLAGS, SQLITE_WIN32_HEAP_INIT_SIZE,
   356         -          SQLITE_WIN32_HEAP_MAX_SIZE);
          847  +          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
          848  +          SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
   357    849         return SQLITE_NOMEM;
   358    850       }
   359    851       pWinMemData->bOwned = TRUE;
   360    852     }
   361    853     assert( pWinMemData->hHeap!=0 );
   362    854     assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
   363    855   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   364         -  assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          856  +  assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
   365    857   #endif
   366    858     return SQLITE_OK;
   367    859   }
   368    860   
   369    861   /*
   370    862   ** Deinitialize this module.
   371    863   */
................................................................................
   372    864   static void winMemShutdown(void *pAppData){
   373    865     winMemData *pWinMemData = (winMemData *)pAppData;
   374    866   
   375    867     if( !pWinMemData ) return;
   376    868     if( pWinMemData->hHeap ){
   377    869       assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
   378    870   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   379         -    assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          871  +    assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
   380    872   #endif
   381    873       if( pWinMemData->bOwned ){
   382         -      if( !HeapDestroy(pWinMemData->hHeap) ){
          874  +      if( !osHeapDestroy(pWinMemData->hHeap) ){
   383    875           sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
   384         -            GetLastError(), (void*)pWinMemData->hHeap);
          876  +                    osGetLastError(), (void*)pWinMemData->hHeap);
   385    877         }
   386    878         pWinMemData->bOwned = FALSE;
   387    879       }
   388    880       pWinMemData->hHeap = NULL;
   389    881     }
   390    882   }
   391    883   
................................................................................
   413    905   
   414    906   void sqlite3MemSetDefault(void){
   415    907     sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
   416    908   }
   417    909   #endif /* SQLITE_WIN32_MALLOC */
   418    910   
   419    911   /*
   420         -** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
          912  +** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
   421    913   **
   422    914   ** Space to hold the returned string is obtained from malloc.
   423    915   */
   424         -static WCHAR *utf8ToUnicode(const char *zFilename){
          916  +static LPWSTR utf8ToUnicode(const char *zFilename){
   425    917     int nChar;
   426         -  WCHAR *zWideFilename;
          918  +  LPWSTR zWideFilename;
   427    919   
   428         -  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
   429         -  zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
          920  +  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
          921  +  zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
   430    922     if( zWideFilename==0 ){
   431    923       return 0;
   432    924     }
   433         -  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
          925  +  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
          926  +                                nChar);
   434    927     if( nChar==0 ){
   435         -    free(zWideFilename);
          928  +    sqlite3_free(zWideFilename);
   436    929       zWideFilename = 0;
   437    930     }
   438    931     return zWideFilename;
   439    932   }
   440    933   
   441    934   /*
   442         -** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
   443         -** obtained from malloc().
          935  +** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
          936  +** obtained from sqlite3_malloc().
   444    937   */
   445         -static char *unicodeToUtf8(const WCHAR *zWideFilename){
          938  +static char *unicodeToUtf8(LPCWSTR zWideFilename){
   446    939     int nByte;
   447    940     char *zFilename;
   448    941   
   449         -  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
   450         -  zFilename = malloc( nByte );
          942  +  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
          943  +  zFilename = sqlite3_malloc( nByte );
   451    944     if( zFilename==0 ){
   452    945       return 0;
   453    946     }
   454         -  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
   455         -                              0, 0);
          947  +  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
          948  +                                0, 0);
   456    949     if( nByte == 0 ){
   457         -    free(zFilename);
          950  +    sqlite3_free(zFilename);
   458    951       zFilename = 0;
   459    952     }
   460    953     return zFilename;
   461    954   }
   462    955   
   463    956   /*
   464         -** Convert an ansi string to microsoft unicode, based on the
          957  +** Convert an ANSI string to Microsoft Unicode, based on the
   465    958   ** current codepage settings for file apis.
   466    959   ** 
   467    960   ** Space to hold the returned string is obtained
   468         -** from malloc.
          961  +** from sqlite3_malloc.
   469    962   */
   470         -static WCHAR *mbcsToUnicode(const char *zFilename){
          963  +static LPWSTR mbcsToUnicode(const char *zFilename){
   471    964     int nByte;
   472         -  WCHAR *zMbcsFilename;
   473         -  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
          965  +  LPWSTR zMbcsFilename;
          966  +  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
   474    967   
   475         -  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
   476         -  zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
          968  +  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
          969  +                                0)*sizeof(WCHAR);
          970  +  zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
   477    971     if( zMbcsFilename==0 ){
   478    972       return 0;
   479    973     }
   480         -  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
          974  +  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
          975  +                                nByte);
   481    976     if( nByte==0 ){
   482         -    free(zMbcsFilename);
          977  +    sqlite3_free(zMbcsFilename);
   483    978       zMbcsFilename = 0;
   484    979     }
   485    980     return zMbcsFilename;
   486    981   }
   487    982   
   488    983   /*
   489         -** Convert microsoft unicode to multibyte character string, based on the
   490         -** user's Ansi codepage.
          984  +** Convert Microsoft Unicode to multi-byte character string, based on the
          985  +** user's ANSI codepage.
   491    986   **
   492    987   ** Space to hold the returned string is obtained from
   493         -** malloc().
          988  +** sqlite3_malloc().
   494    989   */
   495         -static char *unicodeToMbcs(const WCHAR *zWideFilename){
          990  +static char *unicodeToMbcs(LPCWSTR zWideFilename){
   496    991     int nByte;
   497    992     char *zFilename;
   498         -  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
          993  +  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
   499    994   
   500         -  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
   501         -  zFilename = malloc( nByte );
          995  +  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
          996  +  zFilename = sqlite3_malloc( nByte );
   502    997     if( zFilename==0 ){
   503    998       return 0;
   504    999     }
   505         -  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
   506         -                              0, 0);
         1000  +  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
         1001  +                                nByte, 0, 0);
   507   1002     if( nByte == 0 ){
   508         -    free(zFilename);
         1003  +    sqlite3_free(zFilename);
   509   1004       zFilename = 0;
   510   1005     }
   511   1006     return zFilename;
   512   1007   }
   513   1008   
   514   1009   /*
   515   1010   ** Convert multibyte character string to UTF-8.  Space to hold the
   516         -** returned string is obtained from malloc().
         1011  +** returned string is obtained from sqlite3_malloc().
   517   1012   */
   518   1013   char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
   519   1014     char *zFilenameUtf8;
   520         -  WCHAR *zTmpWide;
         1015  +  LPWSTR zTmpWide;
   521   1016   
   522   1017     zTmpWide = mbcsToUnicode(zFilename);
   523   1018     if( zTmpWide==0 ){
   524   1019       return 0;
   525   1020     }
   526   1021     zFilenameUtf8 = unicodeToUtf8(zTmpWide);
   527         -  free(zTmpWide);
         1022  +  sqlite3_free(zTmpWide);
   528   1023     return zFilenameUtf8;
   529   1024   }
   530   1025   
   531   1026   /*
   532   1027   ** Convert UTF-8 to multibyte character string.  Space to hold the 
   533         -** returned string is obtained from malloc().
         1028  +** returned string is obtained from sqlite3_malloc().
   534   1029   */
   535   1030   char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
   536   1031     char *zFilenameMbcs;
   537         -  WCHAR *zTmpWide;
         1032  +  LPWSTR zTmpWide;
   538   1033   
   539   1034     zTmpWide = utf8ToUnicode(zFilename);
   540   1035     if( zTmpWide==0 ){
   541   1036       return 0;
   542   1037     }
   543   1038     zFilenameMbcs = unicodeToMbcs(zTmpWide);
   544         -  free(zTmpWide);
         1039  +  sqlite3_free(zTmpWide);
   545   1040     return zFilenameMbcs;
   546   1041   }
   547   1042   
   548   1043   
   549   1044   /*
   550   1045   ** The return value of getLastErrorMsg
   551   1046   ** is zero if the error message fits in the buffer, or non-zero
................................................................................
   556   1051     ** returns the number of TCHARs written to the output
   557   1052     ** buffer, excluding the terminating null char.
   558   1053     */
   559   1054     DWORD dwLen = 0;
   560   1055     char *zOut = 0;
   561   1056   
   562   1057     if( isNT() ){
   563         -    WCHAR *zTempWide = NULL;
   564         -    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
   565         -                           FORMAT_MESSAGE_FROM_SYSTEM |
   566         -                           FORMAT_MESSAGE_IGNORE_INSERTS,
   567         -                           NULL,
   568         -                           lastErrno,
   569         -                           0,
   570         -                           (LPWSTR) &zTempWide,
   571         -                           0,
   572         -                           0);
         1058  +    LPWSTR zTempWide = NULL;
         1059  +    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
         1060  +                             FORMAT_MESSAGE_FROM_SYSTEM |
         1061  +                             FORMAT_MESSAGE_IGNORE_INSERTS,
         1062  +                             NULL,
         1063  +                             lastErrno,
         1064  +                             0,
         1065  +                             (LPWSTR) &zTempWide,
         1066  +                             0,
         1067  +                             0);
   573   1068       if( dwLen > 0 ){
   574   1069         /* allocate a buffer and convert to UTF8 */
         1070  +      sqlite3BeginBenignMalloc();
   575   1071         zOut = unicodeToUtf8(zTempWide);
         1072  +      sqlite3EndBenignMalloc();
   576   1073         /* free the system buffer allocated by FormatMessage */
   577         -      LocalFree(zTempWide);
         1074  +      osLocalFree(zTempWide);
   578   1075       }
   579   1076   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
   580         -** Since the ASCII version of these Windows API do not exist for WINCE,
         1077  +** Since the ANSI version of these Windows API do not exist for WINCE,
   581   1078   ** it's important to not reference them for WINCE builds.
   582   1079   */
   583   1080   #if SQLITE_OS_WINCE==0
   584   1081     }else{
   585   1082       char *zTemp = NULL;
   586         -    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
   587         -                           FORMAT_MESSAGE_FROM_SYSTEM |
   588         -                           FORMAT_MESSAGE_IGNORE_INSERTS,
   589         -                           NULL,
   590         -                           lastErrno,
   591         -                           0,
   592         -                           (LPSTR) &zTemp,
   593         -                           0,
   594         -                           0);
         1083  +    dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
         1084  +                             FORMAT_MESSAGE_FROM_SYSTEM |
         1085  +                             FORMAT_MESSAGE_IGNORE_INSERTS,
         1086  +                             NULL,
         1087  +                             lastErrno,
         1088  +                             0,
         1089  +                             (LPSTR) &zTemp,
         1090  +                             0,
         1091  +                             0);
   595   1092       if( dwLen > 0 ){
   596   1093         /* allocate a buffer and convert to UTF8 */
         1094  +      sqlite3BeginBenignMalloc();
   597   1095         zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
         1096  +      sqlite3EndBenignMalloc();
   598   1097         /* free the system buffer allocated by FormatMessage */
   599         -      LocalFree(zTemp);
         1098  +      osLocalFree(zTemp);
   600   1099       }
   601   1100   #endif
   602   1101     }
   603   1102     if( 0 == dwLen ){
   604   1103       sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
   605   1104     }else{
   606   1105       /* copy a maximum of nBuf chars to output buffer */
   607   1106       sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
   608   1107       /* free the UTF8 buffer */
   609         -    free(zOut);
         1108  +    sqlite3_free(zOut);
   610   1109     }
   611   1110     return 0;
   612   1111   }
   613   1112   
   614   1113   /*
   615   1114   **
   616   1115   ** This function - winLogErrorAtLine() - is only ever called via the macro
................................................................................
   672   1171   ** to give up with an error.
   673   1172   */
   674   1173   static int retryIoerr(int *pnRetry){
   675   1174     DWORD e;
   676   1175     if( *pnRetry>=win32IoerrRetry ){
   677   1176       return 0;
   678   1177     }
   679         -  e = GetLastError();
         1178  +  e = osGetLastError();
   680   1179     if( e==ERROR_ACCESS_DENIED ||
   681   1180         e==ERROR_LOCK_VIOLATION ||
   682   1181         e==ERROR_SHARING_VIOLATION ){
   683         -    Sleep(win32IoerrRetryDelay*(1+*pnRetry));
         1182  +    osSleep(win32IoerrRetryDelay*(1+*pnRetry));
   684   1183       ++*pnRetry;
   685   1184       return 1;
   686   1185     }
   687   1186     return 0;
   688   1187   }
   689   1188   
   690   1189   /*
................................................................................
   700   1199   }
   701   1200   
   702   1201   #if SQLITE_OS_WINCE
   703   1202   /*************************************************************************
   704   1203   ** This section contains code for WinCE only.
   705   1204   */
   706   1205   /*
   707         -** WindowsCE does not have a localtime() function.  So create a
         1206  +** Windows CE does not have a localtime() function.  So create a
   708   1207   ** substitute.
   709   1208   */
   710   1209   #include <time.h>
   711   1210   struct tm *__cdecl localtime(const time_t *t)
   712   1211   {
   713   1212     static struct tm y;
   714   1213     FILETIME uTm, lTm;
   715   1214     SYSTEMTIME pTm;
   716   1215     sqlite3_int64 t64;
   717   1216     t64 = *t;
   718   1217     t64 = (t64 + 11644473600)*10000000;
   719   1218     uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
   720   1219     uTm.dwHighDateTime= (DWORD)(t64 >> 32);
   721         -  FileTimeToLocalFileTime(&uTm,&lTm);
   722         -  FileTimeToSystemTime(&lTm,&pTm);
         1220  +  osFileTimeToLocalFileTime(&uTm,&lTm);
         1221  +  osFileTimeToSystemTime(&lTm,&pTm);
   723   1222     y.tm_year = pTm.wYear - 1900;
   724   1223     y.tm_mon = pTm.wMonth - 1;
   725   1224     y.tm_wday = pTm.wDayOfWeek;
   726   1225     y.tm_mday = pTm.wDay;
   727   1226     y.tm_hour = pTm.wHour;
   728   1227     y.tm_min = pTm.wMinute;
   729   1228     y.tm_sec = pTm.wSecond;
   730   1229     return &y;
   731   1230   }
   732   1231   
   733         -/* This will never be called, but defined to make the code compile */
   734         -#define GetTempPathA(a,b)
   735         -
   736         -#define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
   737         -#define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
   738         -#define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
   739         -
   740   1232   #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
   741   1233   
   742   1234   /*
   743   1235   ** Acquire a lock on the handle h
   744   1236   */
   745   1237   static void winceMutexAcquire(HANDLE h){
   746   1238      DWORD dwErr;
................................................................................
   754   1246   #define winceMutexRelease(h) ReleaseMutex(h)
   755   1247   
   756   1248   /*
   757   1249   ** Create the mutex and shared memory used for locking in the file
   758   1250   ** descriptor pFile
   759   1251   */
   760   1252   static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
   761         -  WCHAR *zTok;
   762         -  WCHAR *zName = utf8ToUnicode(zFilename);
         1253  +  LPWSTR zTok;
         1254  +  LPWSTR zName;
   763   1255     BOOL bInit = TRUE;
         1256  +
         1257  +  zName = utf8ToUnicode(zFilename);
         1258  +  if( zName==0 ){
         1259  +    /* out of memory */
         1260  +    return FALSE;
         1261  +  }
   764   1262   
   765   1263     /* Initialize the local lockdata */
   766         -  ZeroMemory(&pFile->local, sizeof(pFile->local));
         1264  +  memset(&pFile->local, 0, sizeof(pFile->local));
   767   1265   
   768   1266     /* Replace the backslashes from the filename and lowercase it
   769   1267     ** to derive a mutex name. */
   770         -  zTok = CharLowerW(zName);
         1268  +  zTok = osCharLowerW(zName);
   771   1269     for (;*zTok;zTok++){
   772   1270       if (*zTok == '\\') *zTok = '_';
   773   1271     }
   774   1272   
   775   1273     /* Create/open the named mutex */
   776         -  pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
         1274  +  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
   777   1275     if (!pFile->hMutex){
   778         -    pFile->lastErrno = GetLastError();
         1276  +    pFile->lastErrno = osGetLastError();
   779   1277       winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
   780         -    free(zName);
         1278  +    sqlite3_free(zName);
   781   1279       return FALSE;
   782   1280     }
   783   1281   
   784   1282     /* Acquire the mutex before continuing */
   785   1283     winceMutexAcquire(pFile->hMutex);
   786   1284     
   787   1285     /* Since the names of named mutexes, semaphores, file mappings etc are 
   788   1286     ** case-sensitive, take advantage of that by uppercasing the mutex name
   789   1287     ** and using that as the shared filemapping name.
   790   1288     */
   791         -  CharUpperW(zName);
   792         -  pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
   793         -                                       PAGE_READWRITE, 0, sizeof(winceLock),
   794         -                                       zName);  
         1289  +  osCharUpperW(zName);
         1290  +  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
         1291  +                                        PAGE_READWRITE, 0, sizeof(winceLock),
         1292  +                                        zName);  
   795   1293   
   796   1294     /* Set a flag that indicates we're the first to create the memory so it 
   797   1295     ** must be zero-initialized */
   798         -  if (GetLastError() == ERROR_ALREADY_EXISTS){
         1296  +  if (osGetLastError() == ERROR_ALREADY_EXISTS){
   799   1297       bInit = FALSE;
   800   1298     }
   801   1299   
   802         -  free(zName);
         1300  +  sqlite3_free(zName);
   803   1301   
   804   1302     /* If we succeeded in making the shared memory handle, map it. */
   805   1303     if (pFile->hShared){
   806         -    pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
         1304  +    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, 
   807   1305                FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
   808   1306       /* If mapping failed, close the shared memory handle and erase it */
   809   1307       if (!pFile->shared){
   810         -      pFile->lastErrno = GetLastError();
         1308  +      pFile->lastErrno = osGetLastError();
   811   1309         winLogError(SQLITE_ERROR, pFile->lastErrno,
   812   1310                  "winceCreateLock2", zFilename);
   813         -      CloseHandle(pFile->hShared);
         1311  +      osCloseHandle(pFile->hShared);
   814   1312         pFile->hShared = NULL;
   815   1313       }
   816   1314     }
   817   1315   
   818   1316     /* If shared memory could not be created, then close the mutex and fail */
   819   1317     if (pFile->hShared == NULL){
   820   1318       winceMutexRelease(pFile->hMutex);
   821         -    CloseHandle(pFile->hMutex);
         1319  +    osCloseHandle(pFile->hMutex);
   822   1320       pFile->hMutex = NULL;
   823   1321       return FALSE;
   824   1322     }
   825   1323     
   826   1324     /* Initialize the shared memory if we're supposed to */
   827   1325     if (bInit) {
   828         -    ZeroMemory(pFile->shared, sizeof(winceLock));
         1326  +    memset(pFile->shared, 0, sizeof(winceLock));
   829   1327     }
   830   1328   
   831   1329     winceMutexRelease(pFile->hMutex);
   832   1330     return TRUE;
   833   1331   }
   834   1332   
   835   1333   /*
................................................................................
   852   1350         pFile->shared->bPending = FALSE;
   853   1351       }
   854   1352       if (pFile->local.bExclusive){
   855   1353         pFile->shared->bExclusive = FALSE;
   856   1354       }
   857   1355   
   858   1356       /* De-reference and close our copy of the shared memory handle */
   859         -    UnmapViewOfFile(pFile->shared);
   860         -    CloseHandle(pFile->hShared);
         1357  +    osUnmapViewOfFile(pFile->shared);
         1358  +    osCloseHandle(pFile->hShared);
   861   1359   
   862   1360       /* Done with the mutex */
   863   1361       winceMutexRelease(pFile->hMutex);    
   864         -    CloseHandle(pFile->hMutex);
         1362  +    osCloseHandle(pFile->hMutex);
   865   1363       pFile->hMutex = NULL;
   866   1364     }
   867   1365   }
   868   1366   
   869   1367   /* 
   870         -** An implementation of the LockFile() API of windows for wince
         1368  +** An implementation of the LockFile() API of Windows for CE
   871   1369   */
   872   1370   static BOOL winceLockFile(
   873   1371     HANDLE *phFile,
   874   1372     DWORD dwFileOffsetLow,
   875   1373     DWORD dwFileOffsetHigh,
   876   1374     DWORD nNumberOfBytesToLockLow,
   877   1375     DWORD nNumberOfBytesToLockHigh
................................................................................
   927   1425     }
   928   1426   
   929   1427     winceMutexRelease(pFile->hMutex);
   930   1428     return bReturn;
   931   1429   }
   932   1430   
   933   1431   /*
   934         -** An implementation of the UnlockFile API of windows for wince
         1432  +** An implementation of the UnlockFile API of Windows for CE
   935   1433   */
   936   1434   static BOOL winceUnlockFile(
   937   1435     HANDLE *phFile,
   938   1436     DWORD dwFileOffsetLow,
   939   1437     DWORD dwFileOffsetHigh,
   940   1438     DWORD nNumberOfBytesToUnlockLow,
   941   1439     DWORD nNumberOfBytesToUnlockHigh
................................................................................
   989   1487     }
   990   1488   
   991   1489     winceMutexRelease(pFile->hMutex);
   992   1490     return bReturn;
   993   1491   }
   994   1492   
   995   1493   /*
   996         -** An implementation of the LockFileEx() API of windows for wince
         1494  +** An implementation of the LockFileEx() API of Windows for CE
   997   1495   */
   998   1496   static BOOL winceLockFileEx(
   999   1497     HANDLE *phFile,
  1000   1498     DWORD dwFlags,
  1001   1499     DWORD dwReserved,
  1002   1500     DWORD nNumberOfBytesToLockLow,
  1003   1501     DWORD nNumberOfBytesToLockHigh,
................................................................................
  1022   1520   
  1023   1521   /*****************************************************************************
  1024   1522   ** The next group of routines implement the I/O methods specified
  1025   1523   ** by the sqlite3_io_methods object.
  1026   1524   ******************************************************************************/
  1027   1525   
  1028   1526   /*
  1029         -** Some microsoft compilers lack this definition.
         1527  +** Some Microsoft compilers lack this definition.
  1030   1528   */
  1031   1529   #ifndef INVALID_SET_FILE_POINTER
  1032   1530   # define INVALID_SET_FILE_POINTER ((DWORD)-1)
  1033   1531   #endif
  1034   1532   
  1035   1533   /*
  1036   1534   ** Move the current position of the file handle passed as the first 
................................................................................
  1048   1546     /* API oddity: If successful, SetFilePointer() returns a dword 
  1049   1547     ** containing the lower 32-bits of the new file-offset. Or, if it fails,
  1050   1548     ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, 
  1051   1549     ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
  1052   1550     ** whether an error has actually occured, it is also necessary to call 
  1053   1551     ** GetLastError().
  1054   1552     */
  1055         -  dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  1056         -  if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
  1057         -    pFile->lastErrno = GetLastError();
         1553  +  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
         1554  +  if( (dwRet==INVALID_SET_FILE_POINTER && osGetLastError()!=NO_ERROR) ){
         1555  +    pFile->lastErrno = osGetLastError();
  1058   1556       winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
  1059   1557                "seekWinFile", pFile->zPath);
  1060   1558       return 1;
  1061   1559     }
  1062   1560   
  1063   1561     return 0;
  1064   1562   }
  1065   1563   
  1066   1564   /*
  1067   1565   ** Close a file.
  1068   1566   **
  1069   1567   ** It is reported that an attempt to close a handle might sometimes
  1070         -** fail.  This is a very unreasonable result, but windows is notorious
         1568  +** fail.  This is a very unreasonable result, but Windows is notorious
  1071   1569   ** for being unreasonable so I do not doubt that it might happen.  If
  1072   1570   ** the close fails, we pause for 100 milliseconds and try again.  As
  1073   1571   ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
  1074   1572   ** giving up and returning an error.
  1075   1573   */
  1076   1574   #define MX_CLOSE_ATTEMPT 3
  1077   1575   static int winClose(sqlite3_file *id){
................................................................................
  1078   1576     int rc, cnt = 0;
  1079   1577     winFile *pFile = (winFile*)id;
  1080   1578   
  1081   1579     assert( id!=0 );
  1082   1580     assert( pFile->pShm==0 );
  1083   1581     OSTRACE(("CLOSE %d\n", pFile->h));
  1084   1582     do{
  1085         -    rc = CloseHandle(pFile->h);
         1583  +    rc = osCloseHandle(pFile->h);
  1086   1584       /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  1087         -  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
         1585  +  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) );
  1088   1586   #if SQLITE_OS_WINCE
  1089   1587   #define WINCE_DELETION_ATTEMPTS 3
  1090   1588     winceDestroyLock(pFile);
  1091   1589     if( pFile->zDeleteOnClose ){
  1092   1590       int cnt = 0;
  1093   1591       while(
  1094         -           DeleteFileW(pFile->zDeleteOnClose)==0
  1095         -        && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 
         1592  +           osDeleteFileW(pFile->zDeleteOnClose)==0
         1593  +        && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 
  1096   1594           && cnt++ < WINCE_DELETION_ATTEMPTS
  1097   1595       ){
  1098         -       Sleep(100);  /* Wait a little before trying again */
         1596  +       osSleep(100);  /* Wait a little before trying again */
  1099   1597       }
  1100         -    free(pFile->zDeleteOnClose);
         1598  +    sqlite3_free(pFile->zDeleteOnClose);
  1101   1599     }
  1102   1600   #endif
  1103   1601     OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
  1104   1602     OpenCounter(-1);
  1105   1603     return rc ? SQLITE_OK
  1106         -            : winLogError(SQLITE_IOERR_CLOSE, GetLastError(),
         1604  +            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
  1107   1605                             "winClose", pFile->zPath);
  1108   1606   }
  1109   1607   
  1110   1608   /*
  1111   1609   ** Read data from a file into a buffer.  Return SQLITE_OK if all
  1112   1610   ** bytes were read successfully and SQLITE_IOERR if anything goes
  1113   1611   ** wrong.
................................................................................
  1125   1623     assert( id!=0 );
  1126   1624     SimulateIOError(return SQLITE_IOERR_READ);
  1127   1625     OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
  1128   1626   
  1129   1627     if( seekWinFile(pFile, offset) ){
  1130   1628       return SQLITE_FULL;
  1131   1629     }
  1132         -  while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
         1630  +  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
  1133   1631       if( retryIoerr(&nRetry) ) continue;
  1134         -    pFile->lastErrno = GetLastError();
         1632  +    pFile->lastErrno = osGetLastError();
  1135   1633       return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
  1136   1634                "winRead", pFile->zPath);
  1137   1635     }
  1138   1636     logIoerr(nRetry);
  1139   1637     if( nRead<(DWORD)amt ){
  1140   1638       /* Unread parts of the buffer must be zero-filled */
  1141   1639       memset(&((char*)pBuf)[nRead], 0, amt-nRead);
................................................................................
  1169   1667     rc = seekWinFile(pFile, offset);
  1170   1668     if( rc==0 ){
  1171   1669       u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
  1172   1670       int nRem = amt;               /* Number of bytes yet to be written */
  1173   1671       DWORD nWrite;                 /* Bytes written by each WriteFile() call */
  1174   1672   
  1175   1673       while( nRem>0 ){
  1176         -      if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
         1674  +      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
  1177   1675           if( retryIoerr(&nRetry) ) continue;
  1178   1676           break;
  1179   1677         }
  1180   1678         if( nWrite<=0 ) break;
  1181   1679         aRem += nWrite;
  1182   1680         nRem -= nWrite;
  1183   1681       }
  1184   1682       if( nRem>0 ){
  1185         -      pFile->lastErrno = GetLastError();
         1683  +      pFile->lastErrno = osGetLastError();
  1186   1684         rc = 1;
  1187   1685       }
  1188   1686     }
  1189   1687   
  1190   1688     if( rc ){
  1191   1689       if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
  1192   1690          || ( pFile->lastErrno==ERROR_DISK_FULL )){
................................................................................
  1221   1719       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  1222   1720     }
  1223   1721   
  1224   1722     /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  1225   1723     if( seekWinFile(pFile, nByte) ){
  1226   1724       rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
  1227   1725                "winTruncate1", pFile->zPath);
  1228         -  }else if( 0==SetEndOfFile(pFile->h) ){
  1229         -    pFile->lastErrno = GetLastError();
         1726  +  }else if( 0==osSetEndOfFile(pFile->h) ){
         1727  +    pFile->lastErrno = osGetLastError();
  1230   1728       rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
  1231   1729                "winTruncate2", pFile->zPath);
  1232   1730     }
  1233   1731   
  1234   1732     OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
  1235   1733     return rc;
  1236   1734   }
................................................................................
  1289   1787   
  1290   1788     /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  1291   1789     ** no-op
  1292   1790     */
  1293   1791   #ifdef SQLITE_NO_SYNC
  1294   1792     return SQLITE_OK;
  1295   1793   #else
  1296         -  rc = FlushFileBuffers(pFile->h);
         1794  +  rc = osFlushFileBuffers(pFile->h);
  1297   1795     SimulateIOError( rc=FALSE );
  1298   1796     if( rc ){
  1299   1797       return SQLITE_OK;
  1300   1798     }else{
  1301         -    pFile->lastErrno = GetLastError();
         1799  +    pFile->lastErrno = osGetLastError();
  1302   1800       return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
  1303   1801                "winSync", pFile->zPath);
  1304   1802     }
  1305   1803   #endif
  1306   1804   }
  1307   1805   
  1308   1806   /*
................................................................................
  1312   1810     DWORD upperBits;
  1313   1811     DWORD lowerBits;
  1314   1812     winFile *pFile = (winFile*)id;
  1315   1813     DWORD error;
  1316   1814   
  1317   1815     assert( id!=0 );
  1318   1816     SimulateIOError(return SQLITE_IOERR_FSTAT);
  1319         -  lowerBits = GetFileSize(pFile->h, &upperBits);
         1817  +  lowerBits = osGetFileSize(pFile->h, &upperBits);
  1320   1818     if(   (lowerBits == INVALID_FILE_SIZE)
  1321         -     && ((error = GetLastError()) != NO_ERROR) )
         1819  +     && ((error = osGetLastError()) != NO_ERROR) )
  1322   1820     {
  1323   1821       pFile->lastErrno = error;
  1324   1822       return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
  1325   1823                "winFileSize", pFile->zPath);
  1326   1824     }
  1327   1825     *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
  1328   1826     return SQLITE_OK;
................................................................................
  1334   1832   #ifndef LOCKFILE_FAIL_IMMEDIATELY
  1335   1833   # define LOCKFILE_FAIL_IMMEDIATELY 1
  1336   1834   #endif
  1337   1835   
  1338   1836   /*
  1339   1837   ** Acquire a reader lock.
  1340   1838   ** Different API routines are called depending on whether or not this
  1341         -** is Win95 or WinNT.
         1839  +** is Win9x or WinNT.
  1342   1840   */
  1343   1841   static int getReadLock(winFile *pFile){
  1344   1842     int res;
  1345   1843     if( isNT() ){
  1346   1844       OVERLAPPED ovlp;
  1347   1845       ovlp.Offset = SHARED_FIRST;
  1348   1846       ovlp.OffsetHigh = 0;
  1349   1847       ovlp.hEvent = 0;
  1350         -    res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
  1351         -                     0, SHARED_SIZE, 0, &ovlp);
         1848  +    res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
         1849  +                       0, SHARED_SIZE, 0, &ovlp);
  1352   1850   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  1353   1851   */
  1354   1852   #if SQLITE_OS_WINCE==0
  1355   1853     }else{
  1356   1854       int lk;
  1357   1855       sqlite3_randomness(sizeof(lk), &lk);
  1358   1856       pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
  1359         -    res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
         1857  +    res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  1360   1858   #endif
  1361   1859     }
  1362   1860     if( res == 0 ){
  1363         -    pFile->lastErrno = GetLastError();
         1861  +    pFile->lastErrno = osGetLastError();
  1364   1862       /* No need to log a failure to lock */
  1365   1863     }
  1366   1864     return res;
  1367   1865   }
  1368   1866   
  1369   1867   /*
  1370   1868   ** Undo a readlock
  1371   1869   */
  1372   1870   static int unlockReadLock(winFile *pFile){
  1373   1871     int res;
  1374   1872     if( isNT() ){
  1375         -    res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
         1873  +    res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1376   1874   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  1377   1875   */
  1378   1876   #if SQLITE_OS_WINCE==0
  1379   1877     }else{
  1380         -    res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
         1878  +    res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
  1381   1879   #endif
  1382   1880     }
  1383         -  if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){
  1384         -    pFile->lastErrno = GetLastError();
         1881  +  if( res==0 && osGetLastError()!=ERROR_NOT_LOCKED ){
         1882  +    pFile->lastErrno = osGetLastError();
  1385   1883       winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
  1386   1884                "unlockReadLock", pFile->zPath);
  1387   1885     }
  1388   1886     return res;
  1389   1887   }
  1390   1888   
  1391   1889   /*
................................................................................
  1412   1910   ** This routine will only increase a lock.  The winUnlock() routine
  1413   1911   ** erases all locks at once and returns us immediately to locking level 0.
  1414   1912   ** It is not possible to lower the locking level one step at a time.  You
  1415   1913   ** must go straight to locking level 0.
  1416   1914   */
  1417   1915   static int winLock(sqlite3_file *id, int locktype){
  1418   1916     int rc = SQLITE_OK;    /* Return code from subroutines */
  1419         -  int res = 1;           /* Result of a windows lock call */
         1917  +  int res = 1;           /* Result of a Windows lock call */
  1420   1918     int newLocktype;       /* Set pFile->locktype to this value before exiting */
  1421   1919     int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
  1422   1920     winFile *pFile = (winFile*)id;
  1423   1921     DWORD error = NO_ERROR;
  1424   1922   
  1425   1923     assert( id!=0 );
  1426   1924     OSTRACE(("LOCK %d %d was %d(%d)\n",
................................................................................
  1446   1944     */
  1447   1945     newLocktype = pFile->locktype;
  1448   1946     if(   (pFile->locktype==NO_LOCK)
  1449   1947        || (   (locktype==EXCLUSIVE_LOCK)
  1450   1948            && (pFile->locktype==RESERVED_LOCK))
  1451   1949     ){
  1452   1950       int cnt = 3;
  1453         -    while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
         1951  +    while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
  1454   1952         /* Try 3 times to get the pending lock.  This is needed to work
  1455         -      ** around problems caused by anti-virus software on windows system.
         1953  +      ** around problems caused by indexing and/or anti-virus software on
         1954  +      ** Windows systems.
  1456   1955         ** If you are using this code as a model for alternative VFSes, do not
  1457         -      ** copy this retry logic.  It is a hack intended for windows only.
         1956  +      ** copy this retry logic.  It is a hack intended for Windows only.
  1458   1957         */
  1459   1958         OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
  1460         -      if( cnt ) Sleep(1);
         1959  +      if( cnt ) osSleep(1);
  1461   1960       }
  1462   1961       gotPendingLock = res;
  1463   1962       if( !res ){
  1464         -      error = GetLastError();
         1963  +      error = osGetLastError();
  1465   1964       }
  1466   1965     }
  1467   1966   
  1468   1967     /* Acquire a shared lock
  1469   1968     */
  1470   1969     if( locktype==SHARED_LOCK && res ){
  1471   1970       assert( pFile->locktype==NO_LOCK );
  1472   1971       res = getReadLock(pFile);
  1473   1972       if( res ){
  1474   1973         newLocktype = SHARED_LOCK;
  1475   1974       }else{
  1476         -      error = GetLastError();
         1975  +      error = osGetLastError();
  1477   1976       }
  1478   1977     }
  1479   1978   
  1480   1979     /* Acquire a RESERVED lock
  1481   1980     */
  1482   1981     if( locktype==RESERVED_LOCK && res ){
  1483   1982       assert( pFile->locktype==SHARED_LOCK );
  1484         -    res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         1983  +    res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1485   1984       if( res ){
  1486   1985         newLocktype = RESERVED_LOCK;
  1487   1986       }else{
  1488         -      error = GetLastError();
         1987  +      error = osGetLastError();
  1489   1988       }
  1490   1989     }
  1491   1990   
  1492   1991     /* Acquire a PENDING lock
  1493   1992     */
  1494   1993     if( locktype==EXCLUSIVE_LOCK && res ){
  1495   1994       newLocktype = PENDING_LOCK;
................................................................................
  1498   1997   
  1499   1998     /* Acquire an EXCLUSIVE lock
  1500   1999     */
  1501   2000     if( locktype==EXCLUSIVE_LOCK && res ){
  1502   2001       assert( pFile->locktype>=SHARED_LOCK );
  1503   2002       res = unlockReadLock(pFile);
  1504   2003       OSTRACE(("unreadlock = %d\n", res));
  1505         -    res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
         2004  +    res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1506   2005       if( res ){
  1507   2006         newLocktype = EXCLUSIVE_LOCK;
  1508   2007       }else{
  1509         -      error = GetLastError();
         2008  +      error = osGetLastError();
  1510   2009         OSTRACE(("error-code = %d\n", error));
  1511   2010         getReadLock(pFile);
  1512   2011       }
  1513   2012     }
  1514   2013   
  1515   2014     /* If we are holding a PENDING lock that ought to be released, then
  1516   2015     ** release it now.
  1517   2016     */
  1518   2017     if( gotPendingLock && locktype==SHARED_LOCK ){
  1519         -    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
         2018  +    osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
  1520   2019     }
  1521   2020   
  1522   2021     /* Update the state of the lock has held in the file descriptor then
  1523   2022     ** return the appropriate result code.
  1524   2023     */
  1525   2024     if( res ){
  1526   2025       rc = SQLITE_OK;
................................................................................
  1546   2045     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  1547   2046   
  1548   2047     assert( id!=0 );
  1549   2048     if( pFile->locktype>=RESERVED_LOCK ){
  1550   2049       rc = 1;
  1551   2050       OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
  1552   2051     }else{
  1553         -    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         2052  +    rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1554   2053       if( rc ){
  1555         -      UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         2054  +      osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1556   2055       }
  1557   2056       rc = !rc;
  1558   2057       OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
  1559   2058     }
  1560   2059     *pResOut = rc;
  1561   2060     return SQLITE_OK;
  1562   2061   }
................................................................................
  1578   2077     int rc = SQLITE_OK;
  1579   2078     assert( pFile!=0 );
  1580   2079     assert( locktype<=SHARED_LOCK );
  1581   2080     OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
  1582   2081             pFile->locktype, pFile->sharedLockByte));
  1583   2082     type = pFile->locktype;
  1584   2083     if( type>=EXCLUSIVE_LOCK ){
  1585         -    UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
         2084  +    osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1586   2085       if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
  1587   2086         /* This should never happen.  We should always be able to
  1588   2087         ** reacquire the read lock */
  1589         -      rc = winLogError(SQLITE_IOERR_UNLOCK, GetLastError(),
         2088  +      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
  1590   2089                  "winUnlock", pFile->zPath);
  1591   2090       }
  1592   2091     }
  1593   2092     if( type>=RESERVED_LOCK ){
  1594         -    UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
         2093  +    osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1595   2094     }
  1596   2095     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  1597   2096       unlockReadLock(pFile);
  1598   2097     }
  1599   2098     if( type>=PENDING_LOCK ){
  1600         -    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
         2099  +    osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
  1601   2100     }
  1602   2101     pFile->locktype = (u8)locktype;
  1603   2102     return rc;
  1604   2103   }
  1605   2104   
  1606   2105   /*
  1607   2106   ** Control and query of the open file handle.
................................................................................
  1830   2329     if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
  1831   2330   
  1832   2331     memset(&ovlp, 0, sizeof(OVERLAPPED));
  1833   2332     ovlp.Offset = ofst;
  1834   2333   
  1835   2334     /* Release/Acquire the system-level lock */
  1836   2335     if( lockType==_SHM_UNLCK ){
  1837         -    rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
         2336  +    rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
  1838   2337     }else{
  1839         -    rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
         2338  +    rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
  1840   2339     }
  1841   2340     
  1842   2341     if( rc!= 0 ){
  1843   2342       rc = SQLITE_OK;
  1844   2343     }else{
  1845         -    pFile->lastErrno =  GetLastError();
         2344  +    pFile->lastErrno =  osGetLastError();
  1846   2345       rc = SQLITE_BUSY;
  1847   2346     }
  1848   2347   
  1849   2348     OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
  1850   2349              pFile->hFile.h,
  1851   2350              rc==SQLITE_OK ? "ok" : "failed",
  1852   2351              lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
................................................................................
  1872   2371     assert( winShmMutexHeld() );
  1873   2372     pp = &winShmNodeList;
  1874   2373     while( (p = *pp)!=0 ){
  1875   2374       if( p->nRef==0 ){
  1876   2375         int i;
  1877   2376         if( p->mutex ) sqlite3_mutex_free(p->mutex);
  1878   2377         for(i=0; i<p->nRegion; i++){
  1879         -        bRc = UnmapViewOfFile(p->aRegion[i].pMap);
         2378  +        bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
  1880   2379           OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
  1881         -                 (int)GetCurrentProcessId(), i,
         2380  +                 (int)osGetCurrentProcessId(), i,
  1882   2381                    bRc ? "ok" : "failed"));
  1883         -        bRc = CloseHandle(p->aRegion[i].hMap);
         2382  +        bRc = osCloseHandle(p->aRegion[i].hMap);
  1884   2383           OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
  1885         -                 (int)GetCurrentProcessId(), i,
         2384  +                 (int)osGetCurrentProcessId(), i,
  1886   2385                    bRc ? "ok" : "failed"));
  1887   2386         }
  1888   2387         if( p->hFile.h != INVALID_HANDLE_VALUE ){
  1889   2388           SimulateIOErrorBenign(1);
  1890   2389           winClose((sqlite3_file *)&p->hFile);
  1891   2390           SimulateIOErrorBenign(0);
  1892   2391         }
................................................................................
  1920   2419   
  1921   2420     assert( pDbFd->pShm==0 );    /* Not previously opened */
  1922   2421   
  1923   2422     /* Allocate space for the new sqlite3_shm object.  Also speculatively
  1924   2423     ** allocate space for a new winShmNode and filename.
  1925   2424     */
  1926   2425     p = sqlite3_malloc( sizeof(*p) );
  1927         -  if( p==0 ) return SQLITE_NOMEM;
         2426  +  if( p==0 ) return SQLITE_IOERR_NOMEM;
  1928   2427     memset(p, 0, sizeof(*p));
  1929   2428     nName = sqlite3Strlen30(pDbFd->zPath);
  1930   2429     pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 );
  1931   2430     if( pNew==0 ){
  1932   2431       sqlite3_free(p);
  1933         -    return SQLITE_NOMEM;
         2432  +    return SQLITE_IOERR_NOMEM;
  1934   2433     }
  1935   2434     memset(pNew, 0, sizeof(*pNew));
  1936   2435     pNew->zFilename = (char*)&pNew[1];
  1937   2436     sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
  1938   2437     sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 
  1939   2438   
  1940   2439     /* Look to see if there is an existing winShmNode that can be used.
................................................................................
  1954   2453       pNew = 0;
  1955   2454       ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
  1956   2455       pShmNode->pNext = winShmNodeList;
  1957   2456       winShmNodeList = pShmNode;
  1958   2457   
  1959   2458       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  1960   2459       if( pShmNode->mutex==0 ){
  1961         -      rc = SQLITE_NOMEM;
         2460  +      rc = SQLITE_IOERR_NOMEM;
  1962   2461         goto shm_open_err;
  1963   2462       }
  1964   2463   
  1965   2464       rc = winOpen(pDbFd->pVfs,
  1966   2465                    pShmNode->zFilename,             /* Name of the file (UTF-8) */
  1967   2466                    (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
  1968   2467                    SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
................................................................................
  1974   2473   
  1975   2474       /* Check to see if another process is holding the dead-man switch.
  1976   2475       ** If not, truncate the file to zero length. 
  1977   2476       */
  1978   2477       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  1979   2478         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
  1980   2479         if( rc!=SQLITE_OK ){
  1981         -        rc = winLogError(SQLITE_IOERR_SHMOPEN, GetLastError(),
         2480  +        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
  1982   2481                    "winOpenShm", pDbFd->zPath);
  1983   2482         }
  1984   2483       }
  1985   2484       if( rc==SQLITE_OK ){
  1986   2485         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1987   2486         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1988   2487       }
................................................................................
  2160   2659           assert( (p->sharedMask & mask)==0 );
  2161   2660           p->exclMask |= mask;
  2162   2661         }
  2163   2662       }
  2164   2663     }
  2165   2664     sqlite3_mutex_leave(pShmNode->mutex);
  2166   2665     OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
  2167         -           p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
         2666  +           p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask,
  2168   2667              rc ? "failed" : "ok"));
  2169   2668     return rc;
  2170   2669   }
  2171   2670   
  2172   2671   /*
  2173   2672   ** Implement a memory barrier or memory fence on shared memory.  
  2174   2673   **
................................................................................
  2234   2733   
  2235   2734       /* The requested region is not mapped into this processes address space.
  2236   2735       ** Check to see if it has been allocated (i.e. if the wal-index file is
  2237   2736       ** large enough to contain the requested region).
  2238   2737       */
  2239   2738       rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
  2240   2739       if( rc!=SQLITE_OK ){
  2241         -      rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2740  +      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
  2242   2741                  "winShmMap1", pDbFd->zPath);
  2243   2742         goto shmpage_out;
  2244   2743       }
  2245   2744   
  2246   2745       if( sz<nByte ){
  2247   2746         /* The requested memory region does not exist. If isWrite is set to
  2248   2747         ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
................................................................................
  2249   2748         **
  2250   2749         ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
  2251   2750         ** the requested memory region.
  2252   2751         */
  2253   2752         if( !isWrite ) goto shmpage_out;
  2254   2753         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
  2255   2754         if( rc!=SQLITE_OK ){
  2256         -        rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2755  +        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
  2257   2756                    "winShmMap2", pDbFd->zPath);
  2258   2757           goto shmpage_out;
  2259   2758         }
  2260   2759       }
  2261   2760   
  2262   2761       /* Map the requested memory region into this processes address space. */
  2263   2762       apNew = (struct ShmRegion *)sqlite3_realloc(
................................................................................
  2269   2768       }
  2270   2769       pShmNode->aRegion = apNew;
  2271   2770   
  2272   2771       while( pShmNode->nRegion<=iRegion ){
  2273   2772         HANDLE hMap;                /* file-mapping handle */
  2274   2773         void *pMap = 0;             /* Mapped memory region */
  2275   2774        
  2276         -      hMap = CreateFileMapping(pShmNode->hFile.h, 
         2775  +      hMap = osCreateFileMapping(pShmNode->hFile.h, 
  2277   2776             NULL, PAGE_READWRITE, 0, nByte, NULL
  2278   2777         );
  2279   2778         OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
  2280         -               (int)GetCurrentProcessId(), pShmNode->nRegion, nByte,
         2779  +               (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
  2281   2780                  hMap ? "ok" : "failed"));
  2282   2781         if( hMap ){
  2283   2782           int iOffset = pShmNode->nRegion*szRegion;
  2284   2783           int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
  2285         -        pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
         2784  +        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
  2286   2785               0, iOffset - iOffsetShift, szRegion + iOffsetShift
  2287   2786           );
  2288   2787           OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
  2289         -                 (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
  2290         -                 pMap ? "ok" : "failed"));
         2788  +                 (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
         2789  +                 szRegion, pMap ? "ok" : "failed"));
  2291   2790         }
  2292   2791         if( !pMap ){
  2293         -        pShmNode->lastErrno = GetLastError();
         2792  +        pShmNode->lastErrno = osGetLastError();
  2294   2793           rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
  2295   2794                    "winShmMap3", pDbFd->zPath);
  2296         -        if( hMap ) CloseHandle(hMap);
         2795  +        if( hMap ) osCloseHandle(hMap);
  2297   2796           goto shmpage_out;
  2298   2797         }
  2299   2798   
  2300   2799         pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
  2301   2800         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
  2302   2801         pShmNode->nRegion++;
  2303   2802       }
................................................................................
  2400   2899     SimulateIOError( return SQLITE_IOERR );
  2401   2900   
  2402   2901     if( sqlite3_temp_directory ){
  2403   2902       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
  2404   2903     }else if( isNT() ){
  2405   2904       char *zMulti;
  2406   2905       WCHAR zWidePath[MAX_PATH];
  2407         -    GetTempPathW(MAX_PATH-30, zWidePath);
         2906  +    osGetTempPathW(MAX_PATH-30, zWidePath);
  2408   2907       zMulti = unicodeToUtf8(zWidePath);
  2409   2908       if( zMulti ){
  2410   2909         sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
  2411         -      free(zMulti);
         2910  +      sqlite3_free(zMulti);
  2412   2911       }else{
  2413         -      return SQLITE_NOMEM;
         2912  +      return SQLITE_IOERR_NOMEM;
  2414   2913       }
  2415   2914   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2416         -** Since the ASCII version of these Windows API do not exist for WINCE,
         2915  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2417   2916   ** it's important to not reference them for WINCE builds.
  2418   2917   */
  2419   2918   #if SQLITE_OS_WINCE==0
  2420   2919     }else{
  2421   2920       char *zUtf8;
  2422   2921       char zMbcsPath[MAX_PATH];
  2423         -    GetTempPathA(MAX_PATH-30, zMbcsPath);
         2922  +    osGetTempPathA(MAX_PATH-30, zMbcsPath);
  2424   2923       zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
  2425   2924       if( zUtf8 ){
  2426   2925         sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
  2427         -      free(zUtf8);
         2926  +      sqlite3_free(zUtf8);
  2428   2927       }else{
  2429         -      return SQLITE_NOMEM;
         2928  +      return SQLITE_IOERR_NOMEM;
  2430   2929       }
  2431   2930   #endif
  2432   2931     }
  2433   2932   
  2434   2933     /* Check that the output buffer is large enough for the temporary file 
  2435   2934     ** name. If it is not, return SQLITE_ERROR.
  2436   2935     */
................................................................................
  2545   3044       }
  2546   3045       zUtf8Name = zTmpname;
  2547   3046     }
  2548   3047   
  2549   3048     /* Convert the filename to the system encoding. */
  2550   3049     zConverted = convertUtf8Filename(zUtf8Name);
  2551   3050     if( zConverted==0 ){
  2552         -    return SQLITE_NOMEM;
         3051  +    return SQLITE_IOERR_NOMEM;
  2553   3052     }
  2554   3053   
  2555   3054     if( isReadWrite ){
  2556   3055       dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
  2557   3056     }else{
  2558   3057       dwDesiredAccess = GENERIC_READ;
  2559   3058     }
................................................................................
  2591   3090     /* Reports from the internet are that performance is always
  2592   3091     ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
  2593   3092   #if SQLITE_OS_WINCE
  2594   3093     dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
  2595   3094   #endif
  2596   3095   
  2597   3096     if( isNT() ){
  2598         -    while( (h = CreateFileW((WCHAR*)zConverted,
  2599         -                            dwDesiredAccess,
  2600         -                            dwShareMode, NULL,
  2601         -                            dwCreationDisposition,
  2602         -                            dwFlagsAndAttributes,
  2603         -                            NULL))==INVALID_HANDLE_VALUE &&
  2604         -                            retryIoerr(&cnt) ){}
         3097  +    while( (h = osCreateFileW((LPCWSTR)zConverted,
         3098  +                              dwDesiredAccess,
         3099  +                              dwShareMode, NULL,
         3100  +                              dwCreationDisposition,
         3101  +                              dwFlagsAndAttributes,
         3102  +                              NULL))==INVALID_HANDLE_VALUE &&
         3103  +                              retryIoerr(&cnt) ){}
  2605   3104   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2606         -** Since the ASCII version of these Windows API do not exist for WINCE,
         3105  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2607   3106   ** it's important to not reference them for WINCE builds.
  2608   3107   */
  2609   3108   #if SQLITE_OS_WINCE==0
  2610   3109     }else{
  2611         -    while( (h = CreateFileA((char*)zConverted,
  2612         -                            dwDesiredAccess,
  2613         -                            dwShareMode, NULL,
  2614         -                            dwCreationDisposition,
  2615         -                            dwFlagsAndAttributes,
  2616         -                            NULL))==INVALID_HANDLE_VALUE &&
  2617         -                            retryIoerr(&cnt) ){}
         3110  +    while( (h = osCreateFileA((LPCSTR)zConverted,
         3111  +                              dwDesiredAccess,
         3112  +                              dwShareMode, NULL,
         3113  +                              dwCreationDisposition,
         3114  +                              dwFlagsAndAttributes,
         3115  +                              NULL))==INVALID_HANDLE_VALUE &&
         3116  +                              retryIoerr(&cnt) ){}
  2618   3117   #endif
  2619   3118     }
  2620   3119   
  2621   3120     logIoerr(cnt);
  2622   3121   
  2623   3122     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
  2624   3123              h, zName, dwDesiredAccess, 
  2625   3124              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
  2626   3125   
  2627   3126     if( h==INVALID_HANDLE_VALUE ){
  2628         -    pFile->lastErrno = GetLastError();
         3127  +    pFile->lastErrno = osGetLastError();
  2629   3128       winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
  2630         -    free(zConverted);
         3129  +    sqlite3_free(zConverted);
  2631   3130       if( isReadWrite && !isExclusive ){
  2632   3131         return winOpen(pVfs, zName, id, 
  2633   3132                ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
  2634   3133       }else{
  2635   3134         return SQLITE_CANTOPEN_BKPT;
  2636   3135       }
  2637   3136     }
................................................................................
  2653   3152     pFile->zPath = zName;
  2654   3153     pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
  2655   3154   
  2656   3155   #if SQLITE_OS_WINCE
  2657   3156     if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
  2658   3157          && !winceCreateLock(zName, pFile)
  2659   3158     ){
  2660         -    CloseHandle(h);
  2661         -    free(zConverted);
         3159  +    osCloseHandle(h);
         3160  +    sqlite3_free(zConverted);
  2662   3161       return SQLITE_CANTOPEN_BKPT;
  2663   3162     }
  2664   3163     if( isTemp ){
  2665   3164       pFile->zDeleteOnClose = zConverted;
  2666   3165     }else
  2667   3166   #endif
  2668   3167     {
  2669         -    free(zConverted);
         3168  +    sqlite3_free(zConverted);
  2670   3169     }
  2671   3170   
  2672   3171     OpenCounter(+1);
  2673   3172     return rc;
  2674   3173   }
  2675   3174   
  2676   3175   /*
  2677   3176   ** Delete the named file.
  2678   3177   **
  2679         -** Note that windows does not allow a file to be deleted if some other
         3178  +** Note that Windows does not allow a file to be deleted if some other
  2680   3179   ** process has it open.  Sometimes a virus scanner or indexing program
  2681   3180   ** will open a journal file shortly after it is created in order to do
  2682   3181   ** whatever it does.  While this other process is holding the
  2683   3182   ** file open, we will be unable to delete it.  To work around this
  2684   3183   ** problem, we delay 100 milliseconds and try to delete again.  Up
  2685   3184   ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
  2686   3185   ** up and returning an error.
................................................................................
  2695   3194     void *zConverted;
  2696   3195     UNUSED_PARAMETER(pVfs);
  2697   3196     UNUSED_PARAMETER(syncDir);
  2698   3197   
  2699   3198     SimulateIOError(return SQLITE_IOERR_DELETE);
  2700   3199     zConverted = convertUtf8Filename(zFilename);
  2701   3200     if( zConverted==0 ){
  2702         -    return SQLITE_NOMEM;
         3201  +    return SQLITE_IOERR_NOMEM;
  2703   3202     }
  2704   3203     if( isNT() ){
  2705   3204       rc = 1;
  2706         -    while( GetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES &&
  2707         -           (rc = DeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){}
         3205  +    while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES &&
         3206  +           (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){}
  2708   3207       rc = rc ? SQLITE_OK : SQLITE_ERROR;
  2709   3208   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2710         -** Since the ASCII version of these Windows API do not exist for WINCE,
         3209  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2711   3210   ** it's important to not reference them for WINCE builds.
  2712   3211   */
  2713   3212   #if SQLITE_OS_WINCE==0
  2714   3213     }else{
  2715   3214       rc = 1;
  2716         -    while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
  2717         -           (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){}
         3215  +    while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
         3216  +           (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){}
  2718   3217       rc = rc ? SQLITE_OK : SQLITE_ERROR;
  2719   3218   #endif
  2720   3219     }
  2721   3220     if( rc ){
  2722         -    rc = winLogError(SQLITE_IOERR_DELETE, GetLastError(),
         3221  +    rc = winLogError(SQLITE_IOERR_DELETE, osGetLastError(),
  2723   3222                "winDelete", zFilename);
  2724   3223     }else{
  2725   3224       logIoerr(cnt);
  2726   3225     }
  2727         -  free(zConverted);
         3226  +  sqlite3_free(zConverted);
  2728   3227     OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
  2729   3228     return rc;
  2730   3229   }
  2731   3230   
  2732   3231   /*
  2733   3232   ** Check the existance and status of a file.
  2734   3233   */
................................................................................
  2742   3241     int rc = 0;
  2743   3242     void *zConverted;
  2744   3243     UNUSED_PARAMETER(pVfs);
  2745   3244   
  2746   3245     SimulateIOError( return SQLITE_IOERR_ACCESS; );
  2747   3246     zConverted = convertUtf8Filename(zFilename);
  2748   3247     if( zConverted==0 ){
  2749         -    return SQLITE_NOMEM;
         3248  +    return SQLITE_IOERR_NOMEM;
  2750   3249     }
  2751   3250     if( isNT() ){
  2752   3251       int cnt = 0;
  2753   3252       WIN32_FILE_ATTRIBUTE_DATA sAttrData;
  2754   3253       memset(&sAttrData, 0, sizeof(sAttrData));
  2755         -    while( !(rc = GetFileAttributesExW((WCHAR*)zConverted,
         3254  +    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
  2756   3255                                GetFileExInfoStandard, 
  2757   3256                                &sAttrData)) && retryIoerr(&cnt) ){}
  2758   3257       if( rc ){
  2759   3258         /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
  2760   3259         ** as if it does not exist.
  2761   3260         */
  2762   3261         if(    flags==SQLITE_ACCESS_EXISTS
................................................................................
  2763   3262             && sAttrData.nFileSizeHigh==0 
  2764   3263             && sAttrData.nFileSizeLow==0 ){
  2765   3264           attr = INVALID_FILE_ATTRIBUTES;
  2766   3265         }else{
  2767   3266           attr = sAttrData.dwFileAttributes;
  2768   3267         }
  2769   3268       }else{
  2770         -      DWORD lastErrno = GetLastError();
         3269  +      DWORD lastErrno = osGetLastError();
  2771   3270         logIoerr(cnt);
  2772   3271         if( lastErrno!=ERROR_FILE_NOT_FOUND ){
  2773   3272           winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
  2774         -        free(zConverted);
         3273  +        sqlite3_free(zConverted);
  2775   3274           return SQLITE_IOERR_ACCESS;
  2776   3275         }else{
  2777   3276           attr = INVALID_FILE_ATTRIBUTES;
  2778   3277         }
  2779   3278       }
  2780   3279   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2781         -** Since the ASCII version of these Windows API do not exist for WINCE,
         3280  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2782   3281   ** it's important to not reference them for WINCE builds.
  2783   3282   */
  2784   3283   #if SQLITE_OS_WINCE==0
  2785   3284     }else{
  2786         -    attr = GetFileAttributesA((char*)zConverted);
         3285  +    attr = osGetFileAttributesA((char*)zConverted);
  2787   3286   #endif
  2788   3287     }
  2789         -  free(zConverted);
         3288  +  sqlite3_free(zConverted);
  2790   3289     switch( flags ){
  2791   3290       case SQLITE_ACCESS_READ:
  2792   3291       case SQLITE_ACCESS_EXISTS:
  2793   3292         rc = attr!=INVALID_FILE_ATTRIBUTES;
  2794   3293         break;
  2795   3294       case SQLITE_ACCESS_READWRITE:
  2796   3295         rc = attr!=INVALID_FILE_ATTRIBUTES &&
................................................................................
  2847   3346     ** using the io-error infrastructure to test that SQLite handles this
  2848   3347     ** function failing. This function could fail if, for example, the
  2849   3348     ** current working directory has been unlinked.
  2850   3349     */
  2851   3350     SimulateIOError( return SQLITE_ERROR );
  2852   3351     UNUSED_PARAMETER(nFull);
  2853   3352     zConverted = convertUtf8Filename(zRelative);
         3353  +  if( zConverted==0 ){
         3354  +    return SQLITE_IOERR_NOMEM;
         3355  +  }
  2854   3356     if( isNT() ){
  2855         -    WCHAR *zTemp;
  2856         -    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
  2857         -    zTemp = malloc( nByte*sizeof(zTemp[0]) );
         3357  +    LPWSTR zTemp;
         3358  +    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
         3359  +    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
  2858   3360       if( zTemp==0 ){
  2859         -      free(zConverted);
  2860         -      return SQLITE_NOMEM;
         3361  +      sqlite3_free(zConverted);
         3362  +      return SQLITE_IOERR_NOMEM;
  2861   3363       }
  2862         -    GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
  2863         -    free(zConverted);
         3364  +    osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
         3365  +    sqlite3_free(zConverted);
  2864   3366       zOut = unicodeToUtf8(zTemp);
  2865         -    free(zTemp);
         3367  +    sqlite3_free(zTemp);
  2866   3368   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2867         -** Since the ASCII version of these Windows API do not exist for WINCE,
         3369  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2868   3370   ** it's important to not reference them for WINCE builds.
  2869   3371   */
  2870   3372   #if SQLITE_OS_WINCE==0
  2871   3373     }else{
  2872   3374       char *zTemp;
  2873         -    nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
  2874         -    zTemp = malloc( nByte*sizeof(zTemp[0]) );
         3375  +    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
         3376  +    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
  2875   3377       if( zTemp==0 ){
  2876         -      free(zConverted);
  2877         -      return SQLITE_NOMEM;
         3378  +      sqlite3_free(zConverted);
         3379  +      return SQLITE_IOERR_NOMEM;
  2878   3380       }
  2879         -    GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
  2880         -    free(zConverted);
         3381  +    osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
         3382  +    sqlite3_free(zConverted);
  2881   3383       zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
  2882         -    free(zTemp);
         3384  +    sqlite3_free(zTemp);
  2883   3385   #endif
  2884   3386     }
  2885   3387     if( zOut ){
  2886   3388       sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
  2887         -    free(zOut);
         3389  +    sqlite3_free(zOut);
  2888   3390       return SQLITE_OK;
  2889   3391     }else{
  2890         -    return SQLITE_NOMEM;
         3392  +    return SQLITE_IOERR_NOMEM;
  2891   3393     }
  2892   3394   #endif
  2893   3395   }
  2894   3396   
  2895   3397   /*
  2896   3398   ** Get the sector size of the device used to store
  2897   3399   ** file.
................................................................................
  2913   3415   
  2914   3416     /*
  2915   3417     ** We need to get the full path name of the file
  2916   3418     ** to get the drive letter to look up the sector
  2917   3419     ** size.
  2918   3420     */
  2919   3421     SimulateIOErrorBenign(1);
         3422  +  sqlite3BeginBenignMalloc();
  2920   3423     rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
         3424  +  sqlite3EndBenignMalloc();
  2921   3425     SimulateIOErrorBenign(0);
  2922   3426     if( rc == SQLITE_OK )
  2923   3427     {
  2924         -    void *zConverted = convertUtf8Filename(zFullpath);
         3428  +    void *zConverted;
         3429  +    sqlite3BeginBenignMalloc();
         3430  +    zConverted = convertUtf8Filename(zFullpath);
         3431  +    sqlite3EndBenignMalloc();
  2925   3432       if( zConverted ){
  2926   3433         if( isNT() ){
  2927   3434           /* trim path to just drive reference */
  2928         -        WCHAR *p = zConverted;
         3435  +        LPWSTR p = zConverted;
  2929   3436           for(;*p;p++){
  2930   3437             if( *p == '\\' ){
  2931   3438               *p = '\0';
  2932   3439               break;
  2933   3440             }
  2934   3441           }
  2935         -        dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
  2936         -                                  &dwDummy,
  2937         -                                  &bytesPerSector,
  2938         -                                  &dwDummy,
  2939         -                                  &dwDummy);
         3442  +        dwRet = osGetDiskFreeSpaceW((LPCWSTR)zConverted,
         3443  +                                    &dwDummy,
         3444  +                                    &bytesPerSector,
         3445  +                                    &dwDummy,
         3446  +                                    &dwDummy);
  2940   3447         }else{
  2941   3448           /* trim path to just drive reference */
  2942   3449           char *p = (char *)zConverted;
  2943   3450           for(;*p;p++){
  2944   3451             if( *p == '\\' ){
  2945   3452               *p = '\0';
  2946   3453               break;
  2947   3454             }
  2948   3455           }
  2949         -        dwRet = GetDiskFreeSpaceA((char*)zConverted,
  2950         -                                  &dwDummy,
  2951         -                                  &bytesPerSector,
  2952         -                                  &dwDummy,
  2953         -                                  &dwDummy);
         3456  +        dwRet = osGetDiskFreeSpaceA((char*)zConverted,
         3457  +                                    &dwDummy,
         3458  +                                    &bytesPerSector,
         3459  +                                    &dwDummy,
         3460  +                                    &dwDummy);
  2954   3461         }
  2955         -      free(zConverted);
         3462  +      sqlite3_free(zConverted);
  2956   3463       }
  2957   3464       if( !dwRet ){
  2958   3465         bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
  2959   3466       }
  2960   3467     }
  2961   3468   #endif
  2962   3469     return (int) bytesPerSector; 
................................................................................
  2975   3482     HANDLE h;
  2976   3483     void *zConverted = convertUtf8Filename(zFilename);
  2977   3484     UNUSED_PARAMETER(pVfs);
  2978   3485     if( zConverted==0 ){
  2979   3486       return 0;
  2980   3487     }
  2981   3488     if( isNT() ){
  2982         -    h = LoadLibraryW((WCHAR*)zConverted);
         3489  +    h = osLoadLibraryW((LPCWSTR)zConverted);
  2983   3490   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2984         -** Since the ASCII version of these Windows API do not exist for WINCE,
         3491  +** Since the ANSI version of these Windows API do not exist for WINCE,
  2985   3492   ** it's important to not reference them for WINCE builds.
  2986   3493   */
  2987   3494   #if SQLITE_OS_WINCE==0
  2988   3495     }else{
  2989         -    h = LoadLibraryA((char*)zConverted);
         3496  +    h = osLoadLibraryA((char*)zConverted);
  2990   3497   #endif
  2991   3498     }
  2992         -  free(zConverted);
         3499  +  sqlite3_free(zConverted);
  2993   3500     return (void*)h;
  2994   3501   }
  2995   3502   static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  2996   3503     UNUSED_PARAMETER(pVfs);
  2997         -  getLastErrorMsg(GetLastError(), nBuf, zBufOut);
         3504  +  getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
  2998   3505   }
  2999   3506   static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
  3000   3507     UNUSED_PARAMETER(pVfs);
  3001         -#if SQLITE_OS_WINCE
  3002         -  /* The GetProcAddressA() routine is only available on wince. */
  3003         -  return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
  3004         -#else
  3005         -  /* All other windows platforms expect GetProcAddress() to take
  3006         -  ** an Ansi string regardless of the _UNICODE setting */
  3007         -  return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
  3008         -#endif
         3508  +  return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
  3009   3509   }
  3010   3510   static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
  3011   3511     UNUSED_PARAMETER(pVfs);
  3012         -  FreeLibrary((HANDLE)pHandle);
         3512  +  osFreeLibrary((HANDLE)pHandle);
  3013   3513   }
  3014   3514   #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
  3015   3515     #define winDlOpen  0
  3016   3516     #define winDlError 0
  3017   3517     #define winDlSym   0
  3018   3518     #define winDlClose 0
  3019   3519   #endif
................................................................................
  3027   3527     UNUSED_PARAMETER(pVfs);
  3028   3528   #if defined(SQLITE_TEST)
  3029   3529     n = nBuf;
  3030   3530     memset(zBuf, 0, nBuf);
  3031   3531   #else
  3032   3532     if( sizeof(SYSTEMTIME)<=nBuf-n ){
  3033   3533       SYSTEMTIME x;
  3034         -    GetSystemTime(&x);
         3534  +    osGetSystemTime(&x);
  3035   3535       memcpy(&zBuf[n], &x, sizeof(x));
  3036   3536       n += sizeof(x);
  3037   3537     }
  3038   3538     if( sizeof(DWORD)<=nBuf-n ){
  3039         -    DWORD pid = GetCurrentProcessId();
         3539  +    DWORD pid = osGetCurrentProcessId();
  3040   3540       memcpy(&zBuf[n], &pid, sizeof(pid));
  3041   3541       n += sizeof(pid);
  3042   3542     }
  3043   3543     if( sizeof(DWORD)<=nBuf-n ){
  3044         -    DWORD cnt = GetTickCount();
         3544  +    DWORD cnt = osGetTickCount();
  3045   3545       memcpy(&zBuf[n], &cnt, sizeof(cnt));
  3046   3546       n += sizeof(cnt);
  3047   3547     }
  3048   3548     if( sizeof(LARGE_INTEGER)<=nBuf-n ){
  3049   3549       LARGE_INTEGER i;
  3050         -    QueryPerformanceCounter(&i);
         3550  +    osQueryPerformanceCounter(&i);
  3051   3551       memcpy(&zBuf[n], &i, sizeof(i));
  3052   3552       n += sizeof(i);
  3053   3553     }
  3054   3554   #endif
  3055   3555     return n;
  3056   3556   }
  3057   3557   
  3058   3558   
  3059   3559   /*
  3060   3560   ** Sleep for a little while.  Return the amount of time slept.
  3061   3561   */
  3062   3562   static int winSleep(sqlite3_vfs *pVfs, int microsec){
  3063         -  Sleep((microsec+999)/1000);
         3563  +  osSleep((microsec+999)/1000);
  3064   3564     UNUSED_PARAMETER(pVfs);
  3065   3565     return ((microsec+999)/1000)*1000;
  3066   3566   }
  3067   3567   
  3068   3568   /*
  3069   3569   ** The following variable, if set to a non-zero value, is interpreted as
  3070   3570   ** the number of seconds since 1970 and is used to set the result of
................................................................................
  3095   3595   #endif
  3096   3596     /* 2^32 - to avoid use of LL and warnings in gcc */
  3097   3597     static const sqlite3_int64 max32BitValue = 
  3098   3598         (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
  3099   3599   
  3100   3600   #if SQLITE_OS_WINCE
  3101   3601     SYSTEMTIME time;
  3102         -  GetSystemTime(&time);
         3602  +  osGetSystemTime(&time);
  3103   3603     /* if SystemTimeToFileTime() fails, it returns zero. */
  3104         -  if (!SystemTimeToFileTime(&time,&ft)){
         3604  +  if (!osSystemTimeToFileTime(&time,&ft)){
  3105   3605       return SQLITE_ERROR;
  3106   3606     }
  3107   3607   #else
  3108         -  GetSystemTimeAsFileTime( &ft );
         3608  +  osGetSystemTimeAsFileTime( &ft );
  3109   3609   #endif
  3110   3610   
  3111   3611     *piNow = winFiletimeEpoch +
  3112   3612               ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
  3113   3613                  (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
  3114   3614   
  3115   3615   #ifdef SQLITE_TEST
................................................................................
  3134   3634       *prNow = i/86400000.0;
  3135   3635     }
  3136   3636     return rc;
  3137   3637   }
  3138   3638   
  3139   3639   /*
  3140   3640   ** The idea is that this function works like a combination of
  3141         -** GetLastError() and FormatMessage() on windows (or errno and
  3142         -** strerror_r() on unix). After an error is returned by an OS
         3641  +** GetLastError() and FormatMessage() on Windows (or errno and
         3642  +** strerror_r() on Unix). After an error is returned by an OS
  3143   3643   ** function, SQLite calls this function with zBuf pointing to
  3144   3644   ** a buffer of nBuf bytes. The OS layer should populate the
  3145   3645   ** buffer with a nul-terminated UTF-8 encoded error message
  3146   3646   ** describing the last IO error to have occurred within the calling
  3147   3647   ** thread.
  3148   3648   **
  3149   3649   ** If the error message is too large for the supplied buffer,
................................................................................
  3164   3664   **
  3165   3665   ** However if an error message is supplied, it will be incorporated
  3166   3666   ** by sqlite into the error message available to the user using
  3167   3667   ** sqlite3_errmsg(), possibly making IO errors easier to debug.
  3168   3668   */
  3169   3669   static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  3170   3670     UNUSED_PARAMETER(pVfs);
  3171         -  return getLastErrorMsg(GetLastError(), nBuf, zBuf);
         3671  +  return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
  3172   3672   }
  3173         -
  3174         -
  3175   3673   
  3176   3674   /*
  3177   3675   ** Initialize and deinitialize the operating system interface.
  3178   3676   */
  3179   3677   int sqlite3_os_init(void){
  3180   3678     static sqlite3_vfs winVfs = {
  3181   3679       3,                   /* iVersion */
................................................................................
  3193   3691       winDlSym,            /* xDlSym */
  3194   3692       winDlClose,          /* xDlClose */
  3195   3693       winRandomness,       /* xRandomness */
  3196   3694       winSleep,            /* xSleep */
  3197   3695       winCurrentTime,      /* xCurrentTime */
  3198   3696       winGetLastError,     /* xGetLastError */
  3199   3697       winCurrentTimeInt64, /* xCurrentTimeInt64 */
  3200         -    0,                   /* xSetSystemCall */
  3201         -    0,                   /* xGetSystemCall */
  3202         -    0,                   /* xNextSystemCall */
         3698  +    winSetSystemCall,    /* xSetSystemCall */
         3699  +    winGetSystemCall,    /* xGetSystemCall */
         3700  +    winNextSystemCall,   /* xNextSystemCall */
  3203   3701     };
         3702  +
         3703  +  /* Double-check that the aSyscall[] array has been constructed
         3704  +  ** correctly.  See ticket [bb3a86e890c8e96ab] */
         3705  +  assert( ArraySize(aSyscall)==60 );
  3204   3706   
  3205   3707   #ifndef SQLITE_OMIT_WAL
  3206   3708     /* get memory map allocation granularity */
  3207   3709     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  3208         -  GetSystemInfo(&winSysInfo);
         3710  +  osGetSystemInfo(&winSysInfo);
  3209   3711     assert(winSysInfo.dwAllocationGranularity > 0);
  3210   3712   #endif
  3211   3713   
  3212   3714     sqlite3_vfs_register(&winVfs, 1);
  3213   3715     return SQLITE_OK; 
  3214   3716   }
         3717  +
  3215   3718   int sqlite3_os_end(void){ 
  3216   3719     return SQLITE_OK;
  3217   3720   }
  3218   3721   
  3219   3722   #endif /* SQLITE_OS_WIN */

Changes to src/test_vfs.c.

   984    984       return TCL_ERROR;
   985    985     }
   986    986     Tcl_ResetResult(interp);
   987    987   
   988    988     switch( aSubcmd[i].eCmd ){
   989    989       case CMD_SHM: {
   990    990         Tcl_Obj *pObj;
   991         -      int i;
          991  +      int i, rc;
   992    992         TestvfsBuffer *pBuffer;
   993    993         char *zName;
   994    994         if( objc!=3 && objc!=4 ){
   995    995           Tcl_WrongNumArgs(interp, 2, objv, "FILE ?VALUE?");
   996    996           return TCL_ERROR;
   997    997         }
   998    998         zName = ckalloc(p->pParent->mxPathname);
   999         -      p->pParent->xFullPathname(
          999  +      rc = p->pParent->xFullPathname(
  1000   1000             p->pParent, Tcl_GetString(objv[2]), 
  1001   1001             p->pParent->mxPathname, zName
  1002   1002         );
         1003  +      if( rc!=SQLITE_OK ){
         1004  +        Tcl_AppendResult(interp, "failed to get full path: ",
         1005  +                         Tcl_GetString(objv[2]), 0);
         1006  +        ckfree(zName);
         1007  +        return TCL_ERROR;
         1008  +      }
  1003   1009         for(pBuffer=p->pBuffer; pBuffer; pBuffer=pBuffer->pNext){
  1004   1010           if( 0==strcmp(pBuffer->zFile, zName) ) break;
  1005   1011         }
  1006   1012         ckfree(zName);
  1007   1013         if( !pBuffer ){
  1008   1014           Tcl_AppendResult(interp, "no such file: ", Tcl_GetString(objv[2]), 0);
  1009   1015           return TCL_ERROR;

Changes to test/tester.tcl.

    53     53   #      do_test                TESTNAME SCRIPT EXPECTED
    54     54   #      do_execsql_test        TESTNAME SQL EXPECTED
    55     55   #      do_catchsql_test       TESTNAME SQL EXPECTED
    56     56   #
    57     57   # Commands providing a lower level interface to the global test counters:
    58     58   #
    59     59   #      set_test_counter       COUNTER ?VALUE?
    60         -#      omit_test              TESTNAME REASON
           60  +#      omit_test              TESTNAME REASON ?APPEND?
    61     61   #      fail_test              TESTNAME
    62     62   #      incr_ntest
    63     63   #
    64     64   # Command run at the end of each test file:
    65     65   #
    66     66   #      finish_test
    67     67   #
................................................................................
   270    270     #   --malloctrace=N
   271    271     #   --backtrace=N
   272    272     #   --binarylog=N
   273    273     #   --soak=N
   274    274     #   --file-retries=N
   275    275     #   --file-retry-delay=N
   276    276     #   --start=[$permutation:]$testfile
          277  +  #   --match=$pattern
   277    278     #
   278    279     set cmdlinearg(soft-heap-limit)    0
   279    280     set cmdlinearg(maxerror)        1000
   280    281     set cmdlinearg(malloctrace)        0
   281    282     set cmdlinearg(backtrace)         10
   282    283     set cmdlinearg(binarylog)          0
   283    284     set cmdlinearg(soak)               0
   284    285     set cmdlinearg(file-retries)       0
   285    286     set cmdlinearg(file-retry-delay)   0
   286         -  set cmdlinearg(start)             "" 
          287  +  set cmdlinearg(start)             ""
          288  +  set cmdlinearg(match)             ""
   287    289   
   288    290     set leftover [list]
   289    291     foreach a $argv {
   290    292       switch -regexp -- $a {
   291    293         {^-+pause$} {
   292    294           # Wait for user input before continuing. This is to give the user an 
   293    295           # opportunity to connect profiling tools to the process.
................................................................................
   332    334           set ::G(start:file) $cmdlinearg(start)
   333    335           if {[regexp {(.*):(.*)} $cmdlinearg(start) -> s.perm s.file]} {
   334    336             set ::G(start:permutation) ${s.perm}
   335    337             set ::G(start:file)        ${s.file}
   336    338           }
   337    339           if {$::G(start:file) == ""} {unset ::G(start:file)}
   338    340         }
          341  +      {^-+match=.+$} {
          342  +        foreach {dummy cmdlinearg(match)} [split $a =] break
          343  +
          344  +        set ::G(match) $cmdlinearg(match)
          345  +        if {$::G(match) == ""} {unset ::G(match)}
          346  +      }
   339    347         default {
   340    348           lappend leftover $a
   341    349         }
   342    350       }
   343    351     }
   344    352     set argv $leftover
   345    353   
................................................................................
   410    418       }
   411    419       set ::TC($counter)
   412    420     }
   413    421   }
   414    422   
   415    423   # Record the fact that a sequence of tests were omitted.
   416    424   #
   417         -proc omit_test {name reason} {
          425  +proc omit_test {name reason {append 1}} {
   418    426     set omitList [set_test_counter omit_list]
   419         -  lappend omitList [list $name $reason]
          427  +  if {$append} {
          428  +    lappend omitList [list $name $reason]
          429  +  }
   420    430     set_test_counter omit_list $omitList
   421    431   }
   422    432   
   423    433   # Record the fact that a test failed.
   424    434   #
   425    435   proc fail_test {name} {
   426    436     set f [set_test_counter fail_list]
................................................................................
   467    477     if {[info exists ::G(perm:prefix)]} {
   468    478       set name "$::G(perm:prefix)$name"
   469    479     }
   470    480   
   471    481     incr_ntest
   472    482     puts -nonewline $name...
   473    483     flush stdout
   474         -  if {[catch {uplevel #0 "$cmd;\n"} result]} {
   475         -    puts "\nError: $result"
   476         -    fail_test $name
   477         -  } elseif {[string compare $result $expected]} {
   478         -    puts "\nExpected: \[$expected\]\n     Got: \[$result\]"
   479         -    fail_test $name
          484  +
          485  +  if {![info exists ::G(match)] || [string match $::G(match) $name]} {
          486  +    if {[catch {uplevel #0 "$cmd;\n"} result]} {
          487  +      puts "\nError: $result"
          488  +      fail_test $name
          489  +    } elseif {[string compare $result $expected]} {
          490  +      puts "\nExpected: \[$expected\]\n     Got: \[$result\]"
          491  +      fail_test $name
          492  +    } else {
          493  +      puts " Ok"
          494  +    }
   480    495     } else {
   481         -    puts " Ok"
          496  +    puts " Omitted"
          497  +    omit_test $name "pattern mismatch" 0
   482    498     }
   483    499     flush stdout
   484    500   }
   485    501   
   486    502   proc filepath_normalize {p} {
   487    503     # test cases should be written to assume "unix"-like file paths
   488    504     if {$::tcl_platform(platform)!="unix"} {