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