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 OS_WIN /* This file is used for windows only */ 17 18 19 /* 20 ** A Note About Memory Allocation: 21 ** 22 ** This driver uses malloc()/free() directly rather than going through 23 ** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers 24 ** are designed for use on embedded systems where memory is scarce and 25 ** malloc failures happen frequently. Win32 does not typically run on 26 ** embedded systems, and when it does the developers normally have bigger 27 ** problems to worry about than running out of memory. So there is not 28 ** a compelling need to use the wrappers. 29 ** 30 ** But there is a good reason to not use the wrappers. If we use the 31 ** wrappers then we will get simulated malloc() failures within this 32 ** driver. And that causes all kinds of problems for our tests. We 33 ** could enhance SQLite to deal with simulated malloc failures within 34 ** the OS driver, but the code to deal with those failure would not 35 ** be exercised on Linux (which does not need to malloc() in the driver) 36 ** and so we would have difficulty writing coverage tests for that 37 ** code. Better to leave the code out, we think. 38 ** 39 ** The point of this discussion is as follows: When creating a new 40 ** OS layer for an embedded system, if you use this file as an example, 41 ** avoid the use of malloc()/free(). Those routines work ok on windows 42 ** desktops but not so well in embedded systems. 43 */ 44 45 #include <winbase.h> 46 47 #ifdef __CYGWIN__ 48 # include <sys/cygwin.h> 49 #endif 50 51 /* 52 ** Macros used to determine whether or not to use threads. 53 */ 54 #if defined(THREADSAFE) && THREADSAFE 55 # define SQLITE_W32_THREADS 1 56 #endif 57 58 /* 59 ** Include code that is common to all os_*.c files 60 */ 61 #include "os_common.h" 62 63 /* 64 ** Determine if we are dealing with WindowsCE - which has a much 65 ** reduced API. 66 */ 67 #if defined(_WIN32_WCE) 68 # define OS_WINCE 1 69 # define AreFileApisANSI() 1 70 #else 71 # define OS_WINCE 0 72 #endif 73 74 /* 75 ** WinCE lacks native support for file locking so we have to fake it 76 ** with some code of our own. 77 */ 78 #if OS_WINCE 79 typedef struct winceLock { 80 int nReaders; /* Number of reader locks obtained */ 81 BOOL bPending; /* Indicates a pending lock has been obtained */ 82 BOOL bReserved; /* Indicates a reserved lock has been obtained */ 83 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ 84 } winceLock; 85 #endif 86 87 /* 88 ** The winFile structure is a subclass of sqlite3_file* specific to the win32 89 ** portability layer. 90 */ 91 typedef struct winFile winFile; 92 struct winFile { 93 const sqlite3_io_methods *pMethod;/* Must be first */ 94 HANDLE h; /* Handle for accessing the file */ 95 unsigned char locktype; /* Type of lock currently held on this file */ 96 short sharedLockByte; /* Randomly chosen byte used as a shared lock */ 97 #if OS_WINCE 98 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ 99 HANDLE hMutex; /* Mutex used to control access to shared lock */ 100 HANDLE hShared; /* Shared memory segment used for locking */ 101 winceLock local; /* Locks obtained by this instance of winFile */ 102 winceLock *shared; /* Global shared lock memory for the file */ 103 #endif 104 }; 105 106 107 /* 108 ** The following variable is (normally) set once and never changes 109 ** thereafter. It records whether the operating system is Win95 110 ** or WinNT. 111 ** 112 ** 0: Operating system unknown. 113 ** 1: Operating system is Win95. 114 ** 2: Operating system is WinNT. 115 ** 116 ** In order to facilitate testing on a WinNT system, the test fixture 117 ** can manually set this value to 1 to emulate Win98 behavior. 118 */ 119 #ifdef SQLITE_TEST 120 int sqlite3_os_type = 0; 121 #else 122 static int sqlite3_os_type = 0; 123 #endif 124 125 /* 126 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, 127 ** or WinCE. Return false (zero) for Win95, Win98, or WinME. 128 ** 129 ** Here is an interesting observation: Win95, Win98, and WinME lack 130 ** the LockFileEx() API. But we can still statically link against that 131 ** API as long as we don't call it win running Win95/98/ME. A call to 132 ** this routine is used to determine if the host is Win95/98/ME or 133 ** WinNT/2K/XP so that we will know whether or not we can safely call 134 ** the LockFileEx() API. 135 */ 136 #if OS_WINCE 137 # define isNT() (1) 138 #else 139 static int isNT(void){ 140 if( sqlite3_os_type==0 ){ 141 OSVERSIONINFO sInfo; 142 sInfo.dwOSVersionInfoSize = sizeof(sInfo); 143 GetVersionEx(&sInfo); 144 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; 145 } 146 return sqlite3_os_type==2; 147 } 148 #endif /* OS_WINCE */ 149 150 /* 151 ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 152 ** 153 ** Space to hold the returned string is obtained from malloc. 154 */ 155 static WCHAR *utf8ToUnicode(const char *zFilename){ 156 int nChar; 157 WCHAR *zWideFilename; 158 159 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); 160 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); 161 if( zWideFilename==0 ){ 162 return 0; 163 } 164 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); 165 if( nChar==0 ){ 166 free(zWideFilename); 167 zWideFilename = 0; 168 } 169 return zWideFilename; 170 } 171 172 /* 173 ** Convert microsoft unicode to UTF-8. Space to hold the returned string is 174 ** obtained from malloc(). 175 */ 176 static char *unicodeToUtf8(const WCHAR *zWideFilename){ 177 int nByte; 178 char *zFilename; 179 180 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); 181 zFilename = malloc( nByte ); 182 if( zFilename==0 ){ 183 return 0; 184 } 185 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, 186 0, 0); 187 if( nByte == 0 ){ 188 free(zFilename); 189 zFilename = 0; 190 } 191 return zFilename; 192 } 193 194 /* 195 ** Convert an ansi string to microsoft unicode, based on the 196 ** current codepage settings for file apis. 197 ** 198 ** Space to hold the returned string is obtained 199 ** from malloc. 200 */ 201 static WCHAR *mbcsToUnicode(const char *zFilename){ 202 int nByte; 203 WCHAR *zMbcsFilename; 204 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; 205 206 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); 207 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); 208 if( zMbcsFilename==0 ){ 209 return 0; 210 } 211 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); 212 if( nByte==0 ){ 213 free(zMbcsFilename); 214 zMbcsFilename = 0; 215 } 216 return zMbcsFilename; 217 } 218 219 /* 220 ** Convert microsoft unicode to multibyte character string, based on the 221 ** user's Ansi codepage. 222 ** 223 ** Space to hold the returned string is obtained from 224 ** malloc(). 225 */ 226 static char *unicodeToMbcs(const WCHAR *zWideFilename){ 227 int nByte; 228 char *zFilename; 229 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; 230 231 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); 232 zFilename = malloc( nByte ); 233 if( zFilename==0 ){ 234 return 0; 235 } 236 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, 237 0, 0); 238 if( nByte == 0 ){ 239 free(zFilename); 240 zFilename = 0; 241 } 242 return zFilename; 243 } 244 245 /* 246 ** Convert multibyte character string to UTF-8. Space to hold the 247 ** returned string is obtained from malloc(). 248 */ 249 static char *mbcsToUtf8(const char *zFilename){ 250 char *zFilenameUtf8; 251 WCHAR *zTmpWide; 252 253 zTmpWide = mbcsToUnicode(zFilename); 254 if( zTmpWide==0 ){ 255 return 0; 256 } 257 zFilenameUtf8 = unicodeToUtf8(zTmpWide); 258 free(zTmpWide); 259 return zFilenameUtf8; 260 } 261 262 /* 263 ** Convert UTF-8 to multibyte character string. Space to hold the 264 ** returned string is obtained from malloc(). 265 */ 266 static char *utf8ToMbcs(const char *zFilename){ 267 char *zFilenameMbcs; 268 WCHAR *zTmpWide; 269 270 zTmpWide = utf8ToUnicode(zFilename); 271 if( zTmpWide==0 ){ 272 return 0; 273 } 274 zFilenameMbcs = unicodeToMbcs(zTmpWide); 275 free(zTmpWide); 276 return zFilenameMbcs; 277 } 278 279 #if OS_WINCE 280 /************************************************************************* 281 ** This section contains code for WinCE only. 282 */ 283 /* 284 ** WindowsCE does not have a localtime() function. So create a 285 ** substitute. 286 */ 287 #include <time.h> 288 struct tm *__cdecl localtime(const time_t *t) 289 { 290 static struct tm y; 291 FILETIME uTm, lTm; 292 SYSTEMTIME pTm; 293 sqlite3_int64 t64; 294 t64 = *t; 295 t64 = (t64 + 11644473600)*10000000; 296 uTm.dwLowDateTime = t64 & 0xFFFFFFFF; 297 uTm.dwHighDateTime= t64 >> 32; 298 FileTimeToLocalFileTime(&uTm,&lTm); 299 FileTimeToSystemTime(&lTm,&pTm); 300 y.tm_year = pTm.wYear - 1900; 301 y.tm_mon = pTm.wMonth - 1; 302 y.tm_wday = pTm.wDayOfWeek; 303 y.tm_mday = pTm.wDay; 304 y.tm_hour = pTm.wHour; 305 y.tm_min = pTm.wMinute; 306 y.tm_sec = pTm.wSecond; 307 return &y; 308 } 309 310 /* This will never be called, but defined to make the code compile */ 311 #define GetTempPathA(a,b) 312 313 #define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) 314 #define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) 315 #define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) 316 317 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)] 318 319 /* 320 ** Acquire a lock on the handle h 321 */ 322 static void winceMutexAcquire(HANDLE h){ 323 DWORD dwErr; 324 do { 325 dwErr = WaitForSingleObject(h, INFINITE); 326 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); 327 } 328 /* 329 ** Release a lock acquired by winceMutexAcquire() 330 */ 331 #define winceMutexRelease(h) ReleaseMutex(h) 332 333 /* 334 ** Create the mutex and shared memory used for locking in the file 335 ** descriptor pFile 336 */ 337 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ 338 WCHAR *zTok; 339 WCHAR *zName = utf8ToUnicode(zFilename); 340 BOOL bInit = TRUE; 341 342 /* Initialize the local lockdata */ 343 ZeroMemory(&pFile->local, sizeof(pFile->local)); 344 345 /* Replace the backslashes from the filename and lowercase it 346 ** to derive a mutex name. */ 347 zTok = CharLowerW(zName); 348 for (;*zTok;zTok++){ 349 if (*zTok == '\\') *zTok = '_'; 350 } 351 352 /* Create/open the named mutex */ 353 pFile->hMutex = CreateMutexW(NULL, FALSE, zName); 354 if (!pFile->hMutex){ 355 free(zName); 356 return FALSE; 357 } 358 359 /* Acquire the mutex before continuing */ 360 winceMutexAcquire(pFile->hMutex); 361 362 /* Since the names of named mutexes, semaphores, file mappings etc are 363 ** case-sensitive, take advantage of that by uppercasing the mutex name 364 ** and using that as the shared filemapping name. 365 */ 366 CharUpperW(zName); 367 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, 368 PAGE_READWRITE, 0, sizeof(winceLock), 369 zName); 370 371 /* Set a flag that indicates we're the first to create the memory so it 372 ** must be zero-initialized */ 373 if (GetLastError() == ERROR_ALREADY_EXISTS){ 374 bInit = FALSE; 375 } 376 377 free(zName); 378 379 /* If we succeeded in making the shared memory handle, map it. */ 380 if (pFile->hShared){ 381 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 382 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); 383 /* If mapping failed, close the shared memory handle and erase it */ 384 if (!pFile->shared){ 385 CloseHandle(pFile->hShared); 386 pFile->hShared = NULL; 387 } 388 } 389 390 /* If shared memory could not be created, then close the mutex and fail */ 391 if (pFile->hShared == NULL){ 392 winceMutexRelease(pFile->hMutex); 393 CloseHandle(pFile->hMutex); 394 pFile->hMutex = NULL; 395 return FALSE; 396 } 397 398 /* Initialize the shared memory if we're supposed to */ 399 if (bInit) { 400 ZeroMemory(pFile->shared, sizeof(winceLock)); 401 } 402 403 winceMutexRelease(pFile->hMutex); 404 return TRUE; 405 } 406 407 /* 408 ** Destroy the part of winFile that deals with wince locks 409 */ 410 static void winceDestroyLock(winFile *pFile){ 411 if (pFile->hMutex){ 412 /* Acquire the mutex */ 413 winceMutexAcquire(pFile->hMutex); 414 415 /* The following blocks should probably assert in debug mode, but they 416 are to cleanup in case any locks remained open */ 417 if (pFile->local.nReaders){ 418 pFile->shared->nReaders --; 419 } 420 if (pFile->local.bReserved){ 421 pFile->shared->bReserved = FALSE; 422 } 423 if (pFile->local.bPending){ 424 pFile->shared->bPending = FALSE; 425 } 426 if (pFile->local.bExclusive){ 427 pFile->shared->bExclusive = FALSE; 428 } 429 430 /* De-reference and close our copy of the shared memory handle */ 431 UnmapViewOfFile(pFile->shared); 432 CloseHandle(pFile->hShared); 433 434 /* Done with the mutex */ 435 winceMutexRelease(pFile->hMutex); 436 CloseHandle(pFile->hMutex); 437 pFile->hMutex = NULL; 438 } 439 } 440 441 /* 442 ** An implementation of the LockFile() API of windows for wince 443 */ 444 static BOOL winceLockFile( 445 HANDLE *phFile, 446 DWORD dwFileOffsetLow, 447 DWORD dwFileOffsetHigh, 448 DWORD nNumberOfBytesToLockLow, 449 DWORD nNumberOfBytesToLockHigh 450 ){ 451 winFile *pFile = HANDLE_TO_WINFILE(phFile); 452 BOOL bReturn = FALSE; 453 454 if (!pFile->hMutex) return TRUE; 455 winceMutexAcquire(pFile->hMutex); 456 457 /* Wanting an exclusive lock? */ 458 if (dwFileOffsetLow == SHARED_FIRST 459 && nNumberOfBytesToLockLow == SHARED_SIZE){ 460 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ 461 pFile->shared->bExclusive = TRUE; 462 pFile->local.bExclusive = TRUE; 463 bReturn = TRUE; 464 } 465 } 466 467 /* Want a read-only lock? */ 468 else if ((dwFileOffsetLow >= SHARED_FIRST && 469 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && 470 nNumberOfBytesToLockLow == 1){ 471 if (pFile->shared->bExclusive == 0){ 472 pFile->local.nReaders ++; 473 if (pFile->local.nReaders == 1){ 474 pFile->shared->nReaders ++; 475 } 476 bReturn = TRUE; 477 } 478 } 479 480 /* Want a pending lock? */ 481 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){ 482 /* If no pending lock has been acquired, then acquire it */ 483 if (pFile->shared->bPending == 0) { 484 pFile->shared->bPending = TRUE; 485 pFile->local.bPending = TRUE; 486 bReturn = TRUE; 487 } 488 } 489 /* Want a reserved lock? */ 490 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ 491 if (pFile->shared->bReserved == 0) { 492 pFile->shared->bReserved = TRUE; 493 pFile->local.bReserved = TRUE; 494 bReturn = TRUE; 495 } 496 } 497 498 winceMutexRelease(pFile->hMutex); 499 return bReturn; 500 } 501 502 /* 503 ** An implementation of the UnlockFile API of windows for wince 504 */ 505 static BOOL winceUnlockFile( 506 HANDLE *phFile, 507 DWORD dwFileOffsetLow, 508 DWORD dwFileOffsetHigh, 509 DWORD nNumberOfBytesToUnlockLow, 510 DWORD nNumberOfBytesToUnlockHigh 511 ){ 512 winFile *pFile = HANDLE_TO_WINFILE(phFile); 513 BOOL bReturn = FALSE; 514 515 if (!pFile->hMutex) return TRUE; 516 winceMutexAcquire(pFile->hMutex); 517 518 /* Releasing a reader lock or an exclusive lock */ 519 if (dwFileOffsetLow >= SHARED_FIRST && 520 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){ 521 /* Did we have an exclusive lock? */ 522 if (pFile->local.bExclusive){ 523 pFile->local.bExclusive = FALSE; 524 pFile->shared->bExclusive = FALSE; 525 bReturn = TRUE; 526 } 527 528 /* Did we just have a reader lock? */ 529 else if (pFile->local.nReaders){ 530 pFile->local.nReaders --; 531 if (pFile->local.nReaders == 0) 532 { 533 pFile->shared->nReaders --; 534 } 535 bReturn = TRUE; 536 } 537 } 538 539 /* Releasing a pending lock */ 540 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ 541 if (pFile->local.bPending){ 542 pFile->local.bPending = FALSE; 543 pFile->shared->bPending = FALSE; 544 bReturn = TRUE; 545 } 546 } 547 /* Releasing a reserved lock */ 548 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ 549 if (pFile->local.bReserved) { 550 pFile->local.bReserved = FALSE; 551 pFile->shared->bReserved = FALSE; 552 bReturn = TRUE; 553 } 554 } 555 556 winceMutexRelease(pFile->hMutex); 557 return bReturn; 558 } 559 560 /* 561 ** An implementation of the LockFileEx() API of windows for wince 562 */ 563 static BOOL winceLockFileEx( 564 HANDLE *phFile, 565 DWORD dwFlags, 566 DWORD dwReserved, 567 DWORD nNumberOfBytesToLockLow, 568 DWORD nNumberOfBytesToLockHigh, 569 LPOVERLAPPED lpOverlapped 570 ){ 571 /* If the caller wants a shared read lock, forward this call 572 ** to winceLockFile */ 573 if (lpOverlapped->Offset == SHARED_FIRST && 574 dwFlags == 1 && 575 nNumberOfBytesToLockLow == SHARED_SIZE){ 576 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); 577 } 578 return FALSE; 579 } 580 /* 581 ** End of the special code for wince 582 *****************************************************************************/ 583 #endif /* OS_WINCE */ 584 585 /***************************************************************************** 586 ** The next group of routines implement the I/O methods specified 587 ** by the sqlite3_io_methods object. 588 ******************************************************************************/ 589 590 /* 591 ** Close a file. 592 ** 593 ** It is reported that an attempt to close a handle might sometimes 594 ** fail. This is a very unreasonable result, but windows is notorious 595 ** for being unreasonable so I do not doubt that it might happen. If 596 ** the close fails, we pause for 100 milliseconds and try again. As 597 ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before 598 ** giving up and returning an error. 599 */ 600 #define MX_CLOSE_ATTEMPT 3 601 static int winClose(sqlite3_file *id){ 602 int rc, cnt = 0; 603 winFile *pFile = (winFile*)id; 604 OSTRACE2("CLOSE %d\n", pFile->h); 605 do{ 606 rc = CloseHandle(pFile->h); 607 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); 608 #if OS_WINCE 609 winceDestroyLock(pFile); 610 if( pFile->zDeleteOnClose ){ 611 DeleteFileW(pFile->zDeleteOnClose); 612 free(pFile->zDeleteOnClose); 613 } 614 #endif 615 OpenCounter(-1); 616 return rc ? SQLITE_OK : SQLITE_IOERR; 617 } 618 619 /* 620 ** Some microsoft compilers lack this definition. 621 */ 622 #ifndef INVALID_SET_FILE_POINTER 623 # define INVALID_SET_FILE_POINTER ((DWORD)-1) 624 #endif 625 626 /* 627 ** Read data from a file into a buffer. Return SQLITE_OK if all 628 ** bytes were read successfully and SQLITE_IOERR if anything goes 629 ** wrong. 630 */ 631 static int winRead( 632 sqlite3_file *id, /* File to read from */ 633 void *pBuf, /* Write content into this buffer */ 634 int amt, /* Number of bytes to read */ 635 sqlite3_int64 offset /* Begin reading at this offset */ 636 ){ 637 LONG upperBits = (offset>>32) & 0x7fffffff; 638 LONG lowerBits = offset & 0xffffffff; 639 DWORD rc; 640 DWORD got; 641 winFile *pFile = (winFile*)id; 642 assert( id!=0 ); 643 SimulateIOError(return SQLITE_IOERR_READ); 644 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); 645 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 646 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ 647 return SQLITE_FULL; 648 } 649 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ 650 return SQLITE_IOERR_READ; 651 } 652 if( got==(DWORD)amt ){ 653 return SQLITE_OK; 654 }else{ 655 memset(&((char*)pBuf)[got], 0, amt-got); 656 return SQLITE_IOERR_SHORT_READ; 657 } 658 } 659 660 /* 661 ** Write data from a buffer into a file. Return SQLITE_OK on success 662 ** or some other error code on failure. 663 */ 664 static int winWrite( 665 sqlite3_file *id, /* File to write into */ 666 const void *pBuf, /* The bytes to be written */ 667 int amt, /* Number of bytes to write */ 668 sqlite3_int64 offset /* Offset into the file to begin writing at */ 669 ){ 670 LONG upperBits = (offset>>32) & 0x7fffffff; 671 LONG lowerBits = offset & 0xffffffff; 672 DWORD rc; 673 DWORD wrote; 674 winFile *pFile = (winFile*)id; 675 assert( id!=0 ); 676 SimulateIOError(return SQLITE_IOERR_WRITE); 677 SimulateDiskfullError(return SQLITE_FULL); 678 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); 679 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 680 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ 681 return SQLITE_FULL; 682 } 683 assert( amt>0 ); 684 while( 685 amt>0 686 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 687 && wrote>0 688 ){ 689 amt -= wrote; 690 pBuf = &((char*)pBuf)[wrote]; 691 } 692 if( !rc || amt>(int)wrote ){ 693 return SQLITE_FULL; 694 } 695 return SQLITE_OK; 696 } 697 698 /* 699 ** Truncate an open file to a specified size 700 */ 701 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ 702 LONG upperBits = (nByte>>32) & 0x7fffffff; 703 LONG lowerBits = nByte & 0xffffffff; 704 winFile *pFile = (winFile*)id; 705 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); 706 SimulateIOError(return SQLITE_IOERR_TRUNCATE); 707 SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 708 SetEndOfFile(pFile->h); 709 return SQLITE_OK; 710 } 711 712 #ifdef SQLITE_TEST 713 /* 714 ** Count the number of fullsyncs and normal syncs. This is used to test 715 ** that syncs and fullsyncs are occuring at the right times. 716 */ 717 int sqlite3_sync_count = 0; 718 int sqlite3_fullsync_count = 0; 719 #endif 720 721 /* 722 ** Make sure all writes to a particular file are committed to disk. 723 */ 724 static int winSync(sqlite3_file *id, int flags){ 725 winFile *pFile = (winFile*)id; 726 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); 727 #ifdef SQLITE_TEST 728 if( flags & SQLITE_SYNC_FULL ){ 729 sqlite3_fullsync_count++; 730 } 731 sqlite3_sync_count++; 732 #endif 733 if( FlushFileBuffers(pFile->h) ){ 734 return SQLITE_OK; 735 }else{ 736 return SQLITE_IOERR; 737 } 738 } 739 740 /* 741 ** Determine the current size of a file in bytes 742 */ 743 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ 744 winFile *pFile = (winFile*)id; 745 DWORD upperBits, lowerBits; 746 SimulateIOError(return SQLITE_IOERR_FSTAT); 747 lowerBits = GetFileSize(pFile->h, &upperBits); 748 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; 749 return SQLITE_OK; 750 } 751 752 /* 753 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. 754 */ 755 #ifndef LOCKFILE_FAIL_IMMEDIATELY 756 # define LOCKFILE_FAIL_IMMEDIATELY 1 757 #endif 758 759 /* 760 ** Acquire a reader lock. 761 ** Different API routines are called depending on whether or not this 762 ** is Win95 or WinNT. 763 */ 764 static int getReadLock(winFile *pFile){ 765 int res; 766 if( isNT() ){ 767 OVERLAPPED ovlp; 768 ovlp.Offset = SHARED_FIRST; 769 ovlp.OffsetHigh = 0; 770 ovlp.hEvent = 0; 771 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, 772 0, SHARED_SIZE, 0, &ovlp); 773 }else{ 774 int lk; 775 sqlite3Randomness(sizeof(lk), &lk); 776 pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); 777 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 778 } 779 return res; 780 } 781 782 /* 783 ** Undo a readlock 784 */ 785 static int unlockReadLock(winFile *pFile){ 786 int res; 787 if( isNT() ){ 788 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 789 }else{ 790 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); 791 } 792 return res; 793 } 794 795 /* 796 ** Lock the file with the lock specified by parameter locktype - one 797 ** of the following: 798 ** 799 ** (1) SHARED_LOCK 800 ** (2) RESERVED_LOCK 801 ** (3) PENDING_LOCK 802 ** (4) EXCLUSIVE_LOCK 803 ** 804 ** Sometimes when requesting one lock state, additional lock states 805 ** are inserted in between. The locking might fail on one of the later 806 ** transitions leaving the lock state different from what it started but 807 ** still short of its goal. The following chart shows the allowed 808 ** transitions and the inserted intermediate states: 809 ** 810 ** UNLOCKED -> SHARED 811 ** SHARED -> RESERVED 812 ** SHARED -> (PENDING) -> EXCLUSIVE 813 ** RESERVED -> (PENDING) -> EXCLUSIVE 814 ** PENDING -> EXCLUSIVE 815 ** 816 ** This routine will only increase a lock. The winUnlock() routine 817 ** erases all locks at once and returns us immediately to locking level 0. 818 ** It is not possible to lower the locking level one step at a time. You 819 ** must go straight to locking level 0. 820 */ 821 static int winLock(sqlite3_file *id, int locktype){ 822 int rc = SQLITE_OK; /* Return code from subroutines */ 823 int res = 1; /* Result of a windows lock call */ 824 int newLocktype; /* Set pFile->locktype to this value before exiting */ 825 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ 826 winFile *pFile = (winFile*)id; 827 828 assert( pFile!=0 ); 829 OSTRACE5("LOCK %d %d was %d(%d)\n", 830 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); 831 832 /* If there is already a lock of this type or more restrictive on the 833 ** OsFile, do nothing. Don't use the end_lock: exit path, as 834 ** sqlite3OsEnterMutex() hasn't been called yet. 835 */ 836 if( pFile->locktype>=locktype ){ 837 return SQLITE_OK; 838 } 839 840 /* Make sure the locking sequence is correct 841 */ 842 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); 843 assert( locktype!=PENDING_LOCK ); 844 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); 845 846 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or 847 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of 848 ** the PENDING_LOCK byte is temporary. 849 */ 850 newLocktype = pFile->locktype; 851 if( pFile->locktype==NO_LOCK 852 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) 853 ){ 854 int cnt = 3; 855 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ 856 /* Try 3 times to get the pending lock. The pending lock might be 857 ** held by another reader process who will release it momentarily. 858 */ 859 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); 860 Sleep(1); 861 } 862 gotPendingLock = res; 863 } 864 865 /* Acquire a shared lock 866 */ 867 if( locktype==SHARED_LOCK && res ){ 868 assert( pFile->locktype==NO_LOCK ); 869 res = getReadLock(pFile); 870 if( res ){ 871 newLocktype = SHARED_LOCK; 872 } 873 } 874 875 /* Acquire a RESERVED lock 876 */ 877 if( locktype==RESERVED_LOCK && res ){ 878 assert( pFile->locktype==SHARED_LOCK ); 879 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 880 if( res ){ 881 newLocktype = RESERVED_LOCK; 882 } 883 } 884 885 /* Acquire a PENDING lock 886 */ 887 if( locktype==EXCLUSIVE_LOCK && res ){ 888 newLocktype = PENDING_LOCK; 889 gotPendingLock = 0; 890 } 891 892 /* Acquire an EXCLUSIVE lock 893 */ 894 if( locktype==EXCLUSIVE_LOCK && res ){ 895 assert( pFile->locktype>=SHARED_LOCK ); 896 res = unlockReadLock(pFile); 897 OSTRACE2("unreadlock = %d\n", res); 898 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 899 if( res ){ 900 newLocktype = EXCLUSIVE_LOCK; 901 }else{ 902 OSTRACE2("error-code = %d\n", GetLastError()); 903 getReadLock(pFile); 904 } 905 } 906 907 /* If we are holding a PENDING lock that ought to be released, then 908 ** release it now. 909 */ 910 if( gotPendingLock && locktype==SHARED_LOCK ){ 911 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); 912 } 913 914 /* Update the state of the lock has held in the file descriptor then 915 ** return the appropriate result code. 916 */ 917 if( res ){ 918 rc = SQLITE_OK; 919 }else{ 920 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h, 921 locktype, newLocktype); 922 rc = SQLITE_BUSY; 923 } 924 pFile->locktype = newLocktype; 925 return rc; 926 } 927 928 /* 929 ** This routine checks if there is a RESERVED lock held on the specified 930 ** file by this or any other process. If such a lock is held, return 931 ** non-zero, otherwise zero. 932 */ 933 static int winCheckReservedLock(sqlite3_file *id){ 934 int rc; 935 winFile *pFile = (winFile*)id; 936 assert( pFile!=0 ); 937 if( pFile->locktype>=RESERVED_LOCK ){ 938 rc = 1; 939 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); 940 }else{ 941 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 942 if( rc ){ 943 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 944 } 945 rc = !rc; 946 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); 947 } 948 return rc; 949 } 950 951 /* 952 ** Lower the locking level on file descriptor id to locktype. locktype 953 ** must be either NO_LOCK or SHARED_LOCK. 954 ** 955 ** If the locking level of the file descriptor is already at or below 956 ** the requested locking level, this routine is a no-op. 957 ** 958 ** It is not possible for this routine to fail if the second argument 959 ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine 960 ** might return SQLITE_IOERR; 961 */ 962 static int winUnlock(sqlite3_file *id, int locktype){ 963 int type; 964 winFile *pFile = (winFile*)id; 965 int rc = SQLITE_OK; 966 assert( pFile!=0 ); 967 assert( locktype<=SHARED_LOCK ); 968 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, 969 pFile->locktype, pFile->sharedLockByte); 970 type = pFile->locktype; 971 if( type>=EXCLUSIVE_LOCK ){ 972 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 973 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ 974 /* This should never happen. We should always be able to 975 ** reacquire the read lock */ 976 rc = SQLITE_IOERR_UNLOCK; 977 } 978 } 979 if( type>=RESERVED_LOCK ){ 980 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 981 } 982 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ 983 unlockReadLock(pFile); 984 } 985 if( type>=PENDING_LOCK ){ 986 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); 987 } 988 pFile->locktype = locktype; 989 return rc; 990 } 991 992 /* 993 ** Control and query of the open file handle. 994 */ 995 static int winFileControl(sqlite3_file *id, int op, void *pArg){ 996 switch( op ){ 997 case SQLITE_FCNTL_LOCKSTATE: { 998 *(int*)pArg = ((winFile*)id)->locktype; 999 return SQLITE_OK; 1000 } 1001 } 1002 return SQLITE_ERROR; 1003 } 1004 1005 /* 1006 ** Return the sector size in bytes of the underlying block device for 1007 ** the specified file. This is almost always 512 bytes, but may be 1008 ** larger for some devices. 1009 ** 1010 ** SQLite code assumes this function cannot fail. It also assumes that 1011 ** if two files are created in the same file-system directory (i.e. 1012 ** a database and it's journal file) that the sector size will be the 1013 ** same for both. 1014 */ 1015 static int winSectorSize(sqlite3_file *id){ 1016 return SQLITE_DEFAULT_SECTOR_SIZE; 1017 } 1018 1019 /* 1020 ** Return a vector of device characteristics. 1021 */ 1022 static int winDeviceCharacteristics(sqlite3_file *id){ 1023 return 0; 1024 } 1025 1026 /* 1027 ** This vector defines all the methods that can operate on an 1028 ** sqlite3_file for win32. 1029 */ 1030 static const sqlite3_io_methods winIoMethod = { 1031 1, /* iVersion */ 1032 winClose, 1033 winRead, 1034 winWrite, 1035 winTruncate, 1036 winSync, 1037 winFileSize, 1038 winLock, 1039 winUnlock, 1040 winCheckReservedLock, 1041 winFileControl, 1042 winSectorSize, 1043 winDeviceCharacteristics 1044 }; 1045 1046 /*************************************************************************** 1047 ** Here ends the I/O methods that form the sqlite3_io_methods object. 1048 ** 1049 ** The next block of code implements the VFS methods. 1050 ****************************************************************************/ 1051 1052 /* 1053 ** Convert a UTF-8 filename into whatever form the underlying 1054 ** operating system wants filenames in. Space to hold the result 1055 ** is obtained from malloc and must be freed by the calling 1056 ** function. 1057 */ 1058 static void *convertUtf8Filename(const char *zFilename){ 1059 void *zConverted = 0; 1060 if( isNT() ){ 1061 zConverted = utf8ToUnicode(zFilename); 1062 }else{ 1063 zConverted = utf8ToMbcs(zFilename); 1064 } 1065 /* caller will handle out of memory */ 1066 return zConverted; 1067 } 1068 1069 /* 1070 ** Open a file. 1071 */ 1072 static int winOpen( 1073 sqlite3_vfs *pVfs, /* Not used */ 1074 const char *zName, /* Name of the file (UTF-8) */ 1075 sqlite3_file *id, /* Write the SQLite file handle here */ 1076 int flags, /* Open mode flags */ 1077 int *pOutFlags /* Status return flags */ 1078 ){ 1079 HANDLE h; 1080 DWORD dwDesiredAccess; 1081 DWORD dwShareMode; 1082 DWORD dwCreationDisposition; 1083 DWORD dwFlagsAndAttributes = 0; 1084 int isTemp; 1085 winFile *pFile = (winFile*)id; 1086 void *zConverted = convertUtf8Filename(zName); 1087 if( zConverted==0 ){ 1088 return SQLITE_NOMEM; 1089 } 1090 1091 if( flags & SQLITE_OPEN_READWRITE ){ 1092 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 1093 }else{ 1094 dwDesiredAccess = GENERIC_READ; 1095 } 1096 if( flags & SQLITE_OPEN_CREATE ){ 1097 dwCreationDisposition = OPEN_ALWAYS; 1098 }else{ 1099 dwCreationDisposition = OPEN_EXISTING; 1100 } 1101 if( flags & SQLITE_OPEN_MAIN_DB ){ 1102 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 1103 }else{ 1104 dwShareMode = 0; 1105 } 1106 if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL 1107 | SQLITE_OPEN_SUBJOURNAL) ){ 1108 #if OS_WINCE 1109 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; 1110 #else 1111 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY 1112 | FILE_ATTRIBUTE_HIDDEN 1113 | FILE_FLAG_DELETE_ON_CLOSE; 1114 #endif 1115 isTemp = 1; 1116 }else{ 1117 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 1118 isTemp = 0; 1119 } 1120 /* Reports from the internet are that performance is always 1121 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ 1122 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; 1123 if( isNT() ){ 1124 h = CreateFileW((WCHAR*)zConverted, 1125 dwDesiredAccess, 1126 dwShareMode, 1127 NULL, 1128 dwCreationDisposition, 1129 dwFlagsAndAttributes, 1130 NULL 1131 ); 1132 }else{ 1133 #if OS_WINCE 1134 return SQLITE_NOMEM; 1135 #else 1136 h = CreateFileA((char*)zConverted, 1137 dwDesiredAccess, 1138 dwShareMode, 1139 NULL, 1140 dwCreationDisposition, 1141 dwFlagsAndAttributes, 1142 NULL 1143 ); 1144 #endif 1145 } 1146 if( h==INVALID_HANDLE_VALUE ){ 1147 free(zConverted); 1148 if( flags & SQLITE_OPEN_READWRITE ){ 1149 return winOpen(0, zName, id, 1150 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); 1151 }else{ 1152 return SQLITE_CANTOPEN; 1153 } 1154 } 1155 if( pOutFlags ){ 1156 if( flags & SQLITE_OPEN_READWRITE ){ 1157 *pOutFlags = SQLITE_OPEN_READWRITE; 1158 }else{ 1159 *pOutFlags = SQLITE_OPEN_READONLY; 1160 } 1161 } 1162 memset(pFile, 0, sizeof(*pFile)); 1163 pFile->pMethod = &winIoMethod; 1164 pFile->h = h; 1165 #if OS_WINCE 1166 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == 1167 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) 1168 && !winceCreateLock(zName, pFile) 1169 ){ 1170 CloseHandle(h); 1171 free(zConverted); 1172 return SQLITE_CANTOPEN; 1173 } 1174 if( isTemp ){ 1175 pFile->zDeleteOnClose = zConverted; 1176 }else 1177 #endif 1178 { 1179 free(zConverted); 1180 } 1181 OpenCounter(+1); 1182 return SQLITE_OK; 1183 } 1184 1185 /* 1186 ** Delete the named file. 1187 ** 1188 ** Note that windows does not allow a file to be deleted if some other 1189 ** process has it open. Sometimes a virus scanner or indexing program 1190 ** will open a journal file shortly after it is created in order to do 1191 ** whatever does. While this other process is holding the 1192 ** file open, we will be unable to delete it. To work around this 1193 ** problem, we delay 100 milliseconds and try to delete again. Up 1194 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving 1195 ** up and returning an error. 1196 */ 1197 #define MX_DELETION_ATTEMPTS 5 1198 static int winDelete( 1199 sqlite3_vfs *pVfs, /* Not used on win32 */ 1200 const char *zFilename, /* Name of file to delete */ 1201 int syncDir /* Not used on win32 */ 1202 ){ 1203 int cnt = 0; 1204 int rc; 1205 void *zConverted = convertUtf8Filename(zFilename); 1206 if( zConverted==0 ){ 1207 return SQLITE_NOMEM; 1208 } 1209 SimulateIOError(return SQLITE_IOERR_DELETE); 1210 if( isNT() ){ 1211 do{ 1212 DeleteFileW(zConverted); 1213 }while( (rc = GetFileAttributesW(zConverted))!=0xffffffff 1214 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); 1215 }else{ 1216 #if OS_WINCE 1217 return SQLITE_NOMEM; 1218 #else 1219 do{ 1220 DeleteFileA(zConverted); 1221 }while( (rc = GetFileAttributesA(zConverted))!=0xffffffff 1222 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); 1223 #endif 1224 } 1225 free(zConverted); 1226 OSTRACE2("DELETE \"%s\"\n", zFilename); 1227 return rc==0xffffffff ? SQLITE_OK : SQLITE_IOERR_DELETE; 1228 } 1229 1230 /* 1231 ** Check the existance and status of a file. 1232 */ 1233 static int winAccess( 1234 sqlite3_vfs *pVfs, /* Not used on win32 */ 1235 const char *zFilename, /* Name of file to check */ 1236 int flags /* Type of test to make on this file */ 1237 ){ 1238 DWORD attr; 1239 int rc; 1240 void *zConverted = convertUtf8Filename(zFilename); 1241 if( zConverted==0 ){ 1242 return SQLITE_NOMEM; 1243 } 1244 if( isNT() ){ 1245 attr = GetFileAttributesW((WCHAR*)zConverted); 1246 }else{ 1247 #if OS_WINCE 1248 return SQLITE_NOMEM; 1249 #else 1250 attr = GetFileAttributesA((char*)zConverted); 1251 #endif 1252 } 1253 free(zConverted); 1254 switch( flags ){ 1255 case SQLITE_ACCESS_READ: 1256 case SQLITE_ACCESS_EXISTS: 1257 rc = attr!=0xffffffff; 1258 break; 1259 case SQLITE_ACCESS_READWRITE: 1260 rc = (attr & FILE_ATTRIBUTE_READONLY)==0; 1261 break; 1262 default: 1263 assert(!"Invalid flags argument"); 1264 } 1265 return rc; 1266 } 1267 1268 1269 /* 1270 ** Create a temporary file name in zBuf. zBuf must be big enough to 1271 ** hold at pVfs->mxPathname characters. 1272 */ 1273 static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1274 static char zChars[] = 1275 "abcdefghijklmnopqrstuvwxyz" 1276 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1277 "0123456789"; 1278 int i, j; 1279 char zTempPath[MAX_PATH+1]; 1280 if( sqlite3_temp_directory ){ 1281 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); 1282 }else if( isNT() ){ 1283 char *zMulti; 1284 WCHAR zWidePath[MAX_PATH]; 1285 GetTempPathW(MAX_PATH-30, zWidePath); 1286 zMulti = unicodeToUtf8(zWidePath); 1287 if( zMulti ){ 1288 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); 1289 free(zMulti); 1290 }else{ 1291 return SQLITE_NOMEM; 1292 } 1293 }else{ 1294 char *zUtf8; 1295 char zMbcsPath[MAX_PATH]; 1296 GetTempPathA(MAX_PATH-30, zMbcsPath); 1297 zUtf8 = mbcsToUtf8(zMbcsPath); 1298 if( zUtf8 ){ 1299 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); 1300 free(zUtf8); 1301 }else{ 1302 return SQLITE_NOMEM; 1303 } 1304 } 1305 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} 1306 zTempPath[i] = 0; 1307 sqlite3_snprintf(pVfs->mxPathname-30, zBuf, 1308 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); 1309 j = strlen(zBuf); 1310 sqlite3Randomness(20, &zBuf[j]); 1311 for(i=0; i<20; i++, j++){ 1312 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 1313 } 1314 zBuf[j] = 0; 1315 OSTRACE2("TEMP FILENAME: %s\n", zBuf); 1316 return SQLITE_OK; 1317 } 1318 1319 /* 1320 ** Turn a relative pathname into a full pathname. Write the full 1321 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname 1322 ** bytes in size. 1323 */ 1324 static int winFullPathname( 1325 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 1326 const char *zRelative, /* Possibly relative input path */ 1327 int nFull, /* Size of output buffer in bytes */ 1328 char *zFull /* Output buffer */ 1329 ){ 1330 1331 #if defined(__CYGWIN__) 1332 cygwin_conv_to_full_win32_path(zRelative, zFull); 1333 return SQLITE_OK; 1334 #endif 1335 1336 #if OS_WINCE 1337 /* WinCE has no concept of a relative pathname, or so I am told. */ 1338 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); 1339 return SQLITE_OK; 1340 #endif 1341 1342 #if !OS_WINCE && !defined(__CYGWIN__) 1343 int nByte; 1344 void *zConverted; 1345 char *zOut; 1346 zConverted = convertUtf8Filename(zRelative); 1347 if( isNT() ){ 1348 WCHAR *zTemp; 1349 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; 1350 zTemp = malloc( nByte*sizeof(zTemp[0]) ); 1351 if( zTemp==0 ){ 1352 free(zConverted); 1353 return SQLITE_NOMEM; 1354 } 1355 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); 1356 free(zConverted); 1357 zOut = unicodeToUtf8(zTemp); 1358 free(zTemp); 1359 }else{ 1360 char *zTemp; 1361 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; 1362 zTemp = malloc( nByte*sizeof(zTemp[0]) ); 1363 if( zTemp==0 ){ 1364 free(zConverted); 1365 return SQLITE_NOMEM; 1366 } 1367 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); 1368 free(zConverted); 1369 zOut = mbcsToUtf8(zTemp); 1370 free(zTemp); 1371 } 1372 if( zOut ){ 1373 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); 1374 free(zOut); 1375 return SQLITE_OK; 1376 }else{ 1377 return SQLITE_NOMEM; 1378 } 1379 #endif 1380 } 1381 1382 #ifndef SQLITE_OMIT_LOAD_EXTENSION 1383 /* 1384 ** Interfaces for opening a shared library, finding entry points 1385 ** within the shared library, and closing the shared library. 1386 */ 1387 /* 1388 ** Interfaces for opening a shared library, finding entry points 1389 ** within the shared library, and closing the shared library. 1390 */ 1391 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 1392 HANDLE h; 1393 void *zConverted = convertUtf8Filename(zFilename); 1394 if( zConverted==0 ){ 1395 return 0; 1396 } 1397 if( isNT() ){ 1398 h = LoadLibraryW((WCHAR*)zConverted); 1399 }else{ 1400 #if OS_WINCE 1401 return 0; 1402 #else 1403 h = LoadLibraryA((char*)zConverted); 1404 #endif 1405 } 1406 free(zConverted); 1407 return (void*)h; 1408 } 1409 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 1410 #if OS_WINCE 1411 int error = GetLastError(); 1412 if( error>0x7FFFFFF ){ 1413 sqlite3_snprintf(nBuf, zBufOut, "OsError 0x%x", error); 1414 }else{ 1415 sqlite3_snprintf(nBuf, zBufOut, "OsError %d", error); 1416 } 1417 #else 1418 FormatMessageA( 1419 FORMAT_MESSAGE_FROM_SYSTEM, 1420 NULL, 1421 GetLastError(), 1422 0, 1423 zBufOut, 1424 nBuf-1, 1425 0 1426 ); 1427 #endif 1428 } 1429 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ 1430 #if OS_WINCE 1431 /* The GetProcAddressA() routine is only available on wince. */ 1432 return GetProcAddressA((HANDLE)pHandle, zSymbol); 1433 #else 1434 /* All other windows platforms expect GetProcAddress() to take 1435 ** an Ansi string regardless of the _UNICODE setting */ 1436 return GetProcAddress((HANDLE)pHandle, zSymbol); 1437 #endif 1438 } 1439 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ 1440 FreeLibrary((HANDLE)pHandle); 1441 } 1442 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 1443 #define winDlOpen 0 1444 #define winDlError 0 1445 #define winDlSym 0 1446 #define winDlClose 0 1447 #endif 1448 1449 1450 /* 1451 ** Write up to nBuf bytes of randomness into zBuf. 1452 */ 1453 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1454 int n = 0; 1455 if( sizeof(SYSTEMTIME)<=nBuf-n ){ 1456 SYSTEMTIME x; 1457 GetSystemTime(&x); 1458 memcpy(&zBuf[n], &x, sizeof(x)); 1459 n += sizeof(x); 1460 } 1461 if( sizeof(DWORD)<=nBuf-n ){ 1462 DWORD pid = GetCurrentProcessId(); 1463 memcpy(&zBuf[n], &pid, sizeof(pid)); 1464 n += sizeof(pid); 1465 } 1466 if( sizeof(DWORD)<=nBuf-n ){ 1467 DWORD cnt = GetTickCount(); 1468 memcpy(&zBuf[n], &cnt, sizeof(cnt)); 1469 n += sizeof(cnt); 1470 } 1471 if( sizeof(LARGE_INTEGER)<=nBuf-n ){ 1472 LARGE_INTEGER i; 1473 QueryPerformanceCounter(&i); 1474 memcpy(&zBuf[n], &i, sizeof(i)); 1475 n += sizeof(i); 1476 } 1477 return n; 1478 } 1479 1480 1481 /* 1482 ** Sleep for a little while. Return the amount of time slept. 1483 */ 1484 static int winSleep(sqlite3_vfs *pVfs, int microsec){ 1485 Sleep((microsec+999)/1000); 1486 return ((microsec+999)/1000)*1000; 1487 } 1488 1489 /* 1490 ** The following variable, if set to a non-zero value, becomes the result 1491 ** returned from sqlite3OsCurrentTime(). This is used for testing. 1492 */ 1493 #ifdef SQLITE_TEST 1494 int sqlite3_current_time = 0; 1495 #endif 1496 1497 /* 1498 ** Find the current time (in Universal Coordinated Time). Write the 1499 ** current time and date as a Julian Day number into *prNow and 1500 ** return 0. Return 1 if the time and date cannot be found. 1501 */ 1502 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ 1503 FILETIME ft; 1504 /* FILETIME structure is a 64-bit value representing the number of 1505 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 1506 */ 1507 double now; 1508 #if OS_WINCE 1509 SYSTEMTIME time; 1510 GetSystemTime(&time); 1511 SystemTimeToFileTime(&time,&ft); 1512 #else 1513 GetSystemTimeAsFileTime( &ft ); 1514 #endif 1515 now = ((double)ft.dwHighDateTime) * 4294967296.0; 1516 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5; 1517 #ifdef SQLITE_TEST 1518 if( sqlite3_current_time ){ 1519 *prNow = sqlite3_current_time/86400.0 + 2440587.5; 1520 } 1521 #endif 1522 return 0; 1523 } 1524 1525 1526 /* 1527 ** Return a pointer to the sqlite3DefaultVfs structure. We use 1528 ** a function rather than give the structure global scope because 1529 ** some compilers (MSVC) do not allow forward declarations of 1530 ** initialized structures. 1531 */ 1532 sqlite3_vfs *sqlite3OsDefaultVfs(void){ 1533 static sqlite3_vfs winVfs = { 1534 1, /* iVersion */ 1535 sizeof(winFile), /* szOsFile */ 1536 MAX_PATH, /* mxPathname */ 1537 0, /* pNext */ 1538 "win32", /* zName */ 1539 0, /* pAppData */ 1540 1541 winOpen, /* xOpen */ 1542 winDelete, /* xDelete */ 1543 winAccess, /* xAccess */ 1544 winGetTempname, /* xGetTempName */ 1545 winFullPathname, /* xFullPathname */ 1546 winDlOpen, /* xDlOpen */ 1547 winDlError, /* xDlError */ 1548 winDlSym, /* xDlSym */ 1549 winDlClose, /* xDlClose */ 1550 winRandomness, /* xRandomness */ 1551 winSleep, /* xSleep */ 1552 winCurrentTime /* xCurrentTime */ 1553 }; 1554 1555 return &winVfs; 1556 } 1557 1558 #endif /* OS_WIN */ 1559