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