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