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 if( pFile->nFetchOut>0 ){ 2909 /* File truncation is a no-op if there are outstanding memory mapped 2910 ** pages. This is because truncating the file means temporarily unmapping 2911 ** the file, and that might delete memory out from under existing cursors. 2912 ** 2913 ** This can result in incremental vacuum not truncating the file, 2914 ** if there is an active read cursor when the incremental vacuum occurs. 2915 ** No real harm comes of this - the database file is not corrupted, 2916 ** though some folks might complain that the file is bigger than it 2917 ** needs to be. 2918 ** 2919 ** The only feasible work-around is to defer the truncation until after 2920 ** all references to memory-mapped content are closed. That is doable, 2921 ** but involves adding a few branches in the common write code path which 2922 ** could slow down normal operations slightly. Hence, we have decided for 2923 ** now to simply make trancations a no-op if there are pending reads. We 2924 ** can maybe revisit this decision in the future. 2925 */ 2926 return SQLITE_OK; 2927 } 2928 #endif 2929 2930 assert( pFile ); 2931 SimulateIOError(return SQLITE_IOERR_TRUNCATE); 2932 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", 2933 osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); 2934 2935 /* If the user has configured a chunk-size for this file, truncate the 2936 ** file so that it consists of an integer number of chunks (i.e. the 2937 ** actual file size after the operation may be larger than the requested 2938 ** size). 2939 */ 2940 if( pFile->szChunk>0 ){ 2941 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; 2942 } 2943 2944 #if SQLITE_MAX_MMAP_SIZE>0 2945 if( pFile->pMapRegion ){ 2946 oldMmapSize = pFile->mmapSize; 2947 }else{ 2948 oldMmapSize = 0; 2949 } 2950 winUnmapfile(pFile); 2951 #endif 2952 2953 /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ 2954 if( winSeekFile(pFile, nByte) ){ 2955 rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, 2956 "winTruncate1", pFile->zPath); 2957 }else if( 0==osSetEndOfFile(pFile->h) && 2958 ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ 2959 pFile->lastErrno = lastErrno; 2960 rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, 2961 "winTruncate2", pFile->zPath); 2962 } 2963 2964 #if SQLITE_MAX_MMAP_SIZE>0 2965 if( rc==SQLITE_OK && oldMmapSize>0 ){ 2966 if( oldMmapSize>nByte ){ 2967 winMapfile(pFile, -1); 2968 }else{ 2969 winMapfile(pFile, oldMmapSize); 2970 } 2971 } 2972 #endif 2973 2974 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", 2975 osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); 2976 return rc; 2977 } 2978 2979 #ifdef SQLITE_TEST 2980 /* 2981 ** Count the number of fullsyncs and normal syncs. This is used to test 2982 ** that syncs and fullsyncs are occuring at the right times. 2983 */ 2984 int sqlite3_sync_count = 0; 2985 int sqlite3_fullsync_count = 0; 2986 #endif 2987 2988 /* 2989 ** Make sure all writes to a particular file are committed to disk. 2990 */ 2991 static int winSync(sqlite3_file *id, int flags){ 2992 #ifndef SQLITE_NO_SYNC 2993 /* 2994 ** Used only when SQLITE_NO_SYNC is not defined. 2995 */ 2996 BOOL rc; 2997 #endif 2998 #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ 2999 defined(SQLITE_HAVE_OS_TRACE) 3000 /* 3001 ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or 3002 ** OSTRACE() macros. 3003 */ 3004 winFile *pFile = (winFile*)id; 3005 #else 3006 UNUSED_PARAMETER(id); 3007 #endif 3008 3009 assert( pFile ); 3010 /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ 3011 assert((flags&0x0F)==SQLITE_SYNC_NORMAL 3012 || (flags&0x0F)==SQLITE_SYNC_FULL 3013 ); 3014 3015 /* Unix cannot, but some systems may return SQLITE_FULL from here. This 3016 ** line is to test that doing so does not cause any problems. 3017 */ 3018 SimulateDiskfullError( return SQLITE_FULL ); 3019 3020 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", 3021 osGetCurrentProcessId(), pFile, pFile->h, flags, 3022 pFile->locktype)); 3023 3024 #ifndef SQLITE_TEST 3025 UNUSED_PARAMETER(flags); 3026 #else 3027 if( (flags&0x0F)==SQLITE_SYNC_FULL ){ 3028 sqlite3_fullsync_count++; 3029 } 3030 sqlite3_sync_count++; 3031 #endif 3032 3033 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a 3034 ** no-op 3035 */ 3036 #ifdef SQLITE_NO_SYNC 3037 OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 3038 osGetCurrentProcessId(), pFile, pFile->h)); 3039 return SQLITE_OK; 3040 #else 3041 #if SQLITE_MAX_MMAP_SIZE>0 3042 if( pFile->pMapRegion ){ 3043 if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ 3044 OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " 3045 "rc=SQLITE_OK\n", osGetCurrentProcessId(), 3046 pFile, pFile->pMapRegion)); 3047 }else{ 3048 pFile->lastErrno = osGetLastError(); 3049 OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " 3050 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), 3051 pFile, pFile->pMapRegion)); 3052 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 3053 "winSync1", pFile->zPath); 3054 } 3055 } 3056 #endif 3057 rc = osFlushFileBuffers(pFile->h); 3058 SimulateIOError( rc=FALSE ); 3059 if( rc ){ 3060 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 3061 osGetCurrentProcessId(), pFile, pFile->h)); 3062 return SQLITE_OK; 3063 }else{ 3064 pFile->lastErrno = osGetLastError(); 3065 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", 3066 osGetCurrentProcessId(), pFile, pFile->h)); 3067 return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, 3068 "winSync2", pFile->zPath); 3069 } 3070 #endif 3071 } 3072 3073 /* 3074 ** Determine the current size of a file in bytes 3075 */ 3076 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ 3077 winFile *pFile = (winFile*)id; 3078 int rc = SQLITE_OK; 3079 3080 assert( id!=0 ); 3081 assert( pSize!=0 ); 3082 SimulateIOError(return SQLITE_IOERR_FSTAT); 3083 OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); 3084 3085 #if SQLITE_OS_WINRT 3086 { 3087 FILE_STANDARD_INFO info; 3088 if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, 3089 &info, sizeof(info)) ){ 3090 *pSize = info.EndOfFile.QuadPart; 3091 }else{ 3092 pFile->lastErrno = osGetLastError(); 3093 rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, 3094 "winFileSize", pFile->zPath); 3095 } 3096 } 3097 #else 3098 { 3099 DWORD upperBits; 3100 DWORD lowerBits; 3101 DWORD lastErrno; 3102 3103 lowerBits = osGetFileSize(pFile->h, &upperBits); 3104 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; 3105 if( (lowerBits == INVALID_FILE_SIZE) 3106 && ((lastErrno = osGetLastError())!=NO_ERROR) ){ 3107 pFile->lastErrno = lastErrno; 3108 rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, 3109 "winFileSize", pFile->zPath); 3110 } 3111 } 3112 #endif 3113 OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", 3114 pFile->h, pSize, *pSize, sqlite3ErrName(rc))); 3115 return rc; 3116 } 3117 3118 /* 3119 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. 3120 */ 3121 #ifndef LOCKFILE_FAIL_IMMEDIATELY 3122 # define LOCKFILE_FAIL_IMMEDIATELY 1 3123 #endif 3124 3125 #ifndef LOCKFILE_EXCLUSIVE_LOCK 3126 # define LOCKFILE_EXCLUSIVE_LOCK 2 3127 #endif 3128 3129 /* 3130 ** Historically, SQLite has used both the LockFile and LockFileEx functions. 3131 ** When the LockFile function was used, it was always expected to fail 3132 ** immediately if the lock could not be obtained. Also, it always expected to 3133 ** obtain an exclusive lock. These flags are used with the LockFileEx function 3134 ** and reflect those expectations; therefore, they should not be changed. 3135 */ 3136 #ifndef SQLITE_LOCKFILE_FLAGS 3137 # define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ 3138 LOCKFILE_EXCLUSIVE_LOCK) 3139 #endif 3140 3141 /* 3142 ** Currently, SQLite never calls the LockFileEx function without wanting the 3143 ** call to fail immediately if the lock cannot be obtained. 3144 */ 3145 #ifndef SQLITE_LOCKFILEEX_FLAGS 3146 # define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) 3147 #endif 3148 3149 /* 3150 ** Acquire a reader lock. 3151 ** Different API routines are called depending on whether or not this 3152 ** is Win9x or WinNT. 3153 */ 3154 static int winGetReadLock(winFile *pFile){ 3155 int res; 3156 OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); 3157 if( osIsNT() ){ 3158 #if SQLITE_OS_WINCE 3159 /* 3160 ** NOTE: Windows CE is handled differently here due its lack of the Win32 3161 ** API LockFileEx. 3162 */ 3163 res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); 3164 #else 3165 res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, 3166 SHARED_SIZE, 0); 3167 #endif 3168 } 3169 #ifdef SQLITE_WIN32_HAS_ANSI 3170 else{ 3171 int lk; 3172 sqlite3_randomness(sizeof(lk), &lk); 3173 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); 3174 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, 3175 SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 3176 } 3177 #endif 3178 if( res == 0 ){ 3179 pFile->lastErrno = osGetLastError(); 3180 /* No need to log a failure to lock */ 3181 } 3182 OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); 3183 return res; 3184 } 3185 3186 /* 3187 ** Undo a readlock 3188 */ 3189 static int winUnlockReadLock(winFile *pFile){ 3190 int res; 3191 DWORD lastErrno; 3192 OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); 3193 if( osIsNT() ){ 3194 res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 3195 } 3196 #ifdef SQLITE_WIN32_HAS_ANSI 3197 else{ 3198 res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 3199 } 3200 #endif 3201 if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ 3202 pFile->lastErrno = lastErrno; 3203 winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, 3204 "winUnlockReadLock", pFile->zPath); 3205 } 3206 OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); 3207 return res; 3208 } 3209 3210 /* 3211 ** Lock the file with the lock specified by parameter locktype - one 3212 ** of the following: 3213 ** 3214 ** (1) SHARED_LOCK 3215 ** (2) RESERVED_LOCK 3216 ** (3) PENDING_LOCK 3217 ** (4) EXCLUSIVE_LOCK 3218 ** 3219 ** Sometimes when requesting one lock state, additional lock states 3220 ** are inserted in between. The locking might fail on one of the later 3221 ** transitions leaving the lock state different from what it started but 3222 ** still short of its goal. The following chart shows the allowed 3223 ** transitions and the inserted intermediate states: 3224 ** 3225 ** UNLOCKED -> SHARED 3226 ** SHARED -> RESERVED 3227 ** SHARED -> (PENDING) -> EXCLUSIVE 3228 ** RESERVED -> (PENDING) -> EXCLUSIVE 3229 ** PENDING -> EXCLUSIVE 3230 ** 3231 ** This routine will only increase a lock. The winUnlock() routine 3232 ** erases all locks at once and returns us immediately to locking level 0. 3233 ** It is not possible to lower the locking level one step at a time. You 3234 ** must go straight to locking level 0. 3235 */ 3236 static int winLock(sqlite3_file *id, int locktype){ 3237 int rc = SQLITE_OK; /* Return code from subroutines */ 3238 int res = 1; /* Result of a Windows lock call */ 3239 int newLocktype; /* Set pFile->locktype to this value before exiting */ 3240 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ 3241 winFile *pFile = (winFile*)id; 3242 DWORD lastErrno = NO_ERROR; 3243 3244 assert( id!=0 ); 3245 OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", 3246 pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); 3247 3248 /* If there is already a lock of this type or more restrictive on the 3249 ** OsFile, do nothing. Don't use the end_lock: exit path, as 3250 ** sqlite3OsEnterMutex() hasn't been called yet. 3251 */ 3252 if( pFile->locktype>=locktype ){ 3253 OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); 3254 return SQLITE_OK; 3255 } 3256 3257 /* Do not allow any kind of write-lock on a read-only database 3258 */ 3259 if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){ 3260 return SQLITE_IOERR_LOCK; 3261 } 3262 3263 /* Make sure the locking sequence is correct 3264 */ 3265 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); 3266 assert( locktype!=PENDING_LOCK ); 3267 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); 3268 3269 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or 3270 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of 3271 ** the PENDING_LOCK byte is temporary. 3272 */ 3273 newLocktype = pFile->locktype; 3274 if( pFile->locktype==NO_LOCK 3275 || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) 3276 ){ 3277 int cnt = 3; 3278 while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, 3279 PENDING_BYTE, 0, 1, 0))==0 ){ 3280 /* Try 3 times to get the pending lock. This is needed to work 3281 ** around problems caused by indexing and/or anti-virus software on 3282 ** Windows systems. 3283 ** If you are using this code as a model for alternative VFSes, do not 3284 ** copy this retry logic. It is a hack intended for Windows only. 3285 */ 3286 lastErrno = osGetLastError(); 3287 OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", 3288 pFile->h, cnt, res)); 3289 if( lastErrno==ERROR_INVALID_HANDLE ){ 3290 pFile->lastErrno = lastErrno; 3291 rc = SQLITE_IOERR_LOCK; 3292 OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", 3293 pFile->h, cnt, sqlite3ErrName(rc))); 3294 return rc; 3295 } 3296 if( cnt ) sqlite3_win32_sleep(1); 3297 } 3298 gotPendingLock = res; 3299 if( !res ){ 3300 lastErrno = osGetLastError(); 3301 } 3302 } 3303 3304 /* Acquire a shared lock 3305 */ 3306 if( locktype==SHARED_LOCK && res ){ 3307 assert( pFile->locktype==NO_LOCK ); 3308 res = winGetReadLock(pFile); 3309 if( res ){ 3310 newLocktype = SHARED_LOCK; 3311 }else{ 3312 lastErrno = osGetLastError(); 3313 } 3314 } 3315 3316 /* Acquire a RESERVED lock 3317 */ 3318 if( locktype==RESERVED_LOCK && res ){ 3319 assert( pFile->locktype==SHARED_LOCK ); 3320 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); 3321 if( res ){ 3322 newLocktype = RESERVED_LOCK; 3323 }else{ 3324 lastErrno = osGetLastError(); 3325 } 3326 } 3327 3328 /* Acquire a PENDING lock 3329 */ 3330 if( locktype==EXCLUSIVE_LOCK && res ){ 3331 newLocktype = PENDING_LOCK; 3332 gotPendingLock = 0; 3333 } 3334 3335 /* Acquire an EXCLUSIVE lock 3336 */ 3337 if( locktype==EXCLUSIVE_LOCK && res ){ 3338 assert( pFile->locktype>=SHARED_LOCK ); 3339 res = winUnlockReadLock(pFile); 3340 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, 3341 SHARED_SIZE, 0); 3342 if( res ){ 3343 newLocktype = EXCLUSIVE_LOCK; 3344 }else{ 3345 lastErrno = osGetLastError(); 3346 winGetReadLock(pFile); 3347 } 3348 } 3349 3350 /* If we are holding a PENDING lock that ought to be released, then 3351 ** release it now. 3352 */ 3353 if( gotPendingLock && locktype==SHARED_LOCK ){ 3354 winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); 3355 } 3356 3357 /* Update the state of the lock has held in the file descriptor then 3358 ** return the appropriate result code. 3359 */ 3360 if( res ){ 3361 rc = SQLITE_OK; 3362 }else{ 3363 pFile->lastErrno = lastErrno; 3364 rc = SQLITE_BUSY; 3365 OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", 3366 pFile->h, locktype, newLocktype)); 3367 } 3368 pFile->locktype = (u8)newLocktype; 3369 OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", 3370 pFile->h, pFile->locktype, sqlite3ErrName(rc))); 3371 return rc; 3372 } 3373 3374 /* 3375 ** This routine checks if there is a RESERVED lock held on the specified 3376 ** file by this or any other process. If such a lock is held, return 3377 ** non-zero, otherwise zero. 3378 */ 3379 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ 3380 int res; 3381 winFile *pFile = (winFile*)id; 3382 3383 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); 3384 OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); 3385 3386 assert( id!=0 ); 3387 if( pFile->locktype>=RESERVED_LOCK ){ 3388 res = 1; 3389 OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); 3390 }else{ 3391 res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); 3392 if( res ){ 3393 winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); 3394 } 3395 res = !res; 3396 OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); 3397 } 3398 *pResOut = res; 3399 OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", 3400 pFile->h, pResOut, *pResOut)); 3401 return SQLITE_OK; 3402 } 3403 3404 /* 3405 ** Lower the locking level on file descriptor id to locktype. locktype 3406 ** must be either NO_LOCK or SHARED_LOCK. 3407 ** 3408 ** If the locking level of the file descriptor is already at or below 3409 ** the requested locking level, this routine is a no-op. 3410 ** 3411 ** It is not possible for this routine to fail if the second argument 3412 ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine 3413 ** might return SQLITE_IOERR; 3414 */ 3415 static int winUnlock(sqlite3_file *id, int locktype){ 3416 int type; 3417 winFile *pFile = (winFile*)id; 3418 int rc = SQLITE_OK; 3419 assert( pFile!=0 ); 3420 assert( locktype<=SHARED_LOCK ); 3421 OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", 3422 pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); 3423 type = pFile->locktype; 3424 if( type>=EXCLUSIVE_LOCK ){ 3425 winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 3426 if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ 3427 /* This should never happen. We should always be able to 3428 ** reacquire the read lock */ 3429 rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), 3430 "winUnlock", pFile->zPath); 3431 } 3432 } 3433 if( type>=RESERVED_LOCK ){ 3434 winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); 3435 } 3436 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ 3437 winUnlockReadLock(pFile); 3438 } 3439 if( type>=PENDING_LOCK ){ 3440 winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); 3441 } 3442 pFile->locktype = (u8)locktype; 3443 OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", 3444 pFile->h, pFile->locktype, sqlite3ErrName(rc))); 3445 return rc; 3446 } 3447 3448 /****************************************************************************** 3449 ****************************** No-op Locking ********************************** 3450 ** 3451 ** Of the various locking implementations available, this is by far the 3452 ** simplest: locking is ignored. No attempt is made to lock the database 3453 ** file for reading or writing. 3454 ** 3455 ** This locking mode is appropriate for use on read-only databases 3456 ** (ex: databases that are burned into CD-ROM, for example.) It can 3457 ** also be used if the application employs some external mechanism to 3458 ** prevent simultaneous access of the same database by two or more 3459 ** database connections. But there is a serious risk of database 3460 ** corruption if this locking mode is used in situations where multiple 3461 ** database connections are accessing the same database file at the same 3462 ** time and one or more of those connections are writing. 3463 */ 3464 3465 static int winNolockLock(sqlite3_file *id, int locktype){ 3466 UNUSED_PARAMETER(id); 3467 UNUSED_PARAMETER(locktype); 3468 return SQLITE_OK; 3469 } 3470 3471 static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ 3472 UNUSED_PARAMETER(id); 3473 UNUSED_PARAMETER(pResOut); 3474 return SQLITE_OK; 3475 } 3476 3477 static int winNolockUnlock(sqlite3_file *id, int locktype){ 3478 UNUSED_PARAMETER(id); 3479 UNUSED_PARAMETER(locktype); 3480 return SQLITE_OK; 3481 } 3482 3483 /******************* End of the no-op lock implementation ********************* 3484 ******************************************************************************/ 3485 3486 /* 3487 ** If *pArg is initially negative then this is a query. Set *pArg to 3488 ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. 3489 ** 3490 ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. 3491 */ 3492 static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ 3493 if( *pArg<0 ){ 3494 *pArg = (pFile->ctrlFlags & mask)!=0; 3495 }else if( (*pArg)==0 ){ 3496 pFile->ctrlFlags &= ~mask; 3497 }else{ 3498 pFile->ctrlFlags |= mask; 3499 } 3500 } 3501 3502 /* Forward references to VFS helper methods used for temporary files */ 3503 static int winGetTempname(sqlite3_vfs *, char **); 3504 static int winIsDir(const void *); 3505 static BOOL winIsDriveLetterAndColon(const char *); 3506 3507 /* 3508 ** Control and query of the open file handle. 3509 */ 3510 static int winFileControl(sqlite3_file *id, int op, void *pArg){ 3511 winFile *pFile = (winFile*)id; 3512 OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); 3513 switch( op ){ 3514 case SQLITE_FCNTL_LOCKSTATE: { 3515 *(int*)pArg = pFile->locktype; 3516 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3517 return SQLITE_OK; 3518 } 3519 case SQLITE_FCNTL_LAST_ERRNO: { 3520 *(int*)pArg = (int)pFile->lastErrno; 3521 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3522 return SQLITE_OK; 3523 } 3524 case SQLITE_FCNTL_CHUNK_SIZE: { 3525 pFile->szChunk = *(int *)pArg; 3526 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3527 return SQLITE_OK; 3528 } 3529 case SQLITE_FCNTL_SIZE_HINT: { 3530 if( pFile->szChunk>0 ){ 3531 sqlite3_int64 oldSz; 3532 int rc = winFileSize(id, &oldSz); 3533 if( rc==SQLITE_OK ){ 3534 sqlite3_int64 newSz = *(sqlite3_int64*)pArg; 3535 if( newSz>oldSz ){ 3536 SimulateIOErrorBenign(1); 3537 rc = winTruncate(id, newSz); 3538 SimulateIOErrorBenign(0); 3539 } 3540 } 3541 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3542 return rc; 3543 } 3544 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3545 return SQLITE_OK; 3546 } 3547 case SQLITE_FCNTL_PERSIST_WAL: { 3548 winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); 3549 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3550 return SQLITE_OK; 3551 } 3552 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { 3553 winModeBit(pFile, WINFILE_PSOW, (int*)pArg); 3554 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3555 return SQLITE_OK; 3556 } 3557 case SQLITE_FCNTL_VFSNAME: { 3558 *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); 3559 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3560 return SQLITE_OK; 3561 } 3562 case SQLITE_FCNTL_WIN32_AV_RETRY: { 3563 int *a = (int*)pArg; 3564 if( a[0]>0 ){ 3565 winIoerrRetry = a[0]; 3566 }else{ 3567 a[0] = winIoerrRetry; 3568 } 3569 if( a[1]>0 ){ 3570 winIoerrRetryDelay = a[1]; 3571 }else{ 3572 a[1] = winIoerrRetryDelay; 3573 } 3574 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3575 return SQLITE_OK; 3576 } 3577 case SQLITE_FCNTL_WIN32_GET_HANDLE: { 3578 LPHANDLE phFile = (LPHANDLE)pArg; 3579 *phFile = pFile->h; 3580 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3581 return SQLITE_OK; 3582 } 3583 #ifdef SQLITE_TEST 3584 case SQLITE_FCNTL_WIN32_SET_HANDLE: { 3585 LPHANDLE phFile = (LPHANDLE)pArg; 3586 HANDLE hOldFile = pFile->h; 3587 pFile->h = *phFile; 3588 *phFile = hOldFile; 3589 OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", 3590 hOldFile, pFile->h)); 3591 return SQLITE_OK; 3592 } 3593 #endif 3594 case SQLITE_FCNTL_TEMPFILENAME: { 3595 char *zTFile = 0; 3596 int rc = winGetTempname(pFile->pVfs, &zTFile); 3597 if( rc==SQLITE_OK ){ 3598 *(char**)pArg = zTFile; 3599 } 3600 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3601 return rc; 3602 } 3603 #if SQLITE_MAX_MMAP_SIZE>0 3604 case SQLITE_FCNTL_MMAP_SIZE: { 3605 i64 newLimit = *(i64*)pArg; 3606 int rc = SQLITE_OK; 3607 if( newLimit>sqlite3GlobalConfig.mxMmap ){ 3608 newLimit = sqlite3GlobalConfig.mxMmap; 3609 } 3610 3611 /* The value of newLimit may be eventually cast to (SIZE_T) and passed 3612 ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at 3613 ** least a 64-bit type. */ 3614 if( newLimit>0 && sizeof(SIZE_T)<8 ){ 3615 newLimit = (newLimit & 0x7FFFFFFF); 3616 } 3617 3618 *(i64*)pArg = pFile->mmapSizeMax; 3619 if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ 3620 pFile->mmapSizeMax = newLimit; 3621 if( pFile->mmapSize>0 ){ 3622 winUnmapfile(pFile); 3623 rc = winMapfile(pFile, -1); 3624 } 3625 } 3626 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3627 return rc; 3628 } 3629 #endif 3630 } 3631 OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); 3632 return SQLITE_NOTFOUND; 3633 } 3634 3635 /* 3636 ** Return the sector size in bytes of the underlying block device for 3637 ** the specified file. This is almost always 512 bytes, but may be 3638 ** larger for some devices. 3639 ** 3640 ** SQLite code assumes this function cannot fail. It also assumes that 3641 ** if two files are created in the same file-system directory (i.e. 3642 ** a database and its journal file) that the sector size will be the 3643 ** same for both. 3644 */ 3645 static int winSectorSize(sqlite3_file *id){ 3646 (void)id; 3647 return SQLITE_DEFAULT_SECTOR_SIZE; 3648 } 3649 3650 /* 3651 ** Return a vector of device characteristics. 3652 */ 3653 static int winDeviceCharacteristics(sqlite3_file *id){ 3654 winFile *p = (winFile*)id; 3655 return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | 3656 ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); 3657 } 3658 3659 /* 3660 ** Windows will only let you create file view mappings 3661 ** on allocation size granularity boundaries. 3662 ** During sqlite3_os_init() we do a GetSystemInfo() 3663 ** to get the granularity size. 3664 */ 3665 static SYSTEM_INFO winSysInfo; 3666 3667 #ifndef SQLITE_OMIT_WAL 3668 3669 /* 3670 ** Helper functions to obtain and relinquish the global mutex. The 3671 ** global mutex is used to protect the winLockInfo objects used by 3672 ** this file, all of which may be shared by multiple threads. 3673 ** 3674 ** Function winShmMutexHeld() is used to assert() that the global mutex 3675 ** is held when required. This function is only used as part of assert() 3676 ** statements. e.g. 3677 ** 3678 ** winShmEnterMutex() 3679 ** assert( winShmMutexHeld() ); 3680 ** winShmLeaveMutex() 3681 */ 3682 static sqlite3_mutex *winBigLock = 0; 3683 static void winShmEnterMutex(void){ 3684 sqlite3_mutex_enter(winBigLock); 3685 } 3686 static void winShmLeaveMutex(void){ 3687 sqlite3_mutex_leave(winBigLock); 3688 } 3689 #ifndef NDEBUG 3690 static int winShmMutexHeld(void) { 3691 return sqlite3_mutex_held(winBigLock); 3692 } 3693 #endif 3694 3695 /* 3696 ** Object used to represent a single file opened and mmapped to provide 3697 ** shared memory. When multiple threads all reference the same 3698 ** log-summary, each thread has its own winFile object, but they all 3699 ** point to a single instance of this object. In other words, each 3700 ** log-summary is opened only once per process. 3701 ** 3702 ** winShmMutexHeld() must be true when creating or destroying 3703 ** this object or while reading or writing the following fields: 3704 ** 3705 ** nRef 3706 ** pNext 3707 ** 3708 ** The following fields are read-only after the object is created: 3709 ** 3710 ** fid 3711 ** zFilename 3712 ** 3713 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and 3714 ** winShmMutexHeld() is true when reading or writing any other field 3715 ** in this structure. 3716 ** 3717 */ 3718 struct winShmNode { 3719 sqlite3_mutex *mutex; /* Mutex to access this object */ 3720 char *zFilename; /* Name of the file */ 3721 winFile hFile; /* File handle from winOpen */ 3722 3723 int szRegion; /* Size of shared-memory regions */ 3724 int nRegion; /* Size of array apRegion */ 3725 u8 isReadonly; /* True if read-only */ 3726 u8 isUnlocked; /* True if no DMS lock held */ 3727 3728 struct ShmRegion { 3729 HANDLE hMap; /* File handle from CreateFileMapping */ 3730 void *pMap; 3731 } *aRegion; 3732 DWORD lastErrno; /* The Windows errno from the last I/O error */ 3733 3734 int nRef; /* Number of winShm objects pointing to this */ 3735 winShm *pFirst; /* All winShm objects pointing to this */ 3736 winShmNode *pNext; /* Next in list of all winShmNode objects */ 3737 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3738 u8 nextShmId; /* Next available winShm.id value */ 3739 #endif 3740 }; 3741 3742 /* 3743 ** A global array of all winShmNode objects. 3744 ** 3745 ** The winShmMutexHeld() must be true while reading or writing this list. 3746 */ 3747 static winShmNode *winShmNodeList = 0; 3748 3749 /* 3750 ** Structure used internally by this VFS to record the state of an 3751 ** open shared memory connection. 3752 ** 3753 ** The following fields are initialized when this object is created and 3754 ** are read-only thereafter: 3755 ** 3756 ** winShm.pShmNode 3757 ** winShm.id 3758 ** 3759 ** All other fields are read/write. The winShm.pShmNode->mutex must be held 3760 ** while accessing any read/write fields. 3761 */ 3762 struct winShm { 3763 winShmNode *pShmNode; /* The underlying winShmNode object */ 3764 winShm *pNext; /* Next winShm with the same winShmNode */ 3765 u8 hasMutex; /* True if holding the winShmNode mutex */ 3766 u16 sharedMask; /* Mask of shared locks held */ 3767 u16 exclMask; /* Mask of exclusive locks held */ 3768 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3769 u8 id; /* Id of this connection with its winShmNode */ 3770 #endif 3771 }; 3772 3773 /* 3774 ** Constants used for locking 3775 */ 3776 #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ 3777 #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ 3778 3779 /* 3780 ** Apply advisory locks for all n bytes beginning at ofst. 3781 */ 3782 #define WINSHM_UNLCK 1 3783 #define WINSHM_RDLCK 2 3784 #define WINSHM_WRLCK 3 3785 static int winShmSystemLock( 3786 winShmNode *pFile, /* Apply locks to this open shared-memory segment */ 3787 int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ 3788 int ofst, /* Offset to first byte to be locked/unlocked */ 3789 int nByte /* Number of bytes to lock or unlock */ 3790 ){ 3791 int rc = 0; /* Result code form Lock/UnlockFileEx() */ 3792 3793 /* Access to the winShmNode object is serialized by the caller */ 3794 assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); 3795 3796 OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", 3797 pFile->hFile.h, lockType, ofst, nByte)); 3798 3799 /* Release/Acquire the system-level lock */ 3800 if( lockType==WINSHM_UNLCK ){ 3801 rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); 3802 }else{ 3803 /* Initialize the locking parameters */ 3804 DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; 3805 if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; 3806 rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); 3807 } 3808 3809 if( rc!= 0 ){ 3810 rc = SQLITE_OK; 3811 }else{ 3812 pFile->lastErrno = osGetLastError(); 3813 rc = SQLITE_BUSY; 3814 } 3815 3816 OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", 3817 pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : 3818 "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); 3819 3820 return rc; 3821 } 3822 3823 /* Forward references to VFS methods */ 3824 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); 3825 static int winDelete(sqlite3_vfs *,const char*,int); 3826 3827 /* 3828 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. 3829 ** 3830 ** This is not a VFS shared-memory method; it is a utility function called 3831 ** by VFS shared-memory methods. 3832 */ 3833 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ 3834 winShmNode **pp; 3835 winShmNode *p; 3836 assert( winShmMutexHeld() ); 3837 OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", 3838 osGetCurrentProcessId(), deleteFlag)); 3839 pp = &winShmNodeList; 3840 while( (p = *pp)!=0 ){ 3841 if( p->nRef==0 ){ 3842 int i; 3843 if( p->mutex ){ sqlite3_mutex_free(p->mutex); } 3844 for(i=0; i<p->nRegion; i++){ 3845 BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); 3846 OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", 3847 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3848 UNUSED_VARIABLE_VALUE(bRc); 3849 bRc = osCloseHandle(p->aRegion[i].hMap); 3850 OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", 3851 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3852 UNUSED_VARIABLE_VALUE(bRc); 3853 } 3854 if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ 3855 SimulateIOErrorBenign(1); 3856 winClose((sqlite3_file *)&p->hFile); 3857 SimulateIOErrorBenign(0); 3858 } 3859 if( deleteFlag ){ 3860 SimulateIOErrorBenign(1); 3861 sqlite3BeginBenignMalloc(); 3862 winDelete(pVfs, p->zFilename, 0); 3863 sqlite3EndBenignMalloc(); 3864 SimulateIOErrorBenign(0); 3865 } 3866 *pp = p->pNext; 3867 sqlite3_free(p->aRegion); 3868 sqlite3_free(p); 3869 }else{ 3870 pp = &p->pNext; 3871 } 3872 } 3873 } 3874 3875 /* 3876 ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to 3877 ** take it now. Return SQLITE_OK if successful, or an SQLite error 3878 ** code otherwise. 3879 ** 3880 ** If the DMS cannot be locked because this is a readonly_shm=1 3881 ** connection and no other process already holds a lock, return 3882 ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. 3883 */ 3884 static int winLockSharedMemory(winShmNode *pShmNode){ 3885 int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); 3886 3887 if( rc==SQLITE_OK ){ 3888 if( pShmNode->isReadonly ){ 3889 pShmNode->isUnlocked = 1; 3890 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3891 return SQLITE_READONLY_CANTINIT; 3892 }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ 3893 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3894 return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), 3895 "winLockSharedMemory", pShmNode->zFilename); 3896 } 3897 } 3898 3899 if( rc==SQLITE_OK ){ 3900 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3901 } 3902 3903 return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); 3904 } 3905 3906 /* 3907 ** Open the shared-memory area associated with database file pDbFd. 3908 ** 3909 ** When opening a new shared-memory file, if no other instances of that 3910 ** file are currently open, in this process or in other processes, then 3911 ** the file must be truncated to zero length or have its header cleared. 3912 */ 3913 static int winOpenSharedMemory(winFile *pDbFd){ 3914 struct winShm *p; /* The connection to be opened */ 3915 winShmNode *pShmNode = 0; /* The underlying mmapped file */ 3916 int rc = SQLITE_OK; /* Result code */ 3917 winShmNode *pNew; /* Newly allocated winShmNode */ 3918 int nName; /* Size of zName in bytes */ 3919 3920 assert( pDbFd->pShm==0 ); /* Not previously opened */ 3921 3922 /* Allocate space for the new sqlite3_shm object. Also speculatively 3923 ** allocate space for a new winShmNode and filename. 3924 */ 3925 p = sqlite3MallocZero( sizeof(*p) ); 3926 if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; 3927 nName = sqlite3Strlen30(pDbFd->zPath); 3928 pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); 3929 if( pNew==0 ){ 3930 sqlite3_free(p); 3931 return SQLITE_IOERR_NOMEM_BKPT; 3932 } 3933 pNew->zFilename = (char*)&pNew[1]; 3934 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); 3935 sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 3936 3937 /* Look to see if there is an existing winShmNode that can be used. 3938 ** If no matching winShmNode currently exists, create a new one. 3939 */ 3940 winShmEnterMutex(); 3941 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ 3942 /* TBD need to come up with better match here. Perhaps 3943 ** use FILE_ID_BOTH_DIR_INFO Structure. 3944 */ 3945 if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; 3946 } 3947 if( pShmNode ){ 3948 sqlite3_free(pNew); 3949 }else{ 3950 int inFlags = SQLITE_OPEN_WAL; 3951 int outFlags = 0; 3952 3953 pShmNode = pNew; 3954 pNew = 0; 3955 ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; 3956 pShmNode->pNext = winShmNodeList; 3957 winShmNodeList = pShmNode; 3958 3959 if( sqlite3GlobalConfig.bCoreMutex ){ 3960 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); 3961 if( pShmNode->mutex==0 ){ 3962 rc = SQLITE_IOERR_NOMEM_BKPT; 3963 goto shm_open_err; 3964 } 3965 } 3966 3967 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ 3968 inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; 3969 }else{ 3970 inFlags |= SQLITE_OPEN_READONLY; 3971 } 3972 rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, 3973 (sqlite3_file*)&pShmNode->hFile, 3974 inFlags, &outFlags); 3975 if( rc!=SQLITE_OK ){ 3976 rc = winLogError(rc, osGetLastError(), "winOpenShm", 3977 pShmNode->zFilename); 3978 goto shm_open_err; 3979 } 3980 if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; 3981 3982 rc = winLockSharedMemory(pShmNode); 3983 if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; 3984 } 3985 3986 /* Make the new connection a child of the winShmNode */ 3987 p->pShmNode = pShmNode; 3988 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3989 p->id = pShmNode->nextShmId++; 3990 #endif 3991 pShmNode->nRef++; 3992 pDbFd->pShm = p; 3993 winShmLeaveMutex(); 3994 3995 /* The reference count on pShmNode has already been incremented under 3996 ** the cover of the winShmEnterMutex() mutex and the pointer from the 3997 ** new (struct winShm) object to the pShmNode has been set. All that is 3998 ** left to do is to link the new object into the linked list starting 3999 ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 4000 ** mutex. 4001 */ 4002 sqlite3_mutex_enter(pShmNode->mutex); 4003 p->pNext = pShmNode->pFirst; 4004 pShmNode->pFirst = p; 4005 sqlite3_mutex_leave(pShmNode->mutex); 4006 return rc; 4007 4008 /* Jump here on any error */ 4009 shm_open_err: 4010 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 4011 winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ 4012 sqlite3_free(p); 4013 sqlite3_free(pNew); 4014 winShmLeaveMutex(); 4015 return rc; 4016 } 4017 4018 /* 4019 ** Close a connection to shared-memory. Delete the underlying 4020 ** storage if deleteFlag is true. 4021 */ 4022 static int winShmUnmap( 4023 sqlite3_file *fd, /* Database holding shared memory */ 4024 int deleteFlag /* Delete after closing if true */ 4025 ){ 4026 winFile *pDbFd; /* Database holding shared-memory */ 4027 winShm *p; /* The connection to be closed */ 4028 winShmNode *pShmNode; /* The underlying shared-memory file */ 4029 winShm **pp; /* For looping over sibling connections */ 4030 4031 pDbFd = (winFile*)fd; 4032 p = pDbFd->pShm; 4033 if( p==0 ) return SQLITE_OK; 4034 pShmNode = p->pShmNode; 4035 4036 /* Remove connection p from the set of connections associated 4037 ** with pShmNode */ 4038 sqlite3_mutex_enter(pShmNode->mutex); 4039 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} 4040 *pp = p->pNext; 4041 4042 /* Free the connection p */ 4043 sqlite3_free(p); 4044 pDbFd->pShm = 0; 4045 sqlite3_mutex_leave(pShmNode->mutex); 4046 4047 /* If pShmNode->nRef has reached 0, then close the underlying 4048 ** shared-memory file, too */ 4049 winShmEnterMutex(); 4050 assert( pShmNode->nRef>0 ); 4051 pShmNode->nRef--; 4052 if( pShmNode->nRef==0 ){ 4053 winShmPurge(pDbFd->pVfs, deleteFlag); 4054 } 4055 winShmLeaveMutex(); 4056 4057 return SQLITE_OK; 4058 } 4059 4060 /* 4061 ** Change the lock state for a shared-memory segment. 4062 */ 4063 static int winShmLock( 4064 sqlite3_file *fd, /* Database file holding the shared memory */ 4065 int ofst, /* First lock to acquire or release */ 4066 int n, /* Number of locks to acquire or release */ 4067 int flags /* What to do with the lock */ 4068 ){ 4069 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ 4070 winShm *p = pDbFd->pShm; /* The shared memory being locked */ 4071 winShm *pX; /* For looping over all siblings */ 4072 winShmNode *pShmNode = p->pShmNode; 4073 int rc = SQLITE_OK; /* Result code */ 4074 u16 mask; /* Mask of locks to take or release */ 4075 4076 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); 4077 assert( n>=1 ); 4078 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) 4079 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) 4080 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) 4081 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); 4082 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); 4083 4084 mask = (u16)((1U<<(ofst+n)) - (1U<<ofst)); 4085 assert( n>1 || mask==(1<<ofst) ); 4086 sqlite3_mutex_enter(pShmNode->mutex); 4087 if( flags & SQLITE_SHM_UNLOCK ){ 4088 u16 allMask = 0; /* Mask of locks held by siblings */ 4089 4090 /* See if any siblings hold this same lock */ 4091 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4092 if( pX==p ) continue; 4093 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); 4094 allMask |= pX->sharedMask; 4095 } 4096 4097 /* Unlock the system-level locks */ 4098 if( (mask & allMask)==0 ){ 4099 rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); 4100 }else{ 4101 rc = SQLITE_OK; 4102 } 4103 4104 /* Undo the local locks */ 4105 if( rc==SQLITE_OK ){ 4106 p->exclMask &= ~mask; 4107 p->sharedMask &= ~mask; 4108 } 4109 }else if( flags & SQLITE_SHM_SHARED ){ 4110 u16 allShared = 0; /* Union of locks held by connections other than "p" */ 4111 4112 /* Find out which shared locks are already held by sibling connections. 4113 ** If any sibling already holds an exclusive lock, go ahead and return 4114 ** SQLITE_BUSY. 4115 */ 4116 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4117 if( (pX->exclMask & mask)!=0 ){ 4118 rc = SQLITE_BUSY; 4119 break; 4120 } 4121 allShared |= pX->sharedMask; 4122 } 4123 4124 /* Get shared locks at the system level, if necessary */ 4125 if( rc==SQLITE_OK ){ 4126 if( (allShared & mask)==0 ){ 4127 rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); 4128 }else{ 4129 rc = SQLITE_OK; 4130 } 4131 } 4132 4133 /* Get the local shared locks */ 4134 if( rc==SQLITE_OK ){ 4135 p->sharedMask |= mask; 4136 } 4137 }else{ 4138 /* Make sure no sibling connections hold locks that will block this 4139 ** lock. If any do, return SQLITE_BUSY right away. 4140 */ 4141 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4142 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ 4143 rc = SQLITE_BUSY; 4144 break; 4145 } 4146 } 4147 4148 /* Get the exclusive locks at the system level. Then if successful 4149 ** also mark the local connection as being locked. 4150 */ 4151 if( rc==SQLITE_OK ){ 4152 rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); 4153 if( rc==SQLITE_OK ){ 4154 assert( (p->sharedMask & mask)==0 ); 4155 p->exclMask |= mask; 4156 } 4157 } 4158 } 4159 sqlite3_mutex_leave(pShmNode->mutex); 4160 OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", 4161 osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, 4162 sqlite3ErrName(rc))); 4163 return rc; 4164 } 4165 4166 /* 4167 ** Implement a memory barrier or memory fence on shared memory. 4168 ** 4169 ** All loads and stores begun before the barrier must complete before 4170 ** any load or store begun after the barrier. 4171 */ 4172 static void winShmBarrier( 4173 sqlite3_file *fd /* Database holding the shared memory */ 4174 ){ 4175 UNUSED_PARAMETER(fd); 4176 sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ 4177 winShmEnterMutex(); /* Also mutex, for redundancy */ 4178 winShmLeaveMutex(); 4179 } 4180 4181 /* 4182 ** This function is called to obtain a pointer to region iRegion of the 4183 ** shared-memory associated with the database file fd. Shared-memory regions 4184 ** are numbered starting from zero. Each shared-memory region is szRegion 4185 ** bytes in size. 4186 ** 4187 ** If an error occurs, an error code is returned and *pp is set to NULL. 4188 ** 4189 ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory 4190 ** region has not been allocated (by any client, including one running in a 4191 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If 4192 ** isWrite is non-zero and the requested shared-memory region has not yet 4193 ** been allocated, it is allocated by this function. 4194 ** 4195 ** If the shared-memory region has already been allocated or is allocated by 4196 ** this call as described above, then it is mapped into this processes 4197 ** address space (if it is not already), *pp is set to point to the mapped 4198 ** memory and SQLITE_OK returned. 4199 */ 4200 static int winShmMap( 4201 sqlite3_file *fd, /* Handle open on database file */ 4202 int iRegion, /* Region to retrieve */ 4203 int szRegion, /* Size of regions */ 4204 int isWrite, /* True to extend file if necessary */ 4205 void volatile **pp /* OUT: Mapped memory */ 4206 ){ 4207 winFile *pDbFd = (winFile*)fd; 4208 winShm *pShm = pDbFd->pShm; 4209 winShmNode *pShmNode; 4210 DWORD protect = PAGE_READWRITE; 4211 DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; 4212 int rc = SQLITE_OK; 4213 4214 if( !pShm ){ 4215 rc = winOpenSharedMemory(pDbFd); 4216 if( rc!=SQLITE_OK ) return rc; 4217 pShm = pDbFd->pShm; 4218 } 4219 pShmNode = pShm->pShmNode; 4220 4221 sqlite3_mutex_enter(pShmNode->mutex); 4222 if( pShmNode->isUnlocked ){ 4223 rc = winLockSharedMemory(pShmNode); 4224 if( rc!=SQLITE_OK ) goto shmpage_out; 4225 pShmNode->isUnlocked = 0; 4226 } 4227 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); 4228 4229 if( pShmNode->nRegion<=iRegion ){ 4230 struct ShmRegion *apNew; /* New aRegion[] array */ 4231 int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ 4232 sqlite3_int64 sz; /* Current size of wal-index file */ 4233 4234 pShmNode->szRegion = szRegion; 4235 4236 /* The requested region is not mapped into this processes address space. 4237 ** Check to see if it has been allocated (i.e. if the wal-index file is 4238 ** large enough to contain the requested region). 4239 */ 4240 rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); 4241 if( rc!=SQLITE_OK ){ 4242 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4243 "winShmMap1", pDbFd->zPath); 4244 goto shmpage_out; 4245 } 4246 4247 if( sz<nByte ){ 4248 /* The requested memory region does not exist. If isWrite is set to 4249 ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. 4250 ** 4251 ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate 4252 ** the requested memory region. 4253 */ 4254 if( !isWrite ) goto shmpage_out; 4255 rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); 4256 if( rc!=SQLITE_OK ){ 4257 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4258 "winShmMap2", pDbFd->zPath); 4259 goto shmpage_out; 4260 } 4261 } 4262 4263 /* Map the requested memory region into this processes address space. */ 4264 apNew = (struct ShmRegion *)sqlite3_realloc64( 4265 pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) 4266 ); 4267 if( !apNew ){ 4268 rc = SQLITE_IOERR_NOMEM_BKPT; 4269 goto shmpage_out; 4270 } 4271 pShmNode->aRegion = apNew; 4272 4273 if( pShmNode->isReadonly ){ 4274 protect = PAGE_READONLY; 4275 flags = FILE_MAP_READ; 4276 } 4277 4278 while( pShmNode->nRegion<=iRegion ){ 4279 HANDLE hMap = NULL; /* file-mapping handle */ 4280 void *pMap = 0; /* Mapped memory region */ 4281 4282 #if SQLITE_OS_WINRT 4283 hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, 4284 NULL, protect, nByte, NULL 4285 ); 4286 #elif defined(SQLITE_WIN32_HAS_WIDE) 4287 hMap = osCreateFileMappingW(pShmNode->hFile.h, 4288 NULL, protect, 0, nByte, NULL 4289 ); 4290 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4291 hMap = osCreateFileMappingA(pShmNode->hFile.h, 4292 NULL, protect, 0, nByte, NULL 4293 ); 4294 #endif 4295 OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", 4296 osGetCurrentProcessId(), pShmNode->nRegion, nByte, 4297 hMap ? "ok" : "failed")); 4298 if( hMap ){ 4299 int iOffset = pShmNode->nRegion*szRegion; 4300 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4301 #if SQLITE_OS_WINRT 4302 pMap = osMapViewOfFileFromApp(hMap, flags, 4303 iOffset - iOffsetShift, szRegion + iOffsetShift 4304 ); 4305 #else 4306 pMap = osMapViewOfFile(hMap, flags, 4307 0, iOffset - iOffsetShift, szRegion + iOffsetShift 4308 ); 4309 #endif 4310 OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", 4311 osGetCurrentProcessId(), pShmNode->nRegion, iOffset, 4312 szRegion, pMap ? "ok" : "failed")); 4313 } 4314 if( !pMap ){ 4315 pShmNode->lastErrno = osGetLastError(); 4316 rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, 4317 "winShmMap3", pDbFd->zPath); 4318 if( hMap ) osCloseHandle(hMap); 4319 goto shmpage_out; 4320 } 4321 4322 pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; 4323 pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; 4324 pShmNode->nRegion++; 4325 } 4326 } 4327 4328 shmpage_out: 4329 if( pShmNode->nRegion>iRegion ){ 4330 int iOffset = iRegion*szRegion; 4331 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4332 char *p = (char *)pShmNode->aRegion[iRegion].pMap; 4333 *pp = (void *)&p[iOffsetShift]; 4334 }else{ 4335 *pp = 0; 4336 } 4337 if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; 4338 sqlite3_mutex_leave(pShmNode->mutex); 4339 return rc; 4340 } 4341 4342 #else 4343 # define winShmMap 0 4344 # define winShmLock 0 4345 # define winShmBarrier 0 4346 # define winShmUnmap 0 4347 #endif /* #ifndef SQLITE_OMIT_WAL */ 4348 4349 /* 4350 ** Cleans up the mapped region of the specified file, if any. 4351 */ 4352 #if SQLITE_MAX_MMAP_SIZE>0 4353 static int winUnmapfile(winFile *pFile){ 4354 assert( pFile!=0 ); 4355 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " 4356 "mmapSize=%lld, mmapSizeMax=%lld\n", 4357 osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, 4358 pFile->mmapSize, pFile->mmapSizeMax)); 4359 if( pFile->pMapRegion ){ 4360 if( !osUnmapViewOfFile(pFile->pMapRegion) ){ 4361 pFile->lastErrno = osGetLastError(); 4362 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " 4363 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, 4364 pFile->pMapRegion)); 4365 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4366 "winUnmapfile1", pFile->zPath); 4367 } 4368 pFile->pMapRegion = 0; 4369 pFile->mmapSize = 0; 4370 } 4371 if( pFile->hMap!=NULL ){ 4372 if( !osCloseHandle(pFile->hMap) ){ 4373 pFile->lastErrno = osGetLastError(); 4374 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", 4375 osGetCurrentProcessId(), pFile, pFile->hMap)); 4376 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4377 "winUnmapfile2", pFile->zPath); 4378 } 4379 pFile->hMap = NULL; 4380 } 4381 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4382 osGetCurrentProcessId(), pFile)); 4383 return SQLITE_OK; 4384 } 4385 4386 /* 4387 ** Memory map or remap the file opened by file-descriptor pFd (if the file 4388 ** is already mapped, the existing mapping is replaced by the new). Or, if 4389 ** there already exists a mapping for this file, and there are still 4390 ** outstanding xFetch() references to it, this function is a no-op. 4391 ** 4392 ** If parameter nByte is non-negative, then it is the requested size of 4393 ** the mapping to create. Otherwise, if nByte is less than zero, then the 4394 ** requested size is the size of the file on disk. The actual size of the 4395 ** created mapping is either the requested size or the value configured 4396 ** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. 4397 ** 4398 ** SQLITE_OK is returned if no error occurs (even if the mapping is not 4399 ** recreated as a result of outstanding references) or an SQLite error 4400 ** code otherwise. 4401 */ 4402 static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ 4403 sqlite3_int64 nMap = nByte; 4404 int rc; 4405 4406 assert( nMap>=0 || pFd->nFetchOut==0 ); 4407 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", 4408 osGetCurrentProcessId(), pFd, nByte)); 4409 4410 if( pFd->nFetchOut>0 ) return SQLITE_OK; 4411 4412 if( nMap<0 ){ 4413 rc = winFileSize((sqlite3_file*)pFd, &nMap); 4414 if( rc ){ 4415 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", 4416 osGetCurrentProcessId(), pFd)); 4417 return SQLITE_IOERR_FSTAT; 4418 } 4419 } 4420 if( nMap>pFd->mmapSizeMax ){ 4421 nMap = pFd->mmapSizeMax; 4422 } 4423 nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); 4424 4425 if( nMap==0 && pFd->mmapSize>0 ){ 4426 winUnmapfile(pFd); 4427 } 4428 if( nMap!=pFd->mmapSize ){ 4429 void *pNew = 0; 4430 DWORD protect = PAGE_READONLY; 4431 DWORD flags = FILE_MAP_READ; 4432 4433 winUnmapfile(pFd); 4434 #ifdef SQLITE_MMAP_READWRITE 4435 if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ 4436 protect = PAGE_READWRITE; 4437 flags |= FILE_MAP_WRITE; 4438 } 4439 #endif 4440 #if SQLITE_OS_WINRT 4441 pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); 4442 #elif defined(SQLITE_WIN32_HAS_WIDE) 4443 pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, 4444 (DWORD)((nMap>>32) & 0xffffffff), 4445 (DWORD)(nMap & 0xffffffff), NULL); 4446 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4447 pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, 4448 (DWORD)((nMap>>32) & 0xffffffff), 4449 (DWORD)(nMap & 0xffffffff), NULL); 4450 #endif 4451 if( pFd->hMap==NULL ){ 4452 pFd->lastErrno = osGetLastError(); 4453 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4454 "winMapfile1", pFd->zPath); 4455 /* Log the error, but continue normal operation using xRead/xWrite */ 4456 OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", 4457 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4458 return SQLITE_OK; 4459 } 4460 assert( (nMap % winSysInfo.dwPageSize)==0 ); 4461 assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); 4462 #if SQLITE_OS_WINRT 4463 pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); 4464 #else 4465 pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); 4466 #endif 4467 if( pNew==NULL ){ 4468 osCloseHandle(pFd->hMap); 4469 pFd->hMap = NULL; 4470 pFd->lastErrno = osGetLastError(); 4471 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4472 "winMapfile2", pFd->zPath); 4473 /* Log the error, but continue normal operation using xRead/xWrite */ 4474 OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", 4475 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4476 return SQLITE_OK; 4477 } 4478 pFd->pMapRegion = pNew; 4479 pFd->mmapSize = nMap; 4480 } 4481 4482 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4483 osGetCurrentProcessId(), pFd)); 4484 return SQLITE_OK; 4485 } 4486 #endif /* SQLITE_MAX_MMAP_SIZE>0 */ 4487 4488 /* 4489 ** If possible, return a pointer to a mapping of file fd starting at offset 4490 ** iOff. The mapping must be valid for at least nAmt bytes. 4491 ** 4492 ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. 4493 ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. 4494 ** Finally, if an error does occur, return an SQLite error code. The final 4495 ** value of *pp is undefined in this case. 4496 ** 4497 ** If this function does return a pointer, the caller must eventually 4498 ** release the reference by calling winUnfetch(). 4499 */ 4500 static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ 4501 #if SQLITE_MAX_MMAP_SIZE>0 4502 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4503 #endif 4504 *pp = 0; 4505 4506 OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", 4507 osGetCurrentProcessId(), fd, iOff, nAmt, pp)); 4508 4509 #if SQLITE_MAX_MMAP_SIZE>0 4510 if( pFd->mmapSizeMax>0 ){ 4511 if( pFd->pMapRegion==0 ){ 4512 int rc = winMapfile(pFd, -1); 4513 if( rc!=SQLITE_OK ){ 4514 OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", 4515 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4516 return rc; 4517 } 4518 } 4519 if( pFd->mmapSize >= iOff+nAmt ){ 4520 *pp = &((u8 *)pFd->pMapRegion)[iOff]; 4521 pFd->nFetchOut++; 4522 } 4523 } 4524 #endif 4525 4526 OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", 4527 osGetCurrentProcessId(), fd, pp, *pp)); 4528 return SQLITE_OK; 4529 } 4530 4531 /* 4532 ** If the third argument is non-NULL, then this function releases a 4533 ** reference obtained by an earlier call to winFetch(). The second 4534 ** argument passed to this function must be the same as the corresponding 4535 ** argument that was passed to the winFetch() invocation. 4536 ** 4537 ** Or, if the third argument is NULL, then this function is being called 4538 ** to inform the VFS layer that, according to POSIX, any existing mapping 4539 ** may now be invalid and should be unmapped. 4540 */ 4541 static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ 4542 #if SQLITE_MAX_MMAP_SIZE>0 4543 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4544 4545 /* If p==0 (unmap the entire file) then there must be no outstanding 4546 ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), 4547 ** then there must be at least one outstanding. */ 4548 assert( (p==0)==(pFd->nFetchOut==0) ); 4549 4550 /* If p!=0, it must match the iOff value. */ 4551 assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); 4552 4553 OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", 4554 osGetCurrentProcessId(), pFd, iOff, p)); 4555 4556 if( p ){ 4557 pFd->nFetchOut--; 4558 }else{ 4559 /* FIXME: If Windows truly always prevents truncating or deleting a 4560 ** file while a mapping is held, then the following winUnmapfile() call 4561 ** is unnecessary can be omitted - potentially improving 4562 ** performance. */ 4563 winUnmapfile(pFd); 4564 } 4565 4566 assert( pFd->nFetchOut>=0 ); 4567 #endif 4568 4569 OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4570 osGetCurrentProcessId(), fd)); 4571 return SQLITE_OK; 4572 } 4573 4574 /* 4575 ** Here ends the implementation of all sqlite3_file methods. 4576 ** 4577 ********************** End sqlite3_file Methods ******************************* 4578 ******************************************************************************/ 4579 4580 /* 4581 ** This vector defines all the methods that can operate on an 4582 ** sqlite3_file for win32. 4583 */ 4584 static const sqlite3_io_methods winIoMethod = { 4585 3, /* iVersion */ 4586 winClose, /* xClose */ 4587 winRead, /* xRead */ 4588 winWrite, /* xWrite */ 4589 winTruncate, /* xTruncate */ 4590 winSync, /* xSync */ 4591 winFileSize, /* xFileSize */ 4592 winLock, /* xLock */ 4593 winUnlock, /* xUnlock */ 4594 winCheckReservedLock, /* xCheckReservedLock */ 4595 winFileControl, /* xFileControl */ 4596 winSectorSize, /* xSectorSize */ 4597 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4598 winShmMap, /* xShmMap */ 4599 winShmLock, /* xShmLock */ 4600 winShmBarrier, /* xShmBarrier */ 4601 winShmUnmap, /* xShmUnmap */ 4602 winFetch, /* xFetch */ 4603 winUnfetch /* xUnfetch */ 4604 }; 4605 4606 /* 4607 ** This vector defines all the methods that can operate on an 4608 ** sqlite3_file for win32 without performing any locking. 4609 */ 4610 static const sqlite3_io_methods winIoNolockMethod = { 4611 3, /* iVersion */ 4612 winClose, /* xClose */ 4613 winRead, /* xRead */ 4614 winWrite, /* xWrite */ 4615 winTruncate, /* xTruncate */ 4616 winSync, /* xSync */ 4617 winFileSize, /* xFileSize */ 4618 winNolockLock, /* xLock */ 4619 winNolockUnlock, /* xUnlock */ 4620 winNolockCheckReservedLock, /* xCheckReservedLock */ 4621 winFileControl, /* xFileControl */ 4622 winSectorSize, /* xSectorSize */ 4623 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4624 winShmMap, /* xShmMap */ 4625 winShmLock, /* xShmLock */ 4626 winShmBarrier, /* xShmBarrier */ 4627 winShmUnmap, /* xShmUnmap */ 4628 winFetch, /* xFetch */ 4629 winUnfetch /* xUnfetch */ 4630 }; 4631 4632 static winVfsAppData winAppData = { 4633 &winIoMethod, /* pMethod */ 4634 0, /* pAppData */ 4635 0 /* bNoLock */ 4636 }; 4637 4638 static winVfsAppData winNolockAppData = { 4639 &winIoNolockMethod, /* pMethod */ 4640 0, /* pAppData */ 4641 1 /* bNoLock */ 4642 }; 4643 4644 /**************************************************************************** 4645 **************************** sqlite3_vfs methods **************************** 4646 ** 4647 ** This division contains the implementation of methods on the 4648 ** sqlite3_vfs object. 4649 */ 4650 4651 #if defined(__CYGWIN__) 4652 /* 4653 ** Convert a filename from whatever the underlying operating system 4654 ** supports for filenames into UTF-8. Space to hold the result is 4655 ** obtained from malloc and must be freed by the calling function. 4656 */ 4657 static char *winConvertToUtf8Filename(const void *zFilename){ 4658 char *zConverted = 0; 4659 if( osIsNT() ){ 4660 zConverted = winUnicodeToUtf8(zFilename); 4661 } 4662 #ifdef SQLITE_WIN32_HAS_ANSI 4663 else{ 4664 zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); 4665 } 4666 #endif 4667 /* caller will handle out of memory */ 4668 return zConverted; 4669 } 4670 #endif 4671 4672 /* 4673 ** Convert a UTF-8 filename into whatever form the underlying 4674 ** operating system wants filenames in. Space to hold the result 4675 ** is obtained from malloc and must be freed by the calling 4676 ** function. 4677 */ 4678 static void *winConvertFromUtf8Filename(const char *zFilename){ 4679 void *zConverted = 0; 4680 if( osIsNT() ){ 4681 zConverted = winUtf8ToUnicode(zFilename); 4682 } 4683 #ifdef SQLITE_WIN32_HAS_ANSI 4684 else{ 4685 zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); 4686 } 4687 #endif 4688 /* caller will handle out of memory */ 4689 return zConverted; 4690 } 4691 4692 /* 4693 ** This function returns non-zero if the specified UTF-8 string buffer 4694 ** ends with a directory separator character or one was successfully 4695 ** added to it. 4696 */ 4697 static int winMakeEndInDirSep(int nBuf, char *zBuf){ 4698 if( zBuf ){ 4699 int nLen = sqlite3Strlen30(zBuf); 4700 if( nLen>0 ){ 4701 if( winIsDirSep(zBuf[nLen-1]) ){ 4702 return 1; 4703 }else if( nLen+1<nBuf ){ 4704 zBuf[nLen] = winGetDirSep(); 4705 zBuf[nLen+1] = '\0'; 4706 return 1; 4707 } 4708 } 4709 } 4710 return 0; 4711 } 4712 4713 /* 4714 ** Create a temporary file name and store the resulting pointer into pzBuf. 4715 ** The pointer returned in pzBuf must be freed via sqlite3_free(). 4716 */ 4717 static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ 4718 static char zChars[] = 4719 "abcdefghijklmnopqrstuvwxyz" 4720 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 4721 "0123456789"; 4722 size_t i, j; 4723 int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); 4724 int nMax, nBuf, nDir, nLen; 4725 char *zBuf; 4726 4727 /* It's odd to simulate an io-error here, but really this is just 4728 ** using the io-error infrastructure to test that SQLite handles this 4729 ** function failing. 4730 */ 4731 SimulateIOError( return SQLITE_IOERR ); 4732 4733 /* Allocate a temporary buffer to store the fully qualified file 4734 ** name for the temporary file. If this fails, we cannot continue. 4735 */ 4736 nMax = pVfs->mxPathname; nBuf = nMax + 2; 4737 zBuf = sqlite3MallocZero( nBuf ); 4738 if( !zBuf ){ 4739 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4740 return SQLITE_IOERR_NOMEM_BKPT; 4741 } 4742 4743 /* Figure out the effective temporary directory. First, check if one 4744 ** has been explicitly set by the application; otherwise, use the one 4745 ** configured by the operating system. 4746 */ 4747 nDir = nMax - (nPre + 15); 4748 assert( nDir>0 ); 4749 if( sqlite3_temp_directory ){ 4750 int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); 4751 if( nDirLen>0 ){ 4752 if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ 4753 nDirLen++; 4754 } 4755 if( nDirLen>nDir ){ 4756 sqlite3_free(zBuf); 4757 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4758 return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); 4759 } 4760 sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); 4761 } 4762 } 4763 #if defined(__CYGWIN__) 4764 else{ 4765 static const char *azDirs[] = { 4766 0, /* getenv("SQLITE_TMPDIR") */ 4767 0, /* getenv("TMPDIR") */ 4768 0, /* getenv("TMP") */ 4769 0, /* getenv("TEMP") */ 4770 0, /* getenv("USERPROFILE") */ 4771 "/var/tmp", 4772 "/usr/tmp", 4773 "/tmp", 4774 ".", 4775 0 /* List terminator */ 4776 }; 4777 unsigned int i; 4778 const char *zDir = 0; 4779 4780 if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); 4781 if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); 4782 if( !azDirs[2] ) azDirs[2] = getenv("TMP"); 4783 if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); 4784 if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); 4785 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ 4786 void *zConverted; 4787 if( zDir==0 ) continue; 4788 /* If the path starts with a drive letter followed by the colon 4789 ** character, assume it is already a native Win32 path; otherwise, 4790 ** it must be converted to a native Win32 path via the Cygwin API 4791 ** prior to using it. 4792 */ 4793 if( winIsDriveLetterAndColon(zDir) ){ 4794 zConverted = winConvertFromUtf8Filename(zDir); 4795 if( !zConverted ){ 4796 sqlite3_free(zBuf); 4797 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4798 return SQLITE_IOERR_NOMEM_BKPT; 4799 } 4800 if( winIsDir(zConverted) ){ 4801 sqlite3_snprintf(nMax, zBuf, "%s", zDir); 4802 sqlite3_free(zConverted); 4803 break; 4804 } 4805 sqlite3_free(zConverted); 4806 }else{ 4807 zConverted = sqlite3MallocZero( nMax+1 ); 4808 if( !zConverted ){ 4809 sqlite3_free(zBuf); 4810 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4811 return SQLITE_IOERR_NOMEM_BKPT; 4812 } 4813 if( cygwin_conv_path( 4814 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, 4815 zConverted, nMax+1)<0 ){ 4816 sqlite3_free(zConverted); 4817 sqlite3_free(zBuf); 4818 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); 4819 return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, 4820 "winGetTempname2", zDir); 4821 } 4822 if( winIsDir(zConverted) ){ 4823 /* At this point, we know the candidate directory exists and should 4824 ** be used. However, we may need to convert the string containing 4825 ** its name into UTF-8 (i.e. if it is UTF-16 right now). 4826 */ 4827 char *zUtf8 = winConvertToUtf8Filename(zConverted); 4828 if( !zUtf8 ){ 4829 sqlite3_free(zConverted); 4830 sqlite3_free(zBuf); 4831 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4832 return SQLITE_IOERR_NOMEM_BKPT; 4833 } 4834 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4835 sqlite3_free(zUtf8); 4836 sqlite3_free(zConverted); 4837 break; 4838 } 4839 sqlite3_free(zConverted); 4840 } 4841 } 4842 } 4843 #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) 4844 else if( osIsNT() ){ 4845 char *zMulti; 4846 LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); 4847 if( !zWidePath ){ 4848 sqlite3_free(zBuf); 4849 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4850 return SQLITE_IOERR_NOMEM_BKPT; 4851 } 4852 if( osGetTempPathW(nMax, zWidePath)==0 ){ 4853 sqlite3_free(zWidePath); 4854 sqlite3_free(zBuf); 4855 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4856 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4857 "winGetTempname2", 0); 4858 } 4859 zMulti = winUnicodeToUtf8(zWidePath); 4860 if( zMulti ){ 4861 sqlite3_snprintf(nMax, zBuf, "%s", zMulti); 4862 sqlite3_free(zMulti); 4863 sqlite3_free(zWidePath); 4864 }else{ 4865 sqlite3_free(zWidePath); 4866 sqlite3_free(zBuf); 4867 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4868 return SQLITE_IOERR_NOMEM_BKPT; 4869 } 4870 } 4871 #ifdef SQLITE_WIN32_HAS_ANSI 4872 else{ 4873 char *zUtf8; 4874 char *zMbcsPath = sqlite3MallocZero( nMax ); 4875 if( !zMbcsPath ){ 4876 sqlite3_free(zBuf); 4877 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4878 return SQLITE_IOERR_NOMEM_BKPT; 4879 } 4880 if( osGetTempPathA(nMax, zMbcsPath)==0 ){ 4881 sqlite3_free(zBuf); 4882 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4883 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4884 "winGetTempname3", 0); 4885 } 4886 zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); 4887 if( zUtf8 ){ 4888 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4889 sqlite3_free(zUtf8); 4890 }else{ 4891 sqlite3_free(zBuf); 4892 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4893 return SQLITE_IOERR_NOMEM_BKPT; 4894 } 4895 } 4896 #endif /* SQLITE_WIN32_HAS_ANSI */ 4897 #endif /* !SQLITE_OS_WINRT */ 4898 4899 /* 4900 ** Check to make sure the temporary directory ends with an appropriate 4901 ** separator. If it does not and there is not enough space left to add 4902 ** one, fail. 4903 */ 4904 if( !winMakeEndInDirSep(nDir+1, zBuf) ){ 4905 sqlite3_free(zBuf); 4906 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4907 return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0); 4908 } 4909 4910 /* 4911 ** Check that the output buffer is large enough for the temporary file 4912 ** name in the following format: 4913 ** 4914 ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0" 4915 ** 4916 ** If not, return SQLITE_ERROR. The number 17 is used here in order to 4917 ** account for the space used by the 15 character random suffix and the 4918 ** two trailing NUL characters. The final directory separator character 4919 ** has already added if it was not already present. 4920 */ 4921 nLen = sqlite3Strlen30(zBuf); 4922 if( (nLen + nPre + 17) > nBuf ){ 4923 sqlite3_free(zBuf); 4924 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4925 return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); 4926 } 4927 4928 sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); 4929 4930 j = sqlite3Strlen30(zBuf); 4931 sqlite3_randomness(15, &zBuf[j]); 4932 for(i=0; i<15; i++, j++){ 4933 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 4934 } 4935 zBuf[j] = 0; 4936 zBuf[j+1] = 0; 4937 *pzBuf = zBuf; 4938 4939 OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); 4940 return SQLITE_OK; 4941 } 4942 4943 /* 4944 ** Return TRUE if the named file is really a directory. Return false if 4945 ** it is something other than a directory, or if there is any kind of memory 4946 ** allocation failure. 4947 */ 4948 static int winIsDir(const void *zConverted){ 4949 DWORD attr; 4950 int rc = 0; 4951 DWORD lastErrno; 4952 4953 if( osIsNT() ){ 4954 int cnt = 0; 4955 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 4956 memset(&sAttrData, 0, sizeof(sAttrData)); 4957 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 4958 GetFileExInfoStandard, 4959 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 4960 if( !rc ){ 4961 return 0; /* Invalid name? */ 4962 } 4963 attr = sAttrData.dwFileAttributes; 4964 #if SQLITE_OS_WINCE==0 4965 }else{ 4966 attr = osGetFileAttributesA((char*)zConverted); 4967 #endif 4968 } 4969 return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); 4970 } 4971 4972 /* forward reference */ 4973 static int winAccess( 4974 sqlite3_vfs *pVfs, /* Not used on win32 */ 4975 const char *zFilename, /* Name of file to check */ 4976 int flags, /* Type of test to make on this file */ 4977 int *pResOut /* OUT: Result */ 4978 ); 4979 4980 /* 4981 ** Open a file. 4982 */ 4983 static int winOpen( 4984 sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ 4985 const char *zName, /* Name of the file (UTF-8) */ 4986 sqlite3_file *id, /* Write the SQLite file handle here */ 4987 int flags, /* Open mode flags */ 4988 int *pOutFlags /* Status return flags */ 4989 ){ 4990 HANDLE h; 4991 DWORD lastErrno = 0; 4992 DWORD dwDesiredAccess; 4993 DWORD dwShareMode; 4994 DWORD dwCreationDisposition; 4995 DWORD dwFlagsAndAttributes = 0; 4996 #if SQLITE_OS_WINCE 4997 int isTemp = 0; 4998 #endif 4999 winVfsAppData *pAppData; 5000 winFile *pFile = (winFile*)id; 5001 void *zConverted; /* Filename in OS encoding */ 5002 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ 5003 int cnt = 0; 5004 5005 /* If argument zPath is a NULL pointer, this function is required to open 5006 ** a temporary file. Use this buffer to store the file name in. 5007 */ 5008 char *zTmpname = 0; /* For temporary filename, if necessary. */ 5009 5010 int rc = SQLITE_OK; /* Function Return Code */ 5011 #if !defined(NDEBUG) || SQLITE_OS_WINCE 5012 int eType = flags&0xFFFFFF00; /* Type of file to open */ 5013 #endif 5014 5015 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); 5016 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); 5017 int isCreate = (flags & SQLITE_OPEN_CREATE); 5018 int isReadonly = (flags & SQLITE_OPEN_READONLY); 5019 int isReadWrite = (flags & SQLITE_OPEN_READWRITE); 5020 5021 #ifndef NDEBUG 5022 int isOpenJournal = (isCreate && ( 5023 eType==SQLITE_OPEN_MASTER_JOURNAL 5024 || eType==SQLITE_OPEN_MAIN_JOURNAL 5025 || eType==SQLITE_OPEN_WAL 5026 )); 5027 #endif 5028 5029 OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", 5030 zUtf8Name, id, flags, pOutFlags)); 5031 5032 /* Check the following statements are true: 5033 ** 5034 ** (a) Exactly one of the READWRITE and READONLY flags must be set, and 5035 ** (b) if CREATE is set, then READWRITE must also be set, and 5036 ** (c) if EXCLUSIVE is set, then CREATE must also be set. 5037 ** (d) if DELETEONCLOSE is set, then CREATE must also be set. 5038 */ 5039 assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); 5040 assert(isCreate==0 || isReadWrite); 5041 assert(isExclusive==0 || isCreate); 5042 assert(isDelete==0 || isCreate); 5043 5044 /* The main DB, main journal, WAL file and master journal are never 5045 ** automatically deleted. Nor are they ever temporary files. */ 5046 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); 5047 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); 5048 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); 5049 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); 5050 5051 /* Assert that the upper layer has set one of the "file-type" flags. */ 5052 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB 5053 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 5054 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL 5055 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL 5056 ); 5057 5058 assert( pFile!=0 ); 5059 memset(pFile, 0, sizeof(winFile)); 5060 pFile->h = INVALID_HANDLE_VALUE; 5061 5062 #if SQLITE_OS_WINRT 5063 if( !zUtf8Name && !sqlite3_temp_directory ){ 5064 sqlite3_log(SQLITE_ERROR, 5065 "sqlite3_temp_directory variable should be set for WinRT"); 5066 } 5067 #endif 5068 5069 /* If the second argument to this function is NULL, generate a 5070 ** temporary file name to use 5071 */ 5072 if( !zUtf8Name ){ 5073 assert( isDelete && !isOpenJournal ); 5074 rc = winGetTempname(pVfs, &zTmpname); 5075 if( rc!=SQLITE_OK ){ 5076 OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); 5077 return rc; 5078 } 5079 zUtf8Name = zTmpname; 5080 } 5081 5082 /* Database filenames are double-zero terminated if they are not 5083 ** URIs with parameters. Hence, they can always be passed into 5084 ** sqlite3_uri_parameter(). 5085 */ 5086 assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || 5087 zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); 5088 5089 /* Convert the filename to the system encoding. */ 5090 zConverted = winConvertFromUtf8Filename(zUtf8Name); 5091 if( zConverted==0 ){ 5092 sqlite3_free(zTmpname); 5093 OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); 5094 return SQLITE_IOERR_NOMEM_BKPT; 5095 } 5096 5097 if( winIsDir(zConverted) ){ 5098 sqlite3_free(zConverted); 5099 sqlite3_free(zTmpname); 5100 OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); 5101 return SQLITE_CANTOPEN_ISDIR; 5102 } 5103 5104 if( isReadWrite ){ 5105 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 5106 }else{ 5107 dwDesiredAccess = GENERIC_READ; 5108 } 5109 5110 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 5111 ** created. SQLite doesn't use it to indicate "exclusive access" 5112 ** as it is usually understood. 5113 */ 5114 if( isExclusive ){ 5115 /* Creates a new file, only if it does not already exist. */ 5116 /* If the file exists, it fails. */ 5117 dwCreationDisposition = CREATE_NEW; 5118 }else if( isCreate ){ 5119 /* Open existing file, or create if it doesn't exist */ 5120 dwCreationDisposition = OPEN_ALWAYS; 5121 }else{ 5122 /* Opens a file, only if it exists. */ 5123 dwCreationDisposition = OPEN_EXISTING; 5124 } 5125 5126 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 5127 5128 if( isDelete ){ 5129 #if SQLITE_OS_WINCE 5130 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; 5131 isTemp = 1; 5132 #else 5133 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY 5134 | FILE_ATTRIBUTE_HIDDEN 5135 | FILE_FLAG_DELETE_ON_CLOSE; 5136 #endif 5137 }else{ 5138 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 5139 } 5140 /* Reports from the internet are that performance is always 5141 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ 5142 #if SQLITE_OS_WINCE 5143 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; 5144 #endif 5145 5146 if( osIsNT() ){ 5147 #if SQLITE_OS_WINRT 5148 CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; 5149 extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 5150 extendedParameters.dwFileAttributes = 5151 dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; 5152 extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; 5153 extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; 5154 extendedParameters.lpSecurityAttributes = NULL; 5155 extendedParameters.hTemplateFile = NULL; 5156 do{ 5157 h = osCreateFile2((LPCWSTR)zConverted, 5158 dwDesiredAccess, 5159 dwShareMode, 5160 dwCreationDisposition, 5161 &extendedParameters); 5162 if( h!=INVALID_HANDLE_VALUE ) break; 5163 if( isReadWrite ){ 5164 int rc2, isRO = 0; 5165 sqlite3BeginBenignMalloc(); 5166 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5167 sqlite3EndBenignMalloc(); 5168 if( rc2==SQLITE_OK && isRO ) break; 5169 } 5170 }while( winRetryIoerr(&cnt, &lastErrno) ); 5171 #else 5172 do{ 5173 h = osCreateFileW((LPCWSTR)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 #endif 5189 } 5190 #ifdef SQLITE_WIN32_HAS_ANSI 5191 else{ 5192 do{ 5193 h = osCreateFileA((LPCSTR)zConverted, 5194 dwDesiredAccess, 5195 dwShareMode, NULL, 5196 dwCreationDisposition, 5197 dwFlagsAndAttributes, 5198 NULL); 5199 if( h!=INVALID_HANDLE_VALUE ) break; 5200 if( isReadWrite ){ 5201 int rc2, isRO = 0; 5202 sqlite3BeginBenignMalloc(); 5203 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5204 sqlite3EndBenignMalloc(); 5205 if( rc2==SQLITE_OK && isRO ) break; 5206 } 5207 }while( winRetryIoerr(&cnt, &lastErrno) ); 5208 } 5209 #endif 5210 winLogIoerr(cnt, __LINE__); 5211 5212 OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, 5213 dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5214 5215 if( h==INVALID_HANDLE_VALUE ){ 5216 sqlite3_free(zConverted); 5217 sqlite3_free(zTmpname); 5218 if( isReadWrite && !isExclusive ){ 5219 return winOpen(pVfs, zName, id, 5220 ((flags|SQLITE_OPEN_READONLY) & 5221 ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), 5222 pOutFlags); 5223 }else{ 5224 pFile->lastErrno = lastErrno; 5225 winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); 5226 return SQLITE_CANTOPEN_BKPT; 5227 } 5228 } 5229 5230 if( pOutFlags ){ 5231 if( isReadWrite ){ 5232 *pOutFlags = SQLITE_OPEN_READWRITE; 5233 }else{ 5234 *pOutFlags = SQLITE_OPEN_READONLY; 5235 } 5236 } 5237 5238 OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " 5239 "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? 5240 *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5241 5242 pAppData = (winVfsAppData*)pVfs->pAppData; 5243 5244 #if SQLITE_OS_WINCE 5245 { 5246 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB 5247 && ((pAppData==NULL) || !pAppData->bNoLock) 5248 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK 5249 ){ 5250 osCloseHandle(h); 5251 sqlite3_free(zConverted); 5252 sqlite3_free(zTmpname); 5253 OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); 5254 return rc; 5255 } 5256 } 5257 if( isTemp ){ 5258 pFile->zDeleteOnClose = zConverted; 5259 }else 5260 #endif 5261 { 5262 sqlite3_free(zConverted); 5263 } 5264 5265 sqlite3_free(zTmpname); 5266 pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; 5267 pFile->pVfs = pVfs; 5268 pFile->h = h; 5269 if( isReadonly ){ 5270 pFile->ctrlFlags |= WINFILE_RDONLY; 5271 } 5272 if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ 5273 pFile->ctrlFlags |= WINFILE_PSOW; 5274 } 5275 pFile->lastErrno = NO_ERROR; 5276 pFile->zPath = zName; 5277 #if SQLITE_MAX_MMAP_SIZE>0 5278 pFile->hMap = NULL; 5279 pFile->pMapRegion = 0; 5280 pFile->mmapSize = 0; 5281 pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; 5282 #endif 5283 5284 OpenCounter(+1); 5285 return rc; 5286 } 5287 5288 /* 5289 ** Delete the named file. 5290 ** 5291 ** Note that Windows does not allow a file to be deleted if some other 5292 ** process has it open. Sometimes a virus scanner or indexing program 5293 ** will open a journal file shortly after it is created in order to do 5294 ** whatever it does. While this other process is holding the 5295 ** file open, we will be unable to delete it. To work around this 5296 ** problem, we delay 100 milliseconds and try to delete again. Up 5297 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving 5298 ** up and returning an error. 5299 */ 5300 static int winDelete( 5301 sqlite3_vfs *pVfs, /* Not used on win32 */ 5302 const char *zFilename, /* Name of file to delete */ 5303 int syncDir /* Not used on win32 */ 5304 ){ 5305 int cnt = 0; 5306 int rc; 5307 DWORD attr; 5308 DWORD lastErrno = 0; 5309 void *zConverted; 5310 UNUSED_PARAMETER(pVfs); 5311 UNUSED_PARAMETER(syncDir); 5312 5313 SimulateIOError(return SQLITE_IOERR_DELETE); 5314 OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); 5315 5316 zConverted = winConvertFromUtf8Filename(zFilename); 5317 if( zConverted==0 ){ 5318 OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5319 return SQLITE_IOERR_NOMEM_BKPT; 5320 } 5321 if( osIsNT() ){ 5322 do { 5323 #if SQLITE_OS_WINRT 5324 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5325 memset(&sAttrData, 0, sizeof(sAttrData)); 5326 if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, 5327 &sAttrData) ){ 5328 attr = sAttrData.dwFileAttributes; 5329 }else{ 5330 lastErrno = osGetLastError(); 5331 if( lastErrno==ERROR_FILE_NOT_FOUND 5332 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5333 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5334 }else{ 5335 rc = SQLITE_ERROR; 5336 } 5337 break; 5338 } 5339 #else 5340 attr = osGetFileAttributesW(zConverted); 5341 #endif 5342 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5343 lastErrno = osGetLastError(); 5344 if( lastErrno==ERROR_FILE_NOT_FOUND 5345 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5346 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5347 }else{ 5348 rc = SQLITE_ERROR; 5349 } 5350 break; 5351 } 5352 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5353 rc = SQLITE_ERROR; /* Files only. */ 5354 break; 5355 } 5356 if ( osDeleteFileW(zConverted) ){ 5357 rc = SQLITE_OK; /* Deleted OK. */ 5358 break; 5359 } 5360 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5361 rc = SQLITE_ERROR; /* No more retries. */ 5362 break; 5363 } 5364 } while(1); 5365 } 5366 #ifdef SQLITE_WIN32_HAS_ANSI 5367 else{ 5368 do { 5369 attr = osGetFileAttributesA(zConverted); 5370 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5371 lastErrno = osGetLastError(); 5372 if( lastErrno==ERROR_FILE_NOT_FOUND 5373 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5374 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5375 }else{ 5376 rc = SQLITE_ERROR; 5377 } 5378 break; 5379 } 5380 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5381 rc = SQLITE_ERROR; /* Files only. */ 5382 break; 5383 } 5384 if ( osDeleteFileA(zConverted) ){ 5385 rc = SQLITE_OK; /* Deleted OK. */ 5386 break; 5387 } 5388 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5389 rc = SQLITE_ERROR; /* No more retries. */ 5390 break; 5391 } 5392 } while(1); 5393 } 5394 #endif 5395 if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ 5396 rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); 5397 }else{ 5398 winLogIoerr(cnt, __LINE__); 5399 } 5400 sqlite3_free(zConverted); 5401 OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); 5402 return rc; 5403 } 5404 5405 /* 5406 ** Check the existence and status of a file. 5407 */ 5408 static int winAccess( 5409 sqlite3_vfs *pVfs, /* Not used on win32 */ 5410 const char *zFilename, /* Name of file to check */ 5411 int flags, /* Type of test to make on this file */ 5412 int *pResOut /* OUT: Result */ 5413 ){ 5414 DWORD attr; 5415 int rc = 0; 5416 DWORD lastErrno = 0; 5417 void *zConverted; 5418 UNUSED_PARAMETER(pVfs); 5419 5420 SimulateIOError( return SQLITE_IOERR_ACCESS; ); 5421 OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", 5422 zFilename, flags, pResOut)); 5423 5424 zConverted = winConvertFromUtf8Filename(zFilename); 5425 if( zConverted==0 ){ 5426 OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5427 return SQLITE_IOERR_NOMEM_BKPT; 5428 } 5429 if( osIsNT() ){ 5430 int cnt = 0; 5431 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5432 memset(&sAttrData, 0, sizeof(sAttrData)); 5433 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 5434 GetFileExInfoStandard, 5435 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 5436 if( rc ){ 5437 /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file 5438 ** as if it does not exist. 5439 */ 5440 if( flags==SQLITE_ACCESS_EXISTS 5441 && sAttrData.nFileSizeHigh==0 5442 && sAttrData.nFileSizeLow==0 ){ 5443 attr = INVALID_FILE_ATTRIBUTES; 5444 }else{ 5445 attr = sAttrData.dwFileAttributes; 5446 } 5447 }else{ 5448 winLogIoerr(cnt, __LINE__); 5449 if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ 5450 sqlite3_free(zConverted); 5451 return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", 5452 zFilename); 5453 }else{ 5454 attr = INVALID_FILE_ATTRIBUTES; 5455 } 5456 } 5457 } 5458 #ifdef SQLITE_WIN32_HAS_ANSI 5459 else{ 5460 attr = osGetFileAttributesA((char*)zConverted); 5461 } 5462 #endif 5463 sqlite3_free(zConverted); 5464 switch( flags ){ 5465 case SQLITE_ACCESS_READ: 5466 case SQLITE_ACCESS_EXISTS: 5467 rc = attr!=INVALID_FILE_ATTRIBUTES; 5468 break; 5469 case SQLITE_ACCESS_READWRITE: 5470 rc = attr!=INVALID_FILE_ATTRIBUTES && 5471 (attr & FILE_ATTRIBUTE_READONLY)==0; 5472 break; 5473 default: 5474 assert(!"Invalid flags argument"); 5475 } 5476 *pResOut = rc; 5477 OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", 5478 zFilename, pResOut, *pResOut)); 5479 return SQLITE_OK; 5480 } 5481 5482 /* 5483 ** Returns non-zero if the specified path name starts with a drive letter 5484 ** followed by a colon character. 5485 */ 5486 static BOOL winIsDriveLetterAndColon( 5487 const char *zPathname 5488 ){ 5489 return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); 5490 } 5491 5492 /* 5493 ** Returns non-zero if the specified path name should be used verbatim. If 5494 ** non-zero is returned from this function, the calling function must simply 5495 ** use the provided path name verbatim -OR- resolve it into a full path name 5496 ** using the GetFullPathName Win32 API function (if available). 5497 */ 5498 static BOOL winIsVerbatimPathname( 5499 const char *zPathname 5500 ){ 5501 /* 5502 ** If the path name starts with a forward slash or a backslash, it is either 5503 ** a legal UNC name, a volume relative path, or an absolute path name in the 5504 ** "Unix" format on Windows. There is no easy way to differentiate between 5505 ** the final two cases; therefore, we return the safer return value of TRUE 5506 ** so that callers of this function will simply use it verbatim. 5507 */ 5508 if ( winIsDirSep(zPathname[0]) ){ 5509 return TRUE; 5510 } 5511 5512 /* 5513 ** If the path name starts with a letter and a colon it is either a volume 5514 ** relative path or an absolute path. Callers of this function must not 5515 ** attempt to treat it as a relative path name (i.e. they should simply use 5516 ** it verbatim). 5517 */ 5518 if ( winIsDriveLetterAndColon(zPathname) ){ 5519 return TRUE; 5520 } 5521 5522 /* 5523 ** If we get to this point, the path name should almost certainly be a purely 5524 ** relative one (i.e. not a UNC name, not absolute, and not volume relative). 5525 */ 5526 return FALSE; 5527 } 5528 5529 /* 5530 ** Turn a relative pathname into a full pathname. Write the full 5531 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname 5532 ** bytes in size. 5533 */ 5534 static int winFullPathname( 5535 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 5536 const char *zRelative, /* Possibly relative input path */ 5537 int nFull, /* Size of output buffer in bytes */ 5538 char *zFull /* Output buffer */ 5539 ){ 5540 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5541 DWORD nByte; 5542 void *zConverted; 5543 char *zOut; 5544 #endif 5545 5546 /* If this path name begins with "/X:", where "X" is any alphabetic 5547 ** character, discard the initial "/" from the pathname. 5548 */ 5549 if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ 5550 zRelative++; 5551 } 5552 5553 #if defined(__CYGWIN__) 5554 SimulateIOError( return SQLITE_ERROR ); 5555 UNUSED_PARAMETER(nFull); 5556 assert( nFull>=pVfs->mxPathname ); 5557 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5558 /* 5559 ** NOTE: We are dealing with a relative path name and the data 5560 ** directory has been set. Therefore, use it as the basis 5561 ** for converting the relative path name to an absolute 5562 ** one by prepending the data directory and a slash. 5563 */ 5564 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5565 if( !zOut ){ 5566 return SQLITE_IOERR_NOMEM_BKPT; 5567 } 5568 if( cygwin_conv_path( 5569 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | 5570 CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5571 sqlite3_free(zOut); 5572 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5573 "winFullPathname1", zRelative); 5574 }else{ 5575 char *zUtf8 = winConvertToUtf8Filename(zOut); 5576 if( !zUtf8 ){ 5577 sqlite3_free(zOut); 5578 return SQLITE_IOERR_NOMEM_BKPT; 5579 } 5580 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5581 sqlite3_data_directory, winGetDirSep(), zUtf8); 5582 sqlite3_free(zUtf8); 5583 sqlite3_free(zOut); 5584 } 5585 }else{ 5586 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5587 if( !zOut ){ 5588 return SQLITE_IOERR_NOMEM_BKPT; 5589 } 5590 if( cygwin_conv_path( 5591 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), 5592 zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5593 sqlite3_free(zOut); 5594 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5595 "winFullPathname2", zRelative); 5596 }else{ 5597 char *zUtf8 = winConvertToUtf8Filename(zOut); 5598 if( !zUtf8 ){ 5599 sqlite3_free(zOut); 5600 return SQLITE_IOERR_NOMEM_BKPT; 5601 } 5602 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); 5603 sqlite3_free(zUtf8); 5604 sqlite3_free(zOut); 5605 } 5606 } 5607 return SQLITE_OK; 5608 #endif 5609 5610 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) 5611 SimulateIOError( return SQLITE_ERROR ); 5612 /* WinCE has no concept of a relative pathname, or so I am told. */ 5613 /* WinRT has no way to convert a relative path to an absolute one. */ 5614 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5615 /* 5616 ** NOTE: We are dealing with a relative path name and the data 5617 ** directory has been set. Therefore, use it as the basis 5618 ** for converting the relative path name to an absolute 5619 ** one by prepending the data directory and a backslash. 5620 */ 5621 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5622 sqlite3_data_directory, winGetDirSep(), zRelative); 5623 }else{ 5624 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); 5625 } 5626 return SQLITE_OK; 5627 #endif 5628 5629 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5630 /* It's odd to simulate an io-error here, but really this is just 5631 ** using the io-error infrastructure to test that SQLite handles this 5632 ** function failing. This function could fail if, for example, the 5633 ** current working directory has been unlinked. 5634 */ 5635 SimulateIOError( return SQLITE_ERROR ); 5636 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5637 /* 5638 ** NOTE: We are dealing with a relative path name and the data 5639 ** directory has been set. Therefore, use it as the basis 5640 ** for converting the relative path name to an absolute 5641 ** one by prepending the data directory and a backslash. 5642 */ 5643 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5644 sqlite3_data_directory, winGetDirSep(), zRelative); 5645 return SQLITE_OK; 5646 } 5647 zConverted = winConvertFromUtf8Filename(zRelative); 5648 if( zConverted==0 ){ 5649 return SQLITE_IOERR_NOMEM_BKPT; 5650 } 5651 if( osIsNT() ){ 5652 LPWSTR zTemp; 5653 nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); 5654 if( nByte==0 ){ 5655 sqlite3_free(zConverted); 5656 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5657 "winFullPathname1", zRelative); 5658 } 5659 nByte += 3; 5660 zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); 5661 if( zTemp==0 ){ 5662 sqlite3_free(zConverted); 5663 return SQLITE_IOERR_NOMEM_BKPT; 5664 } 5665 nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); 5666 if( nByte==0 ){ 5667 sqlite3_free(zConverted); 5668 sqlite3_free(zTemp); 5669 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5670 "winFullPathname2", zRelative); 5671 } 5672 sqlite3_free(zConverted); 5673 zOut = winUnicodeToUtf8(zTemp); 5674 sqlite3_free(zTemp); 5675 } 5676 #ifdef SQLITE_WIN32_HAS_ANSI 5677 else{ 5678 char *zTemp; 5679 nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); 5680 if( nByte==0 ){ 5681 sqlite3_free(zConverted); 5682 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5683 "winFullPathname3", zRelative); 5684 } 5685 nByte += 3; 5686 zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); 5687 if( zTemp==0 ){ 5688 sqlite3_free(zConverted); 5689 return SQLITE_IOERR_NOMEM_BKPT; 5690 } 5691 nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); 5692 if( nByte==0 ){ 5693 sqlite3_free(zConverted); 5694 sqlite3_free(zTemp); 5695 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5696 "winFullPathname4", zRelative); 5697 } 5698 sqlite3_free(zConverted); 5699 zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); 5700 sqlite3_free(zTemp); 5701 } 5702 #endif 5703 if( zOut ){ 5704 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); 5705 sqlite3_free(zOut); 5706 return SQLITE_OK; 5707 }else{ 5708 return SQLITE_IOERR_NOMEM_BKPT; 5709 } 5710 #endif 5711 } 5712 5713 #ifndef SQLITE_OMIT_LOAD_EXTENSION 5714 /* 5715 ** Interfaces for opening a shared library, finding entry points 5716 ** within the shared library, and closing the shared library. 5717 */ 5718 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 5719 HANDLE h; 5720 #if defined(__CYGWIN__) 5721 int nFull = pVfs->mxPathname+1; 5722 char *zFull = sqlite3MallocZero( nFull ); 5723 void *zConverted = 0; 5724 if( zFull==0 ){ 5725 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5726 return 0; 5727 } 5728 if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ 5729 sqlite3_free(zFull); 5730 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5731 return 0; 5732 } 5733 zConverted = winConvertFromUtf8Filename(zFull); 5734 sqlite3_free(zFull); 5735 #else 5736 void *zConverted = winConvertFromUtf8Filename(zFilename); 5737 UNUSED_PARAMETER(pVfs); 5738 #endif 5739 if( zConverted==0 ){ 5740 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5741 return 0; 5742 } 5743 if( osIsNT() ){ 5744 #if SQLITE_OS_WINRT 5745 h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); 5746 #else 5747 h = osLoadLibraryW((LPCWSTR)zConverted); 5748 #endif 5749 } 5750 #ifdef SQLITE_WIN32_HAS_ANSI 5751 else{ 5752 h = osLoadLibraryA((char*)zConverted); 5753 } 5754 #endif 5755 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); 5756 sqlite3_free(zConverted); 5757 return (void*)h; 5758 } 5759 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 5760 UNUSED_PARAMETER(pVfs); 5761 winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); 5762 } 5763 static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ 5764 FARPROC proc; 5765 UNUSED_PARAMETER(pVfs); 5766 proc = osGetProcAddressA((HANDLE)pH, zSym); 5767 OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", 5768 (void*)pH, zSym, (void*)proc)); 5769 return (void(*)(void))proc; 5770 } 5771 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ 5772 UNUSED_PARAMETER(pVfs); 5773 osFreeLibrary((HANDLE)pHandle); 5774 OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); 5775 } 5776 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 5777 #define winDlOpen 0 5778 #define winDlError 0 5779 #define winDlSym 0 5780 #define winDlClose 0 5781 #endif 5782 5783 /* State information for the randomness gatherer. */ 5784 typedef struct EntropyGatherer EntropyGatherer; 5785 struct EntropyGatherer { 5786 unsigned char *a; /* Gather entropy into this buffer */ 5787 int na; /* Size of a[] in bytes */ 5788 int i; /* XOR next input into a[i] */ 5789 int nXor; /* Number of XOR operations done */ 5790 }; 5791 5792 #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) 5793 /* Mix sz bytes of entropy into p. */ 5794 static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ 5795 int j, k; 5796 for(j=0, k=p->i; j<sz; j++){ 5797 p->a[k++] ^= x[j]; 5798 if( k>=p->na ) k = 0; 5799 } 5800 p->i = k; 5801 p->nXor += sz; 5802 } 5803 #endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ 5804 5805 /* 5806 ** Write up to nBuf bytes of randomness into zBuf. 5807 */ 5808 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5809 #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) 5810 UNUSED_PARAMETER(pVfs); 5811 memset(zBuf, 0, nBuf); 5812 return nBuf; 5813 #else 5814 EntropyGatherer e; 5815 UNUSED_PARAMETER(pVfs); 5816 memset(zBuf, 0, nBuf); 5817 e.a = (unsigned char*)zBuf; 5818 e.na = nBuf; 5819 e.nXor = 0; 5820 e.i = 0; 5821 { 5822 SYSTEMTIME x; 5823 osGetSystemTime(&x); 5824 xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); 5825 } 5826 { 5827 DWORD pid = osGetCurrentProcessId(); 5828 xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); 5829 } 5830 #if SQLITE_OS_WINRT 5831 { 5832 ULONGLONG cnt = osGetTickCount64(); 5833 xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); 5834 } 5835 #else 5836 { 5837 DWORD cnt = osGetTickCount(); 5838 xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); 5839 } 5840 #endif /* SQLITE_OS_WINRT */ 5841 { 5842 LARGE_INTEGER i; 5843 osQueryPerformanceCounter(&i); 5844 xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); 5845 } 5846 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID 5847 { 5848 UUID id; 5849 memset(&id, 0, sizeof(UUID)); 5850 osUuidCreate(&id); 5851 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5852 memset(&id, 0, sizeof(UUID)); 5853 osUuidCreateSequential(&id); 5854 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5855 } 5856 #endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ 5857 return e.nXor>nBuf ? nBuf : e.nXor; 5858 #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ 5859 } 5860 5861 5862 /* 5863 ** Sleep for a little while. Return the amount of time slept. 5864 */ 5865 static int winSleep(sqlite3_vfs *pVfs, int microsec){ 5866 sqlite3_win32_sleep((microsec+999)/1000); 5867 UNUSED_PARAMETER(pVfs); 5868 return ((microsec+999)/1000)*1000; 5869 } 5870 5871 /* 5872 ** The following variable, if set to a non-zero value, is interpreted as 5873 ** the number of seconds since 1970 and is used to set the result of 5874 ** sqlite3OsCurrentTime() during testing. 5875 */ 5876 #ifdef SQLITE_TEST 5877 int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ 5878 #endif 5879 5880 /* 5881 ** Find the current time (in Universal Coordinated Time). Write into *piNow 5882 ** the current time and date as a Julian Day number times 86_400_000. In 5883 ** other words, write into *piNow the number of milliseconds since the Julian 5884 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the 5885 ** proleptic Gregorian calendar. 5886 ** 5887 ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date 5888 ** cannot be found. 5889 */ 5890 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ 5891 /* FILETIME structure is a 64-bit value representing the number of 5892 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 5893 */ 5894 FILETIME ft; 5895 static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; 5896 #ifdef SQLITE_TEST 5897 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; 5898 #endif 5899 /* 2^32 - to avoid use of LL and warnings in gcc */ 5900 static const sqlite3_int64 max32BitValue = 5901 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + 5902 (sqlite3_int64)294967296; 5903 5904 #if SQLITE_OS_WINCE 5905 SYSTEMTIME time; 5906 osGetSystemTime(&time); 5907 /* if SystemTimeToFileTime() fails, it returns zero. */ 5908 if (!osSystemTimeToFileTime(&time,&ft)){ 5909 return SQLITE_ERROR; 5910 } 5911 #else 5912 osGetSystemTimeAsFileTime( &ft ); 5913 #endif 5914 5915 *piNow = winFiletimeEpoch + 5916 ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 5917 (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; 5918 5919 #ifdef SQLITE_TEST 5920 if( sqlite3_current_time ){ 5921 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; 5922 } 5923 #endif 5924 UNUSED_PARAMETER(pVfs); 5925 return SQLITE_OK; 5926 } 5927 5928 /* 5929 ** Find the current time (in Universal Coordinated Time). Write the 5930 ** current time and date as a Julian Day number into *prNow and 5931 ** return 0. Return 1 if the time and date cannot be found. 5932 */ 5933 static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ 5934 int rc; 5935 sqlite3_int64 i; 5936 rc = winCurrentTimeInt64(pVfs, &i); 5937 if( !rc ){ 5938 *prNow = i/86400000.0; 5939 } 5940 return rc; 5941 } 5942 5943 /* 5944 ** The idea is that this function works like a combination of 5945 ** GetLastError() and FormatMessage() on Windows (or errno and 5946 ** strerror_r() on Unix). After an error is returned by an OS 5947 ** function, SQLite calls this function with zBuf pointing to 5948 ** a buffer of nBuf bytes. The OS layer should populate the 5949 ** buffer with a nul-terminated UTF-8 encoded error message 5950 ** describing the last IO error to have occurred within the calling 5951 ** thread. 5952 ** 5953 ** If the error message is too large for the supplied buffer, 5954 ** it should be truncated. The return value of xGetLastError 5955 ** is zero if the error message fits in the buffer, or non-zero 5956 ** otherwise (if the message was truncated). If non-zero is returned, 5957 ** then it is not necessary to include the nul-terminator character 5958 ** in the output buffer. 5959 ** 5960 ** Not supplying an error message will have no adverse effect 5961 ** on SQLite. It is fine to have an implementation that never 5962 ** returns an error message: 5963 ** 5964 ** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5965 ** assert(zBuf[0]=='\0'); 5966 ** return 0; 5967 ** } 5968 ** 5969 ** However if an error message is supplied, it will be incorporated 5970 ** by sqlite into the error message available to the user using 5971 ** sqlite3_errmsg(), possibly making IO errors easier to debug. 5972 */ 5973 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5974 DWORD e = osGetLastError(); 5975 UNUSED_PARAMETER(pVfs); 5976 if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); 5977 return e; 5978 } 5979 5980 /* 5981 ** Initialize and deinitialize the operating system interface. 5982 */ 5983 int sqlite3_os_init(void){ 5984 static sqlite3_vfs winVfs = { 5985 3, /* iVersion */ 5986 sizeof(winFile), /* szOsFile */ 5987 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 5988 0, /* pNext */ 5989 "win32", /* zName */ 5990 &winAppData, /* pAppData */ 5991 winOpen, /* xOpen */ 5992 winDelete, /* xDelete */ 5993 winAccess, /* xAccess */ 5994 winFullPathname, /* xFullPathname */ 5995 winDlOpen, /* xDlOpen */ 5996 winDlError, /* xDlError */ 5997 winDlSym, /* xDlSym */ 5998 winDlClose, /* xDlClose */ 5999 winRandomness, /* xRandomness */ 6000 winSleep, /* xSleep */ 6001 winCurrentTime, /* xCurrentTime */ 6002 winGetLastError, /* xGetLastError */ 6003 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6004 winSetSystemCall, /* xSetSystemCall */ 6005 winGetSystemCall, /* xGetSystemCall */ 6006 winNextSystemCall, /* xNextSystemCall */ 6007 }; 6008 #if defined(SQLITE_WIN32_HAS_WIDE) 6009 static sqlite3_vfs winLongPathVfs = { 6010 3, /* iVersion */ 6011 sizeof(winFile), /* szOsFile */ 6012 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 6013 0, /* pNext */ 6014 "win32-longpath", /* zName */ 6015 &winAppData, /* pAppData */ 6016 winOpen, /* xOpen */ 6017 winDelete, /* xDelete */ 6018 winAccess, /* xAccess */ 6019 winFullPathname, /* xFullPathname */ 6020 winDlOpen, /* xDlOpen */ 6021 winDlError, /* xDlError */ 6022 winDlSym, /* xDlSym */ 6023 winDlClose, /* xDlClose */ 6024 winRandomness, /* xRandomness */ 6025 winSleep, /* xSleep */ 6026 winCurrentTime, /* xCurrentTime */ 6027 winGetLastError, /* xGetLastError */ 6028 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6029 winSetSystemCall, /* xSetSystemCall */ 6030 winGetSystemCall, /* xGetSystemCall */ 6031 winNextSystemCall, /* xNextSystemCall */ 6032 }; 6033 #endif 6034 static sqlite3_vfs winNolockVfs = { 6035 3, /* iVersion */ 6036 sizeof(winFile), /* szOsFile */ 6037 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 6038 0, /* pNext */ 6039 "win32-none", /* zName */ 6040 &winNolockAppData, /* pAppData */ 6041 winOpen, /* xOpen */ 6042 winDelete, /* xDelete */ 6043 winAccess, /* xAccess */ 6044 winFullPathname, /* xFullPathname */ 6045 winDlOpen, /* xDlOpen */ 6046 winDlError, /* xDlError */ 6047 winDlSym, /* xDlSym */ 6048 winDlClose, /* xDlClose */ 6049 winRandomness, /* xRandomness */ 6050 winSleep, /* xSleep */ 6051 winCurrentTime, /* xCurrentTime */ 6052 winGetLastError, /* xGetLastError */ 6053 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6054 winSetSystemCall, /* xSetSystemCall */ 6055 winGetSystemCall, /* xGetSystemCall */ 6056 winNextSystemCall, /* xNextSystemCall */ 6057 }; 6058 #if defined(SQLITE_WIN32_HAS_WIDE) 6059 static sqlite3_vfs winLongPathNolockVfs = { 6060 3, /* iVersion */ 6061 sizeof(winFile), /* szOsFile */ 6062 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 6063 0, /* pNext */ 6064 "win32-longpath-none", /* zName */ 6065 &winNolockAppData, /* pAppData */ 6066 winOpen, /* xOpen */ 6067 winDelete, /* xDelete */ 6068 winAccess, /* xAccess */ 6069 winFullPathname, /* xFullPathname */ 6070 winDlOpen, /* xDlOpen */ 6071 winDlError, /* xDlError */ 6072 winDlSym, /* xDlSym */ 6073 winDlClose, /* xDlClose */ 6074 winRandomness, /* xRandomness */ 6075 winSleep, /* xSleep */ 6076 winCurrentTime, /* xCurrentTime */ 6077 winGetLastError, /* xGetLastError */ 6078 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6079 winSetSystemCall, /* xSetSystemCall */ 6080 winGetSystemCall, /* xGetSystemCall */ 6081 winNextSystemCall, /* xNextSystemCall */ 6082 }; 6083 #endif 6084 6085 /* Double-check that the aSyscall[] array has been constructed 6086 ** correctly. See ticket [bb3a86e890c8e96ab] */ 6087 assert( ArraySize(aSyscall)==80 ); 6088 6089 /* get memory map allocation granularity */ 6090 memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); 6091 #if SQLITE_OS_WINRT 6092 osGetNativeSystemInfo(&winSysInfo); 6093 #else 6094 osGetSystemInfo(&winSysInfo); 6095 #endif 6096 assert( winSysInfo.dwAllocationGranularity>0 ); 6097 assert( winSysInfo.dwPageSize>0 ); 6098 6099 sqlite3_vfs_register(&winVfs, 1); 6100 6101 #if defined(SQLITE_WIN32_HAS_WIDE) 6102 sqlite3_vfs_register(&winLongPathVfs, 0); 6103 #endif 6104 6105 sqlite3_vfs_register(&winNolockVfs, 0); 6106 6107 #if defined(SQLITE_WIN32_HAS_WIDE) 6108 sqlite3_vfs_register(&winLongPathNolockVfs, 0); 6109 #endif 6110 6111 #ifndef SQLITE_OMIT_WAL 6112 winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); 6113 #endif 6114 6115 return SQLITE_OK; 6116 } 6117 6118 int sqlite3_os_end(void){ 6119 #if SQLITE_OS_WINRT 6120 if( sleepObj!=NULL ){ 6121 osCloseHandle(sleepObj); 6122 sleepObj = NULL; 6123 } 6124 #endif 6125 6126 #ifndef SQLITE_OMIT_WAL 6127 winBigLock = 0; 6128 #endif 6129 6130 return SQLITE_OK; 6131 } 6132 6133 #endif /* SQLITE_OS_WIN */ 6134