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