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