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