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