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