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 int rc; 1922 #ifndef SQLITE_OMIT_AUTOINIT 1923 rc = sqlite3_initialize(); 1924 if( rc ) return rc; 1925 #endif 1926 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 1927 if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ 1928 ppDirectory = &sqlite3_data_directory; 1929 }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ 1930 ppDirectory = &sqlite3_temp_directory; 1931 } 1932 assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE 1933 || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE 1934 ); 1935 assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); 1936 if( ppDirectory ){ 1937 char *zCopy = 0; 1938 if( zValue && zValue[0] ){ 1939 zCopy = sqlite3_mprintf("%s", zValue); 1940 if ( zCopy==0 ){ 1941 rc = SQLITE_NOMEM_BKPT; 1942 goto set_directory8_done; 1943 } 1944 } 1945 sqlite3_free(*ppDirectory); 1946 *ppDirectory = zCopy; 1947 rc = SQLITE_OK; 1948 }else{ 1949 rc = SQLITE_ERROR; 1950 } 1951 set_directory8_done: 1952 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 1953 return rc; 1954 } 1955 1956 /* 1957 ** This function is the same as sqlite3_win32_set_directory (below); however, 1958 ** it accepts a UTF-16 string. 1959 */ 1960 int sqlite3_win32_set_directory16( 1961 unsigned long type, /* Identifier for directory being set or reset */ 1962 const void *zValue /* New value for directory being set or reset */ 1963 ){ 1964 int rc; 1965 char *zUtf8 = 0; 1966 if( zValue ){ 1967 zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); 1968 if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; 1969 } 1970 rc = sqlite3_win32_set_directory8(type, zUtf8); 1971 if( zUtf8 ) sqlite3_free(zUtf8); 1972 return rc; 1973 } 1974 1975 /* 1976 ** This function sets the data directory or the temporary directory based on 1977 ** the provided arguments. The type argument must be 1 in order to set the 1978 ** data directory or 2 in order to set the temporary directory. The zValue 1979 ** argument is the name of the directory to use. The return value will be 1980 ** SQLITE_OK if successful. 1981 */ 1982 int sqlite3_win32_set_directory( 1983 unsigned long type, /* Identifier for directory being set or reset */ 1984 void *zValue /* New value for directory being set or reset */ 1985 ){ 1986 return sqlite3_win32_set_directory16(type, zValue); 1987 } 1988 1989 /* 1990 ** The return value of winGetLastErrorMsg 1991 ** is zero if the error message fits in the buffer, or non-zero 1992 ** otherwise (if the message was truncated). 1993 */ 1994 static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ 1995 /* FormatMessage returns 0 on failure. Otherwise it 1996 ** returns the number of TCHARs written to the output 1997 ** buffer, excluding the terminating null char. 1998 */ 1999 DWORD dwLen = 0; 2000 char *zOut = 0; 2001 2002 if( osIsNT() ){ 2003 #if SQLITE_OS_WINRT 2004 WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; 2005 dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | 2006 FORMAT_MESSAGE_IGNORE_INSERTS, 2007 NULL, 2008 lastErrno, 2009 0, 2010 zTempWide, 2011 SQLITE_WIN32_MAX_ERRMSG_CHARS, 2012 0); 2013 #else 2014 LPWSTR zTempWide = NULL; 2015 dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 2016 FORMAT_MESSAGE_FROM_SYSTEM | 2017 FORMAT_MESSAGE_IGNORE_INSERTS, 2018 NULL, 2019 lastErrno, 2020 0, 2021 (LPWSTR) &zTempWide, 2022 0, 2023 0); 2024 #endif 2025 if( dwLen > 0 ){ 2026 /* allocate a buffer and convert to UTF8 */ 2027 sqlite3BeginBenignMalloc(); 2028 zOut = winUnicodeToUtf8(zTempWide); 2029 sqlite3EndBenignMalloc(); 2030 #if !SQLITE_OS_WINRT 2031 /* free the system buffer allocated by FormatMessage */ 2032 osLocalFree(zTempWide); 2033 #endif 2034 } 2035 } 2036 #ifdef SQLITE_WIN32_HAS_ANSI 2037 else{ 2038 char *zTemp = NULL; 2039 dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | 2040 FORMAT_MESSAGE_FROM_SYSTEM | 2041 FORMAT_MESSAGE_IGNORE_INSERTS, 2042 NULL, 2043 lastErrno, 2044 0, 2045 (LPSTR) &zTemp, 2046 0, 2047 0); 2048 if( dwLen > 0 ){ 2049 /* allocate a buffer and convert to UTF8 */ 2050 sqlite3BeginBenignMalloc(); 2051 zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); 2052 sqlite3EndBenignMalloc(); 2053 /* free the system buffer allocated by FormatMessage */ 2054 osLocalFree(zTemp); 2055 } 2056 } 2057 #endif 2058 if( 0 == dwLen ){ 2059 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); 2060 }else{ 2061 /* copy a maximum of nBuf chars to output buffer */ 2062 sqlite3_snprintf(nBuf, zBuf, "%s", zOut); 2063 /* free the UTF8 buffer */ 2064 sqlite3_free(zOut); 2065 } 2066 return 0; 2067 } 2068 2069 /* 2070 ** 2071 ** This function - winLogErrorAtLine() - is only ever called via the macro 2072 ** winLogError(). 2073 ** 2074 ** This routine is invoked after an error occurs in an OS function. 2075 ** It logs a message using sqlite3_log() containing the current value of 2076 ** error code and, if possible, the human-readable equivalent from 2077 ** FormatMessage. 2078 ** 2079 ** The first argument passed to the macro should be the error code that 2080 ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 2081 ** The two subsequent arguments should be the name of the OS function that 2082 ** failed and the associated file-system path, if any. 2083 */ 2084 #define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) 2085 static int winLogErrorAtLine( 2086 int errcode, /* SQLite error code */ 2087 DWORD lastErrno, /* Win32 last error */ 2088 const char *zFunc, /* Name of OS function that failed */ 2089 const char *zPath, /* File path associated with error */ 2090 int iLine /* Source line number where error occurred */ 2091 ){ 2092 char zMsg[500]; /* Human readable error text */ 2093 int i; /* Loop counter */ 2094 2095 zMsg[0] = 0; 2096 winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); 2097 assert( errcode!=SQLITE_OK ); 2098 if( zPath==0 ) zPath = ""; 2099 for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} 2100 zMsg[i] = 0; 2101 sqlite3_log(errcode, 2102 "os_win.c:%d: (%lu) %s(%s) - %s", 2103 iLine, lastErrno, zFunc, zPath, zMsg 2104 ); 2105 2106 return errcode; 2107 } 2108 2109 /* 2110 ** The number of times that a ReadFile(), WriteFile(), and DeleteFile() 2111 ** will be retried following a locking error - probably caused by 2112 ** antivirus software. Also the initial delay before the first retry. 2113 ** The delay increases linearly with each retry. 2114 */ 2115 #ifndef SQLITE_WIN32_IOERR_RETRY 2116 # define SQLITE_WIN32_IOERR_RETRY 10 2117 #endif 2118 #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY 2119 # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 2120 #endif 2121 static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; 2122 static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; 2123 2124 /* 2125 ** The "winIoerrCanRetry1" macro is used to determine if a particular I/O 2126 ** error code obtained via GetLastError() is eligible to be retried. It 2127 ** must accept the error code DWORD as its only argument and should return 2128 ** non-zero if the error code is transient in nature and the operation 2129 ** responsible for generating the original error might succeed upon being 2130 ** retried. The argument to this macro should be a variable. 2131 ** 2132 ** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it 2133 ** is defined, it will be consulted only when the macro "winIoerrCanRetry1" 2134 ** returns zero. The "winIoerrCanRetry2" macro is completely optional and 2135 ** may be used to include additional error codes in the set that should 2136 ** result in the failing I/O operation being retried by the caller. If 2137 ** defined, the "winIoerrCanRetry2" macro must exhibit external semantics 2138 ** identical to those of the "winIoerrCanRetry1" macro. 2139 */ 2140 #if !defined(winIoerrCanRetry1) 2141 #define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ 2142 ((a)==ERROR_SHARING_VIOLATION) || \ 2143 ((a)==ERROR_LOCK_VIOLATION) || \ 2144 ((a)==ERROR_DEV_NOT_EXIST) || \ 2145 ((a)==ERROR_NETNAME_DELETED) || \ 2146 ((a)==ERROR_SEM_TIMEOUT) || \ 2147 ((a)==ERROR_NETWORK_UNREACHABLE)) 2148 #endif 2149 2150 /* 2151 ** If a ReadFile() or WriteFile() error occurs, invoke this routine 2152 ** to see if it should be retried. Return TRUE to retry. Return FALSE 2153 ** to give up with an error. 2154 */ 2155 static int winRetryIoerr(int *pnRetry, DWORD *pError){ 2156 DWORD e = osGetLastError(); 2157 if( *pnRetry>=winIoerrRetry ){ 2158 if( pError ){ 2159 *pError = e; 2160 } 2161 return 0; 2162 } 2163 if( winIoerrCanRetry1(e) ){ 2164 sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); 2165 ++*pnRetry; 2166 return 1; 2167 } 2168 #if defined(winIoerrCanRetry2) 2169 else if( winIoerrCanRetry2(e) ){ 2170 sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); 2171 ++*pnRetry; 2172 return 1; 2173 } 2174 #endif 2175 if( pError ){ 2176 *pError = e; 2177 } 2178 return 0; 2179 } 2180 2181 /* 2182 ** Log a I/O error retry episode. 2183 */ 2184 static void winLogIoerr(int nRetry, int lineno){ 2185 if( nRetry ){ 2186 sqlite3_log(SQLITE_NOTICE, 2187 "delayed %dms for lock/sharing conflict at line %d", 2188 winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno 2189 ); 2190 } 2191 } 2192 2193 /* 2194 ** This #if does not rely on the SQLITE_OS_WINCE define because the 2195 ** corresponding section in "date.c" cannot use it. 2196 */ 2197 #if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ 2198 (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) 2199 /* 2200 ** The MSVC CRT on Windows CE may not have a localtime() function. 2201 ** So define a substitute. 2202 */ 2203 # include <time.h> 2204 struct tm *__cdecl localtime(const time_t *t) 2205 { 2206 static struct tm y; 2207 FILETIME uTm, lTm; 2208 SYSTEMTIME pTm; 2209 sqlite3_int64 t64; 2210 t64 = *t; 2211 t64 = (t64 + 11644473600)*10000000; 2212 uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); 2213 uTm.dwHighDateTime= (DWORD)(t64 >> 32); 2214 osFileTimeToLocalFileTime(&uTm,&lTm); 2215 osFileTimeToSystemTime(&lTm,&pTm); 2216 y.tm_year = pTm.wYear - 1900; 2217 y.tm_mon = pTm.wMonth - 1; 2218 y.tm_wday = pTm.wDayOfWeek; 2219 y.tm_mday = pTm.wDay; 2220 y.tm_hour = pTm.wHour; 2221 y.tm_min = pTm.wMinute; 2222 y.tm_sec = pTm.wSecond; 2223 return &y; 2224 } 2225 #endif 2226 2227 #if SQLITE_OS_WINCE 2228 /************************************************************************* 2229 ** This section contains code for WinCE only. 2230 */ 2231 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] 2232 2233 /* 2234 ** Acquire a lock on the handle h 2235 */ 2236 static void winceMutexAcquire(HANDLE h){ 2237 DWORD dwErr; 2238 do { 2239 dwErr = osWaitForSingleObject(h, INFINITE); 2240 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); 2241 } 2242 /* 2243 ** Release a lock acquired by winceMutexAcquire() 2244 */ 2245 #define winceMutexRelease(h) ReleaseMutex(h) 2246 2247 /* 2248 ** Create the mutex and shared memory used for locking in the file 2249 ** descriptor pFile 2250 */ 2251 static int winceCreateLock(const char *zFilename, winFile *pFile){ 2252 LPWSTR zTok; 2253 LPWSTR zName; 2254 DWORD lastErrno; 2255 BOOL bLogged = FALSE; 2256 BOOL bInit = TRUE; 2257 2258 zName = winUtf8ToUnicode(zFilename); 2259 if( zName==0 ){ 2260 /* out of memory */ 2261 return SQLITE_IOERR_NOMEM_BKPT; 2262 } 2263 2264 /* Initialize the local lockdata */ 2265 memset(&pFile->local, 0, sizeof(pFile->local)); 2266 2267 /* Replace the backslashes from the filename and lowercase it 2268 ** to derive a mutex name. */ 2269 zTok = osCharLowerW(zName); 2270 for (;*zTok;zTok++){ 2271 if (*zTok == '\\') *zTok = '_'; 2272 } 2273 2274 /* Create/open the named mutex */ 2275 pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); 2276 if (!pFile->hMutex){ 2277 pFile->lastErrno = osGetLastError(); 2278 sqlite3_free(zName); 2279 return winLogError(SQLITE_IOERR, pFile->lastErrno, 2280 "winceCreateLock1", zFilename); 2281 } 2282 2283 /* Acquire the mutex before continuing */ 2284 winceMutexAcquire(pFile->hMutex); 2285 2286 /* Since the names of named mutexes, semaphores, file mappings etc are 2287 ** case-sensitive, take advantage of that by uppercasing the mutex name 2288 ** and using that as the shared filemapping name. 2289 */ 2290 osCharUpperW(zName); 2291 pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, 2292 PAGE_READWRITE, 0, sizeof(winceLock), 2293 zName); 2294 2295 /* Set a flag that indicates we're the first to create the memory so it 2296 ** must be zero-initialized */ 2297 lastErrno = osGetLastError(); 2298 if (lastErrno == ERROR_ALREADY_EXISTS){ 2299 bInit = FALSE; 2300 } 2301 2302 sqlite3_free(zName); 2303 2304 /* If we succeeded in making the shared memory handle, map it. */ 2305 if( pFile->hShared ){ 2306 pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, 2307 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); 2308 /* If mapping failed, close the shared memory handle and erase it */ 2309 if( !pFile->shared ){ 2310 pFile->lastErrno = osGetLastError(); 2311 winLogError(SQLITE_IOERR, pFile->lastErrno, 2312 "winceCreateLock2", zFilename); 2313 bLogged = TRUE; 2314 osCloseHandle(pFile->hShared); 2315 pFile->hShared = NULL; 2316 } 2317 } 2318 2319 /* If shared memory could not be created, then close the mutex and fail */ 2320 if( pFile->hShared==NULL ){ 2321 if( !bLogged ){ 2322 pFile->lastErrno = lastErrno; 2323 winLogError(SQLITE_IOERR, pFile->lastErrno, 2324 "winceCreateLock3", zFilename); 2325 bLogged = TRUE; 2326 } 2327 winceMutexRelease(pFile->hMutex); 2328 osCloseHandle(pFile->hMutex); 2329 pFile->hMutex = NULL; 2330 return SQLITE_IOERR; 2331 } 2332 2333 /* Initialize the shared memory if we're supposed to */ 2334 if( bInit ){ 2335 memset(pFile->shared, 0, sizeof(winceLock)); 2336 } 2337 2338 winceMutexRelease(pFile->hMutex); 2339 return SQLITE_OK; 2340 } 2341 2342 /* 2343 ** Destroy the part of winFile that deals with wince locks 2344 */ 2345 static void winceDestroyLock(winFile *pFile){ 2346 if (pFile->hMutex){ 2347 /* Acquire the mutex */ 2348 winceMutexAcquire(pFile->hMutex); 2349 2350 /* The following blocks should probably assert in debug mode, but they 2351 are to cleanup in case any locks remained open */ 2352 if (pFile->local.nReaders){ 2353 pFile->shared->nReaders --; 2354 } 2355 if (pFile->local.bReserved){ 2356 pFile->shared->bReserved = FALSE; 2357 } 2358 if (pFile->local.bPending){ 2359 pFile->shared->bPending = FALSE; 2360 } 2361 if (pFile->local.bExclusive){ 2362 pFile->shared->bExclusive = FALSE; 2363 } 2364 2365 /* De-reference and close our copy of the shared memory handle */ 2366 osUnmapViewOfFile(pFile->shared); 2367 osCloseHandle(pFile->hShared); 2368 2369 /* Done with the mutex */ 2370 winceMutexRelease(pFile->hMutex); 2371 osCloseHandle(pFile->hMutex); 2372 pFile->hMutex = NULL; 2373 } 2374 } 2375 2376 /* 2377 ** An implementation of the LockFile() API of Windows for CE 2378 */ 2379 static BOOL winceLockFile( 2380 LPHANDLE phFile, 2381 DWORD dwFileOffsetLow, 2382 DWORD dwFileOffsetHigh, 2383 DWORD nNumberOfBytesToLockLow, 2384 DWORD nNumberOfBytesToLockHigh 2385 ){ 2386 winFile *pFile = HANDLE_TO_WINFILE(phFile); 2387 BOOL bReturn = FALSE; 2388 2389 UNUSED_PARAMETER(dwFileOffsetHigh); 2390 UNUSED_PARAMETER(nNumberOfBytesToLockHigh); 2391 2392 if (!pFile->hMutex) return TRUE; 2393 winceMutexAcquire(pFile->hMutex); 2394 2395 /* Wanting an exclusive lock? */ 2396 if (dwFileOffsetLow == (DWORD)SHARED_FIRST 2397 && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ 2398 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ 2399 pFile->shared->bExclusive = TRUE; 2400 pFile->local.bExclusive = TRUE; 2401 bReturn = TRUE; 2402 } 2403 } 2404 2405 /* Want a read-only lock? */ 2406 else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && 2407 nNumberOfBytesToLockLow == 1){ 2408 if (pFile->shared->bExclusive == 0){ 2409 pFile->local.nReaders ++; 2410 if (pFile->local.nReaders == 1){ 2411 pFile->shared->nReaders ++; 2412 } 2413 bReturn = TRUE; 2414 } 2415 } 2416 2417 /* Want a pending lock? */ 2418 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE 2419 && nNumberOfBytesToLockLow == 1){ 2420 /* If no pending lock has been acquired, then acquire it */ 2421 if (pFile->shared->bPending == 0) { 2422 pFile->shared->bPending = TRUE; 2423 pFile->local.bPending = TRUE; 2424 bReturn = TRUE; 2425 } 2426 } 2427 2428 /* Want a reserved lock? */ 2429 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE 2430 && nNumberOfBytesToLockLow == 1){ 2431 if (pFile->shared->bReserved == 0) { 2432 pFile->shared->bReserved = TRUE; 2433 pFile->local.bReserved = TRUE; 2434 bReturn = TRUE; 2435 } 2436 } 2437 2438 winceMutexRelease(pFile->hMutex); 2439 return bReturn; 2440 } 2441 2442 /* 2443 ** An implementation of the UnlockFile API of Windows for CE 2444 */ 2445 static BOOL winceUnlockFile( 2446 LPHANDLE phFile, 2447 DWORD dwFileOffsetLow, 2448 DWORD dwFileOffsetHigh, 2449 DWORD nNumberOfBytesToUnlockLow, 2450 DWORD nNumberOfBytesToUnlockHigh 2451 ){ 2452 winFile *pFile = HANDLE_TO_WINFILE(phFile); 2453 BOOL bReturn = FALSE; 2454 2455 UNUSED_PARAMETER(dwFileOffsetHigh); 2456 UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); 2457 2458 if (!pFile->hMutex) return TRUE; 2459 winceMutexAcquire(pFile->hMutex); 2460 2461 /* Releasing a reader lock or an exclusive lock */ 2462 if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ 2463 /* Did we have an exclusive lock? */ 2464 if (pFile->local.bExclusive){ 2465 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); 2466 pFile->local.bExclusive = FALSE; 2467 pFile->shared->bExclusive = FALSE; 2468 bReturn = TRUE; 2469 } 2470 2471 /* Did we just have a reader lock? */ 2472 else if (pFile->local.nReaders){ 2473 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE 2474 || nNumberOfBytesToUnlockLow == 1); 2475 pFile->local.nReaders --; 2476 if (pFile->local.nReaders == 0) 2477 { 2478 pFile->shared->nReaders --; 2479 } 2480 bReturn = TRUE; 2481 } 2482 } 2483 2484 /* Releasing a pending lock */ 2485 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE 2486 && nNumberOfBytesToUnlockLow == 1){ 2487 if (pFile->local.bPending){ 2488 pFile->local.bPending = FALSE; 2489 pFile->shared->bPending = FALSE; 2490 bReturn = TRUE; 2491 } 2492 } 2493 /* Releasing a reserved lock */ 2494 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE 2495 && nNumberOfBytesToUnlockLow == 1){ 2496 if (pFile->local.bReserved) { 2497 pFile->local.bReserved = FALSE; 2498 pFile->shared->bReserved = FALSE; 2499 bReturn = TRUE; 2500 } 2501 } 2502 2503 winceMutexRelease(pFile->hMutex); 2504 return bReturn; 2505 } 2506 /* 2507 ** End of the special code for wince 2508 *****************************************************************************/ 2509 #endif /* SQLITE_OS_WINCE */ 2510 2511 /* 2512 ** Lock a file region. 2513 */ 2514 static BOOL winLockFile( 2515 LPHANDLE phFile, 2516 DWORD flags, 2517 DWORD offsetLow, 2518 DWORD offsetHigh, 2519 DWORD numBytesLow, 2520 DWORD numBytesHigh 2521 ){ 2522 #if SQLITE_OS_WINCE 2523 /* 2524 ** NOTE: Windows CE is handled differently here due its lack of the Win32 2525 ** API LockFile. 2526 */ 2527 return winceLockFile(phFile, offsetLow, offsetHigh, 2528 numBytesLow, numBytesHigh); 2529 #else 2530 if( osIsNT() ){ 2531 OVERLAPPED ovlp; 2532 memset(&ovlp, 0, sizeof(OVERLAPPED)); 2533 ovlp.Offset = offsetLow; 2534 ovlp.OffsetHigh = offsetHigh; 2535 return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); 2536 }else{ 2537 return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, 2538 numBytesHigh); 2539 } 2540 #endif 2541 } 2542 2543 /* 2544 ** Unlock a file region. 2545 */ 2546 static BOOL winUnlockFile( 2547 LPHANDLE phFile, 2548 DWORD offsetLow, 2549 DWORD offsetHigh, 2550 DWORD numBytesLow, 2551 DWORD numBytesHigh 2552 ){ 2553 #if SQLITE_OS_WINCE 2554 /* 2555 ** NOTE: Windows CE is handled differently here due its lack of the Win32 2556 ** API UnlockFile. 2557 */ 2558 return winceUnlockFile(phFile, offsetLow, offsetHigh, 2559 numBytesLow, numBytesHigh); 2560 #else 2561 if( osIsNT() ){ 2562 OVERLAPPED ovlp; 2563 memset(&ovlp, 0, sizeof(OVERLAPPED)); 2564 ovlp.Offset = offsetLow; 2565 ovlp.OffsetHigh = offsetHigh; 2566 return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); 2567 }else{ 2568 return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, 2569 numBytesHigh); 2570 } 2571 #endif 2572 } 2573 2574 /***************************************************************************** 2575 ** The next group of routines implement the I/O methods specified 2576 ** by the sqlite3_io_methods object. 2577 ******************************************************************************/ 2578 2579 /* 2580 ** Some Microsoft compilers lack this definition. 2581 */ 2582 #ifndef INVALID_SET_FILE_POINTER 2583 # define INVALID_SET_FILE_POINTER ((DWORD)-1) 2584 #endif 2585 2586 /* 2587 ** Move the current position of the file handle passed as the first 2588 ** argument to offset iOffset within the file. If successful, return 0. 2589 ** Otherwise, set pFile->lastErrno and return non-zero. 2590 */ 2591 static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ 2592 #if !SQLITE_OS_WINRT 2593 LONG upperBits; /* Most sig. 32 bits of new offset */ 2594 LONG lowerBits; /* Least sig. 32 bits of new offset */ 2595 DWORD dwRet; /* Value returned by SetFilePointer() */ 2596 DWORD lastErrno; /* Value returned by GetLastError() */ 2597 2598 OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); 2599 2600 upperBits = (LONG)((iOffset>>32) & 0x7fffffff); 2601 lowerBits = (LONG)(iOffset & 0xffffffff); 2602 2603 /* API oddity: If successful, SetFilePointer() returns a dword 2604 ** containing the lower 32-bits of the new file-offset. Or, if it fails, 2605 ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, 2606 ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 2607 ** whether an error has actually occurred, it is also necessary to call 2608 ** GetLastError(). 2609 */ 2610 dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 2611 2612 if( (dwRet==INVALID_SET_FILE_POINTER 2613 && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ 2614 pFile->lastErrno = lastErrno; 2615 winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, 2616 "winSeekFile", pFile->zPath); 2617 OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); 2618 return 1; 2619 } 2620 2621 OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); 2622 return 0; 2623 #else 2624 /* 2625 ** Same as above, except that this implementation works for WinRT. 2626 */ 2627 2628 LARGE_INTEGER x; /* The new offset */ 2629 BOOL bRet; /* Value returned by SetFilePointerEx() */ 2630 2631 x.QuadPart = iOffset; 2632 bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); 2633 2634 if(!bRet){ 2635 pFile->lastErrno = osGetLastError(); 2636 winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, 2637 "winSeekFile", pFile->zPath); 2638 OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); 2639 return 1; 2640 } 2641 2642 OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); 2643 return 0; 2644 #endif 2645 } 2646 2647 #if SQLITE_MAX_MMAP_SIZE>0 2648 /* Forward references to VFS helper methods used for memory mapped files */ 2649 static int winMapfile(winFile*, sqlite3_int64); 2650 static int winUnmapfile(winFile*); 2651 #endif 2652 2653 /* 2654 ** Close a file. 2655 ** 2656 ** It is reported that an attempt to close a handle might sometimes 2657 ** fail. This is a very unreasonable result, but Windows is notorious 2658 ** for being unreasonable so I do not doubt that it might happen. If 2659 ** the close fails, we pause for 100 milliseconds and try again. As 2660 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before 2661 ** giving up and returning an error. 2662 */ 2663 #define MX_CLOSE_ATTEMPT 3 2664 static int winClose(sqlite3_file *id){ 2665 int rc, cnt = 0; 2666 winFile *pFile = (winFile*)id; 2667 2668 assert( id!=0 ); 2669 #ifndef SQLITE_OMIT_WAL 2670 assert( pFile->pShm==0 ); 2671 #endif 2672 assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); 2673 OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", 2674 osGetCurrentProcessId(), pFile, pFile->h)); 2675 2676 #if SQLITE_MAX_MMAP_SIZE>0 2677 winUnmapfile(pFile); 2678 #endif 2679 2680 do{ 2681 rc = osCloseHandle(pFile->h); 2682 /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ 2683 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); 2684 #if SQLITE_OS_WINCE 2685 #define WINCE_DELETION_ATTEMPTS 3 2686 { 2687 winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; 2688 if( pAppData==NULL || !pAppData->bNoLock ){ 2689 winceDestroyLock(pFile); 2690 } 2691 } 2692 if( pFile->zDeleteOnClose ){ 2693 int cnt = 0; 2694 while( 2695 osDeleteFileW(pFile->zDeleteOnClose)==0 2696 && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 2697 && cnt++ < WINCE_DELETION_ATTEMPTS 2698 ){ 2699 sqlite3_win32_sleep(100); /* Wait a little before trying again */ 2700 } 2701 sqlite3_free(pFile->zDeleteOnClose); 2702 } 2703 #endif 2704 if( rc ){ 2705 pFile->h = NULL; 2706 } 2707 OpenCounter(-1); 2708 OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", 2709 osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); 2710 return rc ? SQLITE_OK 2711 : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), 2712 "winClose", pFile->zPath); 2713 } 2714 2715 /* 2716 ** Read data from a file into a buffer. Return SQLITE_OK if all 2717 ** bytes were read successfully and SQLITE_IOERR if anything goes 2718 ** wrong. 2719 */ 2720 static int winRead( 2721 sqlite3_file *id, /* File to read from */ 2722 void *pBuf, /* Write content into this buffer */ 2723 int amt, /* Number of bytes to read */ 2724 sqlite3_int64 offset /* Begin reading at this offset */ 2725 ){ 2726 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) 2727 OVERLAPPED overlapped; /* The offset for ReadFile. */ 2728 #endif 2729 winFile *pFile = (winFile*)id; /* file handle */ 2730 DWORD nRead; /* Number of bytes actually read from file */ 2731 int nRetry = 0; /* Number of retrys */ 2732 2733 assert( id!=0 ); 2734 assert( amt>0 ); 2735 assert( offset>=0 ); 2736 SimulateIOError(return SQLITE_IOERR_READ); 2737 OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " 2738 "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, 2739 pFile->h, pBuf, amt, offset, pFile->locktype)); 2740 2741 #if SQLITE_MAX_MMAP_SIZE>0 2742 /* Deal with as much of this read request as possible by transfering 2743 ** data from the memory mapping using memcpy(). */ 2744 if( offset<pFile->mmapSize ){ 2745 if( offset+amt <= pFile->mmapSize ){ 2746 memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); 2747 OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 2748 osGetCurrentProcessId(), pFile, pFile->h)); 2749 return SQLITE_OK; 2750 }else{ 2751 int nCopy = (int)(pFile->mmapSize - offset); 2752 memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); 2753 pBuf = &((u8 *)pBuf)[nCopy]; 2754 amt -= nCopy; 2755 offset += nCopy; 2756 } 2757 } 2758 #endif 2759 2760 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) 2761 if( winSeekFile(pFile, offset) ){ 2762 OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", 2763 osGetCurrentProcessId(), pFile, pFile->h)); 2764 return SQLITE_FULL; 2765 } 2766 while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ 2767 #else 2768 memset(&overlapped, 0, sizeof(OVERLAPPED)); 2769 overlapped.Offset = (LONG)(offset & 0xffffffff); 2770 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); 2771 while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && 2772 osGetLastError()!=ERROR_HANDLE_EOF ){ 2773 #endif 2774 DWORD lastErrno; 2775 if( winRetryIoerr(&nRetry, &lastErrno) ) continue; 2776 pFile->lastErrno = lastErrno; 2777 OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", 2778 osGetCurrentProcessId(), pFile, pFile->h)); 2779 return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, 2780 "winRead", pFile->zPath); 2781 } 2782 winLogIoerr(nRetry, __LINE__); 2783 if( nRead<(DWORD)amt ){ 2784 /* Unread parts of the buffer must be zero-filled */ 2785 memset(&((char*)pBuf)[nRead], 0, amt-nRead); 2786 OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", 2787 osGetCurrentProcessId(), pFile, pFile->h)); 2788 return SQLITE_IOERR_SHORT_READ; 2789 } 2790 2791 OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 2792 osGetCurrentProcessId(), pFile, pFile->h)); 2793 return SQLITE_OK; 2794 } 2795 2796 /* 2797 ** Write data from a buffer into a file. Return SQLITE_OK on success 2798 ** or some other error code on failure. 2799 */ 2800 static int winWrite( 2801 sqlite3_file *id, /* File to write into */ 2802 const void *pBuf, /* The bytes to be written */ 2803 int amt, /* Number of bytes to write */ 2804 sqlite3_int64 offset /* Offset into the file to begin writing at */ 2805 ){ 2806 int rc = 0; /* True if error has occurred, else false */ 2807 winFile *pFile = (winFile*)id; /* File handle */ 2808 int nRetry = 0; /* Number of retries */ 2809 2810 assert( amt>0 ); 2811 assert( pFile ); 2812 SimulateIOError(return SQLITE_IOERR_WRITE); 2813 SimulateDiskfullError(return SQLITE_FULL); 2814 2815 OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " 2816 "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, 2817 pFile->h, pBuf, amt, offset, pFile->locktype)); 2818 2819 #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 2820 /* Deal with as much of this write request as possible by transfering 2821 ** data from the memory mapping using memcpy(). */ 2822 if( offset<pFile->mmapSize ){ 2823 if( offset+amt <= pFile->mmapSize ){ 2824 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); 2825 OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 2826 osGetCurrentProcessId(), pFile, pFile->h)); 2827 return SQLITE_OK; 2828 }else{ 2829 int nCopy = (int)(pFile->mmapSize - offset); 2830 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); 2831 pBuf = &((u8 *)pBuf)[nCopy]; 2832 amt -= nCopy; 2833 offset += nCopy; 2834 } 2835 } 2836 #endif 2837 2838 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) 2839 rc = winSeekFile(pFile, offset); 2840 if( rc==0 ){ 2841 #else 2842 { 2843 #endif 2844 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) 2845 OVERLAPPED overlapped; /* The offset for WriteFile. */ 2846 #endif 2847 u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ 2848 int nRem = amt; /* Number of bytes yet to be written */ 2849 DWORD nWrite; /* Bytes written by each WriteFile() call */ 2850 DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ 2851 2852 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) 2853 memset(&overlapped, 0, sizeof(OVERLAPPED)); 2854 overlapped.Offset = (LONG)(offset & 0xffffffff); 2855 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); 2856 #endif 2857 2858 while( nRem>0 ){ 2859 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) 2860 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ 2861 #else 2862 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ 2863 #endif 2864 if( winRetryIoerr(&nRetry, &lastErrno) ) continue; 2865 break; 2866 } 2867 assert( nWrite==0 || nWrite<=(DWORD)nRem ); 2868 if( nWrite==0 || nWrite>(DWORD)nRem ){ 2869 lastErrno = osGetLastError(); 2870 break; 2871 } 2872 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) 2873 offset += nWrite; 2874 overlapped.Offset = (LONG)(offset & 0xffffffff); 2875 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); 2876 #endif 2877 aRem += nWrite; 2878 nRem -= nWrite; 2879 } 2880 if( nRem>0 ){ 2881 pFile->lastErrno = lastErrno; 2882 rc = 1; 2883 } 2884 } 2885 2886 if( rc ){ 2887 if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) 2888 || ( pFile->lastErrno==ERROR_DISK_FULL )){ 2889 OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", 2890 osGetCurrentProcessId(), pFile, pFile->h)); 2891 return winLogError(SQLITE_FULL, pFile->lastErrno, 2892 "winWrite1", pFile->zPath); 2893 } 2894 OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", 2895 osGetCurrentProcessId(), pFile, pFile->h)); 2896 return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, 2897 "winWrite2", pFile->zPath); 2898 }else{ 2899 winLogIoerr(nRetry, __LINE__); 2900 } 2901 OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 2902 osGetCurrentProcessId(), pFile, pFile->h)); 2903 return SQLITE_OK; 2904 } 2905 2906 /* 2907 ** Truncate an open file to a specified size 2908 */ 2909 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ 2910 winFile *pFile = (winFile*)id; /* File handle object */ 2911 int rc = SQLITE_OK; /* Return code for this function */ 2912 DWORD lastErrno; 2913 #if SQLITE_MAX_MMAP_SIZE>0 2914 sqlite3_int64 oldMmapSize; 2915 if( pFile->nFetchOut>0 ){ 2916 /* File truncation is a no-op if there are outstanding memory mapped 2917 ** pages. This is because truncating the file means temporarily unmapping 2918 ** the file, and that might delete memory out from under existing cursors. 2919 ** 2920 ** This can result in incremental vacuum not truncating the file, 2921 ** if there is an active read cursor when the incremental vacuum occurs. 2922 ** No real harm comes of this - the database file is not corrupted, 2923 ** though some folks might complain that the file is bigger than it 2924 ** needs to be. 2925 ** 2926 ** The only feasible work-around is to defer the truncation until after 2927 ** all references to memory-mapped content are closed. That is doable, 2928 ** but involves adding a few branches in the common write code path which 2929 ** could slow down normal operations slightly. Hence, we have decided for 2930 ** now to simply make trancations a no-op if there are pending reads. We 2931 ** can maybe revisit this decision in the future. 2932 */ 2933 return SQLITE_OK; 2934 } 2935 #endif 2936 2937 assert( pFile ); 2938 SimulateIOError(return SQLITE_IOERR_TRUNCATE); 2939 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", 2940 osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); 2941 2942 /* If the user has configured a chunk-size for this file, truncate the 2943 ** file so that it consists of an integer number of chunks (i.e. the 2944 ** actual file size after the operation may be larger than the requested 2945 ** size). 2946 */ 2947 if( pFile->szChunk>0 ){ 2948 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; 2949 } 2950 2951 #if SQLITE_MAX_MMAP_SIZE>0 2952 if( pFile->pMapRegion ){ 2953 oldMmapSize = pFile->mmapSize; 2954 }else{ 2955 oldMmapSize = 0; 2956 } 2957 winUnmapfile(pFile); 2958 #endif 2959 2960 /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ 2961 if( winSeekFile(pFile, nByte) ){ 2962 rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, 2963 "winTruncate1", pFile->zPath); 2964 }else if( 0==osSetEndOfFile(pFile->h) && 2965 ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ 2966 pFile->lastErrno = lastErrno; 2967 rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, 2968 "winTruncate2", pFile->zPath); 2969 } 2970 2971 #if SQLITE_MAX_MMAP_SIZE>0 2972 if( rc==SQLITE_OK && oldMmapSize>0 ){ 2973 if( oldMmapSize>nByte ){ 2974 winMapfile(pFile, -1); 2975 }else{ 2976 winMapfile(pFile, oldMmapSize); 2977 } 2978 } 2979 #endif 2980 2981 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", 2982 osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); 2983 return rc; 2984 } 2985 2986 #ifdef SQLITE_TEST 2987 /* 2988 ** Count the number of fullsyncs and normal syncs. This is used to test 2989 ** that syncs and fullsyncs are occuring at the right times. 2990 */ 2991 int sqlite3_sync_count = 0; 2992 int sqlite3_fullsync_count = 0; 2993 #endif 2994 2995 /* 2996 ** Make sure all writes to a particular file are committed to disk. 2997 */ 2998 static int winSync(sqlite3_file *id, int flags){ 2999 #ifndef SQLITE_NO_SYNC 3000 /* 3001 ** Used only when SQLITE_NO_SYNC is not defined. 3002 */ 3003 BOOL rc; 3004 #endif 3005 #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ 3006 defined(SQLITE_HAVE_OS_TRACE) 3007 /* 3008 ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or 3009 ** OSTRACE() macros. 3010 */ 3011 winFile *pFile = (winFile*)id; 3012 #else 3013 UNUSED_PARAMETER(id); 3014 #endif 3015 3016 assert( pFile ); 3017 /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ 3018 assert((flags&0x0F)==SQLITE_SYNC_NORMAL 3019 || (flags&0x0F)==SQLITE_SYNC_FULL 3020 ); 3021 3022 /* Unix cannot, but some systems may return SQLITE_FULL from here. This 3023 ** line is to test that doing so does not cause any problems. 3024 */ 3025 SimulateDiskfullError( return SQLITE_FULL ); 3026 3027 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", 3028 osGetCurrentProcessId(), pFile, pFile->h, flags, 3029 pFile->locktype)); 3030 3031 #ifndef SQLITE_TEST 3032 UNUSED_PARAMETER(flags); 3033 #else 3034 if( (flags&0x0F)==SQLITE_SYNC_FULL ){ 3035 sqlite3_fullsync_count++; 3036 } 3037 sqlite3_sync_count++; 3038 #endif 3039 3040 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a 3041 ** no-op 3042 */ 3043 #ifdef SQLITE_NO_SYNC 3044 OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 3045 osGetCurrentProcessId(), pFile, pFile->h)); 3046 return SQLITE_OK; 3047 #else 3048 #if SQLITE_MAX_MMAP_SIZE>0 3049 if( pFile->pMapRegion ){ 3050 if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ 3051 OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " 3052 "rc=SQLITE_OK\n", osGetCurrentProcessId(), 3053 pFile, pFile->pMapRegion)); 3054 }else{ 3055 pFile->lastErrno = osGetLastError(); 3056 OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " 3057 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), 3058 pFile, pFile->pMapRegion)); 3059 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 3060 "winSync1", pFile->zPath); 3061 } 3062 } 3063 #endif 3064 rc = osFlushFileBuffers(pFile->h); 3065 SimulateIOError( rc=FALSE ); 3066 if( rc ){ 3067 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", 3068 osGetCurrentProcessId(), pFile, pFile->h)); 3069 return SQLITE_OK; 3070 }else{ 3071 pFile->lastErrno = osGetLastError(); 3072 OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", 3073 osGetCurrentProcessId(), pFile, pFile->h)); 3074 return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, 3075 "winSync2", pFile->zPath); 3076 } 3077 #endif 3078 } 3079 3080 /* 3081 ** Determine the current size of a file in bytes 3082 */ 3083 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ 3084 winFile *pFile = (winFile*)id; 3085 int rc = SQLITE_OK; 3086 3087 assert( id!=0 ); 3088 assert( pSize!=0 ); 3089 SimulateIOError(return SQLITE_IOERR_FSTAT); 3090 OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); 3091 3092 #if SQLITE_OS_WINRT 3093 { 3094 FILE_STANDARD_INFO info; 3095 if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, 3096 &info, sizeof(info)) ){ 3097 *pSize = info.EndOfFile.QuadPart; 3098 }else{ 3099 pFile->lastErrno = osGetLastError(); 3100 rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, 3101 "winFileSize", pFile->zPath); 3102 } 3103 } 3104 #else 3105 { 3106 DWORD upperBits; 3107 DWORD lowerBits; 3108 DWORD lastErrno; 3109 3110 lowerBits = osGetFileSize(pFile->h, &upperBits); 3111 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; 3112 if( (lowerBits == INVALID_FILE_SIZE) 3113 && ((lastErrno = osGetLastError())!=NO_ERROR) ){ 3114 pFile->lastErrno = lastErrno; 3115 rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, 3116 "winFileSize", pFile->zPath); 3117 } 3118 } 3119 #endif 3120 OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", 3121 pFile->h, pSize, *pSize, sqlite3ErrName(rc))); 3122 return rc; 3123 } 3124 3125 /* 3126 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. 3127 */ 3128 #ifndef LOCKFILE_FAIL_IMMEDIATELY 3129 # define LOCKFILE_FAIL_IMMEDIATELY 1 3130 #endif 3131 3132 #ifndef LOCKFILE_EXCLUSIVE_LOCK 3133 # define LOCKFILE_EXCLUSIVE_LOCK 2 3134 #endif 3135 3136 /* 3137 ** Historically, SQLite has used both the LockFile and LockFileEx functions. 3138 ** When the LockFile function was used, it was always expected to fail 3139 ** immediately if the lock could not be obtained. Also, it always expected to 3140 ** obtain an exclusive lock. These flags are used with the LockFileEx function 3141 ** and reflect those expectations; therefore, they should not be changed. 3142 */ 3143 #ifndef SQLITE_LOCKFILE_FLAGS 3144 # define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ 3145 LOCKFILE_EXCLUSIVE_LOCK) 3146 #endif 3147 3148 /* 3149 ** Currently, SQLite never calls the LockFileEx function without wanting the 3150 ** call to fail immediately if the lock cannot be obtained. 3151 */ 3152 #ifndef SQLITE_LOCKFILEEX_FLAGS 3153 # define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) 3154 #endif 3155 3156 /* 3157 ** Acquire a reader lock. 3158 ** Different API routines are called depending on whether or not this 3159 ** is Win9x or WinNT. 3160 */ 3161 static int winGetReadLock(winFile *pFile){ 3162 int res; 3163 OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); 3164 if( osIsNT() ){ 3165 #if SQLITE_OS_WINCE 3166 /* 3167 ** NOTE: Windows CE is handled differently here due its lack of the Win32 3168 ** API LockFileEx. 3169 */ 3170 res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); 3171 #else 3172 res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, 3173 SHARED_SIZE, 0); 3174 #endif 3175 } 3176 #ifdef SQLITE_WIN32_HAS_ANSI 3177 else{ 3178 int lk; 3179 sqlite3_randomness(sizeof(lk), &lk); 3180 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); 3181 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, 3182 SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 3183 } 3184 #endif 3185 if( res == 0 ){ 3186 pFile->lastErrno = osGetLastError(); 3187 /* No need to log a failure to lock */ 3188 } 3189 OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); 3190 return res; 3191 } 3192 3193 /* 3194 ** Undo a readlock 3195 */ 3196 static int winUnlockReadLock(winFile *pFile){ 3197 int res; 3198 DWORD lastErrno; 3199 OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); 3200 if( osIsNT() ){ 3201 res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 3202 } 3203 #ifdef SQLITE_WIN32_HAS_ANSI 3204 else{ 3205 res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 3206 } 3207 #endif 3208 if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ 3209 pFile->lastErrno = lastErrno; 3210 winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, 3211 "winUnlockReadLock", pFile->zPath); 3212 } 3213 OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); 3214 return res; 3215 } 3216 3217 /* 3218 ** Lock the file with the lock specified by parameter locktype - one 3219 ** of the following: 3220 ** 3221 ** (1) SHARED_LOCK 3222 ** (2) RESERVED_LOCK 3223 ** (3) PENDING_LOCK 3224 ** (4) EXCLUSIVE_LOCK 3225 ** 3226 ** Sometimes when requesting one lock state, additional lock states 3227 ** are inserted in between. The locking might fail on one of the later 3228 ** transitions leaving the lock state different from what it started but 3229 ** still short of its goal. The following chart shows the allowed 3230 ** transitions and the inserted intermediate states: 3231 ** 3232 ** UNLOCKED -> SHARED 3233 ** SHARED -> RESERVED 3234 ** SHARED -> (PENDING) -> EXCLUSIVE 3235 ** RESERVED -> (PENDING) -> EXCLUSIVE 3236 ** PENDING -> EXCLUSIVE 3237 ** 3238 ** This routine will only increase a lock. The winUnlock() routine 3239 ** erases all locks at once and returns us immediately to locking level 0. 3240 ** It is not possible to lower the locking level one step at a time. You 3241 ** must go straight to locking level 0. 3242 */ 3243 static int winLock(sqlite3_file *id, int locktype){ 3244 int rc = SQLITE_OK; /* Return code from subroutines */ 3245 int res = 1; /* Result of a Windows lock call */ 3246 int newLocktype; /* Set pFile->locktype to this value before exiting */ 3247 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ 3248 winFile *pFile = (winFile*)id; 3249 DWORD lastErrno = NO_ERROR; 3250 3251 assert( id!=0 ); 3252 OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", 3253 pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); 3254 3255 /* If there is already a lock of this type or more restrictive on the 3256 ** OsFile, do nothing. Don't use the end_lock: exit path, as 3257 ** sqlite3OsEnterMutex() hasn't been called yet. 3258 */ 3259 if( pFile->locktype>=locktype ){ 3260 OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); 3261 return SQLITE_OK; 3262 } 3263 3264 /* Do not allow any kind of write-lock on a read-only database 3265 */ 3266 if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){ 3267 return SQLITE_IOERR_LOCK; 3268 } 3269 3270 /* Make sure the locking sequence is correct 3271 */ 3272 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); 3273 assert( locktype!=PENDING_LOCK ); 3274 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); 3275 3276 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or 3277 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of 3278 ** the PENDING_LOCK byte is temporary. 3279 */ 3280 newLocktype = pFile->locktype; 3281 if( pFile->locktype==NO_LOCK 3282 || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) 3283 ){ 3284 int cnt = 3; 3285 while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, 3286 PENDING_BYTE, 0, 1, 0))==0 ){ 3287 /* Try 3 times to get the pending lock. This is needed to work 3288 ** around problems caused by indexing and/or anti-virus software on 3289 ** Windows systems. 3290 ** If you are using this code as a model for alternative VFSes, do not 3291 ** copy this retry logic. It is a hack intended for Windows only. 3292 */ 3293 lastErrno = osGetLastError(); 3294 OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", 3295 pFile->h, cnt, res)); 3296 if( lastErrno==ERROR_INVALID_HANDLE ){ 3297 pFile->lastErrno = lastErrno; 3298 rc = SQLITE_IOERR_LOCK; 3299 OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", 3300 pFile->h, cnt, sqlite3ErrName(rc))); 3301 return rc; 3302 } 3303 if( cnt ) sqlite3_win32_sleep(1); 3304 } 3305 gotPendingLock = res; 3306 if( !res ){ 3307 lastErrno = osGetLastError(); 3308 } 3309 } 3310 3311 /* Acquire a shared lock 3312 */ 3313 if( locktype==SHARED_LOCK && res ){ 3314 assert( pFile->locktype==NO_LOCK ); 3315 res = winGetReadLock(pFile); 3316 if( res ){ 3317 newLocktype = SHARED_LOCK; 3318 }else{ 3319 lastErrno = osGetLastError(); 3320 } 3321 } 3322 3323 /* Acquire a RESERVED lock 3324 */ 3325 if( locktype==RESERVED_LOCK && res ){ 3326 assert( pFile->locktype==SHARED_LOCK ); 3327 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); 3328 if( res ){ 3329 newLocktype = RESERVED_LOCK; 3330 }else{ 3331 lastErrno = osGetLastError(); 3332 } 3333 } 3334 3335 /* Acquire a PENDING lock 3336 */ 3337 if( locktype==EXCLUSIVE_LOCK && res ){ 3338 newLocktype = PENDING_LOCK; 3339 gotPendingLock = 0; 3340 } 3341 3342 /* Acquire an EXCLUSIVE lock 3343 */ 3344 if( locktype==EXCLUSIVE_LOCK && res ){ 3345 assert( pFile->locktype>=SHARED_LOCK ); 3346 res = winUnlockReadLock(pFile); 3347 res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, 3348 SHARED_SIZE, 0); 3349 if( res ){ 3350 newLocktype = EXCLUSIVE_LOCK; 3351 }else{ 3352 lastErrno = osGetLastError(); 3353 winGetReadLock(pFile); 3354 } 3355 } 3356 3357 /* If we are holding a PENDING lock that ought to be released, then 3358 ** release it now. 3359 */ 3360 if( gotPendingLock && locktype==SHARED_LOCK ){ 3361 winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); 3362 } 3363 3364 /* Update the state of the lock has held in the file descriptor then 3365 ** return the appropriate result code. 3366 */ 3367 if( res ){ 3368 rc = SQLITE_OK; 3369 }else{ 3370 pFile->lastErrno = lastErrno; 3371 rc = SQLITE_BUSY; 3372 OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", 3373 pFile->h, locktype, newLocktype)); 3374 } 3375 pFile->locktype = (u8)newLocktype; 3376 OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", 3377 pFile->h, pFile->locktype, sqlite3ErrName(rc))); 3378 return rc; 3379 } 3380 3381 /* 3382 ** This routine checks if there is a RESERVED lock held on the specified 3383 ** file by this or any other process. If such a lock is held, return 3384 ** non-zero, otherwise zero. 3385 */ 3386 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ 3387 int res; 3388 winFile *pFile = (winFile*)id; 3389 3390 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); 3391 OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); 3392 3393 assert( id!=0 ); 3394 if( pFile->locktype>=RESERVED_LOCK ){ 3395 res = 1; 3396 OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); 3397 }else{ 3398 res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); 3399 if( res ){ 3400 winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); 3401 } 3402 res = !res; 3403 OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); 3404 } 3405 *pResOut = res; 3406 OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", 3407 pFile->h, pResOut, *pResOut)); 3408 return SQLITE_OK; 3409 } 3410 3411 /* 3412 ** Lower the locking level on file descriptor id to locktype. locktype 3413 ** must be either NO_LOCK or SHARED_LOCK. 3414 ** 3415 ** If the locking level of the file descriptor is already at or below 3416 ** the requested locking level, this routine is a no-op. 3417 ** 3418 ** It is not possible for this routine to fail if the second argument 3419 ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine 3420 ** might return SQLITE_IOERR; 3421 */ 3422 static int winUnlock(sqlite3_file *id, int locktype){ 3423 int type; 3424 winFile *pFile = (winFile*)id; 3425 int rc = SQLITE_OK; 3426 assert( pFile!=0 ); 3427 assert( locktype<=SHARED_LOCK ); 3428 OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", 3429 pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); 3430 type = pFile->locktype; 3431 if( type>=EXCLUSIVE_LOCK ){ 3432 winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 3433 if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ 3434 /* This should never happen. We should always be able to 3435 ** reacquire the read lock */ 3436 rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), 3437 "winUnlock", pFile->zPath); 3438 } 3439 } 3440 if( type>=RESERVED_LOCK ){ 3441 winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); 3442 } 3443 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ 3444 winUnlockReadLock(pFile); 3445 } 3446 if( type>=PENDING_LOCK ){ 3447 winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); 3448 } 3449 pFile->locktype = (u8)locktype; 3450 OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", 3451 pFile->h, pFile->locktype, sqlite3ErrName(rc))); 3452 return rc; 3453 } 3454 3455 /****************************************************************************** 3456 ****************************** No-op Locking ********************************** 3457 ** 3458 ** Of the various locking implementations available, this is by far the 3459 ** simplest: locking is ignored. No attempt is made to lock the database 3460 ** file for reading or writing. 3461 ** 3462 ** This locking mode is appropriate for use on read-only databases 3463 ** (ex: databases that are burned into CD-ROM, for example.) It can 3464 ** also be used if the application employs some external mechanism to 3465 ** prevent simultaneous access of the same database by two or more 3466 ** database connections. But there is a serious risk of database 3467 ** corruption if this locking mode is used in situations where multiple 3468 ** database connections are accessing the same database file at the same 3469 ** time and one or more of those connections are writing. 3470 */ 3471 3472 static int winNolockLock(sqlite3_file *id, int locktype){ 3473 UNUSED_PARAMETER(id); 3474 UNUSED_PARAMETER(locktype); 3475 return SQLITE_OK; 3476 } 3477 3478 static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ 3479 UNUSED_PARAMETER(id); 3480 UNUSED_PARAMETER(pResOut); 3481 return SQLITE_OK; 3482 } 3483 3484 static int winNolockUnlock(sqlite3_file *id, int locktype){ 3485 UNUSED_PARAMETER(id); 3486 UNUSED_PARAMETER(locktype); 3487 return SQLITE_OK; 3488 } 3489 3490 /******************* End of the no-op lock implementation ********************* 3491 ******************************************************************************/ 3492 3493 /* 3494 ** If *pArg is initially negative then this is a query. Set *pArg to 3495 ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. 3496 ** 3497 ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. 3498 */ 3499 static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ 3500 if( *pArg<0 ){ 3501 *pArg = (pFile->ctrlFlags & mask)!=0; 3502 }else if( (*pArg)==0 ){ 3503 pFile->ctrlFlags &= ~mask; 3504 }else{ 3505 pFile->ctrlFlags |= mask; 3506 } 3507 } 3508 3509 /* Forward references to VFS helper methods used for temporary files */ 3510 static int winGetTempname(sqlite3_vfs *, char **); 3511 static int winIsDir(const void *); 3512 static BOOL winIsLongPathPrefix(const char *); 3513 static BOOL winIsDriveLetterAndColon(const char *); 3514 3515 /* 3516 ** Control and query of the open file handle. 3517 */ 3518 static int winFileControl(sqlite3_file *id, int op, void *pArg){ 3519 winFile *pFile = (winFile*)id; 3520 OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); 3521 switch( op ){ 3522 case SQLITE_FCNTL_LOCKSTATE: { 3523 *(int*)pArg = pFile->locktype; 3524 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3525 return SQLITE_OK; 3526 } 3527 case SQLITE_FCNTL_LAST_ERRNO: { 3528 *(int*)pArg = (int)pFile->lastErrno; 3529 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3530 return SQLITE_OK; 3531 } 3532 case SQLITE_FCNTL_CHUNK_SIZE: { 3533 pFile->szChunk = *(int *)pArg; 3534 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3535 return SQLITE_OK; 3536 } 3537 case SQLITE_FCNTL_SIZE_HINT: { 3538 if( pFile->szChunk>0 ){ 3539 sqlite3_int64 oldSz; 3540 int rc = winFileSize(id, &oldSz); 3541 if( rc==SQLITE_OK ){ 3542 sqlite3_int64 newSz = *(sqlite3_int64*)pArg; 3543 if( newSz>oldSz ){ 3544 SimulateIOErrorBenign(1); 3545 rc = winTruncate(id, newSz); 3546 SimulateIOErrorBenign(0); 3547 } 3548 } 3549 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3550 return rc; 3551 } 3552 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3553 return SQLITE_OK; 3554 } 3555 case SQLITE_FCNTL_PERSIST_WAL: { 3556 winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); 3557 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3558 return SQLITE_OK; 3559 } 3560 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { 3561 winModeBit(pFile, WINFILE_PSOW, (int*)pArg); 3562 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3563 return SQLITE_OK; 3564 } 3565 case SQLITE_FCNTL_VFSNAME: { 3566 *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); 3567 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3568 return SQLITE_OK; 3569 } 3570 case SQLITE_FCNTL_WIN32_AV_RETRY: { 3571 int *a = (int*)pArg; 3572 if( a[0]>0 ){ 3573 winIoerrRetry = a[0]; 3574 }else{ 3575 a[0] = winIoerrRetry; 3576 } 3577 if( a[1]>0 ){ 3578 winIoerrRetryDelay = a[1]; 3579 }else{ 3580 a[1] = winIoerrRetryDelay; 3581 } 3582 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3583 return SQLITE_OK; 3584 } 3585 case SQLITE_FCNTL_WIN32_GET_HANDLE: { 3586 LPHANDLE phFile = (LPHANDLE)pArg; 3587 *phFile = pFile->h; 3588 OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); 3589 return SQLITE_OK; 3590 } 3591 #ifdef SQLITE_TEST 3592 case SQLITE_FCNTL_WIN32_SET_HANDLE: { 3593 LPHANDLE phFile = (LPHANDLE)pArg; 3594 HANDLE hOldFile = pFile->h; 3595 pFile->h = *phFile; 3596 *phFile = hOldFile; 3597 OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", 3598 hOldFile, pFile->h)); 3599 return SQLITE_OK; 3600 } 3601 #endif 3602 case SQLITE_FCNTL_TEMPFILENAME: { 3603 char *zTFile = 0; 3604 int rc = winGetTempname(pFile->pVfs, &zTFile); 3605 if( rc==SQLITE_OK ){ 3606 *(char**)pArg = zTFile; 3607 } 3608 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3609 return rc; 3610 } 3611 #if SQLITE_MAX_MMAP_SIZE>0 3612 case SQLITE_FCNTL_MMAP_SIZE: { 3613 i64 newLimit = *(i64*)pArg; 3614 int rc = SQLITE_OK; 3615 if( newLimit>sqlite3GlobalConfig.mxMmap ){ 3616 newLimit = sqlite3GlobalConfig.mxMmap; 3617 } 3618 3619 /* The value of newLimit may be eventually cast to (SIZE_T) and passed 3620 ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at 3621 ** least a 64-bit type. */ 3622 if( newLimit>0 && sizeof(SIZE_T)<8 ){ 3623 newLimit = (newLimit & 0x7FFFFFFF); 3624 } 3625 3626 *(i64*)pArg = pFile->mmapSizeMax; 3627 if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ 3628 pFile->mmapSizeMax = newLimit; 3629 if( pFile->mmapSize>0 ){ 3630 winUnmapfile(pFile); 3631 rc = winMapfile(pFile, -1); 3632 } 3633 } 3634 OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); 3635 return rc; 3636 } 3637 #endif 3638 } 3639 OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); 3640 return SQLITE_NOTFOUND; 3641 } 3642 3643 /* 3644 ** Return the sector size in bytes of the underlying block device for 3645 ** the specified file. This is almost always 512 bytes, but may be 3646 ** larger for some devices. 3647 ** 3648 ** SQLite code assumes this function cannot fail. It also assumes that 3649 ** if two files are created in the same file-system directory (i.e. 3650 ** a database and its journal file) that the sector size will be the 3651 ** same for both. 3652 */ 3653 static int winSectorSize(sqlite3_file *id){ 3654 (void)id; 3655 return SQLITE_DEFAULT_SECTOR_SIZE; 3656 } 3657 3658 /* 3659 ** Return a vector of device characteristics. 3660 */ 3661 static int winDeviceCharacteristics(sqlite3_file *id){ 3662 winFile *p = (winFile*)id; 3663 return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | 3664 ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); 3665 } 3666 3667 /* 3668 ** Windows will only let you create file view mappings 3669 ** on allocation size granularity boundaries. 3670 ** During sqlite3_os_init() we do a GetSystemInfo() 3671 ** to get the granularity size. 3672 */ 3673 static SYSTEM_INFO winSysInfo; 3674 3675 #ifndef SQLITE_OMIT_WAL 3676 3677 /* 3678 ** Helper functions to obtain and relinquish the global mutex. The 3679 ** global mutex is used to protect the winLockInfo objects used by 3680 ** this file, all of which may be shared by multiple threads. 3681 ** 3682 ** Function winShmMutexHeld() is used to assert() that the global mutex 3683 ** is held when required. This function is only used as part of assert() 3684 ** statements. e.g. 3685 ** 3686 ** winShmEnterMutex() 3687 ** assert( winShmMutexHeld() ); 3688 ** winShmLeaveMutex() 3689 */ 3690 static sqlite3_mutex *winBigLock = 0; 3691 static void winShmEnterMutex(void){ 3692 sqlite3_mutex_enter(winBigLock); 3693 } 3694 static void winShmLeaveMutex(void){ 3695 sqlite3_mutex_leave(winBigLock); 3696 } 3697 #ifndef NDEBUG 3698 static int winShmMutexHeld(void) { 3699 return sqlite3_mutex_held(winBigLock); 3700 } 3701 #endif 3702 3703 /* 3704 ** Object used to represent a single file opened and mmapped to provide 3705 ** shared memory. When multiple threads all reference the same 3706 ** log-summary, each thread has its own winFile object, but they all 3707 ** point to a single instance of this object. In other words, each 3708 ** log-summary is opened only once per process. 3709 ** 3710 ** winShmMutexHeld() must be true when creating or destroying 3711 ** this object or while reading or writing the following fields: 3712 ** 3713 ** nRef 3714 ** pNext 3715 ** 3716 ** The following fields are read-only after the object is created: 3717 ** 3718 ** fid 3719 ** zFilename 3720 ** 3721 ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and 3722 ** winShmMutexHeld() is true when reading or writing any other field 3723 ** in this structure. 3724 ** 3725 */ 3726 struct winShmNode { 3727 sqlite3_mutex *mutex; /* Mutex to access this object */ 3728 char *zFilename; /* Name of the file */ 3729 winFile hFile; /* File handle from winOpen */ 3730 3731 int szRegion; /* Size of shared-memory regions */ 3732 int nRegion; /* Size of array apRegion */ 3733 u8 isReadonly; /* True if read-only */ 3734 u8 isUnlocked; /* True if no DMS lock held */ 3735 3736 struct ShmRegion { 3737 HANDLE hMap; /* File handle from CreateFileMapping */ 3738 void *pMap; 3739 } *aRegion; 3740 DWORD lastErrno; /* The Windows errno from the last I/O error */ 3741 3742 int nRef; /* Number of winShm objects pointing to this */ 3743 winShm *pFirst; /* All winShm objects pointing to this */ 3744 winShmNode *pNext; /* Next in list of all winShmNode objects */ 3745 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3746 u8 nextShmId; /* Next available winShm.id value */ 3747 #endif 3748 }; 3749 3750 /* 3751 ** A global array of all winShmNode objects. 3752 ** 3753 ** The winShmMutexHeld() must be true while reading or writing this list. 3754 */ 3755 static winShmNode *winShmNodeList = 0; 3756 3757 /* 3758 ** Structure used internally by this VFS to record the state of an 3759 ** open shared memory connection. 3760 ** 3761 ** The following fields are initialized when this object is created and 3762 ** are read-only thereafter: 3763 ** 3764 ** winShm.pShmNode 3765 ** winShm.id 3766 ** 3767 ** All other fields are read/write. The winShm.pShmNode->mutex must be held 3768 ** while accessing any read/write fields. 3769 */ 3770 struct winShm { 3771 winShmNode *pShmNode; /* The underlying winShmNode object */ 3772 winShm *pNext; /* Next winShm with the same winShmNode */ 3773 u8 hasMutex; /* True if holding the winShmNode mutex */ 3774 u16 sharedMask; /* Mask of shared locks held */ 3775 u16 exclMask; /* Mask of exclusive locks held */ 3776 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3777 u8 id; /* Id of this connection with its winShmNode */ 3778 #endif 3779 }; 3780 3781 /* 3782 ** Constants used for locking 3783 */ 3784 #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ 3785 #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ 3786 3787 /* 3788 ** Apply advisory locks for all n bytes beginning at ofst. 3789 */ 3790 #define WINSHM_UNLCK 1 3791 #define WINSHM_RDLCK 2 3792 #define WINSHM_WRLCK 3 3793 static int winShmSystemLock( 3794 winShmNode *pFile, /* Apply locks to this open shared-memory segment */ 3795 int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ 3796 int ofst, /* Offset to first byte to be locked/unlocked */ 3797 int nByte /* Number of bytes to lock or unlock */ 3798 ){ 3799 int rc = 0; /* Result code form Lock/UnlockFileEx() */ 3800 3801 /* Access to the winShmNode object is serialized by the caller */ 3802 assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); 3803 3804 OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", 3805 pFile->hFile.h, lockType, ofst, nByte)); 3806 3807 /* Release/Acquire the system-level lock */ 3808 if( lockType==WINSHM_UNLCK ){ 3809 rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); 3810 }else{ 3811 /* Initialize the locking parameters */ 3812 DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; 3813 if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; 3814 rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); 3815 } 3816 3817 if( rc!= 0 ){ 3818 rc = SQLITE_OK; 3819 }else{ 3820 pFile->lastErrno = osGetLastError(); 3821 rc = SQLITE_BUSY; 3822 } 3823 3824 OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", 3825 pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : 3826 "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); 3827 3828 return rc; 3829 } 3830 3831 /* Forward references to VFS methods */ 3832 static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); 3833 static int winDelete(sqlite3_vfs *,const char*,int); 3834 3835 /* 3836 ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. 3837 ** 3838 ** This is not a VFS shared-memory method; it is a utility function called 3839 ** by VFS shared-memory methods. 3840 */ 3841 static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ 3842 winShmNode **pp; 3843 winShmNode *p; 3844 assert( winShmMutexHeld() ); 3845 OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", 3846 osGetCurrentProcessId(), deleteFlag)); 3847 pp = &winShmNodeList; 3848 while( (p = *pp)!=0 ){ 3849 if( p->nRef==0 ){ 3850 int i; 3851 if( p->mutex ){ sqlite3_mutex_free(p->mutex); } 3852 for(i=0; i<p->nRegion; i++){ 3853 BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); 3854 OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", 3855 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3856 UNUSED_VARIABLE_VALUE(bRc); 3857 bRc = osCloseHandle(p->aRegion[i].hMap); 3858 OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", 3859 osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); 3860 UNUSED_VARIABLE_VALUE(bRc); 3861 } 3862 if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ 3863 SimulateIOErrorBenign(1); 3864 winClose((sqlite3_file *)&p->hFile); 3865 SimulateIOErrorBenign(0); 3866 } 3867 if( deleteFlag ){ 3868 SimulateIOErrorBenign(1); 3869 sqlite3BeginBenignMalloc(); 3870 winDelete(pVfs, p->zFilename, 0); 3871 sqlite3EndBenignMalloc(); 3872 SimulateIOErrorBenign(0); 3873 } 3874 *pp = p->pNext; 3875 sqlite3_free(p->aRegion); 3876 sqlite3_free(p); 3877 }else{ 3878 pp = &p->pNext; 3879 } 3880 } 3881 } 3882 3883 /* 3884 ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to 3885 ** take it now. Return SQLITE_OK if successful, or an SQLite error 3886 ** code otherwise. 3887 ** 3888 ** If the DMS cannot be locked because this is a readonly_shm=1 3889 ** connection and no other process already holds a lock, return 3890 ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. 3891 */ 3892 static int winLockSharedMemory(winShmNode *pShmNode){ 3893 int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); 3894 3895 if( rc==SQLITE_OK ){ 3896 if( pShmNode->isReadonly ){ 3897 pShmNode->isUnlocked = 1; 3898 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3899 return SQLITE_READONLY_CANTINIT; 3900 }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ 3901 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3902 return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), 3903 "winLockSharedMemory", pShmNode->zFilename); 3904 } 3905 } 3906 3907 if( rc==SQLITE_OK ){ 3908 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 3909 } 3910 3911 return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); 3912 } 3913 3914 /* 3915 ** Open the shared-memory area associated with database file pDbFd. 3916 ** 3917 ** When opening a new shared-memory file, if no other instances of that 3918 ** file are currently open, in this process or in other processes, then 3919 ** the file must be truncated to zero length or have its header cleared. 3920 */ 3921 static int winOpenSharedMemory(winFile *pDbFd){ 3922 struct winShm *p; /* The connection to be opened */ 3923 winShmNode *pShmNode = 0; /* The underlying mmapped file */ 3924 int rc = SQLITE_OK; /* Result code */ 3925 winShmNode *pNew; /* Newly allocated winShmNode */ 3926 int nName; /* Size of zName in bytes */ 3927 3928 assert( pDbFd->pShm==0 ); /* Not previously opened */ 3929 3930 /* Allocate space for the new sqlite3_shm object. Also speculatively 3931 ** allocate space for a new winShmNode and filename. 3932 */ 3933 p = sqlite3MallocZero( sizeof(*p) ); 3934 if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; 3935 nName = sqlite3Strlen30(pDbFd->zPath); 3936 pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); 3937 if( pNew==0 ){ 3938 sqlite3_free(p); 3939 return SQLITE_IOERR_NOMEM_BKPT; 3940 } 3941 pNew->zFilename = (char*)&pNew[1]; 3942 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); 3943 sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 3944 3945 /* Look to see if there is an existing winShmNode that can be used. 3946 ** If no matching winShmNode currently exists, create a new one. 3947 */ 3948 winShmEnterMutex(); 3949 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ 3950 /* TBD need to come up with better match here. Perhaps 3951 ** use FILE_ID_BOTH_DIR_INFO Structure. 3952 */ 3953 if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; 3954 } 3955 if( pShmNode ){ 3956 sqlite3_free(pNew); 3957 }else{ 3958 int inFlags = SQLITE_OPEN_WAL; 3959 int outFlags = 0; 3960 3961 pShmNode = pNew; 3962 pNew = 0; 3963 ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; 3964 pShmNode->pNext = winShmNodeList; 3965 winShmNodeList = pShmNode; 3966 3967 if( sqlite3GlobalConfig.bCoreMutex ){ 3968 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); 3969 if( pShmNode->mutex==0 ){ 3970 rc = SQLITE_IOERR_NOMEM_BKPT; 3971 goto shm_open_err; 3972 } 3973 } 3974 3975 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ 3976 inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; 3977 }else{ 3978 inFlags |= SQLITE_OPEN_READONLY; 3979 } 3980 rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, 3981 (sqlite3_file*)&pShmNode->hFile, 3982 inFlags, &outFlags); 3983 if( rc!=SQLITE_OK ){ 3984 rc = winLogError(rc, osGetLastError(), "winOpenShm", 3985 pShmNode->zFilename); 3986 goto shm_open_err; 3987 } 3988 if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; 3989 3990 rc = winLockSharedMemory(pShmNode); 3991 if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; 3992 } 3993 3994 /* Make the new connection a child of the winShmNode */ 3995 p->pShmNode = pShmNode; 3996 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) 3997 p->id = pShmNode->nextShmId++; 3998 #endif 3999 pShmNode->nRef++; 4000 pDbFd->pShm = p; 4001 winShmLeaveMutex(); 4002 4003 /* The reference count on pShmNode has already been incremented under 4004 ** the cover of the winShmEnterMutex() mutex and the pointer from the 4005 ** new (struct winShm) object to the pShmNode has been set. All that is 4006 ** left to do is to link the new object into the linked list starting 4007 ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 4008 ** mutex. 4009 */ 4010 sqlite3_mutex_enter(pShmNode->mutex); 4011 p->pNext = pShmNode->pFirst; 4012 pShmNode->pFirst = p; 4013 sqlite3_mutex_leave(pShmNode->mutex); 4014 return rc; 4015 4016 /* Jump here on any error */ 4017 shm_open_err: 4018 winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); 4019 winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ 4020 sqlite3_free(p); 4021 sqlite3_free(pNew); 4022 winShmLeaveMutex(); 4023 return rc; 4024 } 4025 4026 /* 4027 ** Close a connection to shared-memory. Delete the underlying 4028 ** storage if deleteFlag is true. 4029 */ 4030 static int winShmUnmap( 4031 sqlite3_file *fd, /* Database holding shared memory */ 4032 int deleteFlag /* Delete after closing if true */ 4033 ){ 4034 winFile *pDbFd; /* Database holding shared-memory */ 4035 winShm *p; /* The connection to be closed */ 4036 winShmNode *pShmNode; /* The underlying shared-memory file */ 4037 winShm **pp; /* For looping over sibling connections */ 4038 4039 pDbFd = (winFile*)fd; 4040 p = pDbFd->pShm; 4041 if( p==0 ) return SQLITE_OK; 4042 pShmNode = p->pShmNode; 4043 4044 /* Remove connection p from the set of connections associated 4045 ** with pShmNode */ 4046 sqlite3_mutex_enter(pShmNode->mutex); 4047 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} 4048 *pp = p->pNext; 4049 4050 /* Free the connection p */ 4051 sqlite3_free(p); 4052 pDbFd->pShm = 0; 4053 sqlite3_mutex_leave(pShmNode->mutex); 4054 4055 /* If pShmNode->nRef has reached 0, then close the underlying 4056 ** shared-memory file, too */ 4057 winShmEnterMutex(); 4058 assert( pShmNode->nRef>0 ); 4059 pShmNode->nRef--; 4060 if( pShmNode->nRef==0 ){ 4061 winShmPurge(pDbFd->pVfs, deleteFlag); 4062 } 4063 winShmLeaveMutex(); 4064 4065 return SQLITE_OK; 4066 } 4067 4068 /* 4069 ** Change the lock state for a shared-memory segment. 4070 */ 4071 static int winShmLock( 4072 sqlite3_file *fd, /* Database file holding the shared memory */ 4073 int ofst, /* First lock to acquire or release */ 4074 int n, /* Number of locks to acquire or release */ 4075 int flags /* What to do with the lock */ 4076 ){ 4077 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ 4078 winShm *p = pDbFd->pShm; /* The shared memory being locked */ 4079 winShm *pX; /* For looping over all siblings */ 4080 winShmNode *pShmNode; 4081 int rc = SQLITE_OK; /* Result code */ 4082 u16 mask; /* Mask of locks to take or release */ 4083 4084 if( p==0 ) return SQLITE_IOERR_SHMLOCK; 4085 pShmNode = p->pShmNode; 4086 if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; 4087 4088 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); 4089 assert( n>=1 ); 4090 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) 4091 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) 4092 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) 4093 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); 4094 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); 4095 4096 mask = (u16)((1U<<(ofst+n)) - (1U<<ofst)); 4097 assert( n>1 || mask==(1<<ofst) ); 4098 sqlite3_mutex_enter(pShmNode->mutex); 4099 if( flags & SQLITE_SHM_UNLOCK ){ 4100 u16 allMask = 0; /* Mask of locks held by siblings */ 4101 4102 /* See if any siblings hold this same lock */ 4103 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4104 if( pX==p ) continue; 4105 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); 4106 allMask |= pX->sharedMask; 4107 } 4108 4109 /* Unlock the system-level locks */ 4110 if( (mask & allMask)==0 ){ 4111 rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); 4112 }else{ 4113 rc = SQLITE_OK; 4114 } 4115 4116 /* Undo the local locks */ 4117 if( rc==SQLITE_OK ){ 4118 p->exclMask &= ~mask; 4119 p->sharedMask &= ~mask; 4120 } 4121 }else if( flags & SQLITE_SHM_SHARED ){ 4122 u16 allShared = 0; /* Union of locks held by connections other than "p" */ 4123 4124 /* Find out which shared locks are already held by sibling connections. 4125 ** If any sibling already holds an exclusive lock, go ahead and return 4126 ** SQLITE_BUSY. 4127 */ 4128 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4129 if( (pX->exclMask & mask)!=0 ){ 4130 rc = SQLITE_BUSY; 4131 break; 4132 } 4133 allShared |= pX->sharedMask; 4134 } 4135 4136 /* Get shared locks at the system level, if necessary */ 4137 if( rc==SQLITE_OK ){ 4138 if( (allShared & mask)==0 ){ 4139 rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); 4140 }else{ 4141 rc = SQLITE_OK; 4142 } 4143 } 4144 4145 /* Get the local shared locks */ 4146 if( rc==SQLITE_OK ){ 4147 p->sharedMask |= mask; 4148 } 4149 }else{ 4150 /* Make sure no sibling connections hold locks that will block this 4151 ** lock. If any do, return SQLITE_BUSY right away. 4152 */ 4153 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 4154 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ 4155 rc = SQLITE_BUSY; 4156 break; 4157 } 4158 } 4159 4160 /* Get the exclusive locks at the system level. Then if successful 4161 ** also mark the local connection as being locked. 4162 */ 4163 if( rc==SQLITE_OK ){ 4164 rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); 4165 if( rc==SQLITE_OK ){ 4166 assert( (p->sharedMask & mask)==0 ); 4167 p->exclMask |= mask; 4168 } 4169 } 4170 } 4171 sqlite3_mutex_leave(pShmNode->mutex); 4172 OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", 4173 osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, 4174 sqlite3ErrName(rc))); 4175 return rc; 4176 } 4177 4178 /* 4179 ** Implement a memory barrier or memory fence on shared memory. 4180 ** 4181 ** All loads and stores begun before the barrier must complete before 4182 ** any load or store begun after the barrier. 4183 */ 4184 static void winShmBarrier( 4185 sqlite3_file *fd /* Database holding the shared memory */ 4186 ){ 4187 UNUSED_PARAMETER(fd); 4188 sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ 4189 winShmEnterMutex(); /* Also mutex, for redundancy */ 4190 winShmLeaveMutex(); 4191 } 4192 4193 /* 4194 ** This function is called to obtain a pointer to region iRegion of the 4195 ** shared-memory associated with the database file fd. Shared-memory regions 4196 ** are numbered starting from zero. Each shared-memory region is szRegion 4197 ** bytes in size. 4198 ** 4199 ** If an error occurs, an error code is returned and *pp is set to NULL. 4200 ** 4201 ** Otherwise, if the isWrite parameter is 0 and the requested shared-memory 4202 ** region has not been allocated (by any client, including one running in a 4203 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If 4204 ** isWrite is non-zero and the requested shared-memory region has not yet 4205 ** been allocated, it is allocated by this function. 4206 ** 4207 ** If the shared-memory region has already been allocated or is allocated by 4208 ** this call as described above, then it is mapped into this processes 4209 ** address space (if it is not already), *pp is set to point to the mapped 4210 ** memory and SQLITE_OK returned. 4211 */ 4212 static int winShmMap( 4213 sqlite3_file *fd, /* Handle open on database file */ 4214 int iRegion, /* Region to retrieve */ 4215 int szRegion, /* Size of regions */ 4216 int isWrite, /* True to extend file if necessary */ 4217 void volatile **pp /* OUT: Mapped memory */ 4218 ){ 4219 winFile *pDbFd = (winFile*)fd; 4220 winShm *pShm = pDbFd->pShm; 4221 winShmNode *pShmNode; 4222 DWORD protect = PAGE_READWRITE; 4223 DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; 4224 int rc = SQLITE_OK; 4225 4226 if( !pShm ){ 4227 rc = winOpenSharedMemory(pDbFd); 4228 if( rc!=SQLITE_OK ) return rc; 4229 pShm = pDbFd->pShm; 4230 assert( pShm!=0 ); 4231 } 4232 pShmNode = pShm->pShmNode; 4233 4234 sqlite3_mutex_enter(pShmNode->mutex); 4235 if( pShmNode->isUnlocked ){ 4236 rc = winLockSharedMemory(pShmNode); 4237 if( rc!=SQLITE_OK ) goto shmpage_out; 4238 pShmNode->isUnlocked = 0; 4239 } 4240 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); 4241 4242 if( pShmNode->nRegion<=iRegion ){ 4243 struct ShmRegion *apNew; /* New aRegion[] array */ 4244 int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ 4245 sqlite3_int64 sz; /* Current size of wal-index file */ 4246 4247 pShmNode->szRegion = szRegion; 4248 4249 /* The requested region is not mapped into this processes address space. 4250 ** Check to see if it has been allocated (i.e. if the wal-index file is 4251 ** large enough to contain the requested region). 4252 */ 4253 rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); 4254 if( rc!=SQLITE_OK ){ 4255 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4256 "winShmMap1", pDbFd->zPath); 4257 goto shmpage_out; 4258 } 4259 4260 if( sz<nByte ){ 4261 /* The requested memory region does not exist. If isWrite is set to 4262 ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. 4263 ** 4264 ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate 4265 ** the requested memory region. 4266 */ 4267 if( !isWrite ) goto shmpage_out; 4268 rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); 4269 if( rc!=SQLITE_OK ){ 4270 rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), 4271 "winShmMap2", pDbFd->zPath); 4272 goto shmpage_out; 4273 } 4274 } 4275 4276 /* Map the requested memory region into this processes address space. */ 4277 apNew = (struct ShmRegion *)sqlite3_realloc64( 4278 pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) 4279 ); 4280 if( !apNew ){ 4281 rc = SQLITE_IOERR_NOMEM_BKPT; 4282 goto shmpage_out; 4283 } 4284 pShmNode->aRegion = apNew; 4285 4286 if( pShmNode->isReadonly ){ 4287 protect = PAGE_READONLY; 4288 flags = FILE_MAP_READ; 4289 } 4290 4291 while( pShmNode->nRegion<=iRegion ){ 4292 HANDLE hMap = NULL; /* file-mapping handle */ 4293 void *pMap = 0; /* Mapped memory region */ 4294 4295 #if SQLITE_OS_WINRT 4296 hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, 4297 NULL, protect, nByte, NULL 4298 ); 4299 #elif defined(SQLITE_WIN32_HAS_WIDE) 4300 hMap = osCreateFileMappingW(pShmNode->hFile.h, 4301 NULL, protect, 0, nByte, NULL 4302 ); 4303 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4304 hMap = osCreateFileMappingA(pShmNode->hFile.h, 4305 NULL, protect, 0, nByte, NULL 4306 ); 4307 #endif 4308 OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", 4309 osGetCurrentProcessId(), pShmNode->nRegion, nByte, 4310 hMap ? "ok" : "failed")); 4311 if( hMap ){ 4312 int iOffset = pShmNode->nRegion*szRegion; 4313 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4314 #if SQLITE_OS_WINRT 4315 pMap = osMapViewOfFileFromApp(hMap, flags, 4316 iOffset - iOffsetShift, szRegion + iOffsetShift 4317 ); 4318 #else 4319 pMap = osMapViewOfFile(hMap, flags, 4320 0, iOffset - iOffsetShift, szRegion + iOffsetShift 4321 ); 4322 #endif 4323 OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", 4324 osGetCurrentProcessId(), pShmNode->nRegion, iOffset, 4325 szRegion, pMap ? "ok" : "failed")); 4326 } 4327 if( !pMap ){ 4328 pShmNode->lastErrno = osGetLastError(); 4329 rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, 4330 "winShmMap3", pDbFd->zPath); 4331 if( hMap ) osCloseHandle(hMap); 4332 goto shmpage_out; 4333 } 4334 4335 pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; 4336 pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; 4337 pShmNode->nRegion++; 4338 } 4339 } 4340 4341 shmpage_out: 4342 if( pShmNode->nRegion>iRegion ){ 4343 int iOffset = iRegion*szRegion; 4344 int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; 4345 char *p = (char *)pShmNode->aRegion[iRegion].pMap; 4346 *pp = (void *)&p[iOffsetShift]; 4347 }else{ 4348 *pp = 0; 4349 } 4350 if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; 4351 sqlite3_mutex_leave(pShmNode->mutex); 4352 return rc; 4353 } 4354 4355 #else 4356 # define winShmMap 0 4357 # define winShmLock 0 4358 # define winShmBarrier 0 4359 # define winShmUnmap 0 4360 #endif /* #ifndef SQLITE_OMIT_WAL */ 4361 4362 /* 4363 ** Cleans up the mapped region of the specified file, if any. 4364 */ 4365 #if SQLITE_MAX_MMAP_SIZE>0 4366 static int winUnmapfile(winFile *pFile){ 4367 assert( pFile!=0 ); 4368 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " 4369 "mmapSize=%lld, mmapSizeMax=%lld\n", 4370 osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, 4371 pFile->mmapSize, pFile->mmapSizeMax)); 4372 if( pFile->pMapRegion ){ 4373 if( !osUnmapViewOfFile(pFile->pMapRegion) ){ 4374 pFile->lastErrno = osGetLastError(); 4375 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " 4376 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, 4377 pFile->pMapRegion)); 4378 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4379 "winUnmapfile1", pFile->zPath); 4380 } 4381 pFile->pMapRegion = 0; 4382 pFile->mmapSize = 0; 4383 } 4384 if( pFile->hMap!=NULL ){ 4385 if( !osCloseHandle(pFile->hMap) ){ 4386 pFile->lastErrno = osGetLastError(); 4387 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", 4388 osGetCurrentProcessId(), pFile, pFile->hMap)); 4389 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, 4390 "winUnmapfile2", pFile->zPath); 4391 } 4392 pFile->hMap = NULL; 4393 } 4394 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4395 osGetCurrentProcessId(), pFile)); 4396 return SQLITE_OK; 4397 } 4398 4399 /* 4400 ** Memory map or remap the file opened by file-descriptor pFd (if the file 4401 ** is already mapped, the existing mapping is replaced by the new). Or, if 4402 ** there already exists a mapping for this file, and there are still 4403 ** outstanding xFetch() references to it, this function is a no-op. 4404 ** 4405 ** If parameter nByte is non-negative, then it is the requested size of 4406 ** the mapping to create. Otherwise, if nByte is less than zero, then the 4407 ** requested size is the size of the file on disk. The actual size of the 4408 ** created mapping is either the requested size or the value configured 4409 ** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. 4410 ** 4411 ** SQLITE_OK is returned if no error occurs (even if the mapping is not 4412 ** recreated as a result of outstanding references) or an SQLite error 4413 ** code otherwise. 4414 */ 4415 static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ 4416 sqlite3_int64 nMap = nByte; 4417 int rc; 4418 4419 assert( nMap>=0 || pFd->nFetchOut==0 ); 4420 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", 4421 osGetCurrentProcessId(), pFd, nByte)); 4422 4423 if( pFd->nFetchOut>0 ) return SQLITE_OK; 4424 4425 if( nMap<0 ){ 4426 rc = winFileSize((sqlite3_file*)pFd, &nMap); 4427 if( rc ){ 4428 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", 4429 osGetCurrentProcessId(), pFd)); 4430 return SQLITE_IOERR_FSTAT; 4431 } 4432 } 4433 if( nMap>pFd->mmapSizeMax ){ 4434 nMap = pFd->mmapSizeMax; 4435 } 4436 nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); 4437 4438 if( nMap==0 && pFd->mmapSize>0 ){ 4439 winUnmapfile(pFd); 4440 } 4441 if( nMap!=pFd->mmapSize ){ 4442 void *pNew = 0; 4443 DWORD protect = PAGE_READONLY; 4444 DWORD flags = FILE_MAP_READ; 4445 4446 winUnmapfile(pFd); 4447 #ifdef SQLITE_MMAP_READWRITE 4448 if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ 4449 protect = PAGE_READWRITE; 4450 flags |= FILE_MAP_WRITE; 4451 } 4452 #endif 4453 #if SQLITE_OS_WINRT 4454 pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); 4455 #elif defined(SQLITE_WIN32_HAS_WIDE) 4456 pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, 4457 (DWORD)((nMap>>32) & 0xffffffff), 4458 (DWORD)(nMap & 0xffffffff), NULL); 4459 #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA 4460 pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, 4461 (DWORD)((nMap>>32) & 0xffffffff), 4462 (DWORD)(nMap & 0xffffffff), NULL); 4463 #endif 4464 if( pFd->hMap==NULL ){ 4465 pFd->lastErrno = osGetLastError(); 4466 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4467 "winMapfile1", pFd->zPath); 4468 /* Log the error, but continue normal operation using xRead/xWrite */ 4469 OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", 4470 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4471 return SQLITE_OK; 4472 } 4473 assert( (nMap % winSysInfo.dwPageSize)==0 ); 4474 assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); 4475 #if SQLITE_OS_WINRT 4476 pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); 4477 #else 4478 pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); 4479 #endif 4480 if( pNew==NULL ){ 4481 osCloseHandle(pFd->hMap); 4482 pFd->hMap = NULL; 4483 pFd->lastErrno = osGetLastError(); 4484 rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, 4485 "winMapfile2", pFd->zPath); 4486 /* Log the error, but continue normal operation using xRead/xWrite */ 4487 OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", 4488 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4489 return SQLITE_OK; 4490 } 4491 pFd->pMapRegion = pNew; 4492 pFd->mmapSize = nMap; 4493 } 4494 4495 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4496 osGetCurrentProcessId(), pFd)); 4497 return SQLITE_OK; 4498 } 4499 #endif /* SQLITE_MAX_MMAP_SIZE>0 */ 4500 4501 /* 4502 ** If possible, return a pointer to a mapping of file fd starting at offset 4503 ** iOff. The mapping must be valid for at least nAmt bytes. 4504 ** 4505 ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. 4506 ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. 4507 ** Finally, if an error does occur, return an SQLite error code. The final 4508 ** value of *pp is undefined in this case. 4509 ** 4510 ** If this function does return a pointer, the caller must eventually 4511 ** release the reference by calling winUnfetch(). 4512 */ 4513 static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ 4514 #if SQLITE_MAX_MMAP_SIZE>0 4515 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4516 #endif 4517 *pp = 0; 4518 4519 OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", 4520 osGetCurrentProcessId(), fd, iOff, nAmt, pp)); 4521 4522 #if SQLITE_MAX_MMAP_SIZE>0 4523 if( pFd->mmapSizeMax>0 ){ 4524 if( pFd->pMapRegion==0 ){ 4525 int rc = winMapfile(pFd, -1); 4526 if( rc!=SQLITE_OK ){ 4527 OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", 4528 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); 4529 return rc; 4530 } 4531 } 4532 if( pFd->mmapSize >= iOff+nAmt ){ 4533 assert( pFd->pMapRegion!=0 ); 4534 *pp = &((u8 *)pFd->pMapRegion)[iOff]; 4535 pFd->nFetchOut++; 4536 } 4537 } 4538 #endif 4539 4540 OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", 4541 osGetCurrentProcessId(), fd, pp, *pp)); 4542 return SQLITE_OK; 4543 } 4544 4545 /* 4546 ** If the third argument is non-NULL, then this function releases a 4547 ** reference obtained by an earlier call to winFetch(). The second 4548 ** argument passed to this function must be the same as the corresponding 4549 ** argument that was passed to the winFetch() invocation. 4550 ** 4551 ** Or, if the third argument is NULL, then this function is being called 4552 ** to inform the VFS layer that, according to POSIX, any existing mapping 4553 ** may now be invalid and should be unmapped. 4554 */ 4555 static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ 4556 #if SQLITE_MAX_MMAP_SIZE>0 4557 winFile *pFd = (winFile*)fd; /* The underlying database file */ 4558 4559 /* If p==0 (unmap the entire file) then there must be no outstanding 4560 ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), 4561 ** then there must be at least one outstanding. */ 4562 assert( (p==0)==(pFd->nFetchOut==0) ); 4563 4564 /* If p!=0, it must match the iOff value. */ 4565 assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); 4566 4567 OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", 4568 osGetCurrentProcessId(), pFd, iOff, p)); 4569 4570 if( p ){ 4571 pFd->nFetchOut--; 4572 }else{ 4573 /* FIXME: If Windows truly always prevents truncating or deleting a 4574 ** file while a mapping is held, then the following winUnmapfile() call 4575 ** is unnecessary can be omitted - potentially improving 4576 ** performance. */ 4577 winUnmapfile(pFd); 4578 } 4579 4580 assert( pFd->nFetchOut>=0 ); 4581 #endif 4582 4583 OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", 4584 osGetCurrentProcessId(), fd)); 4585 return SQLITE_OK; 4586 } 4587 4588 /* 4589 ** Here ends the implementation of all sqlite3_file methods. 4590 ** 4591 ********************** End sqlite3_file Methods ******************************* 4592 ******************************************************************************/ 4593 4594 /* 4595 ** This vector defines all the methods that can operate on an 4596 ** sqlite3_file for win32. 4597 */ 4598 static const sqlite3_io_methods winIoMethod = { 4599 3, /* iVersion */ 4600 winClose, /* xClose */ 4601 winRead, /* xRead */ 4602 winWrite, /* xWrite */ 4603 winTruncate, /* xTruncate */ 4604 winSync, /* xSync */ 4605 winFileSize, /* xFileSize */ 4606 winLock, /* xLock */ 4607 winUnlock, /* xUnlock */ 4608 winCheckReservedLock, /* xCheckReservedLock */ 4609 winFileControl, /* xFileControl */ 4610 winSectorSize, /* xSectorSize */ 4611 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4612 winShmMap, /* xShmMap */ 4613 winShmLock, /* xShmLock */ 4614 winShmBarrier, /* xShmBarrier */ 4615 winShmUnmap, /* xShmUnmap */ 4616 winFetch, /* xFetch */ 4617 winUnfetch /* xUnfetch */ 4618 }; 4619 4620 /* 4621 ** This vector defines all the methods that can operate on an 4622 ** sqlite3_file for win32 without performing any locking. 4623 */ 4624 static const sqlite3_io_methods winIoNolockMethod = { 4625 3, /* iVersion */ 4626 winClose, /* xClose */ 4627 winRead, /* xRead */ 4628 winWrite, /* xWrite */ 4629 winTruncate, /* xTruncate */ 4630 winSync, /* xSync */ 4631 winFileSize, /* xFileSize */ 4632 winNolockLock, /* xLock */ 4633 winNolockUnlock, /* xUnlock */ 4634 winNolockCheckReservedLock, /* xCheckReservedLock */ 4635 winFileControl, /* xFileControl */ 4636 winSectorSize, /* xSectorSize */ 4637 winDeviceCharacteristics, /* xDeviceCharacteristics */ 4638 winShmMap, /* xShmMap */ 4639 winShmLock, /* xShmLock */ 4640 winShmBarrier, /* xShmBarrier */ 4641 winShmUnmap, /* xShmUnmap */ 4642 winFetch, /* xFetch */ 4643 winUnfetch /* xUnfetch */ 4644 }; 4645 4646 static winVfsAppData winAppData = { 4647 &winIoMethod, /* pMethod */ 4648 0, /* pAppData */ 4649 0 /* bNoLock */ 4650 }; 4651 4652 static winVfsAppData winNolockAppData = { 4653 &winIoNolockMethod, /* pMethod */ 4654 0, /* pAppData */ 4655 1 /* bNoLock */ 4656 }; 4657 4658 /**************************************************************************** 4659 **************************** sqlite3_vfs methods **************************** 4660 ** 4661 ** This division contains the implementation of methods on the 4662 ** sqlite3_vfs object. 4663 */ 4664 4665 #if defined(__CYGWIN__) 4666 /* 4667 ** Convert a filename from whatever the underlying operating system 4668 ** supports for filenames into UTF-8. Space to hold the result is 4669 ** obtained from malloc and must be freed by the calling function. 4670 */ 4671 static char *winConvertToUtf8Filename(const void *zFilename){ 4672 char *zConverted = 0; 4673 if( osIsNT() ){ 4674 zConverted = winUnicodeToUtf8(zFilename); 4675 } 4676 #ifdef SQLITE_WIN32_HAS_ANSI 4677 else{ 4678 zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); 4679 } 4680 #endif 4681 /* caller will handle out of memory */ 4682 return zConverted; 4683 } 4684 #endif 4685 4686 /* 4687 ** Convert a UTF-8 filename into whatever form the underlying 4688 ** operating system wants filenames in. Space to hold the result 4689 ** is obtained from malloc and must be freed by the calling 4690 ** function. 4691 */ 4692 static void *winConvertFromUtf8Filename(const char *zFilename){ 4693 void *zConverted = 0; 4694 if( osIsNT() ){ 4695 zConverted = winUtf8ToUnicode(zFilename); 4696 } 4697 #ifdef SQLITE_WIN32_HAS_ANSI 4698 else{ 4699 zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); 4700 } 4701 #endif 4702 /* caller will handle out of memory */ 4703 return zConverted; 4704 } 4705 4706 /* 4707 ** This function returns non-zero if the specified UTF-8 string buffer 4708 ** ends with a directory separator character or one was successfully 4709 ** added to it. 4710 */ 4711 static int winMakeEndInDirSep(int nBuf, char *zBuf){ 4712 if( zBuf ){ 4713 int nLen = sqlite3Strlen30(zBuf); 4714 if( nLen>0 ){ 4715 if( winIsDirSep(zBuf[nLen-1]) ){ 4716 return 1; 4717 }else if( nLen+1<nBuf ){ 4718 zBuf[nLen] = winGetDirSep(); 4719 zBuf[nLen+1] = '\0'; 4720 return 1; 4721 } 4722 } 4723 } 4724 return 0; 4725 } 4726 4727 /* 4728 ** If sqlite3_temp_directory is not, take the mutex and return true. 4729 ** 4730 ** If sqlite3_temp_directory is NULL, omit the mutex and return false. 4731 */ 4732 static int winTempDirDefined(void){ 4733 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 4734 if( sqlite3_temp_directory!=0 ) return 1; 4735 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 4736 return 0; 4737 } 4738 4739 /* 4740 ** Create a temporary file name and store the resulting pointer into pzBuf. 4741 ** The pointer returned in pzBuf must be freed via sqlite3_free(). 4742 */ 4743 static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ 4744 static char zChars[] = 4745 "abcdefghijklmnopqrstuvwxyz" 4746 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 4747 "0123456789"; 4748 size_t i, j; 4749 int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); 4750 int nMax, nBuf, nDir, nLen; 4751 char *zBuf; 4752 4753 /* It's odd to simulate an io-error here, but really this is just 4754 ** using the io-error infrastructure to test that SQLite handles this 4755 ** function failing. 4756 */ 4757 SimulateIOError( return SQLITE_IOERR ); 4758 4759 /* Allocate a temporary buffer to store the fully qualified file 4760 ** name for the temporary file. If this fails, we cannot continue. 4761 */ 4762 nMax = pVfs->mxPathname; nBuf = nMax + 2; 4763 zBuf = sqlite3MallocZero( nBuf ); 4764 if( !zBuf ){ 4765 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4766 return SQLITE_IOERR_NOMEM_BKPT; 4767 } 4768 4769 /* Figure out the effective temporary directory. First, check if one 4770 ** has been explicitly set by the application; otherwise, use the one 4771 ** configured by the operating system. 4772 */ 4773 nDir = nMax - (nPre + 15); 4774 assert( nDir>0 ); 4775 if( winTempDirDefined() ){ 4776 int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); 4777 if( nDirLen>0 ){ 4778 if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ 4779 nDirLen++; 4780 } 4781 if( nDirLen>nDir ){ 4782 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 4783 sqlite3_free(zBuf); 4784 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4785 return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); 4786 } 4787 sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); 4788 } 4789 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); 4790 } 4791 4792 #if defined(__CYGWIN__) 4793 else{ 4794 static const char *azDirs[] = { 4795 0, /* getenv("SQLITE_TMPDIR") */ 4796 0, /* getenv("TMPDIR") */ 4797 0, /* getenv("TMP") */ 4798 0, /* getenv("TEMP") */ 4799 0, /* getenv("USERPROFILE") */ 4800 "/var/tmp", 4801 "/usr/tmp", 4802 "/tmp", 4803 ".", 4804 0 /* List terminator */ 4805 }; 4806 unsigned int i; 4807 const char *zDir = 0; 4808 4809 if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); 4810 if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); 4811 if( !azDirs[2] ) azDirs[2] = getenv("TMP"); 4812 if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); 4813 if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); 4814 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ 4815 void *zConverted; 4816 if( zDir==0 ) continue; 4817 /* If the path starts with a drive letter followed by the colon 4818 ** character, assume it is already a native Win32 path; otherwise, 4819 ** it must be converted to a native Win32 path via the Cygwin API 4820 ** prior to using it. 4821 */ 4822 if( winIsDriveLetterAndColon(zDir) ){ 4823 zConverted = winConvertFromUtf8Filename(zDir); 4824 if( !zConverted ){ 4825 sqlite3_free(zBuf); 4826 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4827 return SQLITE_IOERR_NOMEM_BKPT; 4828 } 4829 if( winIsDir(zConverted) ){ 4830 sqlite3_snprintf(nMax, zBuf, "%s", zDir); 4831 sqlite3_free(zConverted); 4832 break; 4833 } 4834 sqlite3_free(zConverted); 4835 }else{ 4836 zConverted = sqlite3MallocZero( nMax+1 ); 4837 if( !zConverted ){ 4838 sqlite3_free(zBuf); 4839 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4840 return SQLITE_IOERR_NOMEM_BKPT; 4841 } 4842 if( cygwin_conv_path( 4843 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, 4844 zConverted, nMax+1)<0 ){ 4845 sqlite3_free(zConverted); 4846 sqlite3_free(zBuf); 4847 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); 4848 return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, 4849 "winGetTempname2", zDir); 4850 } 4851 if( winIsDir(zConverted) ){ 4852 /* At this point, we know the candidate directory exists and should 4853 ** be used. However, we may need to convert the string containing 4854 ** its name into UTF-8 (i.e. if it is UTF-16 right now). 4855 */ 4856 char *zUtf8 = winConvertToUtf8Filename(zConverted); 4857 if( !zUtf8 ){ 4858 sqlite3_free(zConverted); 4859 sqlite3_free(zBuf); 4860 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4861 return SQLITE_IOERR_NOMEM_BKPT; 4862 } 4863 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4864 sqlite3_free(zUtf8); 4865 sqlite3_free(zConverted); 4866 break; 4867 } 4868 sqlite3_free(zConverted); 4869 } 4870 } 4871 } 4872 #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) 4873 else if( osIsNT() ){ 4874 char *zMulti; 4875 LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); 4876 if( !zWidePath ){ 4877 sqlite3_free(zBuf); 4878 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4879 return SQLITE_IOERR_NOMEM_BKPT; 4880 } 4881 if( osGetTempPathW(nMax, zWidePath)==0 ){ 4882 sqlite3_free(zWidePath); 4883 sqlite3_free(zBuf); 4884 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4885 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4886 "winGetTempname2", 0); 4887 } 4888 zMulti = winUnicodeToUtf8(zWidePath); 4889 if( zMulti ){ 4890 sqlite3_snprintf(nMax, zBuf, "%s", zMulti); 4891 sqlite3_free(zMulti); 4892 sqlite3_free(zWidePath); 4893 }else{ 4894 sqlite3_free(zWidePath); 4895 sqlite3_free(zBuf); 4896 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4897 return SQLITE_IOERR_NOMEM_BKPT; 4898 } 4899 } 4900 #ifdef SQLITE_WIN32_HAS_ANSI 4901 else{ 4902 char *zUtf8; 4903 char *zMbcsPath = sqlite3MallocZero( nMax ); 4904 if( !zMbcsPath ){ 4905 sqlite3_free(zBuf); 4906 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4907 return SQLITE_IOERR_NOMEM_BKPT; 4908 } 4909 if( osGetTempPathA(nMax, zMbcsPath)==0 ){ 4910 sqlite3_free(zBuf); 4911 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); 4912 return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), 4913 "winGetTempname3", 0); 4914 } 4915 zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); 4916 if( zUtf8 ){ 4917 sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); 4918 sqlite3_free(zUtf8); 4919 }else{ 4920 sqlite3_free(zBuf); 4921 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); 4922 return SQLITE_IOERR_NOMEM_BKPT; 4923 } 4924 } 4925 #endif /* SQLITE_WIN32_HAS_ANSI */ 4926 #endif /* !SQLITE_OS_WINRT */ 4927 4928 /* 4929 ** Check to make sure the temporary directory ends with an appropriate 4930 ** separator. If it does not and there is not enough space left to add 4931 ** one, fail. 4932 */ 4933 if( !winMakeEndInDirSep(nDir+1, zBuf) ){ 4934 sqlite3_free(zBuf); 4935 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4936 return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0); 4937 } 4938 4939 /* 4940 ** Check that the output buffer is large enough for the temporary file 4941 ** name in the following format: 4942 ** 4943 ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0" 4944 ** 4945 ** If not, return SQLITE_ERROR. The number 17 is used here in order to 4946 ** account for the space used by the 15 character random suffix and the 4947 ** two trailing NUL characters. The final directory separator character 4948 ** has already added if it was not already present. 4949 */ 4950 nLen = sqlite3Strlen30(zBuf); 4951 if( (nLen + nPre + 17) > nBuf ){ 4952 sqlite3_free(zBuf); 4953 OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); 4954 return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); 4955 } 4956 4957 sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); 4958 4959 j = sqlite3Strlen30(zBuf); 4960 sqlite3_randomness(15, &zBuf[j]); 4961 for(i=0; i<15; i++, j++){ 4962 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 4963 } 4964 zBuf[j] = 0; 4965 zBuf[j+1] = 0; 4966 *pzBuf = zBuf; 4967 4968 OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); 4969 return SQLITE_OK; 4970 } 4971 4972 /* 4973 ** Return TRUE if the named file is really a directory. Return false if 4974 ** it is something other than a directory, or if there is any kind of memory 4975 ** allocation failure. 4976 */ 4977 static int winIsDir(const void *zConverted){ 4978 DWORD attr; 4979 int rc = 0; 4980 DWORD lastErrno; 4981 4982 if( osIsNT() ){ 4983 int cnt = 0; 4984 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 4985 memset(&sAttrData, 0, sizeof(sAttrData)); 4986 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 4987 GetFileExInfoStandard, 4988 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 4989 if( !rc ){ 4990 return 0; /* Invalid name? */ 4991 } 4992 attr = sAttrData.dwFileAttributes; 4993 #if SQLITE_OS_WINCE==0 4994 }else{ 4995 attr = osGetFileAttributesA((char*)zConverted); 4996 #endif 4997 } 4998 return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); 4999 } 5000 5001 /* forward reference */ 5002 static int winAccess( 5003 sqlite3_vfs *pVfs, /* Not used on win32 */ 5004 const char *zFilename, /* Name of file to check */ 5005 int flags, /* Type of test to make on this file */ 5006 int *pResOut /* OUT: Result */ 5007 ); 5008 5009 /* 5010 ** Open a file. 5011 */ 5012 static int winOpen( 5013 sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ 5014 const char *zName, /* Name of the file (UTF-8) */ 5015 sqlite3_file *id, /* Write the SQLite file handle here */ 5016 int flags, /* Open mode flags */ 5017 int *pOutFlags /* Status return flags */ 5018 ){ 5019 HANDLE h; 5020 DWORD lastErrno = 0; 5021 DWORD dwDesiredAccess; 5022 DWORD dwShareMode; 5023 DWORD dwCreationDisposition; 5024 DWORD dwFlagsAndAttributes = 0; 5025 #if SQLITE_OS_WINCE 5026 int isTemp = 0; 5027 #endif 5028 winVfsAppData *pAppData; 5029 winFile *pFile = (winFile*)id; 5030 void *zConverted; /* Filename in OS encoding */ 5031 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ 5032 int cnt = 0; 5033 5034 /* If argument zPath is a NULL pointer, this function is required to open 5035 ** a temporary file. Use this buffer to store the file name in. 5036 */ 5037 char *zTmpname = 0; /* For temporary filename, if necessary. */ 5038 5039 int rc = SQLITE_OK; /* Function Return Code */ 5040 #if !defined(NDEBUG) || SQLITE_OS_WINCE 5041 int eType = flags&0xFFFFFF00; /* Type of file to open */ 5042 #endif 5043 5044 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); 5045 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); 5046 int isCreate = (flags & SQLITE_OPEN_CREATE); 5047 int isReadonly = (flags & SQLITE_OPEN_READONLY); 5048 int isReadWrite = (flags & SQLITE_OPEN_READWRITE); 5049 5050 #ifndef NDEBUG 5051 int isOpenJournal = (isCreate && ( 5052 eType==SQLITE_OPEN_SUPER_JOURNAL 5053 || eType==SQLITE_OPEN_MAIN_JOURNAL 5054 || eType==SQLITE_OPEN_WAL 5055 )); 5056 #endif 5057 5058 OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", 5059 zUtf8Name, id, flags, pOutFlags)); 5060 5061 /* Check the following statements are true: 5062 ** 5063 ** (a) Exactly one of the READWRITE and READONLY flags must be set, and 5064 ** (b) if CREATE is set, then READWRITE must also be set, and 5065 ** (c) if EXCLUSIVE is set, then CREATE must also be set. 5066 ** (d) if DELETEONCLOSE is set, then CREATE must also be set. 5067 */ 5068 assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); 5069 assert(isCreate==0 || isReadWrite); 5070 assert(isExclusive==0 || isCreate); 5071 assert(isDelete==0 || isCreate); 5072 5073 /* The main DB, main journal, WAL file and super-journal are never 5074 ** automatically deleted. Nor are they ever temporary files. */ 5075 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); 5076 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); 5077 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL ); 5078 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); 5079 5080 /* Assert that the upper layer has set one of the "file-type" flags. */ 5081 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB 5082 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 5083 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL 5084 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL 5085 ); 5086 5087 assert( pFile!=0 ); 5088 memset(pFile, 0, sizeof(winFile)); 5089 pFile->h = INVALID_HANDLE_VALUE; 5090 5091 #if SQLITE_OS_WINRT 5092 if( !zUtf8Name && !sqlite3_temp_directory ){ 5093 sqlite3_log(SQLITE_ERROR, 5094 "sqlite3_temp_directory variable should be set for WinRT"); 5095 } 5096 #endif 5097 5098 /* If the second argument to this function is NULL, generate a 5099 ** temporary file name to use 5100 */ 5101 if( !zUtf8Name ){ 5102 assert( isDelete && !isOpenJournal ); 5103 rc = winGetTempname(pVfs, &zTmpname); 5104 if( rc!=SQLITE_OK ){ 5105 OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); 5106 return rc; 5107 } 5108 zUtf8Name = zTmpname; 5109 } 5110 5111 /* Database filenames are double-zero terminated if they are not 5112 ** URIs with parameters. Hence, they can always be passed into 5113 ** sqlite3_uri_parameter(). 5114 */ 5115 assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || 5116 zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); 5117 5118 /* Convert the filename to the system encoding. */ 5119 zConverted = winConvertFromUtf8Filename(zUtf8Name); 5120 if( zConverted==0 ){ 5121 sqlite3_free(zTmpname); 5122 OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); 5123 return SQLITE_IOERR_NOMEM_BKPT; 5124 } 5125 5126 if( winIsDir(zConverted) ){ 5127 sqlite3_free(zConverted); 5128 sqlite3_free(zTmpname); 5129 OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); 5130 return SQLITE_CANTOPEN_ISDIR; 5131 } 5132 5133 if( isReadWrite ){ 5134 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 5135 }else{ 5136 dwDesiredAccess = GENERIC_READ; 5137 } 5138 5139 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 5140 ** created. SQLite doesn't use it to indicate "exclusive access" 5141 ** as it is usually understood. 5142 */ 5143 if( isExclusive ){ 5144 /* Creates a new file, only if it does not already exist. */ 5145 /* If the file exists, it fails. */ 5146 dwCreationDisposition = CREATE_NEW; 5147 }else if( isCreate ){ 5148 /* Open existing file, or create if it doesn't exist */ 5149 dwCreationDisposition = OPEN_ALWAYS; 5150 }else{ 5151 /* Opens a file, only if it exists. */ 5152 dwCreationDisposition = OPEN_EXISTING; 5153 } 5154 5155 if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){ 5156 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 5157 }else{ 5158 dwShareMode = 0; 5159 } 5160 5161 if( isDelete ){ 5162 #if SQLITE_OS_WINCE 5163 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; 5164 isTemp = 1; 5165 #else 5166 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY 5167 | FILE_ATTRIBUTE_HIDDEN 5168 | FILE_FLAG_DELETE_ON_CLOSE; 5169 #endif 5170 }else{ 5171 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 5172 } 5173 /* Reports from the internet are that performance is always 5174 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ 5175 #if SQLITE_OS_WINCE 5176 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; 5177 #endif 5178 5179 if( osIsNT() ){ 5180 #if SQLITE_OS_WINRT 5181 CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; 5182 extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 5183 extendedParameters.dwFileAttributes = 5184 dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; 5185 extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; 5186 extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; 5187 extendedParameters.lpSecurityAttributes = NULL; 5188 extendedParameters.hTemplateFile = NULL; 5189 do{ 5190 h = osCreateFile2((LPCWSTR)zConverted, 5191 dwDesiredAccess, 5192 dwShareMode, 5193 dwCreationDisposition, 5194 &extendedParameters); 5195 if( h!=INVALID_HANDLE_VALUE ) break; 5196 if( isReadWrite ){ 5197 int rc2, isRO = 0; 5198 sqlite3BeginBenignMalloc(); 5199 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5200 sqlite3EndBenignMalloc(); 5201 if( rc2==SQLITE_OK && isRO ) break; 5202 } 5203 }while( winRetryIoerr(&cnt, &lastErrno) ); 5204 #else 5205 do{ 5206 h = osCreateFileW((LPCWSTR)zConverted, 5207 dwDesiredAccess, 5208 dwShareMode, NULL, 5209 dwCreationDisposition, 5210 dwFlagsAndAttributes, 5211 NULL); 5212 if( h!=INVALID_HANDLE_VALUE ) break; 5213 if( isReadWrite ){ 5214 int rc2, isRO = 0; 5215 sqlite3BeginBenignMalloc(); 5216 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5217 sqlite3EndBenignMalloc(); 5218 if( rc2==SQLITE_OK && isRO ) break; 5219 } 5220 }while( winRetryIoerr(&cnt, &lastErrno) ); 5221 #endif 5222 } 5223 #ifdef SQLITE_WIN32_HAS_ANSI 5224 else{ 5225 do{ 5226 h = osCreateFileA((LPCSTR)zConverted, 5227 dwDesiredAccess, 5228 dwShareMode, NULL, 5229 dwCreationDisposition, 5230 dwFlagsAndAttributes, 5231 NULL); 5232 if( h!=INVALID_HANDLE_VALUE ) break; 5233 if( isReadWrite ){ 5234 int rc2, isRO = 0; 5235 sqlite3BeginBenignMalloc(); 5236 rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); 5237 sqlite3EndBenignMalloc(); 5238 if( rc2==SQLITE_OK && isRO ) break; 5239 } 5240 }while( winRetryIoerr(&cnt, &lastErrno) ); 5241 } 5242 #endif 5243 winLogIoerr(cnt, __LINE__); 5244 5245 OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, 5246 dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5247 5248 if( h==INVALID_HANDLE_VALUE ){ 5249 sqlite3_free(zConverted); 5250 sqlite3_free(zTmpname); 5251 if( isReadWrite && !isExclusive ){ 5252 return winOpen(pVfs, zName, id, 5253 ((flags|SQLITE_OPEN_READONLY) & 5254 ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), 5255 pOutFlags); 5256 }else{ 5257 pFile->lastErrno = lastErrno; 5258 winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); 5259 return SQLITE_CANTOPEN_BKPT; 5260 } 5261 } 5262 5263 if( pOutFlags ){ 5264 if( isReadWrite ){ 5265 *pOutFlags = SQLITE_OPEN_READWRITE; 5266 }else{ 5267 *pOutFlags = SQLITE_OPEN_READONLY; 5268 } 5269 } 5270 5271 OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " 5272 "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? 5273 *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); 5274 5275 pAppData = (winVfsAppData*)pVfs->pAppData; 5276 5277 #if SQLITE_OS_WINCE 5278 { 5279 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB 5280 && ((pAppData==NULL) || !pAppData->bNoLock) 5281 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK 5282 ){ 5283 osCloseHandle(h); 5284 sqlite3_free(zConverted); 5285 sqlite3_free(zTmpname); 5286 OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); 5287 return rc; 5288 } 5289 } 5290 if( isTemp ){ 5291 pFile->zDeleteOnClose = zConverted; 5292 }else 5293 #endif 5294 { 5295 sqlite3_free(zConverted); 5296 } 5297 5298 sqlite3_free(zTmpname); 5299 id->pMethods = pAppData ? pAppData->pMethod : &winIoMethod; 5300 pFile->pVfs = pVfs; 5301 pFile->h = h; 5302 if( isReadonly ){ 5303 pFile->ctrlFlags |= WINFILE_RDONLY; 5304 } 5305 if( (flags & SQLITE_OPEN_MAIN_DB) 5306 && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) 5307 ){ 5308 pFile->ctrlFlags |= WINFILE_PSOW; 5309 } 5310 pFile->lastErrno = NO_ERROR; 5311 pFile->zPath = zName; 5312 #if SQLITE_MAX_MMAP_SIZE>0 5313 pFile->hMap = NULL; 5314 pFile->pMapRegion = 0; 5315 pFile->mmapSize = 0; 5316 pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; 5317 #endif 5318 5319 OpenCounter(+1); 5320 return rc; 5321 } 5322 5323 /* 5324 ** Delete the named file. 5325 ** 5326 ** Note that Windows does not allow a file to be deleted if some other 5327 ** process has it open. Sometimes a virus scanner or indexing program 5328 ** will open a journal file shortly after it is created in order to do 5329 ** whatever it does. While this other process is holding the 5330 ** file open, we will be unable to delete it. To work around this 5331 ** problem, we delay 100 milliseconds and try to delete again. Up 5332 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving 5333 ** up and returning an error. 5334 */ 5335 static int winDelete( 5336 sqlite3_vfs *pVfs, /* Not used on win32 */ 5337 const char *zFilename, /* Name of file to delete */ 5338 int syncDir /* Not used on win32 */ 5339 ){ 5340 int cnt = 0; 5341 int rc; 5342 DWORD attr; 5343 DWORD lastErrno = 0; 5344 void *zConverted; 5345 UNUSED_PARAMETER(pVfs); 5346 UNUSED_PARAMETER(syncDir); 5347 5348 SimulateIOError(return SQLITE_IOERR_DELETE); 5349 OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); 5350 5351 zConverted = winConvertFromUtf8Filename(zFilename); 5352 if( zConverted==0 ){ 5353 OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5354 return SQLITE_IOERR_NOMEM_BKPT; 5355 } 5356 if( osIsNT() ){ 5357 do { 5358 #if SQLITE_OS_WINRT 5359 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5360 memset(&sAttrData, 0, sizeof(sAttrData)); 5361 if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, 5362 &sAttrData) ){ 5363 attr = sAttrData.dwFileAttributes; 5364 }else{ 5365 lastErrno = osGetLastError(); 5366 if( lastErrno==ERROR_FILE_NOT_FOUND 5367 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5368 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5369 }else{ 5370 rc = SQLITE_ERROR; 5371 } 5372 break; 5373 } 5374 #else 5375 attr = osGetFileAttributesW(zConverted); 5376 #endif 5377 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5378 lastErrno = osGetLastError(); 5379 if( lastErrno==ERROR_FILE_NOT_FOUND 5380 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5381 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5382 }else{ 5383 rc = SQLITE_ERROR; 5384 } 5385 break; 5386 } 5387 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5388 rc = SQLITE_ERROR; /* Files only. */ 5389 break; 5390 } 5391 if ( osDeleteFileW(zConverted) ){ 5392 rc = SQLITE_OK; /* Deleted OK. */ 5393 break; 5394 } 5395 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5396 rc = SQLITE_ERROR; /* No more retries. */ 5397 break; 5398 } 5399 } while(1); 5400 } 5401 #ifdef SQLITE_WIN32_HAS_ANSI 5402 else{ 5403 do { 5404 attr = osGetFileAttributesA(zConverted); 5405 if ( attr==INVALID_FILE_ATTRIBUTES ){ 5406 lastErrno = osGetLastError(); 5407 if( lastErrno==ERROR_FILE_NOT_FOUND 5408 || lastErrno==ERROR_PATH_NOT_FOUND ){ 5409 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ 5410 }else{ 5411 rc = SQLITE_ERROR; 5412 } 5413 break; 5414 } 5415 if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ 5416 rc = SQLITE_ERROR; /* Files only. */ 5417 break; 5418 } 5419 if ( osDeleteFileA(zConverted) ){ 5420 rc = SQLITE_OK; /* Deleted OK. */ 5421 break; 5422 } 5423 if ( !winRetryIoerr(&cnt, &lastErrno) ){ 5424 rc = SQLITE_ERROR; /* No more retries. */ 5425 break; 5426 } 5427 } while(1); 5428 } 5429 #endif 5430 if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ 5431 rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); 5432 }else{ 5433 winLogIoerr(cnt, __LINE__); 5434 } 5435 sqlite3_free(zConverted); 5436 OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); 5437 return rc; 5438 } 5439 5440 /* 5441 ** Check the existence and status of a file. 5442 */ 5443 static int winAccess( 5444 sqlite3_vfs *pVfs, /* Not used on win32 */ 5445 const char *zFilename, /* Name of file to check */ 5446 int flags, /* Type of test to make on this file */ 5447 int *pResOut /* OUT: Result */ 5448 ){ 5449 DWORD attr; 5450 int rc = 0; 5451 DWORD lastErrno = 0; 5452 void *zConverted; 5453 UNUSED_PARAMETER(pVfs); 5454 5455 SimulateIOError( return SQLITE_IOERR_ACCESS; ); 5456 OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", 5457 zFilename, flags, pResOut)); 5458 5459 zConverted = winConvertFromUtf8Filename(zFilename); 5460 if( zConverted==0 ){ 5461 OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); 5462 return SQLITE_IOERR_NOMEM_BKPT; 5463 } 5464 if( osIsNT() ){ 5465 int cnt = 0; 5466 WIN32_FILE_ATTRIBUTE_DATA sAttrData; 5467 memset(&sAttrData, 0, sizeof(sAttrData)); 5468 while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, 5469 GetFileExInfoStandard, 5470 &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} 5471 if( rc ){ 5472 /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file 5473 ** as if it does not exist. 5474 */ 5475 if( flags==SQLITE_ACCESS_EXISTS 5476 && sAttrData.nFileSizeHigh==0 5477 && sAttrData.nFileSizeLow==0 ){ 5478 attr = INVALID_FILE_ATTRIBUTES; 5479 }else{ 5480 attr = sAttrData.dwFileAttributes; 5481 } 5482 }else{ 5483 winLogIoerr(cnt, __LINE__); 5484 if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ 5485 sqlite3_free(zConverted); 5486 return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", 5487 zFilename); 5488 }else{ 5489 attr = INVALID_FILE_ATTRIBUTES; 5490 } 5491 } 5492 } 5493 #ifdef SQLITE_WIN32_HAS_ANSI 5494 else{ 5495 attr = osGetFileAttributesA((char*)zConverted); 5496 } 5497 #endif 5498 sqlite3_free(zConverted); 5499 switch( flags ){ 5500 case SQLITE_ACCESS_READ: 5501 case SQLITE_ACCESS_EXISTS: 5502 rc = attr!=INVALID_FILE_ATTRIBUTES; 5503 break; 5504 case SQLITE_ACCESS_READWRITE: 5505 rc = attr!=INVALID_FILE_ATTRIBUTES && 5506 (attr & FILE_ATTRIBUTE_READONLY)==0; 5507 break; 5508 default: 5509 assert(!"Invalid flags argument"); 5510 } 5511 *pResOut = rc; 5512 OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", 5513 zFilename, pResOut, *pResOut)); 5514 return SQLITE_OK; 5515 } 5516 5517 /* 5518 ** Returns non-zero if the specified path name starts with the "long path" 5519 ** prefix. 5520 */ 5521 static BOOL winIsLongPathPrefix( 5522 const char *zPathname 5523 ){ 5524 return ( zPathname[0]=='\\' && zPathname[1]=='\\' 5525 && zPathname[2]=='?' && zPathname[3]=='\\' ); 5526 } 5527 5528 /* 5529 ** Returns non-zero if the specified path name starts with a drive letter 5530 ** followed by a colon character. 5531 */ 5532 static BOOL winIsDriveLetterAndColon( 5533 const char *zPathname 5534 ){ 5535 return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); 5536 } 5537 5538 /* 5539 ** Returns non-zero if the specified path name should be used verbatim. If 5540 ** non-zero is returned from this function, the calling function must simply 5541 ** use the provided path name verbatim -OR- resolve it into a full path name 5542 ** using the GetFullPathName Win32 API function (if available). 5543 */ 5544 static BOOL winIsVerbatimPathname( 5545 const char *zPathname 5546 ){ 5547 /* 5548 ** If the path name starts with a forward slash or a backslash, it is either 5549 ** a legal UNC name, a volume relative path, or an absolute path name in the 5550 ** "Unix" format on Windows. There is no easy way to differentiate between 5551 ** the final two cases; therefore, we return the safer return value of TRUE 5552 ** so that callers of this function will simply use it verbatim. 5553 */ 5554 if ( winIsDirSep(zPathname[0]) ){ 5555 return TRUE; 5556 } 5557 5558 /* 5559 ** If the path name starts with a letter and a colon it is either a volume 5560 ** relative path or an absolute path. Callers of this function must not 5561 ** attempt to treat it as a relative path name (i.e. they should simply use 5562 ** it verbatim). 5563 */ 5564 if ( winIsDriveLetterAndColon(zPathname) ){ 5565 return TRUE; 5566 } 5567 5568 /* 5569 ** If we get to this point, the path name should almost certainly be a purely 5570 ** relative one (i.e. not a UNC name, not absolute, and not volume relative). 5571 */ 5572 return FALSE; 5573 } 5574 5575 /* 5576 ** Turn a relative pathname into a full pathname. Write the full 5577 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname 5578 ** bytes in size. 5579 */ 5580 static int winFullPathnameNoMutex( 5581 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 5582 const char *zRelative, /* Possibly relative input path */ 5583 int nFull, /* Size of output buffer in bytes */ 5584 char *zFull /* Output buffer */ 5585 ){ 5586 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5587 DWORD nByte; 5588 void *zConverted; 5589 char *zOut; 5590 #endif 5591 5592 /* If this path name begins with "/X:" or "\\?\", where "X" is any 5593 ** alphabetic character, discard the initial "/" from the pathname. 5594 */ 5595 if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1) 5596 || winIsLongPathPrefix(zRelative+1)) ){ 5597 zRelative++; 5598 } 5599 5600 #if defined(__CYGWIN__) 5601 SimulateIOError( return SQLITE_ERROR ); 5602 UNUSED_PARAMETER(nFull); 5603 assert( nFull>=pVfs->mxPathname ); 5604 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5605 /* 5606 ** NOTE: We are dealing with a relative path name and the data 5607 ** directory has been set. Therefore, use it as the basis 5608 ** for converting the relative path name to an absolute 5609 ** one by prepending the data directory and a slash. 5610 */ 5611 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5612 if( !zOut ){ 5613 return SQLITE_IOERR_NOMEM_BKPT; 5614 } 5615 if( cygwin_conv_path( 5616 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | 5617 CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5618 sqlite3_free(zOut); 5619 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5620 "winFullPathname1", zRelative); 5621 }else{ 5622 char *zUtf8 = winConvertToUtf8Filename(zOut); 5623 if( !zUtf8 ){ 5624 sqlite3_free(zOut); 5625 return SQLITE_IOERR_NOMEM_BKPT; 5626 } 5627 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5628 sqlite3_data_directory, winGetDirSep(), zUtf8); 5629 sqlite3_free(zUtf8); 5630 sqlite3_free(zOut); 5631 } 5632 }else{ 5633 char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); 5634 if( !zOut ){ 5635 return SQLITE_IOERR_NOMEM_BKPT; 5636 } 5637 if( cygwin_conv_path( 5638 (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), 5639 zRelative, zOut, pVfs->mxPathname+1)<0 ){ 5640 sqlite3_free(zOut); 5641 return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, 5642 "winFullPathname2", zRelative); 5643 }else{ 5644 char *zUtf8 = winConvertToUtf8Filename(zOut); 5645 if( !zUtf8 ){ 5646 sqlite3_free(zOut); 5647 return SQLITE_IOERR_NOMEM_BKPT; 5648 } 5649 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); 5650 sqlite3_free(zUtf8); 5651 sqlite3_free(zOut); 5652 } 5653 } 5654 return SQLITE_OK; 5655 #endif 5656 5657 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) 5658 SimulateIOError( return SQLITE_ERROR ); 5659 /* WinCE has no concept of a relative pathname, or so I am told. */ 5660 /* WinRT has no way to convert a relative path to an absolute one. */ 5661 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5662 /* 5663 ** NOTE: We are dealing with a relative path name and the data 5664 ** directory has been set. Therefore, use it as the basis 5665 ** for converting the relative path name to an absolute 5666 ** one by prepending the data directory and a backslash. 5667 */ 5668 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5669 sqlite3_data_directory, winGetDirSep(), zRelative); 5670 }else{ 5671 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); 5672 } 5673 return SQLITE_OK; 5674 #endif 5675 5676 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) 5677 /* It's odd to simulate an io-error here, but really this is just 5678 ** using the io-error infrastructure to test that SQLite handles this 5679 ** function failing. This function could fail if, for example, the 5680 ** current working directory has been unlinked. 5681 */ 5682 SimulateIOError( return SQLITE_ERROR ); 5683 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ 5684 /* 5685 ** NOTE: We are dealing with a relative path name and the data 5686 ** directory has been set. Therefore, use it as the basis 5687 ** for converting the relative path name to an absolute 5688 ** one by prepending the data directory and a backslash. 5689 */ 5690 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", 5691 sqlite3_data_directory, winGetDirSep(), zRelative); 5692 return SQLITE_OK; 5693 } 5694 zConverted = winConvertFromUtf8Filename(zRelative); 5695 if( zConverted==0 ){ 5696 return SQLITE_IOERR_NOMEM_BKPT; 5697 } 5698 if( osIsNT() ){ 5699 LPWSTR zTemp; 5700 nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); 5701 if( nByte==0 ){ 5702 sqlite3_free(zConverted); 5703 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5704 "winFullPathname1", 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 = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); 5713 if( nByte==0 ){ 5714 sqlite3_free(zConverted); 5715 sqlite3_free(zTemp); 5716 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5717 "winFullPathname2", zRelative); 5718 } 5719 sqlite3_free(zConverted); 5720 zOut = winUnicodeToUtf8(zTemp); 5721 sqlite3_free(zTemp); 5722 } 5723 #ifdef SQLITE_WIN32_HAS_ANSI 5724 else{ 5725 char *zTemp; 5726 nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); 5727 if( nByte==0 ){ 5728 sqlite3_free(zConverted); 5729 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5730 "winFullPathname3", zRelative); 5731 } 5732 nByte += 3; 5733 zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); 5734 if( zTemp==0 ){ 5735 sqlite3_free(zConverted); 5736 return SQLITE_IOERR_NOMEM_BKPT; 5737 } 5738 nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); 5739 if( nByte==0 ){ 5740 sqlite3_free(zConverted); 5741 sqlite3_free(zTemp); 5742 return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), 5743 "winFullPathname4", zRelative); 5744 } 5745 sqlite3_free(zConverted); 5746 zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); 5747 sqlite3_free(zTemp); 5748 } 5749 #endif 5750 if( zOut ){ 5751 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); 5752 sqlite3_free(zOut); 5753 return SQLITE_OK; 5754 }else{ 5755 return SQLITE_IOERR_NOMEM_BKPT; 5756 } 5757 #endif 5758 } 5759 static int winFullPathname( 5760 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 5761 const char *zRelative, /* Possibly relative input path */ 5762 int nFull, /* Size of output buffer in bytes */ 5763 char *zFull /* Output buffer */ 5764 ){ 5765 int rc; 5766 MUTEX_LOGIC( sqlite3_mutex *pMutex; ) 5767 MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) 5768 sqlite3_mutex_enter(pMutex); 5769 rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); 5770 sqlite3_mutex_leave(pMutex); 5771 return rc; 5772 } 5773 5774 #ifndef SQLITE_OMIT_LOAD_EXTENSION 5775 /* 5776 ** Interfaces for opening a shared library, finding entry points 5777 ** within the shared library, and closing the shared library. 5778 */ 5779 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 5780 HANDLE h; 5781 #if defined(__CYGWIN__) 5782 int nFull = pVfs->mxPathname+1; 5783 char *zFull = sqlite3MallocZero( nFull ); 5784 void *zConverted = 0; 5785 if( zFull==0 ){ 5786 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5787 return 0; 5788 } 5789 if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ 5790 sqlite3_free(zFull); 5791 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5792 return 0; 5793 } 5794 zConverted = winConvertFromUtf8Filename(zFull); 5795 sqlite3_free(zFull); 5796 #else 5797 void *zConverted = winConvertFromUtf8Filename(zFilename); 5798 UNUSED_PARAMETER(pVfs); 5799 #endif 5800 if( zConverted==0 ){ 5801 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); 5802 return 0; 5803 } 5804 if( osIsNT() ){ 5805 #if SQLITE_OS_WINRT 5806 h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); 5807 #else 5808 h = osLoadLibraryW((LPCWSTR)zConverted); 5809 #endif 5810 } 5811 #ifdef SQLITE_WIN32_HAS_ANSI 5812 else{ 5813 h = osLoadLibraryA((char*)zConverted); 5814 } 5815 #endif 5816 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); 5817 sqlite3_free(zConverted); 5818 return (void*)h; 5819 } 5820 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 5821 UNUSED_PARAMETER(pVfs); 5822 winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); 5823 } 5824 static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ 5825 FARPROC proc; 5826 UNUSED_PARAMETER(pVfs); 5827 proc = osGetProcAddressA((HANDLE)pH, zSym); 5828 OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", 5829 (void*)pH, zSym, (void*)proc)); 5830 return (void(*)(void))proc; 5831 } 5832 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ 5833 UNUSED_PARAMETER(pVfs); 5834 osFreeLibrary((HANDLE)pHandle); 5835 OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); 5836 } 5837 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 5838 #define winDlOpen 0 5839 #define winDlError 0 5840 #define winDlSym 0 5841 #define winDlClose 0 5842 #endif 5843 5844 /* State information for the randomness gatherer. */ 5845 typedef struct EntropyGatherer EntropyGatherer; 5846 struct EntropyGatherer { 5847 unsigned char *a; /* Gather entropy into this buffer */ 5848 int na; /* Size of a[] in bytes */ 5849 int i; /* XOR next input into a[i] */ 5850 int nXor; /* Number of XOR operations done */ 5851 }; 5852 5853 #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) 5854 /* Mix sz bytes of entropy into p. */ 5855 static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ 5856 int j, k; 5857 for(j=0, k=p->i; j<sz; j++){ 5858 p->a[k++] ^= x[j]; 5859 if( k>=p->na ) k = 0; 5860 } 5861 p->i = k; 5862 p->nXor += sz; 5863 } 5864 #endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ 5865 5866 /* 5867 ** Write up to nBuf bytes of randomness into zBuf. 5868 */ 5869 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 5870 #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) 5871 UNUSED_PARAMETER(pVfs); 5872 memset(zBuf, 0, nBuf); 5873 return nBuf; 5874 #else 5875 EntropyGatherer e; 5876 UNUSED_PARAMETER(pVfs); 5877 memset(zBuf, 0, nBuf); 5878 e.a = (unsigned char*)zBuf; 5879 e.na = nBuf; 5880 e.nXor = 0; 5881 e.i = 0; 5882 { 5883 SYSTEMTIME x; 5884 osGetSystemTime(&x); 5885 xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); 5886 } 5887 { 5888 DWORD pid = osGetCurrentProcessId(); 5889 xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); 5890 } 5891 #if SQLITE_OS_WINRT 5892 { 5893 ULONGLONG cnt = osGetTickCount64(); 5894 xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); 5895 } 5896 #else 5897 { 5898 DWORD cnt = osGetTickCount(); 5899 xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); 5900 } 5901 #endif /* SQLITE_OS_WINRT */ 5902 { 5903 LARGE_INTEGER i; 5904 osQueryPerformanceCounter(&i); 5905 xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); 5906 } 5907 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID 5908 { 5909 UUID id; 5910 memset(&id, 0, sizeof(UUID)); 5911 osUuidCreate(&id); 5912 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5913 memset(&id, 0, sizeof(UUID)); 5914 osUuidCreateSequential(&id); 5915 xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); 5916 } 5917 #endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ 5918 return e.nXor>nBuf ? nBuf : e.nXor; 5919 #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ 5920 } 5921 5922 5923 /* 5924 ** Sleep for a little while. Return the amount of time slept. 5925 */ 5926 static int winSleep(sqlite3_vfs *pVfs, int microsec){ 5927 sqlite3_win32_sleep((microsec+999)/1000); 5928 UNUSED_PARAMETER(pVfs); 5929 return ((microsec+999)/1000)*1000; 5930 } 5931 5932 /* 5933 ** The following variable, if set to a non-zero value, is interpreted as 5934 ** the number of seconds since 1970 and is used to set the result of 5935 ** sqlite3OsCurrentTime() during testing. 5936 */ 5937 #ifdef SQLITE_TEST 5938 int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ 5939 #endif 5940 5941 /* 5942 ** Find the current time (in Universal Coordinated Time). Write into *piNow 5943 ** the current time and date as a Julian Day number times 86_400_000. In 5944 ** other words, write into *piNow the number of milliseconds since the Julian 5945 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the 5946 ** proleptic Gregorian calendar. 5947 ** 5948 ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date 5949 ** cannot be found. 5950 */ 5951 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ 5952 /* FILETIME structure is a 64-bit value representing the number of 5953 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 5954 */ 5955 FILETIME ft; 5956 static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; 5957 #ifdef SQLITE_TEST 5958 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; 5959 #endif 5960 /* 2^32 - to avoid use of LL and warnings in gcc */ 5961 static const sqlite3_int64 max32BitValue = 5962 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + 5963 (sqlite3_int64)294967296; 5964 5965 #if SQLITE_OS_WINCE 5966 SYSTEMTIME time; 5967 osGetSystemTime(&time); 5968 /* if SystemTimeToFileTime() fails, it returns zero. */ 5969 if (!osSystemTimeToFileTime(&time,&ft)){ 5970 return SQLITE_ERROR; 5971 } 5972 #else 5973 osGetSystemTimeAsFileTime( &ft ); 5974 #endif 5975 5976 *piNow = winFiletimeEpoch + 5977 ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 5978 (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; 5979 5980 #ifdef SQLITE_TEST 5981 if( sqlite3_current_time ){ 5982 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; 5983 } 5984 #endif 5985 UNUSED_PARAMETER(pVfs); 5986 return SQLITE_OK; 5987 } 5988 5989 /* 5990 ** Find the current time (in Universal Coordinated Time). Write the 5991 ** current time and date as a Julian Day number into *prNow and 5992 ** return 0. Return 1 if the time and date cannot be found. 5993 */ 5994 static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ 5995 int rc; 5996 sqlite3_int64 i; 5997 rc = winCurrentTimeInt64(pVfs, &i); 5998 if( !rc ){ 5999 *prNow = i/86400000.0; 6000 } 6001 return rc; 6002 } 6003 6004 /* 6005 ** The idea is that this function works like a combination of 6006 ** GetLastError() and FormatMessage() on Windows (or errno and 6007 ** strerror_r() on Unix). After an error is returned by an OS 6008 ** function, SQLite calls this function with zBuf pointing to 6009 ** a buffer of nBuf bytes. The OS layer should populate the 6010 ** buffer with a nul-terminated UTF-8 encoded error message 6011 ** describing the last IO error to have occurred within the calling 6012 ** thread. 6013 ** 6014 ** If the error message is too large for the supplied buffer, 6015 ** it should be truncated. The return value of xGetLastError 6016 ** is zero if the error message fits in the buffer, or non-zero 6017 ** otherwise (if the message was truncated). If non-zero is returned, 6018 ** then it is not necessary to include the nul-terminator character 6019 ** in the output buffer. 6020 ** 6021 ** Not supplying an error message will have no adverse effect 6022 ** on SQLite. It is fine to have an implementation that never 6023 ** returns an error message: 6024 ** 6025 ** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 6026 ** assert(zBuf[0]=='\0'); 6027 ** return 0; 6028 ** } 6029 ** 6030 ** However if an error message is supplied, it will be incorporated 6031 ** by sqlite into the error message available to the user using 6032 ** sqlite3_errmsg(), possibly making IO errors easier to debug. 6033 */ 6034 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 6035 DWORD e = osGetLastError(); 6036 UNUSED_PARAMETER(pVfs); 6037 if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); 6038 return e; 6039 } 6040 6041 /* 6042 ** Initialize and deinitialize the operating system interface. 6043 */ 6044 int sqlite3_os_init(void){ 6045 static sqlite3_vfs winVfs = { 6046 3, /* iVersion */ 6047 sizeof(winFile), /* szOsFile */ 6048 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 6049 0, /* pNext */ 6050 "win32", /* zName */ 6051 &winAppData, /* pAppData */ 6052 winOpen, /* xOpen */ 6053 winDelete, /* xDelete */ 6054 winAccess, /* xAccess */ 6055 winFullPathname, /* xFullPathname */ 6056 winDlOpen, /* xDlOpen */ 6057 winDlError, /* xDlError */ 6058 winDlSym, /* xDlSym */ 6059 winDlClose, /* xDlClose */ 6060 winRandomness, /* xRandomness */ 6061 winSleep, /* xSleep */ 6062 winCurrentTime, /* xCurrentTime */ 6063 winGetLastError, /* xGetLastError */ 6064 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6065 winSetSystemCall, /* xSetSystemCall */ 6066 winGetSystemCall, /* xGetSystemCall */ 6067 winNextSystemCall, /* xNextSystemCall */ 6068 }; 6069 #if defined(SQLITE_WIN32_HAS_WIDE) 6070 static sqlite3_vfs winLongPathVfs = { 6071 3, /* iVersion */ 6072 sizeof(winFile), /* szOsFile */ 6073 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 6074 0, /* pNext */ 6075 "win32-longpath", /* zName */ 6076 &winAppData, /* pAppData */ 6077 winOpen, /* xOpen */ 6078 winDelete, /* xDelete */ 6079 winAccess, /* xAccess */ 6080 winFullPathname, /* xFullPathname */ 6081 winDlOpen, /* xDlOpen */ 6082 winDlError, /* xDlError */ 6083 winDlSym, /* xDlSym */ 6084 winDlClose, /* xDlClose */ 6085 winRandomness, /* xRandomness */ 6086 winSleep, /* xSleep */ 6087 winCurrentTime, /* xCurrentTime */ 6088 winGetLastError, /* xGetLastError */ 6089 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6090 winSetSystemCall, /* xSetSystemCall */ 6091 winGetSystemCall, /* xGetSystemCall */ 6092 winNextSystemCall, /* xNextSystemCall */ 6093 }; 6094 #endif 6095 static sqlite3_vfs winNolockVfs = { 6096 3, /* iVersion */ 6097 sizeof(winFile), /* szOsFile */ 6098 SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ 6099 0, /* pNext */ 6100 "win32-none", /* zName */ 6101 &winNolockAppData, /* pAppData */ 6102 winOpen, /* xOpen */ 6103 winDelete, /* xDelete */ 6104 winAccess, /* xAccess */ 6105 winFullPathname, /* xFullPathname */ 6106 winDlOpen, /* xDlOpen */ 6107 winDlError, /* xDlError */ 6108 winDlSym, /* xDlSym */ 6109 winDlClose, /* xDlClose */ 6110 winRandomness, /* xRandomness */ 6111 winSleep, /* xSleep */ 6112 winCurrentTime, /* xCurrentTime */ 6113 winGetLastError, /* xGetLastError */ 6114 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6115 winSetSystemCall, /* xSetSystemCall */ 6116 winGetSystemCall, /* xGetSystemCall */ 6117 winNextSystemCall, /* xNextSystemCall */ 6118 }; 6119 #if defined(SQLITE_WIN32_HAS_WIDE) 6120 static sqlite3_vfs winLongPathNolockVfs = { 6121 3, /* iVersion */ 6122 sizeof(winFile), /* szOsFile */ 6123 SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ 6124 0, /* pNext */ 6125 "win32-longpath-none", /* zName */ 6126 &winNolockAppData, /* pAppData */ 6127 winOpen, /* xOpen */ 6128 winDelete, /* xDelete */ 6129 winAccess, /* xAccess */ 6130 winFullPathname, /* xFullPathname */ 6131 winDlOpen, /* xDlOpen */ 6132 winDlError, /* xDlError */ 6133 winDlSym, /* xDlSym */ 6134 winDlClose, /* xDlClose */ 6135 winRandomness, /* xRandomness */ 6136 winSleep, /* xSleep */ 6137 winCurrentTime, /* xCurrentTime */ 6138 winGetLastError, /* xGetLastError */ 6139 winCurrentTimeInt64, /* xCurrentTimeInt64 */ 6140 winSetSystemCall, /* xSetSystemCall */ 6141 winGetSystemCall, /* xGetSystemCall */ 6142 winNextSystemCall, /* xNextSystemCall */ 6143 }; 6144 #endif 6145 6146 /* Double-check that the aSyscall[] array has been constructed 6147 ** correctly. See ticket [bb3a86e890c8e96ab] */ 6148 assert( ArraySize(aSyscall)==80 ); 6149 6150 /* get memory map allocation granularity */ 6151 memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); 6152 #if SQLITE_OS_WINRT 6153 osGetNativeSystemInfo(&winSysInfo); 6154 #else 6155 osGetSystemInfo(&winSysInfo); 6156 #endif 6157 assert( winSysInfo.dwAllocationGranularity>0 ); 6158 assert( winSysInfo.dwPageSize>0 ); 6159 6160 sqlite3_vfs_register(&winVfs, 1); 6161 6162 #if defined(SQLITE_WIN32_HAS_WIDE) 6163 sqlite3_vfs_register(&winLongPathVfs, 0); 6164 #endif 6165 6166 sqlite3_vfs_register(&winNolockVfs, 0); 6167 6168 #if defined(SQLITE_WIN32_HAS_WIDE) 6169 sqlite3_vfs_register(&winLongPathNolockVfs, 0); 6170 #endif 6171 6172 #ifndef SQLITE_OMIT_WAL 6173 winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); 6174 #endif 6175 6176 return SQLITE_OK; 6177 } 6178 6179 int sqlite3_os_end(void){ 6180 #if SQLITE_OS_WINRT 6181 if( sleepObj!=NULL ){ 6182 osCloseHandle(sleepObj); 6183 sleepObj = NULL; 6184 } 6185 #endif 6186 6187 #ifndef SQLITE_OMIT_WAL 6188 winBigLock = 0; 6189 #endif 6190 6191 return SQLITE_OK; 6192 } 6193 6194 #endif /* SQLITE_OS_WIN */ 6195