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 sqlite3_mutex *winBigLock = 0; 3635 static void winShmEnterMutex(void){ 3636 sqlite3_mutex_enter(winBigLock); 3637 } 3638 static void winShmLeaveMutex(void){ 3639 sqlite3_mutex_leave(winBigLock); 3640 } 3641 #ifndef NDEBUG 3642 static int winShmMutexHeld(void) { 3643 return sqlite3_mutex_held(winBigLock); 3644 } 3645 #endif 3646 3647 /* 3648 ** Object used to represent a single file opened and mmapped to provide 3649 ** shared memory. When multiple threads all reference the same 3650 ** log-summary, each thread has its own winFile object, but they all 3651 ** point to a single instance of this object. In other words, each 3652 ** log-summary is opened only once per process. 3653 ** 3654 ** winShmMutexHeld() must be true when creating or destroying 3655 ** this object or while reading or writing the following fields: 3656 ** 3657 ** nRef 3658 ** pNext 3659 ** 3660 ** The following fields are read-only after the object is created: 3661 ** 3662 ** fid 3663 ** zFilename 3664 ** 3665 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and 3666 ** winShmMutexHeld() is true when reading or writing any other field 3667 ** in this structure. 3668 ** 3669 */ 3670 struct winShmNode { 3671 sqlite3_mutex *mutex; /* Mutex to access this object */ 3672 char *zFilename; /* Name of the file */ 3673 winFile hFile; /* File handle from winOpen */ 3674 3675 int szRegion; /* Size of shared-memory regions */ 3676 int nRegion; /* Size of array apRegion */ 3677 u8 isReadonly; /* True if read-only */ 3678 u8 isUnlocked; /* True if no DMS lock held */ 3679 3680 struct ShmRegion { 3681 HANDLE hMap; /* File handle from CreateFileMapping */ 3682 void *pMap; 3683 } *aRegion; 3684 DWORD lastErrno; /* The Windows errno from the last I/O error */ 3685 3686 int nRef; /* Number of winShm objects pointing to this */ 3687 winShm *pFirst; /* All winShm objects pointing to this */ 3688 winShmNode *pNext; /* Next in list of all winShmNode objects */ 3689 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3690 u8 nextShmId; /* Next available winShm.id value */ 3691 #endif 3692 }; 3693 3694 /* 3695 ** A global array of all winShmNode objects. 3696 ** 3697 ** The winShmMutexHeld() must be true while reading or writing this list. 3698 */ 3699 static winShmNode *winShmNodeList = 0; 3700 3701 /* 3702 ** Structure used internally by this VFS to record the state of an 3703 ** open shared memory connection. 3704 ** 3705 ** The following fields are initialized when this object is created and 3706 ** are read-only thereafter: 3707 ** 3708 ** winShm.pShmNode 3709 ** winShm.id 3710 ** 3711 ** All other fields are read/write. The winShm.pShmNode->mutex must be held 3712 ** while accessing any read/write fields. 3713 */ 3714 struct winShm { 3715 winShmNode *pShmNode; /* The underlying winShmNode object */ 3716 winShm *pNext; /* Next winShm with the same winShmNode */ 3717 u8 hasMutex; /* True if holding the winShmNode mutex */ 3718 u16 sharedMask; /* Mask of shared locks held */ 3719 u16 exclMask; /* Mask of exclusive locks held */ 3720 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3721 u8 id; /* Id of this connection with its winShmNode */ 3722 #endif 3723 }; 3724 3725 /* 3726 ** Constants used for locking 3727 */ 3728 #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ 3729 #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ 3730 3731 /* 3732 ** Apply advisory locks for all n bytes beginning at ofst. 3733 */ 3734 #define WINSHM_UNLCK 1 3735 #define WINSHM_RDLCK 2 3736 #define WINSHM_WRLCK 3 3737 static int winShmSystemLock( 3738 winShmNode *pFile, /* Apply locks to this open shared-memory segment */ 3739 int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ 3740 int ofst, /* Offset to first byte to be locked/unlocked */ 3741 int nByte /* Number of bytes to lock or unlock */ 3742 ){ 3743 int rc = 0; /* Result code form Lock/UnlockFileEx() */ 3744 3745 /* Access to the winShmNode object is serialized by the caller */ 3746 assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); 3747 3748 OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", 3749 pFile->hFile.h, lockType, ofst, nByte)); 3750 3751 /* Release/Acquire the system-level lock */ 3752 if( lockType==WINSHM_UNLCK ){ 3753 rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); 3754 }else{ 3755 /* Initialize the locking parameters */ 3756 DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; 3757 if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; 3758 rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); 3759 } 3760 3761 if( rc!= 0 ){ 3762 rc = SQLITE_OK; 3763 }else{ 3764 pFile->lastErrno = osGetLastError(); 3765 rc = SQLITE_BUSY; 3766 } 3767 3768 OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", 3769 pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : 3770 "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); 3771 3772 return rc; 3773 } 3774 3775 /* Forward references to VFS methods */ 3776 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); 3777 static int winDelete(sqlite3_vfs *,const char*,int); 3778 3779 /* 3780 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. 3781 ** 3782 ** This is not a VFS shared-memory method; it is a utility function called 3783 ** by VFS shared-memory methods. 3784 */ 3785 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ 3786 winShmNode **pp; 3787 winShmNode *p; 3788 assert( winShmMutexHeld() ); 3789 OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", 3790 osGetCurrentProcessId(), deleteFlag)); 3791 pp = &winShmNodeList; 3792 while( (p = *pp)!=0 ){ 3793 if( p->nRef==0 ){ 3794 int i; 3795 if( p->mutex ){ sqlite3_mutex_free(p->mutex); } 3796 for(i=0; i<p->nRegion; i++){ 3797 BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); 3798 OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", 3799 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3800 UNUSED_VARIABLE_VALUE(bRc); 3801 bRc = osCloseHandle(p->aRegion[i].hMap); 3802 OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", 3803 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3804 UNUSED_VARIABLE_VALUE(bRc); 3805 } 3806 if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ 3807 SimulateIOErrorBenign(1); 3808 winClose((sqlite3_file *)&p->hFile); 3809 SimulateIOErrorBenign(0); 3810 } 3811 if( deleteFlag ){ 3812 SimulateIOErrorBenign(1); 3813 sqlite3BeginBenignMalloc(); 3814 winDelete(pVfs, p->zFilename, 0); 3815 sqlite3EndBenignMalloc(); 3816 SimulateIOErrorBenign(0); 3817 } 3818 *pp = p->pNext; 3819 sqlite3_free(p->aRegion); 3820 sqlite3_free(p); 3821 }else{ 3822 pp = &p->pNext; 3823 } 3824 } 3825 } 3826 3827 /* 3828 ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to 3829 ** take it now. Return SQLITE_OK if successful, or an SQLite error 3830 ** code otherwise. 3831 ** 3832 ** If the DMS cannot be locked because this is a readonly_shm=1 3833 ** connection and no other process already holds a lock, return 3834 ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. 3835 */ 3836 static int winLockSharedMemory(winShmNode *pShmNode){ 3837 int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); 3838 3839 if( rc==SQLITE_OK ){ 3840 if( pShmNode->isReadonly ){ 3841 pShmNode->isUnlocked = 1; 3842 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3843 return SQLITE_READONLY_CANTINIT; 3844 }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ 3845 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3846 return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), 3847 "winLockSharedMemory", pShmNode->zFilename); 3848 } 3849 } 3850 3851 if( rc==SQLITE_OK ){ 3852 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3853 } 3854 3855 return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); 3856 } 3857 3858 /* 3859 ** Open the shared-memory area associated with database file pDbFd. 3860 ** 3861 ** When opening a new shared-memory file, if no other instances of that 3862 ** file are currently open, in this process or in other processes, then 3863 ** the file must be truncated to zero length or have its header cleared. 3864 */ 3865 static int winOpenSharedMemory(winFile *pDbFd){ 3866 struct winShm *p; /* The connection to be opened */ 3867 winShmNode *pShmNode = 0; /* The underlying mmapped file */ 3868 int rc = SQLITE_OK; /* Result code */ 3869 winShmNode *pNew; /* Newly allocated winShmNode */ 3870 int nName; /* Size of zName in bytes */ 3871 3872 assert( pDbFd->pShm==0 ); /* Not previously opened */ 3873 3874 /* Allocate space for the new sqlite3_shm object. Also speculatively 3875 ** allocate space for a new winShmNode and filename. 3876 */ 3877 p = sqlite3MallocZero( sizeof(*p) ); 3878 if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; 3879 nName = sqlite3Strlen30(pDbFd->zPath); 3880 pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); 3881 if( pNew==0 ){ 3882 sqlite3_free(p); 3883 return SQLITE_IOERR_NOMEM_BKPT; 3884 } 3885 pNew->zFilename = (char*)&pNew[1]; 3886 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); 3887 sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 3888 3889 /* Look to see if there is an existing winShmNode that can be used. 3890 ** If no matching winShmNode currently exists, create a new one. 3891 */ 3892 winShmEnterMutex(); 3893 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ 3894 /* TBD need to come up with better match here. Perhaps 3895 ** use FILE_ID_BOTH_DIR_INFO Structure. 3896 */ 3897 if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; 3898 } 3899 if( pShmNode ){ 3900 sqlite3_free(pNew); 3901 }else{ 3902 int inFlags = SQLITE_OPEN_WAL; 3903 int outFlags = 0; 3904 3905 pShmNode = pNew; 3906 pNew = 0; 3907 ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; 3908 pShmNode->pNext = winShmNodeList; 3909 winShmNodeList = pShmNode; 3910 3911 if( sqlite3GlobalConfig.bCoreMutex ){ 3912 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); 3913 if( pShmNode->mutex==0 ){ 3914 rc = SQLITE_IOERR_NOMEM_BKPT; 3915 goto shm_open_err; 3916 } 3917 } 3918 3919 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ 3920 inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; 3921 }else{ 3922 inFlags |= SQLITE_OPEN_READONLY; 3923 } 3924 rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, 3925 (sqlite3_file*)&pShmNode->hFile, 3926 inFlags, &outFlags); 3927 if( rc!=SQLITE_OK ){ 3928 rc = winLogError(rc, osGetLastError(), "winOpenShm", 3929 pShmNode->zFilename); 3930 goto shm_open_err; 3931 } 3932 if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; 3933 3934 rc = winLockSharedMemory(pShmNode); 3935 if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; 3936 } 3937 3938 /* Make the new connection a child of the winShmNode */ 3939 p->pShmNode = pShmNode; 3940 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3941 p->id = pShmNode->nextShmId++; 3942 #endif 3943 pShmNode->nRef++; 3944 pDbFd->pShm = p; 3945 winShmLeaveMutex(); 3946 3947 /* The reference count on pShmNode has already been incremented under 3948 ** the cover of the winShmEnterMutex() mutex and the pointer from the 3949 ** new (struct winShm) object to the pShmNode has been set. All that is 3950 ** left to do is to link the new object into the linked list starting 3951 ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 3952 ** mutex. 3953 */ 3954 sqlite3_mutex_enter(pShmNode->mutex); 3955 p->pNext = pShmNode->pFirst; 3956 pShmNode->pFirst = p; 3957 sqlite3_mutex_leave(pShmNode->mutex); 3958 return rc; 3959 3960 /* Jump here on any error */ 3961 shm_open_err: 3962 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3963 winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ 3964 sqlite3_free(p); 3965 sqlite3_free(pNew); 3966 winShmLeaveMutex(); 3967 return rc; 3968 } 3969 3970 /* 3971 ** Close a connection to shared-memory. Delete the underlying 3972 ** storage if deleteFlag is true. 3973 */ 3974 static int winShmUnmap( 3975 sqlite3_file *fd, /* Database holding shared memory */ 3976 int deleteFlag /* Delete after closing if true */ 3977 ){ 3978 winFile *pDbFd; /* Database holding shared-memory */ 3979 winShm *p; /* The connection to be closed */ 3980 winShmNode *pShmNode; /* The underlying shared-memory file */ 3981 winShm **pp; /* For looping over sibling connections */ 3982 3983 pDbFd = (winFile*)fd; 3984 p = pDbFd->pShm; 3985 if( p==0 ) return SQLITE_OK; 3986 pShmNode = p->pShmNode; 3987 3988 /* Remove connection p from the set of connections associated 3989 ** with pShmNode */ 3990 sqlite3_mutex_enter(pShmNode->mutex); 3991 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} 3992 *pp = p->pNext; 3993 3994 /* Free the connection p */ 3995 sqlite3_free(p); 3996 pDbFd->pShm = 0; 3997 sqlite3_mutex_leave(pShmNode->mutex); 3998 3999 /* If pShmNode->nRef has reached 0, then close the underlying 4000 ** shared-memory file, too */ 4001 winShmEnterMutex(); 4002 assert( pShmNode->nRef>0 ); 4003 pShmNode->nRef--; 4004 if( pShmNode->nRef==0 ){ 4005 winShmPurge(pDbFd->pVfs, deleteFlag); 4006 } 4007 winShmLeaveMutex(); 4008 4009 return SQLITE_OK; 4010 } 4011 4012 /* 4013 ** Change the lock state for a shared-memory segment. 4014 */ 4015 static int winShmLock( 4016 sqlite3_file *fd, /* Database file holding the shared memory */ 4017 int ofst, /* First lock to acquire or release */ 4018 int n, /* Number of locks to acquire or release */ 4019 int flags /* What to do with the lock */ 4020 ){ 4021 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ 4022 winShm *p = pDbFd->pShm; /* The shared memory being locked */ 4023 winShm *pX; /* For looping over all siblings */ 4024 winShmNode *pShmNode = p->pShmNode; 4025 int rc = SQLITE_OK; /* Result code */ 4026 u16 mask; /* Mask of locks to take or release */ 4027 4028 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); 4029 assert( n>=1 ); 4030 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) 4031 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) 4032 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) 4033 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); 4034 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); 4035 4036 mask = (u16)((1U<<(ofst+n)) - (1U<<ofst)); 4037 assert( n>1 || mask==(1<<ofst) ); 4038 sqlite3_mutex_enter(pShmNode->mutex); 4039 if( flags & SQLITE_SHM_UNLOCK ){ 4040 u16 allMask = 0; /* Mask of locks held by siblings */ 4041 4042 /* See if any siblings hold this same lock */ 4043 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4044 if( pX==p ) continue; 4045 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); 4046 allMask |= pX->sharedMask; 4047 } 4048 4049 /* Unlock the system-level locks */ 4050 if( (mask & allMask)==0 ){ 4051 rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); 4052 }else{ 4053 rc = SQLITE_OK; 4054 } 4055 4056 /* Undo the local locks */ 4057 if( rc==SQLITE_OK ){ 4058 p->exclMask &= ~mask; 4059 p->sharedMask &= ~mask; 4060 } 4061 }else if( flags & SQLITE_SHM_SHARED ){ 4062 u16 allShared = 0; /* Union of locks held by connections other than "p" */ 4063 4064 /* Find out which shared locks are already held by sibling connections. 4065 ** If any sibling already holds an exclusive lock, go ahead and return 4066 ** SQLITE_BUSY. 4067 */ 4068 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4069 if( (pX->exclMask & mask)!=0 ){ 4070 rc = SQLITE_BUSY; 4071 break; 4072 } 4073 allShared |= pX->sharedMask; 4074 } 4075 4076 /* Get shared locks at the system level, if necessary */ 4077 if( rc==SQLITE_OK ){ 4078 if( (allShared & mask)==0 ){ 4079 rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); 4080 }else{ 4081 rc = SQLITE_OK; 4082 } 4083 } 4084 4085 /* Get the local shared locks */ 4086 if( rc==SQLITE_OK ){ 4087 p->sharedMask |= mask; 4088 } 4089 }else{ 4090 /* Make sure no sibling connections hold locks that will block this 4091 ** lock. If any do, return SQLITE_BUSY right away. 4092 */ 4093 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4094 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ 4095 rc = SQLITE_BUSY; 4096 break; 4097 } 4098 } 4099 4100 /* Get the exclusive locks at the system level. Then if successful 4101 ** also mark the local connection as being locked. 4102 */ 4103 if( rc==SQLITE_OK ){ 4104 rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); 4105 if( rc==SQLITE_OK ){ 4106 assert( (p->sharedMask & mask)==0 ); 4107 p->exclMask |= mask; 4108 } 4109 } 4110 } 4111 sqlite3_mutex_leave(pShmNode->mutex); 4112 OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", 4113 osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, 4114 sqlite3ErrName(rc))); 4115 return rc; 4116 } 4117 4118 /* 4119 ** Implement a memory barrier or memory fence on shared memory. 4120 ** 4121 ** All loads and stores begun before the barrier must complete before 4122 ** any load or store begun after the barrier. 4123 */ 4124 static void winShmBarrier( 4125 sqlite3_file *fd /* Database holding the shared memory */ 4126 ){ 4127 UNUSED_PARAMETER(fd); 4128 sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ 4129 winShmEnterMutex(); /* Also mutex, for redundancy */ 4130 winShmLeaveMutex(); 4131 } 4132 4133 /* 4134 ** This function is called to obtain a pointer to region iRegion of the 4135 ** shared-memory associated with the database file fd. Shared-memory regions 4136 ** are numbered starting from zero. Each shared-memory region is szRegion 4137 ** bytes in size. 4138 ** 4139 ** If an error occurs, an error code is returned and *pp is set to NULL. 4140 ** 4141 ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory 4142 ** region has not been allocated (by any client, including one running in a 4143 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If 4144 ** isWrite is non-zero and the requested shared-memory region has not yet 4145 ** been allocated, it is allocated by this function. 4146 ** 4147 ** If the shared-memory region has already been allocated or is allocated by 4148 ** this call as described above, then it is mapped into this processes 4149 ** address space (if it is not already), *pp is set to point to the mapped 4150 ** memory and SQLITE_OK returned. 4151 */ 4152 static int winShmMap( 4153 sqlite3_file *fd, /* Handle open on database file */ 4154 int iRegion, /* Region to retrieve */ 4155 int szRegion, /* Size of regions */ 4156 int isWrite, /* True to extend file if necessary */ 4157 void volatile **pp /* OUT: Mapped memory */ 4158 ){ 4159 winFile *pDbFd = (winFile*)fd; 4160 winShm *pShm = pDbFd->pShm; 4161 winShmNode *pShmNode; 4162 DWORD protect = PAGE_READWRITE; 4163 DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; 4164 int rc = SQLITE_OK; 4165 4166 if( !pShm ){ 4167 rc = winOpenSharedMemory(pDbFd); 4168 if( rc!=SQLITE_OK ) return rc; 4169 pShm = pDbFd->pShm; 4170 } 4171 pShmNode = pShm->pShmNode; 4172 4173 sqlite3_mutex_enter(pShmNode->mutex); 4174 if( pShmNode->isUnlocked ){ 4175 rc = winLockSharedMemory(pShmNode); 4176 if( rc!=SQLITE_OK ) goto shmpage_out; 4177 pShmNode->isUnlocked = 0; 4178 } 4179 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); 4180 4181 if( pShmNode->nRegion<=iRegion ){ 4182 struct ShmRegion *apNew; /* New aRegion[] array */ 4183 int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ 4184 sqlite3_int64 sz; /* Current size of wal-index file */ 4185 4186 pShmNode->szRegion = szRegion; 4187 4188 /* The requested region is not mapped into this processes address space. 4189 ** Check to see if it has been allocated (i.e. if the wal-index file is 4190 ** large enough to contain the requested region). 4191 */ 4192 rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); 4193 if( rc!=SQLITE_OK ){ 4194 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4195 "winShmMap1", pDbFd->zPath); 4196 goto shmpage_out; 4197 } 4198 4199 if( sz<nByte ){ 4200 /* The requested memory region does not exist. If isWrite is set to 4201 ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. 4202 ** 4203 ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate 4204 ** the requested memory region. 4205 */ 4206 if( !isWrite ) goto shmpage_out; 4207 rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); 4208 if( rc!=SQLITE_OK ){ 4209 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4210 "winShmMap2", pDbFd->zPath); 4211 goto shmpage_out; 4212 } 4213 } 4214 4215 /* Map the requested memory region into this processes address space. */ 4216 apNew = (struct ShmRegion *)sqlite3_realloc64( 4217 pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) 4218 ); 4219 if( !apNew ){ 4220 rc = SQLITE_IOERR_NOMEM_BKPT; 4221 goto shmpage_out; 4222 } 4223 pShmNode->aRegion = apNew; 4224 4225 if( pShmNode->isReadonly ){ 4226 protect = PAGE_READONLY; 4227 flags = FILE_MAP_READ; 4228 } 4229 4230 while( pShmNode->nRegion<=iRegion ){ 4231 HANDLE hMap = NULL; /* file-mapping handle */ 4232 void *pMap = 0; /* Mapped memory region */ 4233 4234 #if SQLITE_OS_WINRT 4235 hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, 4236 NULL, protect, nByte, NULL 4237 ); 4238 #elif defined(SQLITE_WIN32_HAS_WIDE) 4239 hMap = osCreateFileMappingW(pShmNode->hFile.h, 4240 NULL, protect, 0, nByte, NULL 4241 ); 4242 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4243 hMap = osCreateFileMappingA(pShmNode->hFile.h, 4244 NULL, protect, 0, nByte, NULL 4245 ); 4246 #endif 4247 OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", 4248 osGetCurrentProcessId(), pShmNode->nRegion, nByte, 4249 hMap ? "ok" : "failed")); 4250 if( hMap ){ 4251 int iOffset = pShmNode->nRegion*szRegion; 4252 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4253 #if SQLITE_OS_WINRT 4254 pMap = osMapViewOfFileFromApp(hMap, flags, 4255 iOffset - iOffsetShift, szRegion + iOffsetShift 4256 ); 4257 #else 4258 pMap = osMapViewOfFile(hMap, flags, 4259 0, iOffset - iOffsetShift, szRegion + iOffsetShift 4260 ); 4261 #endif 4262 OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", 4263 osGetCurrentProcessId(), pShmNode->nRegion, iOffset, 4264 szRegion, pMap ? "ok" : "failed")); 4265 } 4266 if( !pMap ){ 4267 pShmNode->lastErrno = osGetLastError(); 4268 rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, 4269 "winShmMap3", pDbFd->zPath); 4270 if( hMap ) osCloseHandle(hMap); 4271 goto shmpage_out; 4272 } 4273 4274 pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; 4275 pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; 4276 pShmNode->nRegion++; 4277 } 4278 } 4279 4280 shmpage_out: 4281 if( pShmNode->nRegion>iRegion ){ 4282 int iOffset = iRegion*szRegion; 4283 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4284 char *p = (char *)pShmNode->aRegion[iRegion].pMap; 4285 *pp = (void *)&p[iOffsetShift]; 4286 }else{ 4287 *pp = 0; 4288 } 4289 if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; 4290 sqlite3_mutex_leave(pShmNode->mutex); 4291 return rc; 4292 } 4293 4294 #else 4295 # define winShmMap 0 4296 # define winShmLock 0 4297 # define winShmBarrier 0 4298 # define winShmUnmap 0 4299 #endif /* #ifndef SQLITE_OMIT_WAL */ 4300 4301 /* 4302 ** Cleans up the mapped region of the specified file, if any. 4303 */ 4304 #if SQLITE_MAX_MMAP_SIZE>0 4305 static int winUnmapfile(winFile *pFile){ 4306 assert( pFile!=0 ); 4307 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " 4308 "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", 4309 osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, 4310 pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); 4311 if( pFile->pMapRegion ){ 4312 if( !osUnmapViewOfFile(pFile->pMapRegion) ){ 4313 pFile->lastErrno = osGetLastError(); 4314 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " 4315 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, 4316 pFile->pMapRegion)); 4317 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4318 "winUnmapfile1", pFile->zPath); 4319 } 4320 pFile->pMapRegion = 0; 4321 pFile->mmapSize = 0; 4322 pFile->mmapSizeActual = 0; 4323 } 4324 if( pFile->hMap!=NULL ){ 4325 if( !osCloseHandle(pFile->hMap) ){ 4326 pFile->lastErrno = osGetLastError(); 4327 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", 4328 osGetCurrentProcessId(), pFile, pFile->hMap)); 4329 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4330 "winUnmapfile2", pFile->zPath); 4331 } 4332 pFile->hMap = NULL; 4333 } 4334 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4335 osGetCurrentProcessId(), pFile)); 4336 return SQLITE_OK; 4337 } 4338 4339 /* 4340 ** Memory map or remap the file opened by file-descriptor pFd (if the file 4341 ** is already mapped, the existing mapping is replaced by the new). Or, if 4342 ** there already exists a mapping for this file, and there are still 4343 ** outstanding xFetch() references to it, this function is a no-op. 4344 ** 4345 ** If parameter nByte is non-negative, then it is the requested size of 4346 ** the mapping to create. Otherwise, if nByte is less than zero, then the 4347 ** requested size is the size of the file on disk. The actual size of the 4348 ** created mapping is either the requested size or the value configured 4349 ** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. 4350 ** 4351 ** SQLITE_OK is returned if no error occurs (even if the mapping is not 4352 ** recreated as a result of outstanding references) or an SQLite error 4353 ** code otherwise. 4354 */ 4355 static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ 4356 sqlite3_int64 nMap = nByte; 4357 int rc; 4358 4359 assert( nMap>=0 || pFd->nFetchOut==0 ); 4360 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", 4361 osGetCurrentProcessId(), pFd, nByte)); 4362 4363 if( pFd->nFetchOut>0 ) return SQLITE_OK; 4364 4365 if( nMap<0 ){ 4366 rc = winFileSize((sqlite3_file*)pFd, &nMap); 4367 if( rc ){ 4368 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", 4369 osGetCurrentProcessId(), pFd)); 4370 return SQLITE_IOERR_FSTAT; 4371 } 4372 } 4373 if( nMap>pFd->mmapSizeMax ){ 4374 nMap = pFd->mmapSizeMax; 4375 } 4376 nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); 4377 4378 if( nMap==0 && pFd->mmapSize>0 ){ 4379 winUnmapfile(pFd); 4380 } 4381 if( nMap!=pFd->mmapSize ){ 4382 void *pNew = 0; 4383 DWORD protect = PAGE_READONLY; 4384 DWORD flags = FILE_MAP_READ; 4385 4386 winUnmapfile(pFd); 4387 #ifdef SQLITE_MMAP_READWRITE 4388 if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ 4389 protect = PAGE_READWRITE; 4390 flags |= FILE_MAP_WRITE; 4391 } 4392 #endif 4393 #if SQLITE_OS_WINRT 4394 pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); 4395 #elif defined(SQLITE_WIN32_HAS_WIDE) 4396 pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, 4397 (DWORD)((nMap>>32) & 0xffffffff), 4398 (DWORD)(nMap & 0xffffffff), NULL); 4399 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4400 pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, 4401 (DWORD)((nMap>>32) & 0xffffffff), 4402 (DWORD)(nMap & 0xffffffff), NULL); 4403 #endif 4404 if( pFd->hMap==NULL ){ 4405 pFd->lastErrno = osGetLastError(); 4406 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4407 "winMapfile1", pFd->zPath); 4408 /* Log the error, but continue normal operation using xRead/xWrite */ 4409 OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", 4410 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4411 return SQLITE_OK; 4412 } 4413 assert( (nMap % winSysInfo.dwPageSize)==0 ); 4414 assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); 4415 #if SQLITE_OS_WINRT 4416 pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); 4417 #else 4418 pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); 4419 #endif 4420 if( pNew==NULL ){ 4421 osCloseHandle(pFd->hMap); 4422 pFd->hMap = NULL; 4423 pFd->lastErrno = osGetLastError(); 4424 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4425 "winMapfile2", pFd->zPath); 4426 /* Log the error, but continue normal operation using xRead/xWrite */ 4427 OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", 4428 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4429 return SQLITE_OK; 4430 } 4431 pFd->pMapRegion = pNew; 4432 pFd->mmapSize = nMap; 4433 pFd->mmapSizeActual = nMap; 4434 } 4435 4436 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4437 osGetCurrentProcessId(), pFd)); 4438 return SQLITE_OK; 4439 } 4440 #endif /* SQLITE_MAX_MMAP_SIZE>0 */ 4441 4442 /* 4443 ** If possible, return a pointer to a mapping of file fd starting at offset 4444 ** iOff. The mapping must be valid for at least nAmt bytes. 4445 ** 4446 ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. 4447 ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. 4448 ** Finally, if an error does occur, return an SQLite error code. The final 4449 ** value of *pp is undefined in this case. 4450 ** 4451 ** If this function does return a pointer, the caller must eventually 4452 ** release the reference by calling winUnfetch(). 4453 */ 4454 static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ 4455 #if SQLITE_MAX_MMAP_SIZE>0 4456 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4457 #endif 4458 *pp = 0; 4459 4460 OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", 4461 osGetCurrentProcessId(), fd, iOff, nAmt, pp)); 4462 4463 #if SQLITE_MAX_MMAP_SIZE>0 4464 if( pFd->mmapSizeMax>0 ){ 4465 if( pFd->pMapRegion==0 ){ 4466 int rc = winMapfile(pFd, -1); 4467 if( rc!=SQLITE_OK ){ 4468 OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", 4469 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4470 return rc; 4471 } 4472 } 4473 if( pFd->mmapSize >= iOff+nAmt ){ 4474 *pp = &((u8 *)pFd->pMapRegion)[iOff]; 4475 pFd->nFetchOut++; 4476 } 4477 } 4478 #endif 4479 4480 OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", 4481 osGetCurrentProcessId(), fd, pp, *pp)); 4482 return SQLITE_OK; 4483 } 4484 4485 /* 4486 ** If the third argument is non-NULL, then this function releases a 4487 ** reference obtained by an earlier call to winFetch(). The second 4488 ** argument passed to this function must be the same as the corresponding 4489 ** argument that was passed to the winFetch() invocation. 4490 ** 4491 ** Or, if the third argument is NULL, then this function is being called 4492 ** to inform the VFS layer that, according to POSIX, any existing mapping 4493 ** may now be invalid and should be unmapped. 4494 */ 4495 static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ 4496 #if SQLITE_MAX_MMAP_SIZE>0 4497 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4498 4499 /* If p==0 (unmap the entire file) then there must be no outstanding 4500 ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), 4501 ** then there must be at least one outstanding. */ 4502 assert( (p==0)==(pFd->nFetchOut==0) ); 4503 4504 /* If p!=0, it must match the iOff value. */ 4505 assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); 4506 4507 OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", 4508 osGetCurrentProcessId(), pFd, iOff, p)); 4509 4510 if( p ){ 4511 pFd->nFetchOut--; 4512 }else{ 4513 /* FIXME: If Windows truly always prevents truncating or deleting a 4514 ** file while a mapping is held, then the following winUnmapfile() call 4515 ** is unnecessary can be omitted - potentially improving 4516 ** performance. */ 4517 winUnmapfile(pFd); 4518 } 4519 4520 assert( pFd->nFetchOut>=0 ); 4521 #endif 4522 4523 OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4524 osGetCurrentProcessId(), fd)); 4525 return SQLITE_OK; 4526 } 4527 4528 /* 4529 ** Here ends the implementation of all sqlite3_file methods. 4530 ** 4531 ********************** End sqlite3_file Methods ******************************* 4532 ******************************************************************************/ 4533 4534 /* 4535 ** This vector defines all the methods that can operate on an 4536 ** sqlite3_file for win32. 4537 */ 4538 static const sqlite3_io_methods winIoMethod = { 4539 3, /* iVersion */ 4540 winClose, /* xClose */ 4541 winRead, /* xRead */ 4542 winWrite, /* xWrite */ 4543 winTruncate, /* xTruncate */ 4544 winSync, /* xSync */ 4545 winFileSize, /* xFileSize */ 4546 winLock, /* xLock */ 4547 winUnlock, /* xUnlock */ 4548 winCheckReservedLock, /* xCheckReservedLock */ 4549 winFileControl, /* xFileControl */ 4550 winSectorSize, /* xSectorSize */ 4551 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4552 winShmMap, /* xShmMap */ 4553 winShmLock, /* xShmLock */ 4554 winShmBarrier, /* xShmBarrier */ 4555 winShmUnmap, /* xShmUnmap */ 4556 winFetch, /* xFetch */ 4557 winUnfetch /* xUnfetch */ 4558 }; 4559 4560 /* 4561 ** This vector defines all the methods that can operate on an 4562 ** sqlite3_file for win32 without performing any locking. 4563 */ 4564 static const sqlite3_io_methods winIoNolockMethod = { 4565 3, /* iVersion */ 4566 winClose, /* xClose */ 4567 winRead, /* xRead */ 4568 winWrite, /* xWrite */ 4569 winTruncate, /* xTruncate */ 4570 winSync, /* xSync */ 4571 winFileSize, /* xFileSize */ 4572 winNolockLock, /* xLock */ 4573 winNolockUnlock, /* xUnlock */ 4574 winNolockCheckReservedLock, /* xCheckReservedLock */ 4575 winFileControl, /* xFileControl */ 4576 winSectorSize, /* xSectorSize */ 4577 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4578 winShmMap, /* xShmMap */ 4579 winShmLock, /* xShmLock */ 4580 winShmBarrier, /* xShmBarrier */ 4581 winShmUnmap, /* xShmUnmap */ 4582 winFetch, /* xFetch */ 4583 winUnfetch /* xUnfetch */ 4584 }; 4585 4586 static winVfsAppData winAppData = { 4587 &winIoMethod, /* pMethod */ 4588 0, /* pAppData */ 4589 0 /* bNoLock */ 4590 }; 4591 4592 static winVfsAppData winNolockAppData = { 4593 &winIoNolockMethod, /* pMethod */ 4594 0, /* pAppData */ 4595 1 /* bNoLock */ 4596 }; 4597 4598 /**************************************************************************** 4599 **************************** sqlite3_vfs methods **************************** 4600 ** 4601 ** This division contains the implementation of methods on the 4602 ** sqlite3_vfs object. 4603 */ 4604 4605 #if defined(__CYGWIN__) 4606 /* 4607 ** Convert a filename from whatever the underlying operating system 4608 ** supports for filenames into UTF-8. Space to hold the result is 4609 ** obtained from malloc and must be freed by the calling function. 4610 */ 4611 static char *winConvertToUtf8Filename(const void *zFilename){ 4612 char *zConverted = 0; 4613 if( osIsNT() ){ 4614 zConverted = winUnicodeToUtf8(zFilename); 4615 } 4616 #ifdef SQLITE_WIN32_HAS_ANSI 4617 else{ 4618 zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); 4619 } 4620 #endif 4621 /* caller will handle out of memory */ 4622 return zConverted; 4623 } 4624 #endif 4625 4626 /* 4627 ** Convert a UTF-8 filename into whatever form the underlying 4628 ** operating system wants filenames in. Space to hold the result 4629 ** is obtained from malloc and must be freed by the calling 4630 ** function. 4631 */ 4632 static void *winConvertFromUtf8Filename(const char *zFilename){ 4633 void *zConverted = 0; 4634 if( osIsNT() ){ 4635 zConverted = winUtf8ToUnicode(zFilename); 4636 } 4637 #ifdef SQLITE_WIN32_HAS_ANSI 4638 else{ 4639 zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); 4640 } 4641 #endif 4642 /* caller will handle out of memory */ 4643 return zConverted; 4644 } 4645 4646 /* 4647 ** This function returns non-zero if the specified UTF-8 string buffer 4648 ** ends with a directory separator character or one was successfully 4649 ** added to it. 4650 */ 4651 static int winMakeEndInDirSep(int nBuf, char *zBuf){ 4652 if( zBuf ){ 4653 int nLen = sqlite3Strlen30(zBuf); 4654 if( nLen>0 ){ 4655 if( winIsDirSep(zBuf[nLen-1]) ){ 4656 return 1; 4657 }else if( nLen+1<nBuf ){ 4658 zBuf[nLen] = winGetDirSep(); 4659 zBuf[nLen+1] = '\0'; 4660 return 1; 4661 } 4662 } 4663 } 4664 return 0; 4665 } 4666 4667 /* 4668 ** Create a temporary file name and store the resulting pointer into pzBuf. 4669 ** The pointer returned in pzBuf must be freed via sqlite3_free(). 4670 */ 4671 static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ 4672 static char zChars[] = 4673 "abcdefghijklmnopqrstuvwxyz" 4674 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 4675 "0123456789"; 4676 size_t i, j; 4677 int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); 4678 int nMax, nBuf, nDir, nLen; 4679 char *zBuf; 4680 4681 /* It's odd to simulate an io-error here, but really this is just 4682 ** using the io-error infrastructure to test that SQLite handles this 4683 ** function failing. 4684 */ 4685 SimulateIOError( return SQLITE_IOERR ); 4686 4687 /* Allocate a temporary buffer to store the fully qualified file 4688 ** name for the temporary file. If this fails, we cannot continue. 4689 */ 4690 nMax = pVfs->mxPathname; nBuf = nMax + 2; 4691 zBuf = sqlite3MallocZero( nBuf ); 4692 if( !zBuf ){ 4693 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4694 return SQLITE_IOERR_NOMEM_BKPT; 4695 } 4696 4697 /* Figure out the effective temporary directory. First, check if one 4698 ** has been explicitly set by the application; otherwise, use the one 4699 ** configured by the operating system. 4700 */ 4701 nDir = nMax - (nPre + 15); 4702 assert( nDir>0 ); 4703 if( sqlite3_temp_directory ){ 4704 int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); 4705 if( nDirLen>0 ){ 4706 if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ 4707 nDirLen++; 4708 } 4709 if( nDirLen>nDir ){ 4710 sqlite3_free(zBuf); 4711 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4712 return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); 4713 } 4714 sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); 4715 } 4716 } 4717 #if defined(__CYGWIN__) 4718 else{ 4719 static const char *azDirs[] = { 4720 0, /* getenv("SQLITE_TMPDIR") */ 4721 0, /* getenv("TMPDIR") */ 4722 0, /* getenv("TMP") */ 4723 0, /* getenv("TEMP") */ 4724 0, /* getenv("USERPROFILE") */ 4725 "/var/tmp", 4726 "/usr/tmp", 4727 "/tmp", 4728 ".", 4729 0 /* List terminator */ 4730 }; 4731 unsigned int i; 4732 const char *zDir = 0; 4733 4734 if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); 4735 if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); 4736 if( !azDirs[2] ) azDirs[2] = getenv("TMP"); 4737 if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); 4738 if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); 4739 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ 4740 void *zConverted; 4741 if( zDir==0 ) continue; 4742 /* If the path starts with a drive letter followed by the colon 4743 ** character, assume it is already a native Win32 path; otherwise, 4744 ** it must be converted to a native Win32 path via the Cygwin API 4745 ** prior to using it. 4746 */ 4747 if( winIsDriveLetterAndColon(zDir) ){ 4748 zConverted = winConvertFromUtf8Filename(zDir); 4749 if( !zConverted ){ 4750 sqlite3_free(zBuf); 4751 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4752 return SQLITE_IOERR_NOMEM_BKPT; 4753 } 4754 if( winIsDir(zConverted) ){ 4755 sqlite3_snprintf(nMax, zBuf, "%s", zDir); 4756 sqlite3_free(zConverted); 4757 break; 4758 } 4759 sqlite3_free(zConverted); 4760 }else{ 4761 zConverted = sqlite3MallocZero( nMax+1 ); 4762 if( !zConverted ){ 4763 sqlite3_free(zBuf); 4764 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4765 return SQLITE_IOERR_NOMEM_BKPT; 4766 } 4767 if( cygwin_conv_path( 4768 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, 4769 zConverted, nMax+1)<0 ){ 4770 sqlite3_free(zConverted); 4771 sqlite3_free(zBuf); 4772 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); 4773 return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, 4774 "winGetTempname2", zDir); 4775 } 4776 if( winIsDir(zConverted) ){ 4777 /* At this point, we know the candidate directory exists and should 4778 ** be used. However, we may need to convert the string containing 4779 ** its name into UTF-8 (i.e. if it is UTF-16 right now). 4780 */ 4781 char *zUtf8 = winConvertToUtf8Filename(zConverted); 4782 if( !zUtf8 ){ 4783 sqlite3_free(zConverted); 4784 sqlite3_free(zBuf); 4785 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4786 return SQLITE_IOERR_NOMEM_BKPT; 4787 } 4788 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4789 sqlite3_free(zUtf8); 4790 sqlite3_free(zConverted); 4791 break; 4792 } 4793 sqlite3_free(zConverted); 4794 } 4795 } 4796 } 4797 #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) 4798 else if( osIsNT() ){ 4799 char *zMulti; 4800 LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); 4801 if( !zWidePath ){ 4802 sqlite3_free(zBuf); 4803 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4804 return SQLITE_IOERR_NOMEM_BKPT; 4805 } 4806 if( osGetTempPathW(nMax, zWidePath)==0 ){ 4807 sqlite3_free(zWidePath); 4808 sqlite3_free(zBuf); 4809 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4810 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4811 "winGetTempname2", 0); 4812 } 4813 zMulti = winUnicodeToUtf8(zWidePath); 4814 if( zMulti ){ 4815 sqlite3_snprintf(nMax, zBuf, "%s", zMulti); 4816 sqlite3_free(zMulti); 4817 sqlite3_free(zWidePath); 4818 }else{ 4819 sqlite3_free(zWidePath); 4820 sqlite3_free(zBuf); 4821 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4822 return SQLITE_IOERR_NOMEM_BKPT; 4823 } 4824 } 4825 #ifdef SQLITE_WIN32_HAS_ANSI 4826 else{ 4827 char *zUtf8; 4828 char *zMbcsPath = sqlite3MallocZero( nMax ); 4829 if( !zMbcsPath ){ 4830 sqlite3_free(zBuf); 4831 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4832 return SQLITE_IOERR_NOMEM_BKPT; 4833 } 4834 if( osGetTempPathA(nMax, zMbcsPath)==0 ){ 4835 sqlite3_free(zBuf); 4836 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4837 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4838 "winGetTempname3", 0); 4839 } 4840 zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); 4841 if( zUtf8 ){ 4842 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4843 sqlite3_free(zUtf8); 4844 }else{ 4845 sqlite3_free(zBuf); 4846 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4847 return SQLITE_IOERR_NOMEM_BKPT; 4848 } 4849 } 4850 #endif /* SQLITE_WIN32_HAS_ANSI */ 4851 #endif /* !SQLITE_OS_WINRT */ 4852 4853 /* 4854 ** Check to make sure the temporary directory ends with an appropriate 4855 ** separator. If it does not and there is not enough space left to add 4856 ** one, fail. 4857 */ 4858 if( !winMakeEndInDirSep(nDir+1, zBuf) ){ 4859 sqlite3_free(zBuf); 4860 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4861 return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0); 4862 } 4863 4864 /* 4865 ** Check that the output buffer is large enough for the temporary file 4866 ** name in the following format: 4867 ** 4868 ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0" 4869 ** 4870 ** If not, return SQLITE_ERROR. The number 17 is used here in order to 4871 ** account for the space used by the 15 character random suffix and the 4872 ** two trailing NUL characters. The final directory separator character 4873 ** has already added if it was not already present. 4874 */ 4875 nLen = sqlite3Strlen30(zBuf); 4876 if( (nLen + nPre + 17) > nBuf ){ 4877 sqlite3_free(zBuf); 4878 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4879 return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); 4880 } 4881 4882 sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); 4883 4884 j = sqlite3Strlen30(zBuf); 4885 sqlite3_randomness(15, &zBuf[j]); 4886 for(i=0; i<15; i++, j++){ 4887 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 4888 } 4889 zBuf[j] = 0; 4890 zBuf[j+1] = 0; 4891 *pzBuf = zBuf; 4892 4893 OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); 4894 return SQLITE_OK; 4895 } 4896 4897 /* 4898 ** Return TRUE if the named file is really a directory. Return false if 4899 ** it is something other than a directory, or if there is any kind of memory 4900 ** allocation failure. 4901 */ 4902 static int winIsDir(const void *zConverted){ 4903 DWORD attr; 4904 int rc = 0; 4905 DWORD lastErrno; 4906 4907 if( osIsNT() ){ 4908 int cnt = 0; 4909 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 4910 memset(&sAttrData, 0, sizeof(sAttrData)); 4911 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 4912 GetFileExInfoStandard, 4913 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 4914 if( !rc ){ 4915 return 0; /* Invalid name? */ 4916 } 4917 attr = sAttrData.dwFileAttributes; 4918 #if SQLITE_OS_WINCE==0 4919 }else{ 4920 attr = osGetFileAttributesA((char*)zConverted); 4921 #endif 4922 } 4923 return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); 4924 } 4925 4926 /* forward reference */ 4927 static int winAccess( 4928 sqlite3_vfs *pVfs, /* Not used on win32 */ 4929 const char *zFilename, /* Name of file to check */ 4930 int flags, /* Type of test to make on this file */ 4931 int *pResOut /* OUT: Result */ 4932 ); 4933 4934 /* 4935 ** Open a file. 4936 */ 4937 static int winOpen( 4938 sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ 4939 const char *zName, /* Name of the file (UTF-8) */ 4940 sqlite3_file *id, /* Write the SQLite file handle here */ 4941 int flags, /* Open mode flags */ 4942 int *pOutFlags /* Status return flags */ 4943 ){ 4944 HANDLE h; 4945 DWORD lastErrno = 0; 4946 DWORD dwDesiredAccess; 4947 DWORD dwShareMode; 4948 DWORD dwCreationDisposition; 4949 DWORD dwFlagsAndAttributes = 0; 4950 #if SQLITE_OS_WINCE 4951 int isTemp = 0; 4952 #endif 4953 winVfsAppData *pAppData; 4954 winFile *pFile = (winFile*)id; 4955 void *zConverted; /* Filename in OS encoding */ 4956 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ 4957 int cnt = 0; 4958 4959 /* If argument zPath is a NULL pointer, this function is required to open 4960 ** a temporary file. Use this buffer to store the file name in. 4961 */ 4962 char *zTmpname = 0; /* For temporary filename, if necessary. */ 4963 4964 int rc = SQLITE_OK; /* Function Return Code */ 4965 #if !defined(NDEBUG) || SQLITE_OS_WINCE 4966 int eType = flags&0xFFFFFF00; /* Type of file to open */ 4967 #endif 4968 4969 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); 4970 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); 4971 int isCreate = (flags & SQLITE_OPEN_CREATE); 4972 int isReadonly = (flags & SQLITE_OPEN_READONLY); 4973 int isReadWrite = (flags & SQLITE_OPEN_READWRITE); 4974 4975 #ifndef NDEBUG 4976 int isOpenJournal = (isCreate && ( 4977 eType==SQLITE_OPEN_MASTER_JOURNAL 4978 || eType==SQLITE_OPEN_MAIN_JOURNAL 4979 || eType==SQLITE_OPEN_WAL 4980 )); 4981 #endif 4982 4983 OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", 4984 zUtf8Name, id, flags, pOutFlags)); 4985 4986 /* Check the following statements are true: 4987 ** 4988 ** (a) Exactly one of the READWRITE and READONLY flags must be set, and 4989 ** (b) if CREATE is set, then READWRITE must also be set, and 4990 ** (c) if EXCLUSIVE is set, then CREATE must also be set. 4991 ** (d) if DELETEONCLOSE is set, then CREATE must also be set. 4992 */ 4993 assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); 4994 assert(isCreate==0 || isReadWrite); 4995 assert(isExclusive==0 || isCreate); 4996 assert(isDelete==0 || isCreate); 4997 4998 /* The main DB, main journal, WAL file and master journal are never 4999 ** automatically deleted. Nor are they ever temporary files. */ 5000 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); 5001 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); 5002 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); 5003 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); 5004 5005 /* Assert that the upper layer has set one of the "file-type" flags. */ 5006 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB 5007 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 5008 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL 5009 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL 5010 ); 5011 5012 assert( pFile!=0 ); 5013 memset(pFile, 0, sizeof(winFile)); 5014 pFile->h = INVALID_HANDLE_VALUE; 5015 5016 #if SQLITE_OS_WINRT 5017 if( !zUtf8Name && !sqlite3_temp_directory ){ 5018 sqlite3_log(SQLITE_ERROR, 5019 "sqlite3_temp_directory variable should be set for WinRT"); 5020 } 5021 #endif 5022 5023 /* If the second argument to this function is NULL, generate a 5024 ** temporary file name to use 5025 */ 5026 if( !zUtf8Name ){ 5027 assert( isDelete && !isOpenJournal ); 5028 rc = winGetTempname(pVfs, &zTmpname); 5029 if( rc!=SQLITE_OK ){ 5030 OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); 5031 return rc; 5032 } 5033 zUtf8Name = zTmpname; 5034 } 5035 5036 /* Database filenames are double-zero terminated if they are not 5037 ** URIs with parameters. Hence, they can always be passed into 5038 ** sqlite3_uri_parameter(). 5039 */ 5040 assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || 5041 zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); 5042 5043 /* Convert the filename to the system encoding. */ 5044 zConverted = winConvertFromUtf8Filename(zUtf8Name); 5045 if( zConverted==0 ){ 5046 sqlite3_free(zTmpname); 5047 OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); 5048 return SQLITE_IOERR_NOMEM_BKPT; 5049 } 5050 5051 if( winIsDir(zConverted) ){ 5052 sqlite3_free(zConverted); 5053 sqlite3_free(zTmpname); 5054 OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); 5055 return SQLITE_CANTOPEN_ISDIR; 5056 } 5057 5058 if( isReadWrite ){ 5059 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 5060 }else{ 5061 dwDesiredAccess = GENERIC_READ; 5062 } 5063 5064 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 5065 ** created. SQLite doesn't use it to indicate "exclusive access" 5066 ** as it is usually understood. 5067 */ 5068 if( isExclusive ){ 5069 /* Creates a new file, only if it does not already exist. */ 5070 /* If the file exists, it fails. */ 5071 dwCreationDisposition = CREATE_NEW; 5072 }else if( isCreate ){ 5073 /* Open existing file, or create if it doesn't exist */ 5074 dwCreationDisposition = OPEN_ALWAYS; 5075 }else{ 5076 /* Opens a file, only if it exists. */ 5077 dwCreationDisposition = OPEN_EXISTING; 5078 } 5079 5080 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 5081 5082 if( isDelete ){ 5083 #if SQLITE_OS_WINCE 5084 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; 5085 isTemp = 1; 5086 #else 5087 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY 5088 | FILE_ATTRIBUTE_HIDDEN 5089 | FILE_FLAG_DELETE_ON_CLOSE; 5090 #endif 5091 }else{ 5092 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 5093 } 5094 /* Reports from the internet are that performance is always 5095 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ 5096 #if SQLITE_OS_WINCE 5097 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; 5098 #endif 5099 5100 if( osIsNT() ){ 5101 #if SQLITE_OS_WINRT 5102 CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; 5103 extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 5104 extendedParameters.dwFileAttributes = 5105 dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; 5106 extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; 5107 extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; 5108 extendedParameters.lpSecurityAttributes = NULL; 5109 extendedParameters.hTemplateFile = NULL; 5110 do{ 5111 h = osCreateFile2((LPCWSTR)zConverted, 5112 dwDesiredAccess, 5113 dwShareMode, 5114 dwCreationDisposition, 5115 &extendedParameters); 5116 if( h!=INVALID_HANDLE_VALUE ) break; 5117 if( isReadWrite ){ 5118 int rc2, isRO = 0; 5119 sqlite3BeginBenignMalloc(); 5120 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5121 sqlite3EndBenignMalloc(); 5122 if( rc2==SQLITE_OK && isRO ) break; 5123 } 5124 }while( winRetryIoerr(&cnt, &lastErrno) ); 5125 #else 5126 do{ 5127 h = osCreateFileW((LPCWSTR)zConverted, 5128 dwDesiredAccess, 5129 dwShareMode, NULL, 5130 dwCreationDisposition, 5131 dwFlagsAndAttributes, 5132 NULL); 5133 if( h!=INVALID_HANDLE_VALUE ) break; 5134 if( isReadWrite ){ 5135 int rc2, isRO = 0; 5136 sqlite3BeginBenignMalloc(); 5137 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5138 sqlite3EndBenignMalloc(); 5139 if( rc2==SQLITE_OK && isRO ) break; 5140 } 5141 }while( winRetryIoerr(&cnt, &lastErrno) ); 5142 #endif 5143 } 5144 #ifdef SQLITE_WIN32_HAS_ANSI 5145 else{ 5146 do{ 5147 h = osCreateFileA((LPCSTR)zConverted, 5148 dwDesiredAccess, 5149 dwShareMode, NULL, 5150 dwCreationDisposition, 5151 dwFlagsAndAttributes, 5152 NULL); 5153 if( h!=INVALID_HANDLE_VALUE ) break; 5154 if( isReadWrite ){ 5155 int rc2, isRO = 0; 5156 sqlite3BeginBenignMalloc(); 5157 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5158 sqlite3EndBenignMalloc(); 5159 if( rc2==SQLITE_OK && isRO ) break; 5160 } 5161 }while( winRetryIoerr(&cnt, &lastErrno) ); 5162 } 5163 #endif 5164 winLogIoerr(cnt, __LINE__); 5165 5166 OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, 5167 dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5168 5169 if( h==INVALID_HANDLE_VALUE ){ 5170 sqlite3_free(zConverted); 5171 sqlite3_free(zTmpname); 5172 if( isReadWrite && !isExclusive ){ 5173 return winOpen(pVfs, zName, id, 5174 ((flags|SQLITE_OPEN_READONLY) & 5175 ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), 5176 pOutFlags); 5177 }else{ 5178 pFile->lastErrno = lastErrno; 5179 winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); 5180 return SQLITE_CANTOPEN_BKPT; 5181 } 5182 } 5183 5184 if( pOutFlags ){ 5185 if( isReadWrite ){ 5186 *pOutFlags = SQLITE_OPEN_READWRITE; 5187 }else{ 5188 *pOutFlags = SQLITE_OPEN_READONLY; 5189 } 5190 } 5191 5192 OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " 5193 "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? 5194 *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5195 5196 pAppData = (winVfsAppData*)pVfs->pAppData; 5197 5198 #if SQLITE_OS_WINCE 5199 { 5200 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB 5201 && ((pAppData==NULL) || !pAppData->bNoLock) 5202 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK 5203 ){ 5204 osCloseHandle(h); 5205 sqlite3_free(zConverted); 5206 sqlite3_free(zTmpname); 5207 OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); 5208 return rc; 5209 } 5210 } 5211 if( isTemp ){ 5212 pFile->zDeleteOnClose = zConverted; 5213 }else 5214 #endif 5215 { 5216 sqlite3_free(zConverted); 5217 } 5218 5219 sqlite3_free(zTmpname); 5220 pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; 5221 pFile->pVfs = pVfs; 5222 pFile->h = h; 5223 if( isReadonly ){ 5224 pFile->ctrlFlags |= WINFILE_RDONLY; 5225 } 5226 if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ 5227 pFile->ctrlFlags |= WINFILE_PSOW; 5228 } 5229 pFile->lastErrno = NO_ERROR; 5230 pFile->zPath = zName; 5231 #if SQLITE_MAX_MMAP_SIZE>0 5232 pFile->hMap = NULL; 5233 pFile->pMapRegion = 0; 5234 pFile->mmapSize = 0; 5235 pFile->mmapSizeActual = 0; 5236 pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; 5237 #endif 5238 5239 OpenCounter(+1); 5240 return rc; 5241 } 5242 5243 /* 5244 ** Delete the named file. 5245 ** 5246 ** Note that Windows does not allow a file to be deleted if some other 5247 ** process has it open. Sometimes a virus scanner or indexing program 5248 ** will open a journal file shortly after it is created in order to do 5249 ** whatever it does. While this other process is holding the 5250 ** file open, we will be unable to delete it. To work around this 5251 ** problem, we delay 100 milliseconds and try to delete again. Up 5252 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving 5253 ** up and returning an error. 5254 */ 5255 static int winDelete( 5256 sqlite3_vfs *pVfs, /* Not used on win32 */ 5257 const char *zFilename, /* Name of file to delete */ 5258 int syncDir /* Not used on win32 */ 5259 ){ 5260 int cnt = 0; 5261 int rc; 5262 DWORD attr; 5263 DWORD lastErrno = 0; 5264 void *zConverted; 5265 UNUSED_PARAMETER(pVfs); 5266 UNUSED_PARAMETER(syncDir); 5267 5268 SimulateIOError(return SQLITE_IOERR_DELETE); 5269 OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); 5270 5271 zConverted = winConvertFromUtf8Filename(zFilename); 5272 if( zConverted==0 ){ 5273 OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5274 return SQLITE_IOERR_NOMEM_BKPT; 5275 } 5276 if( osIsNT() ){ 5277 do { 5278 #if SQLITE_OS_WINRT 5279 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5280 memset(&sAttrData, 0, sizeof(sAttrData)); 5281 if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, 5282 &sAttrData) ){ 5283 attr = sAttrData.dwFileAttributes; 5284 }else{ 5285 lastErrno = osGetLastError(); 5286 if( lastErrno==ERROR_FILE_NOT_FOUND 5287 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5288 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5289 }else{ 5290 rc = SQLITE_ERROR; 5291 } 5292 break; 5293 } 5294 #else 5295 attr = osGetFileAttributesW(zConverted); 5296 #endif 5297 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5298 lastErrno = osGetLastError(); 5299 if( lastErrno==ERROR_FILE_NOT_FOUND 5300 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5301 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5302 }else{ 5303 rc = SQLITE_ERROR; 5304 } 5305 break; 5306 } 5307 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5308 rc = SQLITE_ERROR; /* Files only. */ 5309 break; 5310 } 5311 if ( osDeleteFileW(zConverted) ){ 5312 rc = SQLITE_OK; /* Deleted OK. */ 5313 break; 5314 } 5315 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5316 rc = SQLITE_ERROR; /* No more retries. */ 5317 break; 5318 } 5319 } while(1); 5320 } 5321 #ifdef SQLITE_WIN32_HAS_ANSI 5322 else{ 5323 do { 5324 attr = osGetFileAttributesA(zConverted); 5325 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5326 lastErrno = osGetLastError(); 5327 if( lastErrno==ERROR_FILE_NOT_FOUND 5328 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5329 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5330 }else{ 5331 rc = SQLITE_ERROR; 5332 } 5333 break; 5334 } 5335 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5336 rc = SQLITE_ERROR; /* Files only. */ 5337 break; 5338 } 5339 if ( osDeleteFileA(zConverted) ){ 5340 rc = SQLITE_OK; /* Deleted OK. */ 5341 break; 5342 } 5343 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5344 rc = SQLITE_ERROR; /* No more retries. */ 5345 break; 5346 } 5347 } while(1); 5348 } 5349 #endif 5350 if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ 5351 rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); 5352 }else{ 5353 winLogIoerr(cnt, __LINE__); 5354 } 5355 sqlite3_free(zConverted); 5356 OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); 5357 return rc; 5358 } 5359 5360 /* 5361 ** Check the existence and status of a file. 5362 */ 5363 static int winAccess( 5364 sqlite3_vfs *pVfs, /* Not used on win32 */ 5365 const char *zFilename, /* Name of file to check */ 5366 int flags, /* Type of test to make on this file */ 5367 int *pResOut /* OUT: Result */ 5368 ){ 5369 DWORD attr; 5370 int rc = 0; 5371 DWORD lastErrno = 0; 5372 void *zConverted; 5373 UNUSED_PARAMETER(pVfs); 5374 5375 SimulateIOError( return SQLITE_IOERR_ACCESS; ); 5376 OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", 5377 zFilename, flags, pResOut)); 5378 5379 zConverted = winConvertFromUtf8Filename(zFilename); 5380 if( zConverted==0 ){ 5381 OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5382 return SQLITE_IOERR_NOMEM_BKPT; 5383 } 5384 if( osIsNT() ){ 5385 int cnt = 0; 5386 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5387 memset(&sAttrData, 0, sizeof(sAttrData)); 5388 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 5389 GetFileExInfoStandard, 5390 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 5391 if( rc ){ 5392 /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file 5393 ** as if it does not exist. 5394 */ 5395 if( flags==SQLITE_ACCESS_EXISTS 5396 && sAttrData.nFileSizeHigh==0 5397 && sAttrData.nFileSizeLow==0 ){ 5398 attr = INVALID_FILE_ATTRIBUTES; 5399 }else{ 5400 attr = sAttrData.dwFileAttributes; 5401 } 5402 }else{ 5403 winLogIoerr(cnt, __LINE__); 5404 if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ 5405 sqlite3_free(zConverted); 5406 return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", 5407 zFilename); 5408 }else{ 5409 attr = INVALID_FILE_ATTRIBUTES; 5410 } 5411 } 5412 } 5413 #ifdef SQLITE_WIN32_HAS_ANSI 5414 else{ 5415 attr = osGetFileAttributesA((char*)zConverted); 5416 } 5417 #endif 5418 sqlite3_free(zConverted); 5419 switch( flags ){ 5420 case SQLITE_ACCESS_READ: 5421 case SQLITE_ACCESS_EXISTS: 5422 rc = attr!=INVALID_FILE_ATTRIBUTES; 5423 break; 5424 case SQLITE_ACCESS_READWRITE: 5425 rc = attr!=INVALID_FILE_ATTRIBUTES && 5426 (attr & FILE_ATTRIBUTE_READONLY)==0; 5427 break; 5428 default: 5429 assert(!"Invalid flags argument"); 5430 } 5431 *pResOut = rc; 5432 OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", 5433 zFilename, pResOut, *pResOut)); 5434 return SQLITE_OK; 5435 } 5436 5437 /* 5438 ** Returns non-zero if the specified path name starts with a drive letter 5439 ** followed by a colon character. 5440 */ 5441 static BOOL winIsDriveLetterAndColon( 5442 const char *zPathname 5443 ){ 5444 return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); 5445 } 5446 5447 /* 5448 ** Returns non-zero if the specified path name should be used verbatim. If 5449 ** non-zero is returned from this function, the calling function must simply 5450 ** use the provided path name verbatim -OR- resolve it into a full path name 5451 ** using the GetFullPathName Win32 API function (if available). 5452 */ 5453 static BOOL winIsVerbatimPathname( 5454 const char *zPathname 5455 ){ 5456 /* 5457 ** If the path name starts with a forward slash or a backslash, it is either 5458 ** a legal UNC name, a volume relative path, or an absolute path name in the 5459 ** "Unix" format on Windows. There is no easy way to differentiate between 5460 ** the final two cases; therefore, we return the safer return value of TRUE 5461 ** so that callers of this function will simply use it verbatim. 5462 */ 5463 if ( winIsDirSep(zPathname[0]) ){ 5464 return TRUE; 5465 } 5466 5467 /* 5468 ** If the path name starts with a letter and a colon it is either a volume 5469 ** relative path or an absolute path. Callers of this function must not 5470 ** attempt to treat it as a relative path name (i.e. they should simply use 5471 ** it verbatim). 5472 */ 5473 if ( winIsDriveLetterAndColon(zPathname) ){ 5474 return TRUE; 5475 } 5476 5477 /* 5478 ** If we get to this point, the path name should almost certainly be a purely 5479 ** relative one (i.e. not a UNC name, not absolute, and not volume relative). 5480 */ 5481 return FALSE; 5482 } 5483 5484 /* 5485 ** Turn a relative pathname into a full pathname. Write the full 5486 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname 5487 ** bytes in size. 5488 */ 5489 static int winFullPathname( 5490 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 5491 const char *zRelative, /* Possibly relative input path */ 5492 int nFull, /* Size of output buffer in bytes */ 5493 char *zFull /* Output buffer */ 5494 ){ 5495 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5496 DWORD nByte; 5497 void *zConverted; 5498 char *zOut; 5499 #endif 5500 5501 /* If this path name begins with "/X:", where "X" is any alphabetic 5502 ** character, discard the initial "/" from the pathname. 5503 */ 5504 if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ 5505 zRelative++; 5506 } 5507 5508 #if defined(__CYGWIN__) 5509 SimulateIOError( return SQLITE_ERROR ); 5510 UNUSED_PARAMETER(nFull); 5511 assert( nFull>=pVfs->mxPathname ); 5512 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5513 /* 5514 ** NOTE: We are dealing with a relative path name and the data 5515 ** directory has been set. Therefore, use it as the basis 5516 ** for converting the relative path name to an absolute 5517 ** one by prepending the data directory and a slash. 5518 */ 5519 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5520 if( !zOut ){ 5521 return SQLITE_IOERR_NOMEM_BKPT; 5522 } 5523 if( cygwin_conv_path( 5524 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | 5525 CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5526 sqlite3_free(zOut); 5527 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5528 "winFullPathname1", zRelative); 5529 }else{ 5530 char *zUtf8 = winConvertToUtf8Filename(zOut); 5531 if( !zUtf8 ){ 5532 sqlite3_free(zOut); 5533 return SQLITE_IOERR_NOMEM_BKPT; 5534 } 5535 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5536 sqlite3_data_directory, winGetDirSep(), zUtf8); 5537 sqlite3_free(zUtf8); 5538 sqlite3_free(zOut); 5539 } 5540 }else{ 5541 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5542 if( !zOut ){ 5543 return SQLITE_IOERR_NOMEM_BKPT; 5544 } 5545 if( cygwin_conv_path( 5546 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), 5547 zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5548 sqlite3_free(zOut); 5549 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5550 "winFullPathname2", zRelative); 5551 }else{ 5552 char *zUtf8 = winConvertToUtf8Filename(zOut); 5553 if( !zUtf8 ){ 5554 sqlite3_free(zOut); 5555 return SQLITE_IOERR_NOMEM_BKPT; 5556 } 5557 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); 5558 sqlite3_free(zUtf8); 5559 sqlite3_free(zOut); 5560 } 5561 } 5562 return SQLITE_OK; 5563 #endif 5564 5565 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) 5566 SimulateIOError( return SQLITE_ERROR ); 5567 /* WinCE has no concept of a relative pathname, or so I am told. */ 5568 /* WinRT has no way to convert a relative path to an absolute one. */ 5569 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5570 /* 5571 ** NOTE: We are dealing with a relative path name and the data 5572 ** directory has been set. Therefore, use it as the basis 5573 ** for converting the relative path name to an absolute 5574 ** one by prepending the data directory and a backslash. 5575 */ 5576 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5577 sqlite3_data_directory, winGetDirSep(), zRelative); 5578 }else{ 5579 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); 5580 } 5581 return SQLITE_OK; 5582 #endif 5583 5584 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5585 /* It's odd to simulate an io-error here, but really this is just 5586 ** using the io-error infrastructure to test that SQLite handles this 5587 ** function failing. This function could fail if, for example, the 5588 ** current working directory has been unlinked. 5589 */ 5590 SimulateIOError( return SQLITE_ERROR ); 5591 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5592 /* 5593 ** NOTE: We are dealing with a relative path name and the data 5594 ** directory has been set. Therefore, use it as the basis 5595 ** for converting the relative path name to an absolute 5596 ** one by prepending the data directory and a backslash. 5597 */ 5598 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5599 sqlite3_data_directory, winGetDirSep(), zRelative); 5600 return SQLITE_OK; 5601 } 5602 zConverted = winConvertFromUtf8Filename(zRelative); 5603 if( zConverted==0 ){ 5604 return SQLITE_IOERR_NOMEM_BKPT; 5605 } 5606 if( osIsNT() ){ 5607 LPWSTR zTemp; 5608 nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); 5609 if( nByte==0 ){ 5610 sqlite3_free(zConverted); 5611 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5612 "winFullPathname1", zRelative); 5613 } 5614 nByte += 3; 5615 zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); 5616 if( zTemp==0 ){ 5617 sqlite3_free(zConverted); 5618 return SQLITE_IOERR_NOMEM_BKPT; 5619 } 5620 nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); 5621 if( nByte==0 ){ 5622 sqlite3_free(zConverted); 5623 sqlite3_free(zTemp); 5624 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5625 "winFullPathname2", zRelative); 5626 } 5627 sqlite3_free(zConverted); 5628 zOut = winUnicodeToUtf8(zTemp); 5629 sqlite3_free(zTemp); 5630 } 5631 #ifdef SQLITE_WIN32_HAS_ANSI 5632 else{ 5633 char *zTemp; 5634 nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); 5635 if( nByte==0 ){ 5636 sqlite3_free(zConverted); 5637 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5638 "winFullPathname3", zRelative); 5639 } 5640 nByte += 3; 5641 zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); 5642 if( zTemp==0 ){ 5643 sqlite3_free(zConverted); 5644 return SQLITE_IOERR_NOMEM_BKPT; 5645 } 5646 nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); 5647 if( nByte==0 ){ 5648 sqlite3_free(zConverted); 5649 sqlite3_free(zTemp); 5650 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5651 "winFullPathname4", zRelative); 5652 } 5653 sqlite3_free(zConverted); 5654 zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); 5655 sqlite3_free(zTemp); 5656 } 5657 #endif 5658 if( zOut ){ 5659 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); 5660 sqlite3_free(zOut); 5661 return SQLITE_OK; 5662 }else{ 5663 return SQLITE_IOERR_NOMEM_BKPT; 5664 } 5665 #endif 5666 } 5667 5668 #ifndef SQLITE_OMIT_LOAD_EXTENSION 5669 /* 5670 ** Interfaces for opening a shared library, finding entry points 5671 ** within the shared library, and closing the shared library. 5672 */ 5673 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 5674 HANDLE h; 5675 #if defined(__CYGWIN__) 5676 int nFull = pVfs->mxPathname+1; 5677 char *zFull = sqlite3MallocZero( nFull ); 5678 void *zConverted = 0; 5679 if( zFull==0 ){ 5680 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5681 return 0; 5682 } 5683 if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ 5684 sqlite3_free(zFull); 5685 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5686 return 0; 5687 } 5688 zConverted = winConvertFromUtf8Filename(zFull); 5689 sqlite3_free(zFull); 5690 #else 5691 void *zConverted = winConvertFromUtf8Filename(zFilename); 5692 UNUSED_PARAMETER(pVfs); 5693 #endif 5694 if( zConverted==0 ){ 5695 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5696 return 0; 5697 } 5698 if( osIsNT() ){ 5699 #if SQLITE_OS_WINRT 5700 h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); 5701 #else 5702 h = osLoadLibraryW((LPCWSTR)zConverted); 5703 #endif 5704 } 5705 #ifdef SQLITE_WIN32_HAS_ANSI 5706 else{ 5707 h = osLoadLibraryA((char*)zConverted); 5708 } 5709 #endif 5710 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); 5711 sqlite3_free(zConverted); 5712 return (void*)h; 5713 } 5714 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 5715 UNUSED_PARAMETER(pVfs); 5716 winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); 5717 } 5718 static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ 5719 FARPROC proc; 5720 UNUSED_PARAMETER(pVfs); 5721 proc = osGetProcAddressA((HANDLE)pH, zSym); 5722 OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", 5723 (void*)pH, zSym, (void*)proc)); 5724 return (void(*)(void))proc; 5725 } 5726 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ 5727 UNUSED_PARAMETER(pVfs); 5728 osFreeLibrary((HANDLE)pHandle); 5729 OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); 5730 } 5731 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 5732 #define winDlOpen 0 5733 #define winDlError 0 5734 #define winDlSym 0 5735 #define winDlClose 0 5736 #endif 5737 5738 /* State information for the randomness gatherer. */ 5739 typedef struct EntropyGatherer EntropyGatherer; 5740 struct EntropyGatherer { 5741 unsigned char *a; /* Gather entropy into this buffer */ 5742 int na; /* Size of a[] in bytes */ 5743 int i; /* XOR next input into a[i] */ 5744 int nXor; /* Number of XOR operations done */ 5745 }; 5746 5747 #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) 5748 /* Mix sz bytes of entropy into p. */ 5749 static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ 5750 int j, k; 5751 for(j=0, k=p->i; j<sz; j++){ 5752 p->a[k++] ^= x[j]; 5753 if( k>=p->na ) k = 0; 5754 } 5755 p->i = k; 5756 p->nXor += sz; 5757 } 5758 #endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ 5759 5760 /* 5761 ** Write up to nBuf bytes of randomness into zBuf. 5762 */ 5763 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5764 #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) 5765 UNUSED_PARAMETER(pVfs); 5766 memset(zBuf, 0, nBuf); 5767 return nBuf; 5768 #else 5769 EntropyGatherer e; 5770 UNUSED_PARAMETER(pVfs); 5771 memset(zBuf, 0, nBuf); 5772 e.a = (unsigned char*)zBuf; 5773 e.na = nBuf; 5774 e.nXor = 0; 5775 e.i = 0; 5776 { 5777 SYSTEMTIME x; 5778 osGetSystemTime(&x); 5779 xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); 5780 } 5781 { 5782 DWORD pid = osGetCurrentProcessId(); 5783 xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); 5784 } 5785 #if SQLITE_OS_WINRT 5786 { 5787 ULONGLONG cnt = osGetTickCount64(); 5788 xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); 5789 } 5790 #else 5791 { 5792 DWORD cnt = osGetTickCount(); 5793 xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); 5794 } 5795 #endif /* SQLITE_OS_WINRT */ 5796 { 5797 LARGE_INTEGER i; 5798 osQueryPerformanceCounter(&i); 5799 xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); 5800 } 5801 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID 5802 { 5803 UUID id; 5804 memset(&id, 0, sizeof(UUID)); 5805 osUuidCreate(&id); 5806 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5807 memset(&id, 0, sizeof(UUID)); 5808 osUuidCreateSequential(&id); 5809 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5810 } 5811 #endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ 5812 return e.nXor>nBuf ? nBuf : e.nXor; 5813 #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ 5814 } 5815 5816 5817 /* 5818 ** Sleep for a little while. Return the amount of time slept. 5819 */ 5820 static int winSleep(sqlite3_vfs *pVfs, int microsec){ 5821 sqlite3_win32_sleep((microsec+999)/1000); 5822 UNUSED_PARAMETER(pVfs); 5823 return ((microsec+999)/1000)*1000; 5824 } 5825 5826 /* 5827 ** The following variable, if set to a non-zero value, is interpreted as 5828 ** the number of seconds since 1970 and is used to set the result of 5829 ** sqlite3OsCurrentTime() during testing. 5830 */ 5831 #ifdef SQLITE_TEST 5832 int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ 5833 #endif 5834 5835 /* 5836 ** Find the current time (in Universal Coordinated Time). Write into *piNow 5837 ** the current time and date as a Julian Day number times 86_400_000. In 5838 ** other words, write into *piNow the number of milliseconds since the Julian 5839 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the 5840 ** proleptic Gregorian calendar. 5841 ** 5842 ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date 5843 ** cannot be found. 5844 */ 5845 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ 5846 /* FILETIME structure is a 64-bit value representing the number of 5847 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 5848 */ 5849 FILETIME ft; 5850 static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; 5851 #ifdef SQLITE_TEST 5852 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; 5853 #endif 5854 /* 2^32 - to avoid use of LL and warnings in gcc */ 5855 static const sqlite3_int64 max32BitValue = 5856 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + 5857 (sqlite3_int64)294967296; 5858 5859 #if SQLITE_OS_WINCE 5860 SYSTEMTIME time; 5861 osGetSystemTime(&time); 5862 /* if SystemTimeToFileTime() fails, it returns zero. */ 5863 if (!osSystemTimeToFileTime(&time,&ft)){ 5864 return SQLITE_ERROR; 5865 } 5866 #else 5867 osGetSystemTimeAsFileTime( &ft ); 5868 #endif 5869 5870 *piNow = winFiletimeEpoch + 5871 ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 5872 (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; 5873 5874 #ifdef SQLITE_TEST 5875 if( sqlite3_current_time ){ 5876 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; 5877 } 5878 #endif 5879 UNUSED_PARAMETER(pVfs); 5880 return SQLITE_OK; 5881 } 5882 5883 /* 5884 ** Find the current time (in Universal Coordinated Time). Write the 5885 ** current time and date as a Julian Day number into *prNow and 5886 ** return 0. Return 1 if the time and date cannot be found. 5887 */ 5888 static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ 5889 int rc; 5890 sqlite3_int64 i; 5891 rc = winCurrentTimeInt64(pVfs, &i); 5892 if( !rc ){ 5893 *prNow = i/86400000.0; 5894 } 5895 return rc; 5896 } 5897 5898 /* 5899 ** The idea is that this function works like a combination of 5900 ** GetLastError() and FormatMessage() on Windows (or errno and 5901 ** strerror_r() on Unix). After an error is returned by an OS 5902 ** function, SQLite calls this function with zBuf pointing to 5903 ** a buffer of nBuf bytes. The OS layer should populate the 5904 ** buffer with a nul-terminated UTF-8 encoded error message 5905 ** describing the last IO error to have occurred within the calling 5906 ** thread. 5907 ** 5908 ** If the error message is too large for the supplied buffer, 5909 ** it should be truncated. The return value of xGetLastError 5910 ** is zero if the error message fits in the buffer, or non-zero 5911 ** otherwise (if the message was truncated). If non-zero is returned, 5912 ** then it is not necessary to include the nul-terminator character 5913 ** in the output buffer. 5914 ** 5915 ** Not supplying an error message will have no adverse effect 5916 ** on SQLite. It is fine to have an implementation that never 5917 ** returns an error message: 5918 ** 5919 ** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5920 ** assert(zBuf[0]=='\0'); 5921 ** return 0; 5922 ** } 5923 ** 5924 ** However if an error message is supplied, it will be incorporated 5925 ** by sqlite into the error message available to the user using 5926 ** sqlite3_errmsg(), possibly making IO errors easier to debug. 5927 */ 5928 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5929 DWORD e = osGetLastError(); 5930 UNUSED_PARAMETER(pVfs); 5931 if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); 5932 return e; 5933 } 5934 5935 /* 5936 ** Initialize and deinitialize the operating system interface. 5937 */ 5938 int sqlite3_os_init(void){ 5939 static sqlite3_vfs winVfs = { 5940 3, /* iVersion */ 5941 sizeof(winFile), /* szOsFile */ 5942 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 5943 0, /* pNext */ 5944 "win32", /* zName */ 5945 &winAppData, /* pAppData */ 5946 winOpen, /* xOpen */ 5947 winDelete, /* xDelete */ 5948 winAccess, /* xAccess */ 5949 winFullPathname, /* xFullPathname */ 5950 winDlOpen, /* xDlOpen */ 5951 winDlError, /* xDlError */ 5952 winDlSym, /* xDlSym */ 5953 winDlClose, /* xDlClose */ 5954 winRandomness, /* xRandomness */ 5955 winSleep, /* xSleep */ 5956 winCurrentTime, /* xCurrentTime */ 5957 winGetLastError, /* xGetLastError */ 5958 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 5959 winSetSystemCall, /* xSetSystemCall */ 5960 winGetSystemCall, /* xGetSystemCall */ 5961 winNextSystemCall, /* xNextSystemCall */ 5962 }; 5963 #if defined(SQLITE_WIN32_HAS_WIDE) 5964 static sqlite3_vfs winLongPathVfs = { 5965 3, /* iVersion */ 5966 sizeof(winFile), /* szOsFile */ 5967 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 5968 0, /* pNext */ 5969 "win32-longpath", /* zName */ 5970 &winAppData, /* pAppData */ 5971 winOpen, /* xOpen */ 5972 winDelete, /* xDelete */ 5973 winAccess, /* xAccess */ 5974 winFullPathname, /* xFullPathname */ 5975 winDlOpen, /* xDlOpen */ 5976 winDlError, /* xDlError */ 5977 winDlSym, /* xDlSym */ 5978 winDlClose, /* xDlClose */ 5979 winRandomness, /* xRandomness */ 5980 winSleep, /* xSleep */ 5981 winCurrentTime, /* xCurrentTime */ 5982 winGetLastError, /* xGetLastError */ 5983 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 5984 winSetSystemCall, /* xSetSystemCall */ 5985 winGetSystemCall, /* xGetSystemCall */ 5986 winNextSystemCall, /* xNextSystemCall */ 5987 }; 5988 #endif 5989 static sqlite3_vfs winNolockVfs = { 5990 3, /* iVersion */ 5991 sizeof(winFile), /* szOsFile */ 5992 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 5993 0, /* pNext */ 5994 "win32-none", /* zName */ 5995 &winNolockAppData, /* pAppData */ 5996 winOpen, /* xOpen */ 5997 winDelete, /* xDelete */ 5998 winAccess, /* xAccess */ 5999 winFullPathname, /* xFullPathname */ 6000 winDlOpen, /* xDlOpen */ 6001 winDlError, /* xDlError */ 6002 winDlSym, /* xDlSym */ 6003 winDlClose, /* xDlClose */ 6004 winRandomness, /* xRandomness */ 6005 winSleep, /* xSleep */ 6006 winCurrentTime, /* xCurrentTime */ 6007 winGetLastError, /* xGetLastError */ 6008 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6009 winSetSystemCall, /* xSetSystemCall */ 6010 winGetSystemCall, /* xGetSystemCall */ 6011 winNextSystemCall, /* xNextSystemCall */ 6012 }; 6013 #if defined(SQLITE_WIN32_HAS_WIDE) 6014 static sqlite3_vfs winLongPathNolockVfs = { 6015 3, /* iVersion */ 6016 sizeof(winFile), /* szOsFile */ 6017 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 6018 0, /* pNext */ 6019 "win32-longpath-none", /* zName */ 6020 &winNolockAppData, /* pAppData */ 6021 winOpen, /* xOpen */ 6022 winDelete, /* xDelete */ 6023 winAccess, /* xAccess */ 6024 winFullPathname, /* xFullPathname */ 6025 winDlOpen, /* xDlOpen */ 6026 winDlError, /* xDlError */ 6027 winDlSym, /* xDlSym */ 6028 winDlClose, /* xDlClose */ 6029 winRandomness, /* xRandomness */ 6030 winSleep, /* xSleep */ 6031 winCurrentTime, /* xCurrentTime */ 6032 winGetLastError, /* xGetLastError */ 6033 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6034 winSetSystemCall, /* xSetSystemCall */ 6035 winGetSystemCall, /* xGetSystemCall */ 6036 winNextSystemCall, /* xNextSystemCall */ 6037 }; 6038 #endif 6039 6040 /* Double-check that the aSyscall[] array has been constructed 6041 ** correctly. See ticket [bb3a86e890c8e96ab] */ 6042 assert( ArraySize(aSyscall)==80 ); 6043 6044 /* get memory map allocation granularity */ 6045 memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); 6046 #if SQLITE_OS_WINRT 6047 osGetNativeSystemInfo(&winSysInfo); 6048 #else 6049 osGetSystemInfo(&winSysInfo); 6050 #endif 6051 assert( winSysInfo.dwAllocationGranularity>0 ); 6052 assert( winSysInfo.dwPageSize>0 ); 6053 6054 sqlite3_vfs_register(&winVfs, 1); 6055 6056 #if defined(SQLITE_WIN32_HAS_WIDE) 6057 sqlite3_vfs_register(&winLongPathVfs, 0); 6058 #endif 6059 6060 sqlite3_vfs_register(&winNolockVfs, 0); 6061 6062 #if defined(SQLITE_WIN32_HAS_WIDE) 6063 sqlite3_vfs_register(&winLongPathNolockVfs, 0); 6064 #endif 6065 6066 #ifndef SQLITE_OMIT_WAL 6067 winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); 6068 #endif 6069 6070 return SQLITE_OK; 6071 } 6072 6073 int sqlite3_os_end(void){ 6074 #if SQLITE_OS_WINRT 6075 if( sleepObj!=NULL ){ 6076 osCloseHandle(sleepObj); 6077 sleepObj = NULL; 6078 } 6079 #endif 6080 6081 #ifndef SQLITE_OMIT_WAL 6082 winBigLock = 0; 6083 #endif 6084 6085 return SQLITE_OK; 6086 } 6087 6088 #endif /* SQLITE_OS_WIN */ 6089