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