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