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